Docker ortamlarını terminal üzerinden yönetmek bir süre sonra yorucu hale gelir. Onlarca container, birden fazla compose dosyası, log takibi, kaynak kullanımı izleme… Tüm bunları tek bir web arayüzünden yönetebilmek hem zaman kazandırır hem de ekip arkadaşlarınızın Docker bilgisi olmadan bile operasyonları yürütmesine olanak tanır. Portainer tam olarak bu sorunu çözer ve Docker Compose uygulamalarını yönetmede gerçekten güçlü bir araçtır.
Portainer Nedir ve Neden Kullanmalısınız?
Portainer, Docker ve Kubernetes ortamlarını web arayüzü üzerinden yönetmenizi sağlayan açık kaynaklı bir container yönetim platformudur. CE (Community Edition) sürümü ücretsizdir ve çoğu kullanım senaryosu için fazlasıyla yeterlidir.
Portainer’ın öne çıktığı noktalar şunlardır:
- Stack yönetimi: Docker Compose dosyalarını “stack” olarak yükleyip yönetebilirsiniz
- Gerçek zamanlı izleme: Container CPU, bellek ve ağ kullanımını anlık takip edebilirsiniz
- Log görüntüleme: Her container’ın loglarını tarayıcıdan okuyabilirsiniz
- Çoklu ortam desteği: Birden fazla Docker host’unu tek arayüzden yönetebilirsiniz
- Rol tabanlı erişim: Takım üyelerine farklı yetki seviyeleri atayabilirsiniz
- Image yönetimi: Image çekme, silme ve inceleme işlemlerini kolayca yapabilirsiniz
Özellikle birden fazla kişinin çalıştığı ortamlarda veya müşterilere self-servis bir panel sunmak istediğinizde Portainer hayat kurtarır.
Portainer Kurulumu
Portainer’ı kurmak için önce bir Docker volume oluşturup ardından container’ı ayağa kaldırmanız gerekir.
# Portainer verisi için volume oluştur
docker volume create portainer_data
# Portainer CE container'ını başlat
docker run -d
-p 8000:8000
-p 9443:9443
--name portainer
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
portainer/portainer-ce:latest
Kurulum tamamlandıktan sonra https://sunucu-ip:9443 adresine giderek Portainer’a erişebilirsiniz. İlk girişte admin kullanıcısı için parola belirlemeniz istenecektir.
Eğer Portainer’ı kenisi de bir Compose dosyasıyla yönetmek isterseniz, bu yaklaşım daha düzenli bir yapı sağlar:
# portainer-docker-compose.yml
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "8000:8000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
environment:
- TZ=Europe/Istanbul
volumes:
portainer_data:
driver: local
docker compose -f portainer-docker-compose.yml up -d
Stack Kavramı: Compose Dosyalarının Portainer Karşılığı
Portainer dünyasında Docker Compose projelerine stack denir. Bir stack, bir veya birden fazla servisi içeren, tek bir Compose dosyasıyla tanımlanan uygulama grubudur. Stack’ler üç farklı yöntemle oluşturulabilir:
- Web editor: Compose içeriğini doğrudan tarayıcıda yazabilirsiniz
- Upload: Yerel makinenizdeki compose dosyasını yükleyebilirsiniz
- Git repository: Bir Git reposundan otomatik çekme yapabilirsiniz
Git repository seçeneği özellikle GitOps iş akışları için çok değerlidir. Reponuzdaki compose dosyası değiştiğinde Portainer otomatik olarak stack’i güncelleyebilir.
İlk Stack’i Oluşturma: Gerçek Dünya Örneği
Örnek olarak bir WordPress + MySQL + Redis stack’i oluşturalım. Portainer arayüzünde sol menüden “Stacks” seçeneğine tıklayın, ardından “+ Add stack” butonuna basın.
Stack adını wordpress-production olarak girin ve Web editor sekmesinde şu Compose içeriğini yapıştırın:
version: '3.8'
services:
db:
image: mysql:8.0
container_name: wp_mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
networks:
- wp_network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:6.4-php8.2-apache
container_name: wp_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
WORDPRESS_DB_USER: ${MYSQL_USER}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_CONFIG_EXTRA: |
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
volumes:
- wp_data:/var/www/html
networks:
- wp_network
redis:
image: redis:7-alpine
container_name: wp_redis
restart: unless-stopped
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- wp_network
networks:
wp_network:
driver: bridge
volumes:
mysql_data:
wp_data:
redis_data:
Dikkat edin, compose dosyasında ${MYSQL_ROOT_PASSWORD} gibi environment variable’lar kullandık. Portainer bu değişkenleri arayüzün alt kısmındaki “Environment variables” bölümünden almanızı sağlar. Hassas bilgileri doğrudan YAML dosyasına yazmamanız güvenlik açısından kritik önem taşır.
Environment variables bölümüne şu değerleri ekleyin:
MYSQL_ROOT_PASSWORD= güçlü-bir-parolaMYSQL_DATABASE= wordpressMYSQL_USER= wpuserMYSQL_PASSWORD= kullanici-parolasi
“Deploy the stack” butonuna tıkladığınızda Portainer tüm servisleri sırayla başlatacaktır.
Stack Yönetimi: Güncelleme, Durdurma ve Silme
Stack oluşturduktan sonra Portainer arayüzü üzerinden birçok işlemi kolayca yapabilirsiniz.
Stack Güncelleme
Bir image güncellemek veya compose dosyasını değiştirmek istediğinizde stack detay sayfasına gidip “Editor” sekmesinden değişikliklerinizi yapın ve “Update the stack” butonuna tıklayın. Portainer değişen servisleri yeniden oluşturacaktır.
Örneğin WordPress imajını güncellemek için sadece ilgili satırı değiştirmeniz yeterlidir:
# Eski
image: wordpress:6.4-php8.2-apache
# Yeni
image: wordpress:6.5-php8.3-apache
Stack’i Tamamen Yeniden Dağıtma
Bazen tüm stack’i sıfırdan başlatmanız gerekebilir. Bunu terminal üzerinden yapmak isterseniz:
# Portainer ile yönetilen stack'lerin compose dosyaları bu dizinde bulunur
ls /var/lib/docker/volumes/portainer_data/_data/compose/
# Stack ID'sini öğrendikten sonra manuel müdahale yapılabilir
# Ancak bunu Portainer arayüzü üzerinden yapmak daha güvenlidir
Git Entegrasyonu ile GitOps İş Akışı
Portainer’ın en güçlü özelliklerinden biri Git repository entegrasyonudur. Ekibinizin compose dosyalarını bir Git reposunda tutması ve Portainer’ın bu repodan otomatik deployment yapması, production ortamlarında müthiş bir kolaylık sağlar.
Stack oluştururken “Repository” sekmesini seçin ve şu bilgileri doldurun:
- Repository URL:
https://github.com/sirketiniz/infra-configs - Repository reference:
refs/heads/main - Compose path:
production/wordpress/docker-compose.yml
Eğer özel bir repo kullanıyorsanız authentication bilgilerini de girmeniz gerekir.
Auto update seçeneğini aktif ederek polling aralığını 5 dakika olarak ayarlarsanız, repoya her push yaptığınızda Portainer otomatik olarak stack’i güncelleyecektir. CI/CD pipeline’ınızla birleştirdiğinizde tam anlamıyla bir GitOps akışı elde edersiniz.
Webhook tabanlı güncelleme için Portainer size özel bir webhook URL’i verir. Bu URL’yi GitHub Actions veya GitLab CI pipeline’ınıza ekleyebilirsiniz:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Trigger Portainer Webhook
run: |
curl -X POST "${{ secrets.PORTAINER_WEBHOOK_URL }}"
Container Yönetimi: Log, Exec ve İzleme
Stack oluşturduktan sonra container’larla doğrudan etkileşim kurmak için Portainer’ın container yönetim ekranlarını kullanabilirsiniz.
Log Takibi
Container detay sayfasında “Logs” butonuna tıkladığınızda gerçek zamanlı log akışını görebilirsiniz. Özellikle hata ayıklama sırasında bu ekran çok değerlidir.
Terminal üzerinden aynı işlemi yapabilirsiniz:
# Container adını biliyorsanız
docker logs wp_app --follow --tail 100
# Belirli bir zaman dilimindeki logları görmek için
docker logs wp_app --since "2024-01-15T10:00:00" --until "2024-01-15T11:00:00"
Container İçine Bağlanma (Exec)
Portainer’ın “Console” özelliği, container içine tarayıcı üzerinden bağlanmanızı sağlar. Bu özellik özellikle SSH erişiminin olmadığı ortamlarda büyük kolaylık sağlar.
“Exec” butonuna tıklayın, /bin/bash veya /bin/sh yazın ve “Connect” deyin. Artık container içinde terminal oturumunuz açıktır.
Aynı işlemi terminalde şöyle yaparsınız:
# Container içine bash ile bağlan
docker exec -it wp_app /bin/bash
# Tek satırlık komut çalıştırma
docker exec wp_app wp --info
# MySQL container'ına bağlanma
docker exec -it wp_mysql mysql -u root -p
Kaynak Kullanımı İzleme
Portainer’ın container detay sayfasındaki “Stats” sekmesi CPU, bellek, ağ ve disk I/O metriklerini gerçek zamanlı grafiklerle gösterir. Ancak bu ekran sadece anlık veri sunar, tarihsel veri görmek için Grafana + Prometheus gibi bir monitoring stack’i kurmanız gerekir.
Portainer ile Nginx Proxy Manager Entegrasyonu
Gerçek dünya senaryolarında birden fazla uygulamayı aynı sunucuda çalıştırıyorsanız, bir reverse proxy çözümüne ihtiyaç duyarsınız. Nginx Proxy Manager ve Portainer’ı birlikte kullanmak bu sorunu çözer.
Portainer üzerinden yeni bir stack oluşturun ve adını nginx-proxy-manager koyun:
version: '3.8'
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx_proxy_manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
networks:
- proxy_network
networks:
proxy_network:
external: false
name: proxy_network
volumes:
npm_data:
npm_letsencrypt:
Artık diğer stack’leri bu ağa bağlayarak Nginx Proxy Manager üzerinden yönlendirme yapabilirsiniz. WordPress stack’inizi güncellerken proxy_network harici ağına bağlayın:
networks:
wp_network:
driver: bridge
proxy_network:
external: true
Ve wordpress servisine de bu ağı ekleyin:
wordpress:
networks:
- wp_network
- proxy_network
Birden Fazla Docker Host Yönetimi
Portainer’ın gerçek gücü birden fazla sunucuyu tek panelden yönetme yeteneğinde ortaya çıkar. Bunu iki farklı şekilde yapabilirsiniz:
Portainer Agent yöntemi daha güvenli ve önerilen yaklaşımdır. Uzak sunuculara Portainer Agent kurarsınız, ardından Portainer’dan bu agent’lara bağlantı tanımlarsınız.
Uzak sunucuda agent kurulumu:
# Uzak sunucuda çalıştırın
docker run -d
-p 9001:9001
--name portainer_agent
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v /var/lib/docker/volumes:/var/lib/docker/volumes
portainer/agent:latest
Ardından Portainer arayüzünde “Environments” menüsüne gidip “Add environment” tıklayın. “Docker Standalone” seçin ve agent URL’ini tcp://uzak-sunucu-ip:9001 şeklinde girin.
Birden fazla ortamınız olduğunda environment seçiciden hızlıca geçiş yapabilirsiniz. Production, staging ve development ortamlarınızı tek arayüzden yönetmek inanılmaz zaman tasarrufu sağlar.
Güvenlik Yapılandırması
Portainer’ı production ortamında kullanıyorsanız bazı güvenlik önlemleri almanız şarttır.
SSL Sertifikası
Portainer varsayılan olarak 9443 portunda self-signed sertifika kullanır. Let’s Encrypt sertifikası kullanmak için reverse proxy arkasına almanız veya kendi sertifikanızı mount etmeniz gerekir:
# Kendi sertifikanızı kullanma
docker run -d
-p 9443:9443
--name portainer
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
-v /path/to/cert.pem:/certs/portainer.crt:ro
-v /path/to/key.pem:/certs/portainer.key:ro
portainer/portainer-ce:latest
--sslcert /certs/portainer.crt
--sslkey /certs/portainer.key
Güvenlik Duvarı Kuralları
Portainer portlarını herkese açık bırakmayın:
# Sadece belirli IP'nin erişimine izin ver
ufw allow from 10.0.0.0/24 to any port 9443
ufw allow from 10.0.0.0/24 to any port 9001
# Genel erişimi engelle
ufw deny 9443
ufw deny 9001
Kullanıcı ve Rol Yönetimi
Portainer CE sürümünde kullanıcı oluşturabilir ve bunlara farklı roller atayabilirsiniz:
- Administrator: Tam erişim, tüm ortamları yönetebilir
- Standard user: Yetki verilen kaynaklara sınırlı erişim
- Edge administrator: Sadece edge agent’ları yönetebilir
Ekip arkadaşlarınıza sadece ihtiyaç duydukları minimum yetkileri verin. Bir developer’ın production veritabanı container’ını silmesini istemezsiniz.
Backup ve Restore Stratejisi
Portainer konfigürasyonunun yedeğini almak önemlidir. Portainer’ın tüm konfigürasyonu portainer_data volume’unda saklanır.
# Portainer volume'unu yedekle
docker run --rm
-v portainer_data:/data
-v $(pwd)/backup:/backup
ubuntu tar czf /backup/portainer-backup-$(date +%Y%m%d).tar.gz /data
# Yedeği geri yükle
docker stop portainer
docker run --rm
-v portainer_data:/data
-v $(pwd)/backup:/backup
ubuntu bash -c "cd / && tar xzf /backup/portainer-backup-20240115.tar.gz"
docker start portainer
Stack backup’ları için ise Git repository kullanmak en iyi pratiktir. Tüm compose dosyalarınızı bir Git reposunda tutarsanız, Portainer’ı sıfırdan kurduğunuzda bile stack’lerinizi hızlıca geri yükleyebilirsiniz.
Yaygın Sorunlar ve Çözümleri
Stack Deploy Sonrası Container’lar Başlamıyor
Bu durumda önce stack event log’larını kontrol edin. Portainer stack detay sayfasında “Events” sekmesi sorunun kaynağını genellikle açıkça gösterir.
# Terminal üzerinden container başlangıç loglarını kontrol et
docker compose -f /path/to/compose.yml logs --no-color 2>&1 | head -100
# Belirli bir container'ın exit kodunu öğren
docker inspect wp_mysql --format='{{.State.ExitCode}}'
Environment Variable’lar Tanınmıyor
Portainer’da stack oluştururken environment variable’ları “Environment variables” bölümünde tanımlamanız gerekir. Alternatif olarak .env dosyasını compose dosyasıyla aynı stack içinde kullanabilirsiniz ancak Portainer bu dosyayı otomatik okumaz. En güvenilir yöntem her değişkeni Portainer arayüzünden tek tek tanımlamaktır.
Port Çakışması
Birden fazla stack aynı portu kullanmaya çalışıyorsa deployment başarısız olur. Stack detay sayfasındaki hata mesajı genellikle hangi portun çakıştığını söyler.
# Hangi port'un kullanıldığını kontrol et
ss -tlnp | grep :80
# veya
netstat -tlnp | grep :80
Sonuç
Portainer, Docker Compose uygulamalarını yönetme konusunda sysadmin iş akışını önemli ölçüde kolaylaştırır. Tek bir web arayüzünden stack deployment, container log takibi, kaynak izleme ve çoklu sunucu yönetimi yapabilmek, özellikle küçük ve orta ölçekli operasyonlarda büyük verimlilik sağlar.
Başlangıç için önerim şu sırayla ilerlemek: Önce Portainer’ı kendi bir compose stack’i olarak kurun. Ardından mevcut uygulamalarınızı birer birer Portainer’a taşıyın. Git entegrasyonunu aktif edin ve compose dosyalarınızı bir repoda tutmaya başlayın. Son olarak ekip üyeleriniz için uygun rolleri tanımlayın.
Portainer mükemmel bir araç olmakla birlikte, Kubernetes ortamlarında veya çok büyük ölçekli deploymentlarda yetersiz kalabilir. Bu noktada ArgoCD veya Rancher gibi araçlara geçiş düşünülebilir. Ancak küçük ve orta ölçekli Docker ortamları için Portainer, karmaşıklık ve yetenek arasındaki dengeyi mükemmel biçimde kurar.