VPS.TC
| $
Sunucu Durumu
Turkey İstanbul, Türkiye
Aktif
USA New York, ABD
Aktif
Sepet Toplamı:
Sepeti Görüntüle
VPS’te Docker Kurulumu ve İlk Konteyneri Çalıştırma
Nasıl Yapılır?

VPS’te Docker Kurulumu ve İlk Konteyneri Çalıştırma

Defne avatarı Defne Ağustos 29, 2026 11 dk okuma 0 Yorumlar
Paylaş:

VPS üzerinde Docker kurmadan önce bilmeniz gerekenler

Bir VPS’e bağlandığınızda kurulum komutları genellikle işin kolay kısmıdır. Asıl uğraş, konteynerin hangi porta açılacağı, verinin nerede tutulacağı ve disk dolduğunda ne olacağı gibi sorularla başlar. Docker uygulamayı bağımlılıklarıyla birlikte taşımayı kolaylaştırır; host güvenliği, yedekleme ve izleme sorumluluğunu ise sizin yerinize üstlenmez.

Bu kurulumda Ubuntu 22.04 veya 24.04 LTS kullanacağım. Komutların çoğu Debian 12 üzerinde de aynıdır; yine de depo adreslerini ve paket adlarını dağıtımınıza göre doğrulayın. Önce Docker Engine’i kuracak, ardından basit bir Nginx konteyneri çalıştırıp dışarıdan erişimi test edeceğiz.

Başlamadan sunucunun kaynaklarını kontrol edin. Docker daemon’un kendisi genellikle asıl yük değildir; RAM ve disk tüketimini çoğunlukla konteyner içindeki uygulamalar belirler. Veritabanı, web sunucusu ve monitoring servislerini aynı VPS’te çalıştıracaksanız kullanılabilir belleği, disk türünü ve yedekleme alanını birlikte düşünün.

🚀 VPS Sunucu ile Hızınızı Artırın!

Yüksek performanslı SSD depolama ve %99.9 uptime garantisi ile projelerinizi hızlandırın.

Hemen Başla
cat /etc/os-release
uname -a
nproc
free -h
df -h

free -h çıktısında swap olmaması tek başına hata sayılmaz. Düşük RAM’li VPS’lerde kısa süreli bellek artışı ise konteynerleri ve host sistemini aynı anda etkileyebilir. Ben yeni sunucularda önce temel monitoring’i kurup kaynak davranışını gözlemliyorum. Yeni VPS hazırlığıyla ilgili daha geniş bir kontrol sırası arıyorsanız Yeni VPS Sunucuyu 30 Dakikada Canlıya Alma Rehberi yazısındaki temel adımlar işinize yarar.

Eski Docker paketlerini temizleyin

Ubuntu depolarında veya daha önce eklenmiş üçüncü taraf depolarda Docker’ın farklı paketleri bulunabilir. Yarım kalmış bir kurulum varsa önce mevcut durumu görün:

docker --version 2>/dev/null || true
dpkg -l | grep -E 'docker|containerd' || true
systemctl status docker --no-pager 2>/dev/null || true

Yeni ve kullanılmayan bir VPS’te aşağıdaki paketleri kaldırmak çoğu zaman güvenlidir. Üzerinde çalışan konteynerler, imajlar veya volume’lar varsa bu komutu düşünmeden kullanmayın. Paketleri kaldırmak her zaman veri dizinlerini silmez; yine de geri dönüş planı olmadan temizlik yapmak iyi bir yönetim yöntemi değildir.

☁️ Cloud Sunucu ile Esneklik Kazanın!

Ölçeklenebilir kaynaklar ve anlık yedekleme ile bulutun gücünü deneyimleyin.

Keşfet
sudo apt remove -y docker.io docker-doc docker-compose podman-docker containerd runc

