Docker Kurulumu: VDS Sunucuya Docker ve Docker Compose Kurma Rehberi
Ubuntu 24.04 ve Debian 13 VDS'inize Docker'ı resmi depodan kurun, Docker Compose ile örnek bir uygulama çalıştırın, verileri kalıcı volume'larda tutun ve UFW'yi atlayan Docker port tuzağını kapatın.

Docker, bir uygulamayı ihtiyaç duyduğu her şeyle birlikte paketleyip tek komutla çalıştırmanızı sağlar. VDS'inize bir web uygulaması, bot, izleme aracı ya da veritabanı kurarken "bende çalışıyordu" sorununu ortadan kaldırır; uygulamaları birbirinden ayırır, güncellemeyi ve taşımayı kolaylaştırır. Bu rehberde Docker'ı resmi Docker deposundan kuruyor, Docker Compose ile örnek bir uygulama ayağa kaldırıyor, verileri kalıcı volume'larda tutuyor ve VDS sahiplerinin en sık düştüğü güvenlik duvarı port tuzağını nasıl kapatacağınızı gösteriyoruz.
Komutlar Ubuntu 24.04 ve Debian 13 için yazıldı; AlmaLinux 8 için farklı olan adımlar ayrıca belirtildi. Örneklerdeki 203.0.113.10 yerine kendi VDS IP adresinizi kullanın.
Docker mı, Doğrudan Kurulum mu?
Docker her iş için şart değildir. Tek bir web sitesi yayınlayacaksanız Nginx, PHP ve veritabanını doğrudan sunucuya kurmak daha az katman demektir. Docker şu durumlarda öne çıkar:
- Aynı sunucuda farklı sürüm isteyen uygulamalar çalıştıracaksanız (ör. biri PHP 8.1, diğeri PHP 8.3 isteyen iki proje).
- Uygulamanın geliştiricisi hazır bir Docker imajı ve compose dosyası sunuyorsa (izleme araçları, otomasyon araçları, botlar, oyun sunucusu yönetim panelleri).
- Uygulamayı ileride başka bir sunucuya taşımayı düşünüyorsanız; compose dosyası ve volume yedekleriyle taşıma birkaç komuta iner.
- Denemeler yapıp sunucuyu kirletmeden geri almak istiyorsanız; kapsayıcıyı silmek, kurduğunuz her şeyi siler.
Başlamadan Önce
- İşletim sistemi: Docker'ın resmi deposu Ubuntu 24.04 ve Debian 13'ü destekler. Ubuntu 20.04'ün standart desteği sona erdiği için Docker artık bu sürümü resmi olarak desteklemiyor. Sunucunuz Ubuntu 20.04 ise, verilerinizi yedekledikten sonra panelden yeniden kurulum yapıp Ubuntu 24.04 seçmeniz en temiz yoldur.
- Kaynak: Docker'ın kendisi çok az kaynak harcar; asıl ihtiyacı çalıştıracağınız kapsayıcılar belirler. Birkaç küçük servis için 2 GB RAM yeterlidir, veritabanı ve birden fazla uygulama için 4 GB ve üzerini planlayın.
- Temel güvenlik: Docker'dan önce SSH anahtarı, sudo kullanıcısı ve güvenlik duvarı ayarlarını yapmanızı öneririz. Adımlar Ubuntu Sunucu Güvenliği rehberimizde.
1. Adım: Çakışan Eski Paketleri Kaldırın
Dağıtımların kendi depolarında docker.io gibi resmi olmayan paketler bulunur ve Docker'ın resmi paketleriyle çakışır. Kurulumdan önce varsa kaldırın:
sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)
Bu paketlerden hiçbiri kurulu değilse apt bir şey kaldırmaz; bu normaldir. /var/lib/docker altındaki eski kapsayıcı verileri bu komutla silinmez.
2. Adım: Resmi Docker Deposunu Ekleyin
Önce Docker'ın imza anahtarını indirin:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Ardından depoyu tanımlayın:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Debian 13 kullanıyorsanız iki komutta da linux/ubuntu yerine linux/debian yazın. Suites satırı sürüm adını (Ubuntu 24.04 için noble, Debian 13 için trixie) kendiliğinden bulur.
3. Adım: Docker Engine ve Compose Eklentisini Kurun
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Kurulumla birlikte Docker servisi başlar ve açılışta otomatik çalışacak şekilde ayarlanır. Doğrulamak için:
sudo systemctl is-active docker
docker --version
docker compose version
sudo docker run --rm hello-world
hello-world kapsayıcısı "Hello from Docker!" mesajını yazdırıyorsa kurulum tamamdır.

