Docker & DevOps

    Rootless Docker Kurulumu

    Docker'ı root olmadan çalıştırmanın kurulumu, port kısıtları ve gerçek dünyadaki sınırları.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Docker'ı standart biçimde kurduğunuzda arka planda root olarak çalışan bir servis (daemon) oluşur ve docker grubundaki her kullanıcı bu servise komut gönderebilir. Bunun pek konuşulmayan sonucu şudur: bir kullanıcıyı docker grubuna eklemek, ona pratikte root yetkisi vermektir — çünkü host kök dizinini bağlayan ayrıcalıklı bir konteyner başlatmak birkaç saniyelik iştir. Rootless Docker, tam olarak bu bağı koparmak için vardır: daemon'ı da konteynerleri de sıradan bir kullanıcının yetkisiyle çalıştırır.

    Bu rehberde rootless Docker kurulumunu baştan sona yapacağız: kullanıcı ad alanlarının nasıl çalıştığını, subuid/subgid eşlemelerinin neden gerektiğini, kurulum betiğinin ne yaptığını, systemd kullanıcı servisinin nasıl kalıcı hale getirileceğini ve en çok takılınan konu olan 80/443 port meselesinin nasıl çözüleceğini göreceğiz. Ayrıca dürüst bir "ne zaman kullanmayın" bölümü de ekledim; rootless her senaryo için doğru cevap değildir.

    Rootless Docker Ne Değiştirir#

    Normal kurulumda konteyner içindeki root, host çekirdeğindeki UID 0 ile aynıdır. Rootless modda ise kullanıcı ad alanı (user namespace) devreye girer: konteyner içinde UID 0 görünen süreç, host tarafında size ayrılmış yüksek bir UID aralığına — örneğin 100000 ve sonrası — eşlenir. Yani konteynerden kaçmayı başaran bir süreç, host'ta root değil, sıradan bir kullanıcı olarak devam eder.

    Bunun pratik anlamı büyüktür. Bir konteyner /etc/shadow dosyasını okuyamaz, sistem servislerini durduramaz, çekirdek modülü yükleyemez. Kaçış hâlâ mümkündür ama kazancı çok daha küçüktür. Buna karşılık bazı yetenekleri kaybedersiniz; aşağıdaki tablo dengeyi özetliyor:

    KonuKlasik DockerRootless Docker
    Daemon kullanıcısırootsıradan kullanıcı
    Kaçış sonrası yetkihost'ta roothost'ta sıradan kullanıcı
    80/443 portu bağlamadoğrudanek ayar gerekir
    Ağ performansıyerelbiraz düşük (kullanıcı alanı ağı)
    Cgroup kaynak limitleritamcgroup v2 ve delegasyon gerekir
    Aygıt erişimimümkünçoğunlukla kısıtlı
    Birden fazla kullanıcıtek paylaşılan daemonkullanıcı başına ayrı daemon

    Son satır önemli bir kullanım senaryosuna işaret eder: aynı sunucuda birden fazla kişi çalışıyorsa, her birinin kendi rootless daemon'ı olur ve birbirlerinin konteynerlerini göremezler. Klasik kurulumda ise docker grubundaki herkes tüm konteynerleri yönetebilir. Genel güvenlik önlemlerinin tamamı için Docker güvenlik en iyi pratikleri yazısına da göz atın; rootless, o listedeki önlemlerin yerine geçmez, üzerine eklenir.

    Ön Koşullar: subuid, subgid ve Çekirdek Ayarları#

    Rootless modun temeli, kullanıcınıza ayrılmış bir UID/GID aralığıdır. Modern dağıtımlarda kullanıcı oluşturulurken bu aralık otomatik atanır; kontrol edin:

    # Kullanıcınıza ayrılmış aralıkları görün
    grep "^$(whoami):" /etc/subuid /etc/subgid
    # /etc/subuid:kullanici:100000:65536
    # /etc/subgid:kullanici:100000:65536
    

    Çıktı boşsa aralığı elle tanımlamanız gerekir. 65536 genişlik standarttır ve kullanıcılar arasında çakışmamalıdır:

    sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 kullanici
    

    Ardından gerekli paketleri kurun. uidmap paketi eşlemeyi yapan newuidmap/newgidmap araçlarını sağlar ve olmadan kurulum ilerlemez:

    # Debian / Ubuntu
    sudo apt update && sudo apt install -y uidmap dbus-user-session slirp4netns fuse-overlayfs
    
    # AlmaLinux / Rocky
    sudo dnf install -y shadow-utils fuse-overlayfs iptables
    

    Çalışma zamanı dizinlerinin oturum kapansa bile ayakta kalması için kullanıcı için "lingering" özelliğini açın. Bu adım atlanırsa SSH oturumunuz kapandığında tüm konteynerleriniz durur — sunucuda bunu fark etmek genellikle ertesi gün olur:

    sudo loginctl enable-linger kullanici
    

    Bazı dağıtımlarda ayrıcalıksız kullanıcı ad alanları güvenlik gerekçesiyle kapalıdır. Kontrol edip gerekirse kalıcı olarak açın:

    sysctl kernel.unprivileged_userns_clone
    # 0 dönerse:
    echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-rootless.conf
    sudo sysctl --system
    

    Kurulum Adımları#

    Kurulum betiği kullanıcı dizinine yazar ve sudo gerektirmez. Zaten kurulu bir sistem geneli Docker varsa, ikisi çakışmaz ama farklı soketleri kullandıklarını unutmayın.

    1. Kurulum betiğini indirip çalıştırın:
    curl -fsSL https://get.docker.com/rootless | sh
    # Kurulum ~/bin altına dockerd-rootless.sh ve docker ikililerini yerleştirir
    
    1. Kabuk ortamınıza gerekli değişkenleri ekleyin. DOCKER_HOST en kritik olanıdır; bu değişken olmadan docker komutu sistem soketine bağlanmaya çalışır ve "permission denied" alırsınız:
    cat >> ~/.bashrc << 'EOF'
    export PATH=$HOME/bin:$PATH
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
    EOF
    source ~/.bashrc
    
    1. Kullanıcı servisini başlatın ve açılışta çalışacak biçimde etkinleştirin:
    systemctl --user start docker
    systemctl --user enable docker
    systemctl --user status docker --no-pager
    
    1. Kurulumu doğrulayın. Burada asıl bakacağınız satır, çalışan sürecin kullanıcısıdır:
    docker info | grep -Ei "rootless|Cgroup|Storage Driver"
    # Context: rootless
    # Cgroup Driver: systemd
    # Storage Driver: overlay2
    
    docker run --rm alpine id
    # uid=0(root) gid=0(root) → konteyner içinde root
    ps -o user= -p $(pgrep -f dockerd | head -1)
    # kullanici → ama host tarafında sıradan kullanıcı
    

    Bu son iki komut rootless modun özünü gösterir: konteyner kendini root sanır, host ise onu sizin kullanıcınız olarak görür.

    80 ve 443 Portları Meselesi#

    Rootless kurulumda en çok takılınan nokta budur. Linux'ta 1024 altındaki portları bağlamak ayrıcalık gerektirir, dolayısıyla -p 80:80 denemesi hata verir:

    docker run -d -p 80:80 nginx:alpine
    # Error: rootlesskit: failed to expose port: permission denied
    

    Üç çözüm var ve hangisini seçeceğiniz senaryonuza bağlı.

    Birincisi, yüksek port kullanmak. En temiz ve en az yan etkili yöntemdir: konteyneri 8080'de yayımlar, önüne sistem düzeyinde çalışan bir ters proxy koyarsınız. Zaten üretimde SSL sonlandıran bir proxy olacaksa bu yaklaşım hiçbir şey kaybettirmez. Proxy katmanını Traefik ile ters proxy ya da Nginx Proxy Manager yazılarındaki gibi kurabilirsiniz — ancak dikkat: bu proxy'yi de rootless çalıştırırsanız aynı port sorununu yaşarsınız.

    İkincisi, ayrıcalıklı port eşiğini düşürmek. Sistem genelinde 80 ve üzerini ayrıcalıksız kullanıcılara açarsınız:

    echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/99-rootless-port.conf
    sudo sysctl --system
    

    Bu ayar sistem genelidir ve yalnızca Docker'ı değil, o sunucudaki her kullanıcıyı etkiler. Tek kişilik bir sunucuda kabul edilebilir, çok kullanıcılı bir makinede düşünülmesi gerekir.

    Üçüncüsü, yönlendirme kuralı yazmak. Host üzerinde 80'e geleni 8080'e taşırsınız; bu, sysctl değişikliğine göre daha dar kapsamlıdır ama kalıcı olması için güvenlik duvarı yapılandırmanıza eklenmelidir:

    # Örnek: gelen 80 trafiğini yerel 8080'e taşı
    sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    

    Bir başka ayrıntı: rootless modda konteynerlere gelen isteklerin kaynak IP'si varsayılan ağ sürücüsünde host'un iç adresi olarak görünebilir. Erişim loglarında gerçek ziyaretçi IP'sine ihtiyacınız varsa bunu önündeki proxy'nin X-Forwarded-For başlığından okumanız gerekir.

    Bilinen Kısıtlar ve Ne Zaman Kullanılmamalı#

    Rootless her senaryoya uygun değildir ve bunu baştan bilmek, yarı yolda geri dönmekten iyidir.

    Kaynak limitleri cgroup v2 ve systemd delegasyonu gerektirir. Modern dağıtımlarda bu varsayılan olarak hazırdır, ancak eski çekirdeklerde --memory ve --cpus bayrakları sessizce yok sayılabilir. Limitlerin gerçekten uygulandığını doğrulamak için konteyner başlatıp kontrol edin; limit belirleme yöntemlerini Docker konteyner kaynak limitleri yazısında ele aldık.

    Ağ performansı biraz düşüktür, çünkü trafik kullanıcı alanında çalışan bir ağ yığınından geçer. Sıradan web yükleri için fark hissedilmez, ancak çok yüksek paket hacmi olan işlerde ölçmekte fayda vardır.

    Aygıt erişimi ve özel depolama sürücüleri genellikle çalışmaz. GPU kullanan iş yükleri, doğrudan disk erişimi isteyen uygulamalar ve bazı ağ araçları rootless modda ek yapılandırma ister ya da hiç çalışmaz.

    Sistem servisleri için de uygun değildir. Sunucu açılışında mutlaka ayağa kalkması gereken ve kullanıcı oturumundan bağımsız olması istenen kritik servisler için enable-linger yeterli olsa da, klasik systemd servisi daha öngörülebilirdir.

    Özetle: geliştirme makinesi, çok kullanıcılı paylaşımlı sunucu, düşük riskli iç servisler ve CI çalıştırıcıları rootless için çok uygun senaryolardır. GPU iş yükleri, ağır ağ trafiği ve donanım erişimi gerektiren durumlar ise klasik kurulumda kalmalıdır.

    Günlük Bakım: Güncelleme, Yedek ve İzleme#

    Rootless kurulumda bakım işleri de kullanıcı düzeyine iner ve bu, alışkanlıklarınızı biraz değiştirir. Docker'ı güncellemek için sistem paket yöneticisi yerine kurulum betiğini yeniden çalıştırırsınız; komut yalnızca sizin ev dizininizi etkiler:

    # Servisi durdur, güncelle, tekrar başlat
    systemctl --user stop docker
    curl -fsSL https://get.docker.com/rootless | sh
    systemctl --user start docker
    docker version --format '{{.Server.Version}}'
    

    Yedekleme tarafında bilmeniz gereken tek şey, verilerin yerinin değiştiğidir. Klasik kurulumda /var/lib/docker altında olan her şey rootless modda ev dizinindedir:

    # Hacimlerin ve imajların gerçek yeri
    du -sh ~/.local/share/docker/*
    # Çalışma zamanı soketi ve geçici dosyalar
    ls -l /run/user/$(id -u)/docker.sock
    

    Bu, ev dizininizin bulunduğu bölümün dolması hâlinde Docker'ın da duracağı anlamına gelir. Sunucuda /home ayrı bir bölümdeyse boyutunu buna göre planlayın ve doluluk için bir eşik uyarısı kurun.

    İzleme tarafında servis loglarına systemd kullanıcı birimi üzerinden ulaşırsınız; journalctl komutunu --user bayrağıyla çalıştırmayı unutmak, "log yok" sanılan durumların en sık nedenidir:

    # Daemon logları
    journalctl --user -u docker -n 100 --no-pager
    
    # Servisin gerçekten etkin olup olmadığı
    systemctl --user is-enabled docker
    

    Son olarak bir alışkanlık önerisi: rootless kurulumda birden fazla kullanıcının kendi daemon'ı olabileceği için, sunucuda kimin ne çalıştırdığını görmek istediğinizde tek bir docker ps yetmez. Host tarafında süreçlere bakmak daha kesin bir tablo verir: ps -eo user,pid,comm | grep -E "dockerd|containerd" çıktısı hangi kullanıcının kendi daemon'ını çalıştırdığını doğrudan gösterir.

    Sık Yapılan Hatalar#

    Cannot connect to the Docker daemonDOCKER_HOST değişkeni ayarlanmamıştır ya da yeni açtığınız kabuk .bashrc dosyasını okumamıştır. echo $DOCKER_HOST çıktısı boşsa değişkeni tekrar tanımlayın. Bu hatanın klasik kurulumdaki karşılıklarını Docker daemon socket permission denied yazısında topladık.

    SSH kapanınca konteynerler duruyorloginctl enable-linger çalıştırılmamıştır. Bu tek komut, kullanıcı servislerinin oturumdan bağımsız yaşamasını sağlar.

    newuidmap: write to uid_map faileduidmap paketi kurulu değil ya da /etc/subuid içindeki aralık eksik veya çakışıyordur. Aralığın genişliğinin en az 65536 olduğundan ve başka bir kullanıcıyla kesişmediğinden emin olun.

    Kurulum betiği "systemd bulunamadı" diyor — Kullanıcı systemd oturumu yoktur. dbus-user-session paketini kurup oturumu kapatıp açmak genellikle çözer.

    Hem sistem hem rootless Docker karışıyor — İki daemon ayrı soketler kullanır ve docker ps çıktıları farklıdır. Hangi bağlama komut gönderdiğinizi docker context ls ile görebilir, docker context use rootless ile açıkça seçebilirsiniz.

    Disk hızlı doluyor — Rootless modda veriler ~/.local/share/docker altındadır, yani /var yerine ev dizininizin bulunduğu bölümü doldurur. Bölüm planlamanızı buna göre yapın; temizlik yöntemleri için Docker diski doldurdu, nasıl temizlenir yazısına bakın.

    Sıkça Sorulan Sorular#

    Rootless Docker gerçekten daha güvenli mi#

    Evet, ama sihirli bir kalkan değildir. Sağladığı somut kazanç, konteynerden kaçış senaryosunun sonucunu "host'ta root" yerine "host'ta sıradan kullanıcı" haline getirmesidir; bu, saldırganın yapabileceklerini ciddi biçimde daraltır. Buna karşılık uygulama katmanındaki açıklar, zayıf parolalar ve açık bırakılmış portlar rootless modda da aynen geçerlidir. Diğer sertleştirme önlemlerinin yerine değil, üzerine ekleyin.

    Mevcut konteynerlerimi rootless kuruluma taşıyabilir miyim#

    Doğrudan taşınmaz; iki daemon ayrı veri dizinleri kullanır. Pratik yol, imajları yeniden çekip konteynerleri compose dosyalarınızla yeniden oluşturmaktır. Kalıcı veri hacimlerdeyse, hacim içeriğini arşivleyip yeni ortamda geri açmanız gerekir. Bu yüzden geçişi planlarken önce veri yedeğini almak ve bir bakım penceresi belirlemek doğru olur.

    Rootless modda docker compose çalışır mı#

    Evet, Compose eklentisi rootless daemon ile sorunsuz çalışır; DOCKER_HOST doğru ayarlandığı sürece hiçbir fark hissetmezsiniz. Yalnızca compose dosyanızda 1024 altındaki portlar varsa bunları yüksek portlarla değiştirmeniz ya da yukarıdaki port çözümlerinden birini uygulamanız gerekir.

    Neden konteyner içinde hâlâ root görüyorum#

    Bu beklenen davranıştır ve kafa karıştırıcı olduğu için özellikle vurgulamakta fayda var. Konteyner içindeki id komutu uid=0 gösterir, çünkü kullanıcı ad alanı içinde gerçekten root'sunuzdur. Ancak host tarafında bu kimlik yüksek bir UID'ye eşlenir. Yani "konteyner içinde root" ile "host'ta root" artık aynı şey değildir.

    Performans kaybı ne kadar#

    CPU ve bellek açısından kayda değer bir fark yoktur. Fark ağ ve dosya sistemi katmanında ortaya çıkar: kullanıcı alanı ağ yığını ek işlem yükü getirir, fuse-overlayfs kullanılıyorsa dosya işlemleri biraz yavaşlar. Tipik web uygulamalarında bu farklar veritabanı gecikmesinin yanında görünmez kalır; yoğun G/Ç yapan iş yüklerinde ise ölçüm yapmadan karar vermeyin.

    Kurumsal üretim ortamında kullanılır mı#

    Kullanılır, özellikle çok kullanıcılı derleme sunucularında ve düşük ayrıcalık ilkesinin öncelikli olduğu ortamlarda yaygındır. Ancak donanım erişimi, GPU, özel ağ sürücüleri veya yüksek paket hacmi gerektiren iş yükleri için klasik kurulum tercih edilir. Karar verirken uygulamanızın gerçekten ihtiyaç duyduğu yetenekleri listeleyip rootless kısıtlarıyla karşılaştırmak en pratik yöntemdir.

    Kapanış#

    Rootless Docker kurulumunda akılda tutulacaklar sade: subuid/subgid aralığının tanımlı olduğunu doğrulayın, uidmap ve dbus-user-session paketlerini kurun, DOCKER_HOST değişkenini kabuk profilinize ekleyin, loginctl enable-linger ile servisin oturumdan bağımsız yaşamasını sağlayın ve 80/443 ihtiyacını yüksek port artı ters proxy ile çözün. Kurulumdan sonra docker info çıktısında rootless ibaresini görmek, her şeyin yerine oturduğunun en hızlı doğrulamasıdır.

    Bu tür bir kurulum için sunucu üzerinde tam yetki ve kendi çekirdek ayarlarınızı değiştirebilme imkânı gerekir; VDS ve bulut sunucu paketlerimiz bunu doğrudan sağlar. Daha yüksek yalıtım isteyen senaryolarda dedicated sunucu, sunucu bakımını devretmek istediğinizde ise sunucu yönetimi hizmetimiz uygun bir tamamlayıcı olur.

    DockerGüvenlikLinux

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.