Ben bir keresinde test sunucusu sandığım makinede eski bir Docker kurulumu bulup doğrudan temizliğe girişmiştim. Hostname’i ikinci kez kontrol edince bunun müşteri staging ortamı değil, production’a yakın bir yardımcı sunucu olduğunu fark ettim. Silme işleminden hemen önce hostname çalıştırmak ve production shell’lerinin prompt’una hostname eklemek o günün kalıcı dersiydi.

Docker Engine için resmi depoyu ekleme

Ubuntu’nun kendi deposundaki Docker sürümü, dağıtım sürümüne göre geriden gelebilir. Uzun süre çalışacak VPS’lerde Docker’ın resmi apt deposunu kullanmak sürüm ve güncelleme yönetimini daha öngörülebilir kılar. Kurulumdan önce paket listesini yenileyip yardımcı paketleri yükleyin.

sudo apt update
sudo apt install -y ca-certificates curl

Docker’ın imza anahtarını ayrı bir keyring dizininde saklayacağız. Eski dokümanlarda sık görülen apt-key yöntemi artık tercih edilmiyor.

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 mimariyi ve Ubuntu kod adını kullanarak depo kaydını oluşturun:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu 
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | 
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Bu satırdaki signed-by bölümü, anahtarın yalnızca bu depo için kullanılmasını sağlar. Ardından 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

Kurulumdan sonra servisi ve sürümü kontrol edin:

sudo systemctl enable --now docker
sudo systemctl is-active docker
docker version
sudo docker run --rm hello-world

is-active komutunun active döndürmesi servisin çalıştığını gösterir. hello-world imajı indirip kısa bir konteyner çalıştırır ve çıkar. İlk çalıştırmada Docker Hub’a bağlantı gerektiğinden DNS veya çıkış trafiği sorunu varsa kontrol burada takılabilir.

Docker komutlarını sudo olmadan çalıştırmak

Kurulumdan sonra Docker komutlarını varsayılan olarak root yetkisiyle çalıştırmanız gerekir. Kendi kullanıcı hesabınızı docker grubuna eklemek daha pratik görünür:

sudo usermod -aG docker "$USER"
newgrp docker
docker ps

Buradaki -aG bayrağı önemli. Sadece -G kullanırsanız kullanıcının mevcut grup üyeliklerini ezebilirsiniz. newgrp docker mevcut oturumda yeni grup üyeliğini etkinleştirir; SSH bağlantısını kapatıp yeniden açmak da aynı işi yapar.

Bu kolaylığın güvenlik bedeli var. docker grubuna üyelik pratikte root’a çok yakın yetki verir. Host dosya sistemini bir konteynere bağlamak veya ayrıcalıklı bir konteyner başlatmak mümkün olduğundan bu gruba yalnızca güvendiğiniz yönetici hesaplarını ekleyin. Her işi root kullanıcısıyla yapmamak iyi bir alışkanlık; Docker grubunu herkese açmak bunun daha şık görünen başka bir biçimi olur.

Paylaşımlı bir ekip sunucusunda rootless Docker’ı ayrıca değerlendirebilirsiniz. Rootless mod, daemon ve konteynerleri root olmayan kullanıcıyla çalıştırır; bazı ağ ve depolama özellikleri için ek ayar gerekir. Tek kullanıcılı basit bir VPS’te klasik kurulum anlaşılır olabilir. Çok kullanıcılı ortamlarda ise güvenlik modelini baştan tasarlayın.

İlk konteyner: Nginx ile küçük bir test

Kurulumun gerçekten çalıştığını görmek için basit bir Nginx konteyneri açalım. Host üzerindeki 8080 portunu konteynerin 80 portuna bağlayacağız.

docker run -d 
  --name web-test 
  --restart unless-stopped 
  -p 8080:80 
  nginx:1.27-alpine

-d konteyneri arka planda çalıştırır, --name hatırlanabilir bir ad verir. --restart unless-stopped, Docker servisi yeniden başladığında konteyneri otomatik olarak kaldırır. -p 8080:80 ifadesinde soldaki port VPS’e, sağdaki port konteynerin içine aittir.

