İçindekiler
- 1 Kısa Bir Hikâye ve Yol Haritası: Neden Docker, Neden Şimdi?
- 2 Neyi Nereye Koyuyoruz? Kalıcı Depolama Mantığını Kafada Oturtmak
- 3 VPS’i Hazırlama: Küçük Ama Etkili Dokunuşlar
- 4 docker-compose ile Yığın: Nginx + WordPress (FPM) + MariaDB + Redis
- 5 Nginx Yapılandırması: PHP-FPM, ACME Doğrulaması ve Güvenli Trafik
- 6 Let’s Encrypt: Sertifika Alma ve Otomatik Yenileme
- 7 WordPress’in İncelikleri: Redis, Eklentiler ve Medya
- 8 Günlük Hayat: Yedekleme, Güncelleme, Gözlem ve Sorun Giderme
- 9 Kapanış: Küçük Adımlarla Sağlam Bir Yapı
- 10 Ek: Faydalı Kaynaklar ve Notlar
Kısa Bir Hikâye ve Yol Haritası: Neden Docker, Neden Şimdi?
Hiç başınıza geldi mi? Küçük bir blogu “yarın taşırım” diye erteleyip, bir sabah admin paneline giremediğiniz… Geçen ay ofiste aynen böyle bir sabaha uyandım. Bir arkadaşın WordPress sitesi taşınacak, ama eski sunucuda konfigürasyonlar karışmış, PHP sürümü farklı, eklentiler dağınık. O an düşündüm: Hem taşımayı kolaylaştıran hem de yarın değiştirmek istediğimde elim kolum bağlanmayan bir düzen lazım. İşte bu yüzden Docker’ı seviyorum; parçaları birer kutu gibi bir araya getirip, söküp takabiliyorum. Bugün sana, bu kutulardan oluşan rahat bir evi nasıl kurduğumu anlatacağım.
Plan basit: WordPress’i PHP-FPM ile çalıştıracağız, önünde Nginx olacak. Veritabanı olarak MariaDB, önbellek için Redis devreye girecek. Üstüne Let’s Encrypt ile ücretsiz SSL sertifikası ve docker-compose ile “her şey bir dosyada” konforu. Bir de kalıcı depolama meselesi var; güncellemelerden sonra upload klasörünün uçup gitmesi, veritabanının buhar olması istemeyiz. Hepsini adım adım kuracağız, hatta birkaç gerçek hayattan tuyo ile ufak pürüzlere de önceden merhem süreceğiz. Hazırsan başlayalım.
Neyi Nereye Koyuyoruz? Kalıcı Depolama Mantığını Kafada Oturtmak
Şöyle düşün: VPS’in mutfağı senin kalıcı kilerindir. Kabı değiştirsen de içindekiler kalsın istersin. Docker’da bu işi volumes ile yapıyoruz. WordPress’in kodları ve özellikle wp-content klasörü (yani temalar, eklentiler, yüklenen görseller) kalıcı bir volume üzerinde durmalı. MariaDB’nin veri dosyaları da ayrı bir volume’a. Redis’in verilerini de saklamak isteyebilirsin; append-only ayarıyla, yeniden başlatıldığında kaldığı yerden devam eder.
Bir de SSL sertifikaları var. Let’s Encrypt ile alacağımız sertifikalar ve yenileme işi için ACME doğrulamasında kullanılan dosyalar yine volume’larda tutulmalı. Böylece nginx’i güncellesek, WordPress’i yenilesek, hatta konteynerları tamamen değiştirsek bile veriler olduğu yerde durur. Bu kalıcılık hissi gerçekten insanı rahatlatıyor. Güncellemeyi akşam yaparsın, sabah sorunsuz uyanırsın.
Bu noktada şunu da söyleyeyim: Dosya izinleri çoğu zaman ufak bir taş gibi ayakkabının içine kaçıp can sıkar. WordPress konteynerindeki kullanıcı genelde www-data olur. Volume’ı ilk kez doldurduktan sonra gerekirse izinleri kontrol et; yükleme sorunlarının ciddi bir kısmı buradan çıkar.
VPS’i Hazırlama: Küçük Ama Etkili Dokunuşlar
VPS’te işe önce basit bir temizlikle başlarım: Sistem güncellemelerini alırım, bir kullanıcı oluşturur, SSH için ufak sıkılaştırmalar yaparım. Sonra Docker ve docker-compose’u kurarım. Beni en çok rahatlatan şey, tüm yığının tek bir docker-compose.yml dosyasında toplanması. Tek komutla ayağa kalkar, tek komutla kapanır. Kibrit kutusundan karton bir ev değil, gayet sağlam bir düzen kurduğumu hissederim.
DNS tarafını unutma. Alan adının A/AAAA kayıtları VPS’ini göstermeli. Eğer IPv6 kullanıyorsan ve bunun üzerine oynamak istersen, daha önce paylaştığım IPv6‑only VPS üzerinde yayın yapma deneyimi ilham verebilir. Ama bugün işi sade tutacağız: Alan adına www ve kök domaini aynı sunucuya yönelt yeter.
Son olarak ufak bir not: Güvenlik ayarlarına girmek istersen ve TLS tarafını elden geçirmek hoşuna gidiyorsa, Nginx için detaylı bir rehberim var; TLS 1.3, OCSP Stapling ve Brotli kısmını kurarken yanına alman güzel olur. Birazdan Let’s Encrypt ile sertifika alacağız, ama ince ayarları oradan yürütmek ayrı bir keyif.
docker-compose ile Yığın: Nginx + WordPress (FPM) + MariaDB + Redis
Mesela şöyle düşün: Her servis kendi odasında. Kapılar açık; Nginx ön kapı, WordPress oturma odası, MariaDB kütüphane, Redis de not defteri. Hepsi bir ağda konuşuyor. Aşağıdaki örnek docker-compose.yml bu düzeni kuruyor. Değerleri kendi alan adına, şifrelerine göre değiştirmeni bekliyor.
version: "3.9"
services:
db:
image: mariadb:10.11
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: unless-stopped
environment:
- MARIADB_DATABASE=wordpress
- MARIADB_USER=wpuser
- MARIADB_PASSWORD=degistir-bunu
- MARIADB_ROOT_PASSWORD=degistir-bunu-daha-da-guclu
volumes:
- db_data:/var/lib/mysql
networks:
- wpnet
redis:
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- wpnet
wordpress:
image: wordpress:php8.2-fpm
restart: unless-stopped
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=wpuser
- WORDPRESS_DB_PASSWORD=degistir-bunu
- WORDPRESS_DB_NAME=wordpress
# Basit Redis entegrasyonu için ek sabitler
- WORDPRESS_CONFIG_EXTRA=define('WP_REDIS_HOST','redis'); define('WP_REDIS_PORT',6379);
volumes:
- wp_data:/var/www/html
depends_on:
- db
- redis
networks:
- wpnet
nginx:
image: nginx:1.25-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wp_data:/var/www/html:ro
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- certbot:/etc/letsencrypt
- certbot-challenges:/var/www/certbot
depends_on:
- wordpress
networks:
- wpnet
certbot:
image: certbot/certbot
# İlk kurulum ve yenilemeler için çalıştıracağız; daimi açık kalması gerekmiyor
volumes:
- certbot:/etc/letsencrypt
- certbot-challenges:/var/www/certbot
networks:
- wpnet
networks:
wpnet:
driver: bridge
volumes:
db_data:
redis_data:
wp_data:
certbot:
certbot-challenges:
Burada dikkat: WordPress’i php-fpm imajıyla çalıştırıyoruz. Nginx, PHP işlemlerini fastcgi üzerinden WordPress konteynerine gönderiyor. Nginx konfigürasyonunu birazdan paylaşacağım. Bu yolla Apache ile gelen “hepsi bir arada” çözüme göre daha esnek davranabiliyorsun. Bu tercih hem kaynak kullanımında esneklik veriyor hem de Nginx ayarlarına daha hakim olmanı sağlıyor.
İmaj seçimlerinde kararsız kalırsan WordPress’in resmi Docker sayfasına göz atmak iyi gelir; WordPress Docker imajının açıklamaları işini kolaylaştırır. docker-compose yazımında takılırsan da pratik örneklerle dolu Compose belgeleri elinin altında olsun.
Nginx Yapılandırması: PHP-FPM, ACME Doğrulaması ve Güvenli Trafik
İki dosya hazırlayacağız: Genel ayarlar için nginx/nginx.conf ve siteye özel ayarlar için nginx/conf.d/site.conf. Örnekleri minimal tuttum; ek sıkılaştırmaları kendi ihtiyaçlarına göre genişletebilirsin.
nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server_tokens off;
# GZip'i hafifçe açalım
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml+rss application/xml text/javascript;
include /etc/nginx/conf.d/*.conf;
}
nginx/conf.d/site.conf
Burada example.com yerine kendi alan adını yaz. İlk başta SSL dosyaları olmayacağı için 80 numaralı porttan başlayacağız. Let’s Encrypt’i aldıktan sonra 443 bloğunu da aktif hale getireceğiz.
server {
listen 80;
server_name example.com www.example.com;
# ACME doğrulaması için webroot
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
}
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass wordpress:9000;
fastcgi_read_timeout 300;
}
location ~* .(jpg|jpeg|gif|png|css|js|ico|webp|avif|svg)$ {
expires 30d;
access_log off;
}
}
# Sertifika alındıktan sonra etkinleştir
# server {
# listen 443 ssl http2;
# server_name example.com www.example.com;
# root /var/www/html;
# index index.php index.html index.htm;
#
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
#
# location / {
# try_files $uri $uri/ /index.php?$args;
# }
# location ~ .php$ {
# include fastcgi_params;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_pass wordpress:9000;
# fastcgi_read_timeout 300;
# }
# location ~* .(jpg|jpeg|gif|png|css|js|ico|webp|avif|svg)$ {
# expires 30d;
# access_log off;
# }
# }
HTTP/2 ve HTTP/3 gibi yeni nesil protokoller site deneyimini gözle görülür biçimde akıcılaştırabiliyor. Bu konuyu merak edersen Nginx ve Cloudflare’da HTTP/2‑HTTP/3 kurulumunu anlattığım rehbere göz at. SSL tarafında daha derine inmek istersen de az önce paylaştığım TLS rehberi cebinde dursun.
Let’s Encrypt: Sertifika Alma ve Otomatik Yenileme
Gelelim şapkanın içinden tavşanı çıkardığımız ana. Nginx ayakta, 80’den yayın yapıyor. Artık webroot yöntemiyle Let’s Encrypt’ten sertifikamızı alabiliriz. Bunun için certbot konteynerini tek seferlik çalıştıracağız. Aşağıdaki komutta alan adını ve e‑postayı kendine göre düzenle.
# İlk defa sertifika almak için (webroot yöntemi)
docker compose run --rm certbot certonly
--webroot -w /var/www/certbot
-d example.com -d www.example.com
--email [email protected] --agree-tos --no-eff-email
# Nginx'i yeni sertifikalarla yeniden yükle
docker compose exec -T nginx nginx -s reload
Artık 443 bloğunu etkinleştirip siteyi tamamen HTTPS’e taşıyabilirsin. Uzun vadede yenilemeyi otomatikleştirmek en rahatı. Sunucuda bir cron girdisi ile iki satırlık bir rutin yeterli. Günün sakin bir saatini seç, yenile, sonra Nginx’i sessizce reload et.
# crontab -e ile ekleyebilirsin (örnek: her gün 03:17'de dener)
17 3 * * * cd /path/to/proje && /usr/bin/docker compose run --rm certbot renew --quiet --webroot -w /var/www/certbot && /usr/bin/docker compose exec -T nginx nginx -s reload
Kurulum sırasında takılırsan, resmi Certbot belgeleri net adımlarla yardımcı oluyor. Alternatif ACME istemcileri de var ama bu düzen hem anlaşılır hem de taşınması kolay. Bu arada güvenlik başlıklarını derinleştirmek istersen, HSTS, OCSP Stapling gibi ayarları eklemek için modern TLS mutfağı yazısını kaynak alabilirsin.
WordPress’in İncelikleri: Redis, Eklentiler ve Medya
WordPress ayağa kalktıktan sonra önbellekleme kısmına küçük bir dokunuş yaparsan nefes aldırırsın. Redis için popüler bir eklentiyi kurup aktif edersin, WP_REDIS_HOST ve WP_REDIS_PORT zaten çevrede hazırdır. Dinamik sayfaların hafiflemesi özellikle yoğun saatlerde güzel bir fark yaratır. Aynı şekilde görseller için akıllı bir strateji kurmak uzun vadede en büyük kazançlardan biri olur.
Medya tarafında yükler büyüdükçe depolama derdi can sıkmaya başlar. O noktada “içerik yaşam döngüsü”nü düşünmek iyi gelir. Görselleri bir nesne depolamaya taşıyıp CDN ile sunmak hem VPS’ini rahatlatır hem de dünya genelinde hız kazandırır. Bu konuda adım adım bir yürüyüş istersen WordPress medyayı S3’e taşıma ve CDN rehberi, uygulama örnekleriyle oldukça pratik.
Yine pratik bir not: Eklenti güncellemeleri bazen sürpriz yapar. docker-compose ile çalışırken bir şeyleri bozarsan eski haline dönmek iki komut sürer, ama veritabanı ve wp-content güvende olduğu için ruhun dinlenir. Yine de major güncellemeler öncesi hızlı bir yedek almak her zaman içimi rahatlatır. Birazdan yedeklemeye dair pratik bir öneri bırakacağım.
Günlük Hayat: Yedekleme, Güncelleme, Gözlem ve Sorun Giderme
Yedekleme dediğimde gözlerin dolmasın, basit tutacağız. Veritabanı için mysqldump, dosyalar için tar veya restic gibi araçlar iş görür. Uzaktaki bir S3 uyumlu depoya atıp sürümleme açtığında, geçmişe dönmek çocuk oyuncağına döner. Detaylı bir yaklaşım arıyorsan restic ve S3 uyumlu yedekleme yazım, şifreleme ve saklama politikalarına kadar değiniyor.
Güncellemeye gelince, imajları tazeleyip yeniden ayağa kaldırmak için küçük bir ritüelim var. Compose dosyasını sakince gözden geçirir, sonra imajları çekip hizmeti kesmeden yeniden yaratırım. Genellikle şuna benzer bir akış yeter: docker compose pull, ardından docker compose up -d. Bir şeyler ters giderse docker compose logs ile bakarım. Log’ları daha derli toplu görmek istersen, ileride merkezi bir sistem kurup rahatlamak güzel olur; bunun için Loki + Promtail + Grafana ile merkezi loglama rehberini önerebilirim.
Performans ve sağlık göstergelerini izlemek için hafif bir dashboard kurmak da işini ciddileştirir. CPU, RAM, disk ve ping grafikleri insanın içine su serper. Bu başlıkta yeniysen VPS izleme ve alarm kurulumuna giriş yazısı iyi bir başlangıç noktası. Küçük uyarıları erken fark edince, büyük patlamalar genelde hiç yaşanmaz.
Son olarak ufak hatalarla karşılaşırsan paniğe gerek yok. 403 görüyorsan çoğunlukla dosya izinleri ya da Nginx’in root yolu ile ilgilidir. 502 ise genellikle PHP-FPM’e ulaşamamak demektir; fastcgi_pass hedefini kontrol et. SSL hata veriyorsa sertifika yollarını doğru yazıp yazmadığını ve Nginx’i reload edip etmediğini düşün. Her seferinde bir parçayı doğrulayıp ilerlemek, tüm gizemi hızla çözer.
Kapanış: Küçük Adımlarla Sağlam Bir Yapı
Toparlayalım. Docker sayesinde WordPress’i katman katman kurduk: Nginx ön yüzde trafiği yönetti, WordPress FPM ile hızlıca cevap verdi, MariaDB verileri güvenle sakladı, Redis sayfaları şişirmeden servis etti. Let’s Encrypt ile SSL’i cebimize attık, kalıcı volume’larla güncellemelerden korkmadan yaşar hale geldik. Bütün bu kurgu, yarın taşıman gerektiğinde de omzunu daha az ağrıtır; dosyalar bir kenarda, veritabanı bir kenarda, servisler dosdoğru bir komutla yeniden ayağa kalkar.
Pratik bir tavsiye: Üretime geçmeden önce alan adını bir hosts kaydıyla kendi makinen üzerinden test et. Küçük bir log takibi yap, görseller düzgün dönüyor mu, admin paneli akıcı mı bak. Sonra DNS’i çevir, SSL’i yenilemeyi otomatiğe bağla, haftalık minik bir yedek planı belirle. İnan, bu üçlü kombinasyon sizi uzun süre huzurlu tutar.
Umarım bu rehber sana ilham olmuştur. Kurarken takıldığın yerde bir nefes al, bir parçayı sadeleştir, sonra devam et. Benim mutlu sonum genelde “docker compose up -d” ile başlıyor. Senin de öyle olsun. Bir dahaki yazıda görüşmek üzere.
Ek: Faydalı Kaynaklar ve Notlar
– Docker Compose’un resmi dokümantasyonu: Adım adım örnekler
– WordPress’in resmi Docker imaj sayfası: etiketler, ortam değişkenleri ve varyantlar
– Sertifika yönetimi için: Certbot belgeleri
