Ubuntu 24.04 uzerinde Docker Compose kurulumu ve ayarları
Ubuntu 24.04 uzerinde Docker Engine ve Compose v2 kurulumunu yapın. UFW port cakışmalarını engelleyin, veritabanı yedekleme yontemlerini ogrenin ve iki servisli ornekleri calıstırın.
Ne inşa ediyorsunuz
Docker Compose, bu sitedeki hemen hemen her şeyin temelini oluşturur. Nextcloud, Vaultwarden, n8n, Immich, Rocket.Chat gibi rehberlerin her biri "bu compose dosyasını yazın" ifadesiyle başlar; bu sayfa ise söz konusu dosyanın gerçekte ne anlama geldiğini açıklar. Ubuntu 24.04 üzerinde Docker'ın kendi apt deposundan Docker Engine ve Compose v2 eklentisini kuracak, ardından iki servisli gerçek bir yığın olan Miniflux (küçük bir RSS okuyucu) ve PostgreSQL'i ayağa kaldıracaksınız. Bu ikili, daha büyük uygulamaların kullandığı tüm kalıpları test etmenizi sağlar: sabitlenmiş imajlar, sağlık kontrolüne (healthcheck) sahip bir veritabanı, adlandırılmış bir birim (volume), bir .env dosyasındaki gizli veriler ve yalnızca localhost'a yayınlanan bir port.
Kurulum beş dakika sürer. Bu rehberin geri kalanı, ileride sorun yaratabilecek kısımları ele alır: docker grubunun aslında root yetkilerine sahip olması, yayınlanan portların ufw kurallarınızı doğrudan devre dışı bırakması ve docker compose down üzerinde veritabanınızı onay istemeden silen o tek bayrak (flag).
Ön koşullar: temiz bir Ubuntu 24.04 KVM VPS, sudo yetkisine sahip bir kullanıcı ve en az bir gigabayt RAM. Mevcut bir Docker kurulumu da kullanılabilir; ilk bölüm nelerin kaldırılması gerektiğini açıklar.
Ubuntu deposundan değil, Docker deposundan kurulum
İlk komuttan önce kaçınılması gereken iki hatalı yol vardır. Ubuntu'nun kendi docker.io paketi çalışır ancak Docker'ın sürümlerinin gerisinde kalır ve diğer her şeyin varsaydığı eklenti yapısını içermez. Ayrıca tire işareti içeren bağımsız docker-compose ikili dosyası, Compose v1'dir: Python tabanlıdır, 2023 itibarıyla ömrünü tamamlamıştır ve eski eğitimlerin çalışmama sebebidir. Günümüzdeki Compose, boşluk içeren docker compose komutudur; motorla aynı depodan kurulan bir CLI eklentisidir.
Bunlardan herhangi biri sistemde mevcutsa, Ubuntu'nun kendi eklenti paketi olan docker-compose-v2 dahil olmak üzere önce bunları temizleyin; böylece her şey tek bir depodan gelir:
sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runcYeni bir VPS üzerinde normal çıktı Package 'docker.io' is not installed, so not removed şeklindedir. Ardından Docker deposunu ekleyin ve kurulumu yapın:
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
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
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginÜç katmanı da doğrulayın:
docker --version
docker compose version
sudo docker run --rm hello-worldİlk iki komut sürüm dizilerini yazdırır, Docker Compose version v2.x.x ise ölü v1 ikili dosyası yerine eklentiye sahip olduğunuzu doğrular. hello-world komutunun çıktısı Hello from Docker! ile bitmelidir. Paket, servisi açılışta etkinleştirir; systemctl is-enabled docker komutu enabled çıktısını verir.
docker grubu root yetkisindedir, sonuçlarını bilerek karar verin
Şu anda her docker komutu sudo gerektirir, çünkü /var/run/docker.sock adresindeki daemon soketinin sahibi root kullanıcısı ve docker grubudur. Bu gruba dahil değilseniz, Docker ile ilgili en çok aranan şu hatayı alırsınız:
permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sockStandart çözüm şudur:
sudo usermod -aG docker $USERGrup üyeliği oturum açma sırasında geçerli olur, bu nedenle hata mevcut kabuğunuzda devam edecektir. Bu oturum için newgrp docker komutunu çalıştırın veya oturumu kapatıp tekrar açın; id komutu artık gruplarınız arasında docker değerini listelemelidir.
Şimdi dürüst olma vakti: docker grubuna üye olmak, ana makinede root yetkisine sahip olmak demektir. "Root benzeri" veya "yükseltilmiş" değil, doğrudan root. Bu gruptaki herkes docker run --rm -it -v /:/host alpine chroot /host komutunu çalıştırabilir ve parola sormaksızın tüm dosya sisteminin sahibi olabilir. Bu grup güvenlik için değil, kolaylık sağlamak için vardır.
Docker'ın rootless modu gerçek bir alternatiftir; daemon doğrudan sizin yetkisiz kullanıcınızla çalışır. Bunun bazı maliyetleri vardır: 1024 altındaki portlar ek yapılandırma gerektirir, ağ trafiği ölçülebilir bir ek yük getiren bir kullanıcı alanı katmanı üzerinden akar ve bazı imajlar gerçek root yetkisi olmadan düzgün çalışmaz. Tek bir yöneticinin bulunduğu ve zaten sudo yetkisine sahip olduğu bir VPS üzerinde, bu grup değişikliği pratikte hiçbir şeyi değiştirmez ve buradaki tüm rehberler bunu varsayar; ancak bu yetkiyi asla sudo'dan daha az önemliymiş gibi dağıtmayın.
Compose dosyasının anatomisi
Her yığın (stack) için ayrı bir dizin oluşturun. Dizin adı proje adı olur; bu isim container'lar, ağlar ve volume'lar için ön ek görevi görür:
sudo mkdir -p /opt/miniflux && sudo chown $USER /opt/miniflux && cd /opt/minifluxcompose.yml dosyasını oluşturun (modern isimlendirme budur; docker-compose.yml hala çalışır). Eski version: anahtarını kullanmayın; artık geçersizdir ve Compose bunu gördüğünde uyarı verir.
services:
miniflux:
image: miniflux/miniflux:2.2.9
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- DATABASE_URL=postgres://miniflux:${POSTGRES_PASSWORD}@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=miniflux
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux", "-d", "miniflux"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:Yukarıdaki her satır bir karardır. Bunları tek tek ele alın.
İmaj sürümlerini sabitleyin, :latest ve pull işlemi denetimsiz bir yükseltmedir
postgres:latest yerine postgres:16-alpine kullanın. Bir etiket (tag) sabit değildir: :latest, her pull işleminde geliştiricinin en son gönderdiği imaja yönlenir. Bunu, öğreneceğiniz rutin yükseltme alışkanlığı olan docker compose pull && docker compose up -d ile birleştirdiğinizde, :latest ifadesi, ana sürüm yükseltmelerinin siz istediğinizde değil, geliştirici yayınladığında gerçekleşeceği anlamına gelir. PostgreSQL özelinde bu varsayımsal bir durum değildir: 16'dan 17'ye sürpriz bir geçiş, uyumsuz bir veri dizini nedeniyle container'ın sürekli çökmesine (crash-loop) neden olur; çünkü Postgres ana sürüm yükseltmeleri yeniden başlatma değil, dump ve restore işlemi gerektirir.
En azından ana sürümü sabitleyin (postgres:16-alpine, 16.x yama sürümlerini takip eder) ve uygulamaları miniflux/miniflux:2.2.9 gibi kesin bir sürüme kilitleyin. Projenin sürümler (releases) sayfasını kontrol edin ve dosyayı yazarken güncel olan sürümü kullanın. Bu durumda yükseltme, bilinçli olarak yaptığınız ve git diff içinde görülebilen tek satırlık bir düzenlemeye dönüşür.
127.0.0.1 adresine yayınlayın, çünkü Docker ufw kurallarını atlar
"127.0.0.1:8080:8080"; ana makine adresi, ana makine portu, container portu. Çoğu eğitim "8080:8080" yazar; bu, 0.0.0.0:8080:8080 için kısaltmadır: yani tüm arayüzlerde, halka açık olanlar dahil, dinleme yapar.
İşte herkesin bir kez düştüğü tuzak budur. Docker, bir portu yayınlarken paketin hedef adresini filtrelemeden önce container'ın dahili IP'sine yeniden yazan bir DNAT kuralı oluşturur. Bu nedenle paket FORWARD yolunu izler ve ufw kurallarınızın bulunduğu INPUT katmanına asla uğramaz. sudo ufw deny 8080 başarı raporu verir, ufw status portun reddedildiğini gösterir ancak servis tüm internete yanıt vermeye devam eder. Güvenlik duvarınız bozuk değildir; tasarım gereği atlatılmaktadır. Docker neden ufw'yi atlar ve container trafiği nasıl filtrelenir başlıklı yazı, bu mekanizmayı ve halka açık kalması gereken portlar için DOCKER-USER çözümünü detaylandırır.
Tüm sorunu ortadan kaldıran alışkanlık şudur: Özel bir nedeniniz yoksa yayınlanan portları 127.0.0.1 adresine bağlayın ve dünyaya açılması gereken her şeyin önüne bir reverse proxy koyun. Bu sayfanın ardından gelen Traefik reverse proxy rehberi tam olarak bunu inşa eder; 80 ve 443 portlarını yöneten, TLS ile diğer her şeye ana bilgisayar adına göre yönlendirme yapan tek bir container yapısı. (Eski bir Traefik v2 kurulumundan mı geliyorsunuz? Traefik v2'den v3'e geçiş rehberi, isim değişikliklerini ve kural güncellemelerini kapsar.)
Yığını başlattıktan sonra bağlamayı doğrulayın: sudo ss -tlnp | grep 8080 komutu 0.0.0.0:8080 veya *:8080 değil, 127.0.0.1:8080 çıktısını vermelidir.
İsimlendirilmiş volume'lar ve bind mount'lar
db-data:/var/lib/postgresql/data isimlendirilmiş bir volume'dur: Docker, /var/lib/docker/volumes/ altında bir dizin oluşturur, yönetir ve bunu container içine bağlar. Alternatifi ise ana makinede seçtiğiniz bir yolu eşleyen bind mount, yani ./data:/var/lib/postgresql/data yöntemidir.
Uygulamada geçerli olan ayrım şudur: Sadece container'ların eriştiği veriler için isimlendirilmiş volume'lar kullanın (özellikle veritabanları). Docker, volume'u imajın beklediği sahiplik bilgileriyle başlatır ve dosya izinleri sorunsuz çalışır. Ana makineden sizin eriştiğiniz dosyalar için bind mount'lar kullanın (metin düzenleyiciyle değiştirdiğiniz yapılandırma dosyaları, rsync ile veri aktardığınız bir medya kütüphanesi veya yolu sizin için belirgin olması gereken her şey). Bind mount'larda yaşanan klasik hata sahiplik sorunudur: container UID 999 ile çalışır, ana makine dizininiz UID 1000'e aittir ve uygulama başlangıçta loglarda permission denied hatası vererek durur. İsimlendirilmiş volume'lar bu hata sınıfını büyük ölçüde ortadan kaldırır; bunun bedeli ise verinin aşağıda açıklanan, Docker tarafından yönetilen bir yolda tutulmasıdır.
environment ve .env, sırları git'ten uzak tutun
${POSTGRES_PASSWORD} kabuğunuzdan okunmaz; Compose bunu compose.yml dosyasının yanındaki .env adlı dosyadan içe aktarır. Oluşturun:
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me-to-something-long
ADMIN_PASSWORD=change-me-too
EOF
chmod 600 .env
echo ".env" >> .gitignoreGerçek değerleri openssl rand -hex 24 ile oluşturun. Bilinçli olarak base64 değil, hex kullanın: bu parola DATABASE_URL bağlantı dizisinin içine yerleşir ve base64'ün ürettiği /, + ve = karakterleri URL ayrıştırmasını bozar. Bu hata, sözdizimi hatası olarak değil, kimlik doğrulama hatası olarak ortaya çıkar ve bir akşamınızı harcamanıza neden olur. .gitignore satırı ilk commit'ten önce eklenmelidir: compose dosyası yayınlanabilir ve sürümlenebilir, ancak .env dosyası asla yayınlanmamalıdır. Git geçmişine girmiş bir sır, artık değiştirilmesi (rotate) gereken bir sırdır. Yığını eksik bir değişkenle başlatırsanız, Compose yüksek sesle uyarır ve boş bir dize ile devam eder; bu da Postgres parolası için başarısız bir dağıtım demektir:
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string.docker compose config, tamamen içe aktarılmış dosyayı yazdırır; container'ların gerçekte ne alacağını kontrol etmenin en hızlı yolu budur. Çıktının sırlarınızı içerdiğini unutmayın.
depends_on hiçbir şeyi beklemez, healthcheck eklemediğiniz sürece
Yalın bir depends_on: [db] sadece başlatma sırasını kontrol eder: Compose önce Postgres'i, bir an sonra uygulamayı başlatır; oysa Postgres'in bağlantıları kabul etmesine daha saniyeler vardır. Uygulama veritabanına ulaşır, başarısız olur ve yazılımın kalitesine göre ya çöker ya da yeniden dener.
Güvenilir sürüm, yukarıdaki dosyanın kullandığı yöntemdir: db servisi bir healthcheck tanımlar (Postgres tam olarak bunun için pg_isready ile gelir) ve uygulama condition: service_healthy ile depends_on beyan eder. Compose veritabanını başlatır, kontrolü her 10 saniyede bir sorgular ve ancak kontrol başarılı olduğunda Miniflux'ı başlatır. Veritabanı asla sağlıklı duruma gelmezse (hatalı parola, bozuk volume vb.), uygulama asla başlamaz ve Compose size hangi bağımlılığın başarısız olduğunu söyler:
dependency failed to start: container miniflux-db-1 is unhealthyBu mesaj sizi gerçek hatanın bulunduğu docker compose logs db kısmına yönlendirir.
restart: unless-stopped
Her iki serviste de restart: unless-stopped kullanılması, container'ların bir çökme veya VPS yeniden başlatmasından sonra geri gelmesini sağlar; ancak siz kasıtlı olarak docker compose stop komutunu çalıştırdıysanız kapalı kalırlar. Alternatifi olan always, manuel durdurmadan sonra bile container'ları diriltir ki bu genellikle istediğiniz bir durum değildir. Bir yeniden başlatma politikası olmazsa, sabah 04:00'te gerçekleşen bir çekirdek güncellemesi sonrası yeniden başlatma, siz fark edene kadar servislerinizi sessizce devre dışı bırakır.
Günlük işlemler
Günlük tüm işlemler, proje dizininden çalıştırılan beş komuttan ibarettir.
docker compose up -d # create and start; idempotent, recreates only what changed
docker compose ps # status, ports, and health of this project's containers
docker compose logs -f miniflux # follow one service's logs; --tail 100 for recent history
docker compose pull && docker compose up -d # upgrade to the pinned tags
docker compose down # stop and remove containers and the networkup -d komutunu tekrar tekrar çalıştırmak güvenlidir; dosya ile mevcut durum arasındaki farkı karşılaştırır ve yalnızca yapılandırması veya imajı değişen servisleri etkiler. Yükseltme çifti, sabitlenmiş etiketlerinizin (pinned tags) işaret ettiği sürümleri çeker: postgres:16-alpine altındaki yama sürümleri güncellenir, ancak siz düzenlemediğiniz sürece tam sürüm sabitlemeleri değişmez; zaten amaç da budur. Yükseltmelerden sonra eski imajlar birikir; disk alanını geri kazanmak için docker image prune -f kullanın.
Şimdi yıkıcı olan komuta gelelim, yüksek sesle belirtmek gerekir: docker compose down komutunu çalıştırmak güvenlidir; container'lar ve ağ yapısı geçicidir, verileriniz ise volume içinde tutulur. docker compose down -v komutu adlandırılmış volume'leri de siler. Bu, veritabanınızın anında ve geri dönüşü olmaksızın, herhangi bir onay istemeden silinmesi demektir. -v bayrağı, denemeleri temizlemek için mevcuttur; gerçek verilerin bulunduğu bir yığında, bu komuta rm -rf komutuna yaklaştığınız gibi yaklaşın. /var/lib/docker/volumes/ altında bir çöp kutusu bulunmaz.
Çalışan bir container içinde tek seferlik bir kabuk (shell) oturumu açmak için: docker compose exec db psql -U miniflux sizi veritabanına, docker compose exec miniflux sh ise uygulama içinde bir kabuğa ulaştırır.
Verilerinizin gerçekte nerede saklandığı
Named volume'lar proje öneki alır; bu nedenle db-data, miniflux adlı bir dizin içinde miniflux_db-data haline gelir:
docker volume ls
docker volume inspect miniflux_db-datainspect çıktısı, önemli olan satırı içerir:
"Mountpoint": "/var/lib/docker/volumes/miniflux_db-data/_data"Bu dizin veritabanıdır, ana makine dosya sisteminde root sahipliğindedir ve down, yükseltmeler ve container yeniden oluşturma işlemlerinden sonra varlığını korur. Ayrıca yedeklerinizin mutlaka alması gereken veriler tam olarak bunlardır.
Named volume yedekleme
Standart yöntem, birimi salt okunur olarak bir ana makine dizinine bağlayan ve içeriği tar ile arşivleyen geçici bir container kullanmaktır:
docker run --rm \
-v miniflux_db-data:/data:ro \
-v "$PWD":/backup \
alpine:3.22 tar czf /backup/miniflux-db-$(date +%F).tar.gz -C /data .Kurulum gerektirmez, arka planda çalışan bir süreç bırakmaz. Geri yükleme işlemi ise bunun tam tersidir; tar xzf komutu ile aynı bağlama noktaları tersine çevrilerek boş bir birime aktarım yapılır.
Veritabanları için önemli bir uyarı: çalışan bir Postgres veri dizinini tar ile arşivlemek, yazma işlemi sırasında tutarsız bir durum oluşturabilir ve veritabanının düzgün başlamasını engelleyebilir. Arşivleme süresince docker compose stop komutunu kullanın veya daha iyisi, yapısı gereği tutarlı olan mantıksal bir döküm (logical dump) alın:
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz-T bayrağı, Compose tarafından varsayılan olarak atanan sözde terminali (pseudo-terminal) devre dışı bırakır; döküm çıktısını bir TTY üzerinden aktarmak veriyi bozabilir. Bu komutlardan birini cron içine ekleyin ve sonucu VPS dışına kopyalayın; verinin bulunduğu diskle aynı diskte tutulan bir kopya, yedek değil yalnızca bir kopyadır. Nextcloud rehberi, tam olarak bu iki yöntemi temel alan planlı bir yedekleme rutini oluşturur.
Hata modları ve karşılaşacağınız dizgeler
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock, henüz docker grubunda değilsiniz veya gruptasınız ancak oturumunuz bu değişiklikten önce açılmış. id etkin gruplarınızı gösterir; newgrp docker mevcut kabuğu düzeltir, oturumu kapatıp açmak ise tümünü düzeltir.
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?, farklı bir sorun: daemon'ın kendisi çalışmıyor. sudo systemctl status docker ve sudo journalctl -u docker -n 50 nedenini açıklar. Bir VPS üzerinde klasik neden disk doluluğudur, önce df -h /var/lib/docker komutunu çalıştırın.
Bind for 127.0.0.1:8080 failed: port is already allocated, başka bir container bu host portunu zaten kullanıyor. docker ps hangisinin kullandığını gösterir; genellikle docker run hafta önceki denemelerden kalan eski bir container buna sebep olur. Eğer docker ps temizse, Docker dışı bir süreç portu tutuyordur: sudo ss -tlnp | grep 8080 bu süreci isimlendirir.
yaml: line 14: did not find expected key, belirtilen satırda veya hemen üzerinde bir girinti hatası var. Compose dosyaları YAML formatındadır: iki boşluklu girinti kullanın, sadece boşluk karakteri kullanın ve herhangi bir yerde tab karakteri bulunması işlemin başarısız olmasına neden olur. docker compose config dosyayı başlatmadan doğrular; her düzenlemeden sonra bu komutu çalıştırmak iyi bir alışkanlıktır.
ufw sürprizi hiçbir hata mesajı vermez, bu da onu tehlikeli kılar: dağıtım başarılı görünür, ufw status doğru görünür ancak dışarıdan yapılan bir port taraması veritabanınızı yine de bulur. Yukarıdaki portlar bölümünü tekrar okuyun, her ports: girdisini eksik 127.0.0.1: öneki için kontrol edin ve farklı bir makineden curl http://your-vps-ip:8080 ile doğrulayın; "connection refused" almanız gereken cevaptır.
Buradan itibaren, Traefik rehberi bu tek yığını tek bir HTTPS giriş noktası arkasında birçok uygulamaya dönüştürür ve 2026 yılında self-host etmeye değer olanlar bu yapı üzerinde çalıştırabileceğiniz uygulamaların listesidir. Bu yığınlardan birkaçı çalışmaya başladığında ve her biri kendi giriş formunu oluşturduğunda, Authentik gibi self-hosted bir SSO sunucusu bunları aynı proxy arkasında tek bir hesap altında birleştirir.
bir VPS üzerinde Minecraft sunucusu gibi bir oyun sunucusu, üzerinde pratik yapılabilecek uygun bir ilk Compose projesidir. Her gün açtığınız bir uygulama üzerinde öğrenmeyi tercih ediyorsanız self-host edilen bir egzersiz takip uygulaması olan openGym, image tag yerine bir git tag'e sabitlenmiş küçük bir stack'tir ve ilk passkey'i kaydetmeden önce önünde TLS bulunmasını gerektirir. Fotoğraflar, insanların genellikle başka birinin cloud ortamından geri almak istediği ilk verilerdir. PhotoPrism ve Immich'i karşılaştırmak, bir volume'ü bunlardan birine bağlamadan önce gereken RAM miktarını ve üstlenilecek yedekleme düzenini netleştirir. İki servis yetersiz gelmeye başladığında Notion tarzı bir çalışma alanı olarak AFFiNE'i ayağa kaldırmak, aynı kalıpları dört container'a taşır ve yukarıda sabitlenen tag'lerin, healthcheck'lerin ve adlandırılmış volume'lerin alışkanlığa dönüşüp dönüşmediğini görmek için iyi bir testtir.
FAQ
Neden "permission denied while trying to connect to the Docker daemon socket" hatası alıyorum?
Kullanıcınız docker grubuna dahil değildir veya mevcut oturum başladıktan sonra eklenmiştir; grup üyeliği yalnızca giriş yapıldığında geçerli olur. sudo usermod -aG docker $USER komutunu çalıştırın, ardından newgrp docker komutunu uygulayın veya oturumu kapatıp tekrar açın, son olarak id ile durumu doğrulayın. Bu grup, ana makine üzerinde root ile eşdeğer erişim yetkisi sağlar; bu nedenle yalnızca sudo yetkisi vereceğiniz kullanıcıları ekleyin.
docker compose down verilerimi siler mi?
Düz docker compose down komutu verileri silmez; yalnızca container'ları ve proje ağını kaldırır. İsimlendirilmiş volume'lar (named volumes) korunur ve bir sonraki up -d komutunda tekrar bağlanır. docker compose down -v komutu ise yıkıcıdır: isimlendirilmiş volume'ları, yani veritabanınızı, herhangi bir onay istemeden ve geri dönüşü olmaksızın siler. Doğrulanmış bir yedeğiniz yoksa, gerçek veri içeren bir stack üzerinde asla -v komutunu çalıştırmayın.
docker-compose ile docker compose arasındaki fark nedir?
docker-compose (tireli), 2023 yılında ömrünü tamamlayan ve yeni sunuculara kurulmaması gereken, Python tabanlı bağımsız bir binary olan Compose v1'dir. docker compose (boşluklu) ise Docker'ın apt deposundan docker-compose-plugin olarak kurulan, Docker CLI için geliştirilmiş Go tabanlı bir eklenti olan Compose v2'dir. Komutlar ve YAML yapıları neredeyse tamamen uyumludur; bu nedenle eski bir rehberde docker-compose up ifadesini gördüğünüzde docker compose up yazın.
ufw portu engellemesine rağmen Docker container'ıma internetten neden erişebiliyorum?
Docker, portları iptables üzerindeki PREROUTING zincirinde DNAT kuralları ile yayınladığı ve yeniden yazılan paketler Docker'ın kendi zincirleri üzerinden FORWARD yolunu izlediği için, bu paketler ufw kurallarının uygulandığı INPUT zincirine asla ulaşmaz. Bu nedenle ufw deny 8080, yayınlanan bir container portu üzerinde hiçbir etkiye sahip değildir. Sorunu kaynağında çözün: portları 127.0.0.1: adresine yayınlayın ve servisleri bir reverse proxy üzerinden dış dünyaya açın.
İsimlendirilmiş volume (named volume) mu yoksa bind mount mu kullanmalıyım?
İsimlendirilmiş volume'ları, özellikle veritabanları gibi yalnızca container'ın eriştiği veriler için kullanın; çünkü Docker, imajın beklediği sahiplik ayarlarını otomatik yapar ve izinler sorunsuz çalışır. Bind mount'ları ise düzenlediğiniz yapılandırma dosyaları, yüklediğiniz medya dosyaları veya yolu sizin için belirgin olması gereken her türlü dosya için kullanın. Bir container, bind mount üzerinde permission denied hatası vererek başlamıyorsa, ilk olarak ana makine ile container arasındaki UID uyumsuzluğunu kontrol edin.