İmaj etiketini açıkça yazmayı tercih ediyorum. latest ilk denemede kolaydır; hangi sürümün çekildiğini daha sonra anlamayı zorlaştırır. Üretimde daha belirli bir sürüm veya test sürecinizden geçmiş bir digest kullanmak daha kontrollü olur.

Konteynerin ve port eşlemesinin durumuna bakın:

docker ps
docker port web-test
curl -I http://127.0.0.1:8080

Beklenen yanıtta HTTP/1.1 200 OK benzeri bir satır görürsünüz. VPS’in dış IP adresinden test etmek için kendi bilgisayarınızdan http://SUNUCU_IP:8080 adresini açabilirsiniz. Açılmıyorsa hemen konteyneri yeniden başlatmayın. Önce docker ps, docker logs web-test, ss -lntp ve güvenlik duvarı kurallarını kontrol edin.

Portu tüm internete açmak zorunda değilsiniz

Komuttaki -p 8080:80 eşlemesi varsayılan olarak tüm arayüzlerde dinler. Yalnızca VPS’in kendi içinden test edecekseniz portu loopback adresine bağlayabilirsiniz:

docker rm -f web-test
docker run -d 
  --name web-test 
  --restart unless-stopped 
  -p 127.0.0.1:8080:80 
  nginx:1.27-alpine

Bu biçimde dışarıdan doğrudan erişim kapanır. Nginx’i host üzerinde reverse proxy olarak kullanıp trafiği yalnızca proxy üzerinden alabilirsiniz. Gerçek bir alan adı, TLS ve reverse proxy planınız varsa konteyneri rastgele yüksek bir porttan internete açmak yerine erişim akışını baştan belirleyin.

UFW kullanıyorsanız 8080 portunu açmak için şu komut çalışır:

sudo ufw status verbose
sudo ufw allow 8080/tcp
sudo ufw reload

Test bittikten sonra bu kuralı açık bırakmayın. Docker’ın iptables veya nftables kurallarıyla UFW davranışının beklediğinizden farklı olabildiği durumlar var. İnternete açık bir VPS’te güvenlik duvarını, SSH erişimini ve Docker’ın yayınladığı portları birlikte inceleyin. Linux sunucu güvenliği için temel kontrolleri Linux Sunucu Güvenliği için Zorunlu 10 Temel Adım yazısında ayrıca ele almıştım.

Logları okumadan yeniden başlatmayın

Bir konteynerin çalışıyor görünmesi uygulamanın sağlıklı olduğu anlamına gelmez. İlk bakacağım ekranlardan biri log çıktısıdır:

docker logs --tail 100 web-test
docker inspect web-test
docker stats --no-stream web-test

docker logs konteynerin standart çıktısını gösterir. inspect ağ, mount, ortam değişkeni ve restart ayarlarını JSON olarak döndürür. stats ise tek seferlik CPU, bellek ve ağ kullanımını verir. Üretimde bu bilgileri yalnızca terminal komutlarına bırakmak yerine merkezi loglama ve monitoring kurmak gerekir.

Bir ara test sunucusu sandığım makinede yanlış Compose projesinin içinden işlem yapmıştım. docker compose ps çıktısındaki konteyner adları beklediğimden farklı gelince durdum; doğru sunucuda olsam da yanlış proje dizinindeydim. O günden beri yıkıcı bir komuttan önce hem hostname hem de pwd çalıştırıyorum. İki saniye sürüyor.

Docker daemon’un log sürücüsünü kontrol edin:

docker info --format '{{.LoggingDriver}}'
cat /etc/docker/daemon.json 2>/dev/null || true