Eski rehberlerdeki
docker-compose(tireli) komutu ayrı bir programdı ve artık geliştirilmiyor. Güncel kullanımdocker compose(boşluklu) eklentisidir; bu rehberdeki tüm komutlar bu biçimdedir.
AlmaLinux 8'de kurulum
AlmaLinux 8'de Docker, RHEL deposundan kurulur. Sistemde Podman ve Buildah kuruluysa önce bunları kaldırın:
sudo dnf remove -y podman buildah runc
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
GPG anahtarı sorulursa parmak izini onaylayın. Bu adımdan sonraki bölümler tüm dağıtımlarda aynıdır.
4. Adım: Docker'ı sudo Olmadan Kullanmak (Dikkatle)
Varsayılan olarak docker komutları sudo ister. Kendi kullanıcınızı docker grubuna eklerseniz sudo'suz çalıştırabilirsiniz:
sudo usermod -aG docker $USER
Değişikliğin geçerli olması için oturumu kapatıp yeniden açın. Önemli: docker grubundaki bir kullanıcı pratikte root yetkisine sahiptir; çünkü bir kapsayıcıya sunucunun tüm diskini bağlayabilir. Bu grubu yalnız sunucuyu yöneten kendi kullanıcınıza verin.
5. Adım: Örnek Uygulama: Docker Compose ile WordPress
Compose, birden fazla kapsayıcıyı tek bir YAML dosyasında tanımlamanızı sağlar. Örnek olarak bir WordPress sitesi ile MariaDB veritabanını birlikte ayağa kaldıralım. Önce bir proje klasörü açın:
mkdir -p ~/uygulamalar/wordpress && cd ~/uygulamalar/wordpress
Şifreleri YAML dosyasına yazmak yerine aynı klasörde bir .env dosyasında tutun:
nano .env
DB_SIFRE=BurayaUzunVeRastgeleBirSifre
DB_ROOT_SIFRE=BurayaBaskaUzunBirSifre
chmod 600 .env
Ardından compose.yaml dosyasını oluşturun:
services:
db:
image: mariadb:11.4
restart: unless-stopped
environment:
MARIADB_DATABASE: wordpress
MARIADB_USER: wordpress
MARIADB_PASSWORD: ${DB_SIFRE}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_SIFRE}
volumes:
- db_veri:/var/lib/mysql
wordpress:
image: wordpress:php8.3-apache
restart: unless-stopped
depends_on:
- db
ports:
- "127.0.0.1:8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${DB_SIFRE}
volumes:
- wp_dosyalar:/var/www/html
volumes:
db_veri:
wp_dosyalar:

Dosyada dikkat etmeniz gereken noktalar:
- Eski
version:satırı yok. Güncel Compose bu satırı kullanmaz; yazarsanız yalnız uyarı verir. restart: unless-stoppedkapsayıcının sunucu yeniden başladığında kendiliğinden açılmasını sağlar.- Veritabanının
portssatırı yok. WordPress veritabanına Compose'un oluşturduğu iç ağ üzerindendbadıyla ulaşır; veritabanının dışarıya açılmasına gerek yoktur. 127.0.0.1:8080:80WordPress'i yalnız sunucunun kendisine açar. Bunun nedenini bir sonraki bölümde anlatıyoruz.
Uygulamayı başlatın:
docker compose up -d
docker compose ps
docker compose logs -f wordpress
docker compose ps çıktısında iki servisin de Up durumda olması gerekir. Logları izlemeyi Ctrl+C ile bırakabilirsiniz; kapsayıcılar çalışmaya devam eder.

Güvenlik Duvarı Tuzağı: Docker Portları UFW'yi Atlar
VDS'te Docker kullananların en sık yaşadığı güvenlik sorunu budur: UFW'de deny incoming ayarlı ve 8080 portuna izin vermediğiniz hâlde, ports: - "8080:80" yazdığınız bir kapsayıcıya internetten herkes ulaşabilir.
Bunun nedeni Docker'ın yayınladığı portlar için kendi yönlendirme kurallarını eklemesidir. Gelen paket sunucuya ulaştığında Docker onu doğrudan kapsayıcıya yönlendirir; paket, UFW'nin denetlediği "sunucuya gelen trafik" zincirinden hiç geçmez. Docker'ın kendi belgeleri de bu davranışı açıkça belirtir. AnkSOFT panelindeki Güvenlik Duvarı da sunucuya gelen trafiği süzdüğü için aynı durum geçerlidir: Docker'ın dışarıya yayınladığı bir portu UFW veya panel kuralıyla kapatmış olmazsınız.

