Sunucu Yönetimi 10 dk okuma

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 Kurulumu: VDS Sunucuya Docker ve Docker Compose Kurma Rehberi
AnkSOFT
Yayıncı

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.

Docker kurulumunu doğrulama: docker --version, docker compose version ve hello-world çıktısı

Eski rehberlerdeki docker-compose (tireli) komutu ayrı bir programdı ve artık geliştirilmiyor. Güncel kullanım docker 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:

compose.yaml dosyası: MariaDB ve WordPress servisleri, 127.0.0.1 port bağlama ve kalıcı volume'lar

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-stopped kapsayıcının sunucu yeniden başladığında kendiliğinden açılmasını sağlar.
  • Veritabanının ports satırı yok. WordPress veritabanına Compose'un oluşturduğu iç ağ üzerinden db adıyla ulaşır; veritabanının dışarıya açılmasına gerek yoktur.
  • 127.0.0.1:8080:80 WordPress'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.

docker compose up -d ve docker compose ps çıktısı: kapsayıcılar çalışıyor


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.

Docker port tuzağı şeması: yayınlanan port güvenlik duvarını atlar, 127.0.0.1'e bağlamak dış erişimi kapatır

Çö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

  1. UFW'de kapalı sanılan portun açık olması. ports: - "8080:80" herkese açar. Dışarıya açılması gerekmeyen her portu 127.0.0.1: ile bağlayın.
  2. Veritabanı portunu yayınlamak. 3306:3306 satırı veritabanınızı internete açar. Kapsayıcılar arası iletişim için port yayınlamanız gerekmez.
  3. Verileri volume dışında tutmak. Kapsayıcının içine yazılan dosyalar docker compose down ve yeniden oluşturmada kaybolur.
  4. docker compose down -v ile verileri silmek. -v volume'ları da siler. Uygulamayı durdurmak için docker compose stop ya da down (seçeneksiz) yeterlidir.
  5. Dağıtımın docker.io paketiyle resmi paketi karıştırmak. Çakışan paketleri kaldırmadan kurulum yaparsanız servis başlamayabilir.
  6. latest etiketine güvenmek. image: mariadb:latest bir güncellemede büyük sürüm atlayabilir. Veritabanlarında mariadb:11.4 gibi sabit sürüm etiketi kullanın.
  7. Şifreleri compose.yaml içine yazıp paylaşmak. Şifreleri .env dosyasında tutun, dosyayı Git deposuna eklemeyin.

Özet

  1. Çakışan paketleri kaldırın, resmi Docker deposunu ekleyin.
  2. docker-ce ve docker-compose-plugin paketlerini kurun, hello-world ile doğrulayın.
  3. Uygulamayı compose.yaml ile tanımlayın, şifreleri .env dosyasında tutun.
  4. 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.
  5. 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

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.

TR| EN