Varsayılan json-file sürücüsü logları host üzerinde tutar. Uzun süre çalışan uygulamalarda log rotasyonu ayarlamayı düşünün. Örneğin /etc/docker/daemon.json dosyasına şu ayarlar eklenebilir:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Dosyayı değiştirdikten sonra daemon’u yeniden başlatmanız gerekir. Bu ayar yeni başlatılan konteynerler için geçerli olur; mevcut konteynerleri kaldırıp yeniden oluşturmanız gerekebilir. Önce dosyanın geçerli JSON olduğunu python3 -m json.tool /etc/docker/daemon.json ile doğrulayın. Küçük bir virgül hatası Docker’ın hiç başlamamasına neden olabilir.

Veriyi konteynerin dışına çıkarın

Nginx test konteyneri stateless olduğu için silip yeniden oluşturmak sorun değildir. Veritabanı, Nextcloud, Vaultwarden veya CMS çalıştırırken durum değişir. Konteyner silindiğinde uygulamanın verisi writable katmanda tutuluyorsa kaybolabilir. Kalıcı veriler için named volume veya host bind mount kullanın.

docker volume create web-data
docker run -d 
  --name web-volume-test 
  --restart unless-stopped 
  -p 127.0.0.1:8081:80 
  -v web-data:/usr/share/nginx/html:ro 
  nginx:1.27-alpine

web-data, Docker tarafından yönetilen bir volume’dur. Yerini görmek için:

docker volume inspect web-data

Host üzerindeki belirli bir dizini kullanmak isterseniz önce dizini oluşturup sahiplik ve izinlerini uygulamaya göre düzenleyin:

sudo install -d -m 0755 /srv/web/html
sudo docker run -d 
  --name web-bind-test 
  -p 127.0.0.1:8082:80 
  -v /srv/web/html:/usr/share/nginx/html:ro 
  nginx:1.27-alpine

Buradaki :ro mount’u salt okunur yapar. Web sunucusunun içerik yazmasına gerek yoksa bu kısıtlama işe yarar. İzin sorunu yaşadığınızda chmod -R 777 ile kaçmak yerine konteyner içindeki kullanıcıyı ve host dizininin sahibini inceleyin. Bu komut sorunu çözmekten çok sorunun adını değiştirir.

Yedek tarafını da planlayın. Docker volume’larını yedeklemek yalnızca volume dizinini kopyalamaktan ibaret değildir; veritabanı gibi servislerde tutarlı dump almak gerekir. Ben VPS yedeklerinde rsync ve borgbackup kullanıyor, ayda bir geri dönüş provası yapıyorum. Test edilmemiş yedek, sunucuda duran büyük bir iyimserlik dosyasıdır.

Tek komut yerine Compose kullanmak

İlk konteyneri docker run ile başlatmak öğreticidir. Uygulama büyüdüğünde uzun komutları tekrar tekrar yazmak yerine Compose dosyası daha okunaklı olur. Docker Compose eklentisinin kurulduğunu şu komutla kontrol edin:

docker compose version

Basit Nginx örneğini bir proje dizinine taşıyalım:

sudo install -d -m 0755 /opt/web-test
sudo chown "$USER":"$USER" /opt/web-test
cd /opt/web-test
vim compose.yaml

compose.yaml içeriği:

services:
  web:
    image: nginx:1.27-alpine
    container_name: web-compose
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro

İçeriği oluşturup servisi başlatın:

mkdir -p html
printf '%sn' '<h1>Docker VPS testi başarılı</h1>' > html/index.html
docker compose up -d
docker compose ps
curl http://127.0.0.1:8080

Compose dosyasının bulunduğu dizin burada önemlidir. Komutları başka bir klasörde çalıştırırsanız Docker Compose dosyasını bulamayabilir. Ben de bir keresinde doğru sunucuda, yanlış proje dizininde docker compose down çalıştırmıştım. Konteyneri geri açmak kolaydı; hangi dosyanın hangi servise ait olduğunu hatırlamak daha zordu.

Compose ile servisleri durdurmak ve kaldırmak arasındaki farkı bilin:

docker compose stop
docker compose start
docker compose down