Çözüm 1: Portu yalnız 127.0.0.1'e bağlayın (önerilen)
Bir kapsayıcının dışarıdan doğrudan erişilmesi gerekmiyorsa portu sunucunun yerel adresine bağlayın:
ports:
- "127.0.0.1:8080:80"
Böylece uygulamaya yalnız sunucunun içinden ulaşılır. Siteyi internete açmak için sunucuda çalışan bir ters vekil (reverse proxy) kullanırsınız: Nginx 80 ve 443'ü dinler, istekleri 127.0.0.1:8080 adresine iletir ve SSL'i o sağlar. Nginx ve ücretsiz SSL kurulumunu LEMP Kurulumu rehberimizde bulabilirsiniz; WordPress örneği için gereken Nginx bloğu şu kadardır:
server {
listen 80;
server_name ornek.com www.ornek.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Çözüm 2: Hiç port yayınlamayın
Veritabanı, önbellek (Redis) ve kuyruk gibi yalnız diğer kapsayıcıların kullandığı servislerde ports satırını tamamen kaldırın. Aynı Compose dosyasındaki servisler birbirine servis adıyla zaten ulaşır.
Çözüm 3: Dışarıya açılması gereken portlar
Bir oyun sunucusu ya da doğrudan erişilmesi gereken bir servis için "25565:25565" gibi yayınlamanız gerekiyorsa, o portun internete açık olduğunu kabul ederek yayınlayın. Erişimi belirli IP'lerle sınırlamanız gerekiyorsa kuralı Docker'ın bu iş için ayırdığı DOCKER-USER zincirine yazmanız gerekir; bu ileri düzey bir ayardır ve yanlış kural kapsayıcıların ağını kesebilir.
Yayınlanmış portları görmek için:
docker ps --format "table {{.Names}}\t{{.Ports}}"
sudo ss -tulpn | grep docker-proxy
Çıktıda 0.0.0.0:8080->80/tcp görüyorsanız port herkese açıktır; 127.0.0.1:8080->80/tcp görüyorsanız yalnız sunucu içinden erişilir.
Kalıcı Veri: Volume'lar ve Yedek
Bir kapsayıcıyı silip yeniden oluşturduğunuzda içindeki dosyalar kaybolur; kalıcı olması gereken her şey volume'da tutulmalıdır. Örnekteki db_veri ve wp_dosyalar adlandırılmış volume'lardır ve docker compose down komutuyla silinmez.
docker volume ls
docker volume inspect wordpress_db_veri
Compose, volume adının başına proje klasörünün adını ekler (wordpress_db_veri). Volume'ları silmek için açıkça docker compose down -v yazmanız gerekir; bu komut verileri kalıcı olarak siler, yalnız uygulamayı tamamen kaldırırken kullanın.
Bir volume'un yedeğini almak için geçici bir kapsayıcıyla arşivleyebilirsiniz:
mkdir -p ~/yedekler
docker run --rm -v wordpress_wp_dosyalar:/veri -v ~/yedekler:/yedek alpine \
tar czf /yedek/wp-dosyalar-$(date +%F).tar.gz -C /veri .
Veritabanını ise çalışan kapsayıcıdan dışa aktarmak daha güvenlidir:
docker compose exec db sh -c 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --all-databases' > ~/yedekler/db-$(date +%F).sql
Yedekleri sunucunun dışına (kendi bilgisayarınıza ya da ayrı bir depolama alanına) kopyalamayı unutmayın. Sunucu üzerindeki yedek, disk sorunu ya da yanlış bir silme işleminde sizi korumaz.
Bakım: Güncelleme, Log ve Disk
Kapsayıcıları güncellemek: yeni imajları çekip yeniden oluşturun. Volume'lar korunur:
docker compose pull
docker compose up -d
docker image prune -f
Logların diski doldurmasını önlemek: Docker varsayılan olarak logları sınırsız tutar. /etc/docker/daemon.json dosyasını oluşturun:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
sudo systemctl restart docker
Bu ayar yeni oluşturulan kapsayıcılara uygulanır; mevcutlar için docker compose up -d --force-recreate çalıştırın. Disk kullanımını görmek için docker system df komutunu kullanın.
Docker Engine'i güncellemek: resmi depodan kurduğunuz için normal sistem güncellemesiyle gelir: sudo apt update && sudo apt upgrade.
Kapsayıcılara kaynak sınırı koymak
Bellek sızıntısı olan tek bir kapsayıcı, sunucudaki tüm RAM'i tüketip diğer servisleri de durdurabilir. Compose dosyasında her servise üst sınır verebilirsiniz:
wordpress:
# ...
mem_limit: 1g
cpus: 1.5
Sınırı aşan kapsayıcı yalnız kendisi yeniden başlar; sunucunun geri kalanı etkilenmez. Hangi kapsayıcının ne kadar kaynak kullandığını anlık görmek için docker stats komutunu kullanın. Sürekli sınıra dayanan bir kapsayıcı, sunucunuzun büyütülmesi gerektiğinin ya da uygulamada bir sorun olduğunun işaretidir.
Sık kullanılan komutlar
| İşlem | Komut |
|---|---|
| Çalışan kapsayıcıları listele | docker ps |
| Tüm kapsayıcılar (durmuşlar dahil) | docker ps -a |
| Bir servisin loglarını izle | docker compose logs -f wordpress |
| Kapsayıcının içinde komut çalıştır | docker compose exec wordpress bash |
| Uygulamayı durdur / başlat | docker compose stop / docker compose start |
| Uygulamayı kaldır (veriler kalır) | docker compose down |
| Kaynak kullanımı | docker stats |
| Kullanılmayan imajları temizle | docker image prune -a |
docker compose komutlarını her zaman compose.yaml dosyasının bulunduğu klasörde çalıştırın; başka klasörde çalıştırırsanız Compose projeyi bulamaz.
En Sık Yapılan Hatalar
- UFW'de kapalı sanılan portun açık olması.
ports: - "8080:80"herkese açar. Dışarıya açılması gerekmeyen her portu127.0.0.1:ile bağlayın. - Veritabanı portunu yayınlamak.
3306:3306satırı veritabanınızı internete açar. Kapsayıcılar arası iletişim için port yayınlamanız gerekmez. - Verileri volume dışında tutmak. Kapsayıcının içine yazılan dosyalar
docker compose downve yeniden oluşturmada kaybolur. docker compose down -vile verileri silmek.-vvolume'ları da siler. Uygulamayı durdurmak içindocker compose stopya dadown(seçeneksiz) yeterlidir.- Dağıtımın
docker.iopaketiyle resmi paketi karıştırmak. Çakışan paketleri kaldırmadan kurulum yaparsanız servis başlamayabilir. latestetiketine güvenmek.image: mariadb:latestbir güncellemede büyük sürüm atlayabilir. Veritabanlarındamariadb:11.4gibi sabit sürüm etiketi kullanın.- Şifreleri
compose.yamliçine yazıp paylaşmak. Şifreleri.envdosyasında tutun, dosyayı Git deposuna eklemeyin.
Özet
- Çakışan paketleri kaldırın, resmi Docker deposunu ekleyin.
docker-cevedocker-compose-pluginpaketlerini kurun,hello-worldile doğrulayın.- Uygulamayı
compose.yamlile tanımlayın, şifreleri.envdosyasında tutun. - Dışarıya açılması gerekmeyen portları
127.0.0.1:ile bağlayın; siteyi Nginx ters vekil ve SSL ile yayınlayın. - Kalıcı verileri volume'larda tutun, yedeklerinizi sunucu dışına alın.
Docker kapsayıcılarınızı NVMe diskli, DDoS korumalı ve Türkiye lokasyonlu bir sanal sunucuda çalıştırmak için VDS paketlerimizi inceleyin. Sanal sunucu kavramına yeniyseniz VDS nedir rehberimiz iyi bir başlangıçtır. Bir adımda takılırsanız destek talebi açın; talebinize hata mesajını ve docker compose ps çıktısını ekleyin.
Kaynaklar
- Install Docker Engine on Ubuntu – Docker Docs: resmi depo kurulumu (Debian sayfası da aynı yapıdadır)
- Packet filtering and firewalls – Docker Docs: yayınlanan portların güvenlik duvarıyla ilişkisi
- Docker Compose – Docker Docs
Sıkça Sorulan Sorular
VDS'ye Docker nasıl kurulur?
Çakışan eski paketleri kaldırın, Docker'ın resmi apt deposunu ve imza anahtarını ekleyin, ardından docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin ve docker-compose-plugin paketlerini kurun. Kurulumu sudo docker run --rm hello-world ile doğrulayın.
Docker portları neden UFW kurallarını atlıyor?
Docker yayınladığı portlar için kendi yönlendirme kurallarını ekler; gelen paket doğrudan kapsayıcıya yönlendirildiği için UFW'nin ve panel güvenlik duvarının süzdüğü gelen trafik zincirinden geçmez. Dışarıya açılması gerekmeyen portları 127.0.0.1:8080:80 biçiminde yalnız yerel adrese bağlayın.
docker compose ile docker-compose arasındaki fark nedir?
Tireli docker-compose eski, ayrı bir programdı ve artık geliştirilmiyor. Güncel kullanım Docker'ın eklentisi olan boşluklu docker compose komutudur; docker-compose-plugin paketiyle kurulur.
Docker kapsayıcısını silersem verilerim gider mi?
Kapsayıcının içine yazılan veriler gider; adlandırılmış volume'lardaki veriler kalır. docker compose down volume'ları silmez, docker compose down -v ise siler. Kalıcı olması gereken her şeyi volume'da tutun ve yedeğini sunucu dışına alın.
Ubuntu 20.04 VDS'ye Docker kurabilir miyim?
Docker'ın resmi deposu Ubuntu 20.04'ü artık desteklemiyor. Verilerinizi yedekledikten sonra panelden yeniden kurulum yapıp Ubuntu 24.04 ya da Debian 13 seçmenizi öneririz.