stop konteynerleri durdurur, start yeniden başlatır. down ise Compose tarafından oluşturulan konteynerleri ve ağı kaldırır; named volume’ları varsayılan olarak silmez. down -v kullanırken iki kez düşünün. Üretim verisini tek komutla kaldırmak teknik olarak mümkün olduğu için iyi bir fikir haline gelmez.

Docker ağını ve VPS güvenliğini kontrol edin

Docker konteynerleri varsayılan olarak bridge ağında çalışır. Aynı Compose projesindeki servisler servis adıyla birbirine erişebilir; örneğin uygulama konteyneri veritabanına db:5432 üzerinden bağlanabilir. Veritabanı portunu host’a yayınlamadığınız sürece dışarıya açmanız gerekmez.

docker network ls
docker network inspect bridge
ss -lntp

ss -lntp çıktısında yalnızca beklediğiniz portları görmeye çalışın. SSH için 22, reverse proxy için 80 ve 443 açık olabilir; test amacıyla bıraktığınız 8080 gibi portlar bir süre sonra unutulur. Fail2ban ve nftables SSH saldırılarını azaltmaya yardımcı olur. SSH portunu değiştirmek tek başına güvenlik değildir.

Docker imajlarını güvenilir kaynaklardan çekin, imaj etiketlerini pinleyin ve konteyneri gereksiz yetkilerle çalıştırmayın. --privileged seçeneğini açıklamasını bilmeden kullanmayın. Host dizinlerini mount ederken yalnızca gereken yolu verin; tüm / dizinini konteynere bağlamak izolasyon fikrini kendi elinizle zayıflatır.

İmaj güncellemelerinde de plansız hareket etmeyin:

docker compose pull
docker compose up -d
docker image prune

docker image prune kullanılmayan imajları temizler ve varsayılan olarak onay ister. Önce hangi imajların gerektiğini kontrol edin; geri dönüş için eski imajı tutmak isteyebilirsiniz. Daha kontrollü bir akışta yeni etiketi staging VPS’te test eder, healthcheck ve logları inceler, ardından production’a geçerim.

İlk kurulumdan sonra kısa kontrol listesi

VPS Docker kurulumu bittikten sonra birkaç kontrolü sırayla yapmak, “çalıştı galiba” ile düzgün hazırlanmış bir servis arasındaki farkı gösterir:

  • systemctl is-active docker ile Docker servisinin durumunu doğrulayın.
  • docker ps ile beklenen konteynerleri ve restart durumunu kontrol edin.
  • docker logs ile uygulamanın hata üretmediğine bakın.
  • ss -lntp ve güvenlik duvarı kurallarıyla yayınlanan portları inceleyin.
  • Kalıcı verileri volume veya kontrollü bind mount ile saklayın.
  • RAM, CPU, disk ve log boyutunu monitoring sisteminize ekleyin.
  • İmaj sürümlerini ve güncelleme tarihlerini not edin.
  • Yedekten gerçekten geri dönebileceğiniz bir test yapın.

VPS’iniz düşük kaynaklıysa konteyner sayısını artırmadan önce uygulamaların bellek sınırlarını ve swap davranışını ölçün. Bir konteynerin host’u tüketmesine izin vermek yalnızca o servisin değil, aynı VPS’teki diğer servislerin de kesilmesine yol açabilir. Bu yüzden önce kendi Proxmox lab’ımda sınırları zorlar, sonra müşteri sunucusunda değişiklik yaparım.

İlk Nginx konteyneriniz curl ile yanıt verdiğinde iş bitmiş sayılmaz. Ertesi gün servis yeniden başladıktan sonra veri duruyor mu, port gerçekten kapalı mı, loglar diski dolduruyor mu? Benim kurulum kontrolüm bu üç soruya dürüst bir cevap verebildiğimde tamamlanıyor. Kırmızı production prompt’u da o zaman biraz daha az geriyor.

Defne avatarı
Yazar

Defne

vps.tc blog yazarı. Sistem yönetimi, Linux ve hosting dünyası üzerine yazıyor.