{"id":1650,"date":"2025-11-10T21:48:44","date_gmt":"2025-11-10T18:48:44","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/docker-compose-ile-wordpress-nginx-mariadb-redis-nasil-tatli-tatli-akiyor-kalici-hacimler-otomatik-yedek-ve-guncelleme-akisi\/"},"modified":"2025-11-10T21:48:44","modified_gmt":"2025-11-10T18:48:44","slug":"docker-compose-ile-wordpress-nginx-mariadb-redis-nasil-tatli-tatli-akiyor-kalici-hacimler-otomatik-yedek-ve-guncelleme-akisi","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/docker-compose-ile-wordpress-nginx-mariadb-redis-nasil-tatli-tatli-akiyor-kalici-hacimler-otomatik-yedek-ve-guncelleme-akisi\/","title":{"rendered":"Docker Compose ile WordPress + Nginx + MariaDB + Redis Nas\u0131l Tatl\u0131 Tatl\u0131 Ak\u0131yor? Kal\u0131c\u0131 Hacimler, Otomatik Yedek ve G\u00fcncelleme Ak\u0131\u015f\u0131"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Hikaye_Gibi_Bir_Giris_Kucuk_Bir_Tikaniklik_Buyuk_Bir_Akis\"><span class=\"toc_number toc_depth_1\">1<\/span> Hikaye Gibi Bir Giri\u015f: K\u00fc\u00e7\u00fck Bir T\u0131kan\u0131kl\u0131k, B\u00fcy\u00fck Bir Ak\u0131\u015f<\/a><\/li><li><a href=\"#Resmi_Netlestirelim_WordPress_Nginx_MariaDB_ve_Redis_Nasil_Konusur\"><span class=\"toc_number toc_depth_1\">2<\/span> Resmi Netle\u015ftirelim: WordPress, Nginx, MariaDB ve Redis Nas\u0131l Konu\u015fur?<\/a><\/li><li><a href=\"#Kalici_Hacimler_Dosyalar_Nerede_Neden_Bu_Kadar_Onemli\"><span class=\"toc_number toc_depth_1\">3<\/span> Kal\u0131c\u0131 Hacimler: Dosyalar Nerede, Neden Bu Kadar \u00d6nemli?<\/a><\/li><li><a href=\"#docker-composeyml_Calisir_Bir_Ornek_ve_Kucuk_Sirlar\"><span class=\"toc_number toc_depth_1\">4<\/span> docker-compose.yml: \u00c7al\u0131\u015f\u0131r Bir \u00d6rnek ve K\u00fc\u00e7\u00fck S\u0131rlar<\/a><ul><li><a href=\"#Compose_Dosyasi\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Compose Dosyas\u0131<\/a><\/li><li><a href=\"#env_Dosyasi\"><span class=\"toc_number toc_depth_2\">4.2<\/span> .env Dosyas\u0131<\/a><\/li><li><a href=\"#Yedek_Scripti\"><span class=\"toc_number toc_depth_2\">4.3<\/span> Yedek Script\u2019i<\/a><\/li><li><a href=\"#Ilk_Calistirma\"><span class=\"toc_number toc_depth_2\">4.4<\/span> \u0130lk \u00c7al\u0131\u015ft\u0131rma<\/a><\/li><\/ul><\/li><li><a href=\"#Nginx_ve_Redis_Vitrini_Parlatmak_Icerigi_Hizlandirmak\"><span class=\"toc_number toc_depth_1\">5<\/span> Nginx ve Redis: Vitrini Parlatmak, \u0130\u00e7eri\u011fi H\u0131zland\u0131rmak<\/a><ul><li><a href=\"#Nginx_Yapilandirmasi\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Nginx Yap\u0131land\u0131rmas\u0131<\/a><\/li><li><a href=\"#Redisi_WordPresse_Tanitmak\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Redis\u2019i WordPress\u2019e Tan\u0131tmak<\/a><\/li><\/ul><\/li><li><a href=\"#Otomatik_Yedek_ve_Geri_Yukleme_ile_Guncelleme_Akisi_Once_Emniyet_Sonra_Cesaret\"><span class=\"toc_number toc_depth_1\">6<\/span> Otomatik Yedek ve Geri Y\u00fckleme ile G\u00fcncelleme Ak\u0131\u015f\u0131: \u00d6nce Emniyet, Sonra Cesaret<\/a><ul><li><a href=\"#Yedek_Akisi\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Yedek Ak\u0131\u015f\u0131<\/a><\/li><li><a href=\"#Geri_Yukleme_Komutlari\"><span class=\"toc_number toc_depth_2\">6.2<\/span> Geri Y\u00fckleme Komutlar\u0131<\/a><\/li><li><a href=\"#Guncelleme_Akisi\"><span class=\"toc_number toc_depth_2\">6.3<\/span> G\u00fcncelleme Ak\u0131\u015f\u0131<\/a><\/li><li><a href=\"#WP-CLI_ile_Guncelleme\"><span class=\"toc_number toc_depth_2\">6.4<\/span> WP-CLI ile G\u00fcncelleme<\/a><\/li><li><a href=\"#Uygulama_Imajlarini_Guncellemek\"><span class=\"toc_number toc_depth_2\">6.5<\/span> Uygulama \u0130majlar\u0131n\u0131 G\u00fcncellemek<\/a><\/li><li><a href=\"#Ince_Ayarlar_ve_Kucuk_Taktikler\"><span class=\"toc_number toc_depth_2\">6.6<\/span> \u0130nce Ayarlar ve K\u00fc\u00e7\u00fck Taktikler<\/a><\/li><li><a href=\"#Compose_Referanslarina_Bakmak_Iyi_Gelir\"><span class=\"toc_number toc_depth_2\">6.7<\/span> Compose Referanslar\u0131na Bakmak \u0130yi Gelir<\/a><\/li><\/ul><\/li><li><a href=\"#Kapanis_Bir_Kez_Kur_Hep_Guven\"><span class=\"toc_number toc_depth_1\">7<\/span> Kapan\u0131\u015f: Bir Kez Kur, Hep G\u00fcven<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"Hikaye_Gibi_Bir_Giris_Kucuk_Bir_Tikaniklik_Buyuk_Bir_Akis\">Hikaye Gibi Bir Giri\u015f: K\u00fc\u00e7\u00fck Bir T\u0131kan\u0131kl\u0131k, B\u00fcy\u00fck Bir Ak\u0131\u015f<\/span><\/h2>\n<p>Hi\u00e7 canl\u0131 sitede minik bir d\u00fczenlemeyi yay\u0131nlay\u0131p, sonra \u201cBir \u015feyler yava\u015flad\u0131 ama nereden?\u201d diye ekran kar\u015f\u0131s\u0131nda i\u00e7 \u00e7ektiniz mi? Ben bir sabah tam da bu tabloyla kar\u015f\u0131la\u015ft\u0131m. Edit\u00f6r bir g\u00f6rseli de\u011fi\u015ftirmi\u015f, eklentilerden biri de hem veritaban\u0131n\u0131 hem disk yazmalar\u0131n\u0131 biraz s\u0131k\u0131\u015ft\u0131rm\u0131\u015f. Sayfalar a\u00e7\u0131l\u0131yor ama bir a\u011f\u0131rl\u0131k var. O an d\u00fc\u015f\u00fcnd\u00fcm: \u015eu kurdu\u011fumuz WordPress\u2019i biraz daha sa\u011flam bir altyap\u0131n\u0131n \u00fcst\u00fcne koyman\u0131n zaman\u0131 gelmedi mi?<\/p>\n<p>\u0130\u015fte bu yaz\u0131 tam oradan do\u011fdu. <strong>Docker Compose ile WordPress + Nginx + MariaDB + Redis<\/strong> kurulumunu tek bir nefeste anlatmak istiyorum. \u00dcstelik sadece \u00e7al\u0131\u015ft\u0131r\u0131p b\u0131rakmak de\u011fil; <strong>kal\u0131c\u0131 hacimler<\/strong> ile verinin g\u00fcvenini, <strong>otomatik yedek<\/strong> ak\u0131\u015f\u0131yla i\u00e7 huzuru ve <strong>g\u00fcncelleme ak\u0131\u015f\u0131<\/strong> ile \u201chadi bakal\u0131m, korkmadan bast\u0131m g\u00fcncelle\u201d \u00f6zg\u00fcvenini beraber kuraca\u011f\u0131z. Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: Bir kez d\u00fczenini kurdunuz mu, sonras\u0131 rutin bir sabah kahvesi gibi. Kokusu tan\u0131d\u0131k, tad\u0131 dengeli.<\/p>\n<p>Yol boyunca basit \u00f6rnekler, k\u00fc\u00e7\u00fck notlar ve \u201cbunu b\u00f6yle yap\u0131nca rahat ediyorsun\u201d diyece\u011fim anlar olacak. Teknik terimleri zorlamadan, ama i\u015fin p\u00fcf noktalar\u0131n\u0131 saklamadan anlataca\u011f\u0131m. Haz\u0131rsan\u0131z ba\u015flayal\u0131m.<\/p>\n<h2 id=\"section-2\"><span id=\"Resmi_Netlestirelim_WordPress_Nginx_MariaDB_ve_Redis_Nasil_Konusur\">Resmi Netle\u015ftirelim: WordPress, Nginx, MariaDB ve Redis Nas\u0131l Konu\u015fur?<\/span><\/h2>\n<p>G\u00f6z\u00fcn\u00fczde \u015f\u00f6yle canland\u0131r\u0131n: Sahnenin ortas\u0131nda WordPress var. Kula\u011f\u0131nda bir yanda <strong>MariaDB<\/strong>\u2019nin verileri, di\u011fer yanda <strong>Redis<\/strong>\u2019in h\u0131zl\u0131 f\u0131s\u0131lt\u0131lar\u0131. \u00d6n tarafta ise sahnenin \u0131\u015f\u0131klar\u0131n\u0131 ayarlayan <strong>Nginx<\/strong>. Ziyaret\u00e7i geldi mi Nginx kar\u015f\u0131lar, WordPress\u2019e do\u011fru iletir, WordPress de \u201cveriyi soral\u0131m\u201d der ve MariaDB\u2019ye d\u00f6ner. Ayn\u0131 sorular tekrar tekrar sorulmas\u0131n diye Redis devreye girer, \u201cBunun cevab\u0131 bende var\u201d der ve site birden ferahlar.<\/p>\n<p>Docker Compose burada b\u00fct\u00fcn bu oyuncular\u0131 tek bir yerde toplar. \u201c\u015eu konteyner Nginx, \u015fu WordPress, \u015fu MariaDB, \u015fu da Redis\u201d diye dosyada anlat\u0131rs\u0131n\u0131z, hepsini ayn\u0131 a\u011fda bulu\u015fturursunuz. En g\u00fczel taraf\u0131, her biri kendi kutusunda. Yani Nginx\u2019i g\u00fcncellersiniz, MariaDB\u2019ye dokunmaz. Redis\u2019i ayarlars\u0131n\u0131z, WordPress huzurla i\u015fine devam eder. K\u00fc\u00e7\u00fck bir tiyatro ekibi gibi, herkes rol\u00fcn\u00fc bilir.<\/p>\n<p>Bu kompozisyonun g\u00fcc\u00fc, par\u00e7alar\u0131n net ayr\u0131lmas\u0131ndan geliyor. Siz sadece ak\u0131\u015f\u0131 y\u00f6netirsiniz. Bir dosyada (Compose) \u201c\u015fu portlar, \u015fu hacimler, \u015fu de\u011fi\u015fkenler\u201d dersiniz ve tekrar edilebilir bir d\u00fczen kurars\u0131n\u0131z. Tam da bu y\u00fczden harekete ge\u00e7iyoruz.<\/p>\n<h2 id=\"section-3\"><span id=\"Kalici_Hacimler_Dosyalar_Nerede_Neden_Bu_Kadar_Onemli\">Kal\u0131c\u0131 Hacimler: Dosyalar Nerede, Neden Bu Kadar \u00d6nemli?<\/span><\/h2>\n<p>WordPress\u2019te verinin kalbi iki yerde atar: <strong>veritaban\u0131<\/strong> ve <strong>wp-content<\/strong>. Biri yaz\u0131lar\u0131n\u0131z, ayarlar\u0131n\u0131z, yorumlar\u0131n\u0131z; di\u011feri temalar, eklentiler, g\u00f6rseller. Konteynerler gelip ge\u00e7icidir; bug\u00fcn var, yar\u0131n g\u00fcncellenir. Ama bu iki set, yani <strong>db_data<\/strong> ve <strong>wp_data<\/strong>, kal\u0131c\u0131 olmal\u0131. \u0130\u015fte bu y\u00fczden <strong>volume<\/strong> kullan\u0131r\u0131z.<\/p>\n<p>Redis i\u00e7in de kal\u0131c\u0131l\u0131k isteyebilirsiniz. Baz\u0131 kurulumlarda Redis sadece ge\u00e7ici bellektir; kapand\u0131\u011f\u0131nda silinse de sorun olmaz. Ama bazen \u201cAOF\u201d denilen g\u00fcnl\u00fck tutma ayar\u0131yla kal\u0131c\u0131la\u015ft\u0131r\u0131rs\u0131n\u0131z. Bu, \u00f6zellikle nesne \u00f6nbelle\u011fini uzun s\u00fcreli saklamak istedi\u011finizde faydal\u0131 olur. Ben genelde \u201ci\u015fimi g\u00f6rs\u00fcn, ama kapans\u0131n da d\u00fcnyan\u0131n sonu olmas\u0131n\u201d yakla\u015f\u0131m\u0131nday\u0131m; Redis\u2019i taktiksel, veritaban\u0131n\u0131 stratejik d\u00fc\u015f\u00fcn\u00fcr\u00fcm.<\/p>\n<p>Kal\u0131c\u0131 hacimler, sadece veri g\u00fcveni de\u011fil, <strong>yedek ak\u0131\u015f\u0131n\u0131n basitle\u015fmesi<\/strong> demek. \u00c7\u00fcnk\u00fc \u201cal \u015fu klas\u00f6r\u00fc ve \u015fu veritaban\u0131n\u0131 yedekle\u201d talimat\u0131 birka\u00e7 sat\u0131rl\u0131k bir script\u2019e d\u00f6n\u00fc\u015f\u00fcr. Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: wp-content\u2019i s\u0131k\u0131\u015ft\u0131r, veritaban\u0131n\u0131 d\u0131\u015fa aktar, ikisini birlikte sakla. Geri y\u00fcklemek de ayn\u0131 kadar d\u00fcz, bu kadar.<\/p>\n<h2 id=\"section-4\"><span id=\"docker-composeyml_Calisir_Bir_Ornek_ve_Kucuk_Sirlar\">docker-compose.yml: \u00c7al\u0131\u015f\u0131r Bir \u00d6rnek ve K\u00fc\u00e7\u00fck S\u0131rlar<\/span><\/h2>\n<h3><span id=\"Compose_Dosyasi\">Compose Dosyas\u0131<\/span><\/h3>\n<p>A\u015fa\u011f\u0131daki \u00f6rnek, tek bir klas\u00f6rden aya\u011fa kalkacak temel bir d\u00fczen sunuyor. Nginx, WordPress (PHP-FPM), MariaDB ve Redis bir a\u011fda bulu\u015fuyor; kal\u0131c\u0131 hacimler ba\u011flan\u0131yor; ufak sa\u011fl\u0131k kontrolleri konuluyor. \u00dcst\u00fcne bir de otomatik yedek i\u00e7in k\u00fc\u00e7\u00fck bir servis haz\u0131rl\u0131yoruz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">version: &quot;3.9&quot;\n\nservices:\n  db:\n    image: mariadb:10.11\n    container_name: wp_db\n    command: [&quot;--skip-log-bin&quot;, &quot;--innodb-buffer-pool-size=256M&quot;]\n    environment:\n      - MARIADB_DATABASE=${DB_NAME}\n      - MARIADB_USER=${DB_USER}\n      - MARIADB_PASSWORD=${DB_PASSWORD}\n      - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}\n    volumes:\n      - db_data:\/var\/lib\/mysql\n    healthcheck:\n      test: [&quot;CMD&quot;, &quot;mysqladmin&quot;, &quot;ping&quot;, &quot;-h&quot;, &quot;127.0.0.1&quot;]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n    restart: unless-stopped\n\n  redis:\n    image: redis:7-alpine\n    container_name: wp_redis\n    command: [&quot;redis-server&quot;, &quot;--appendonly&quot;, &quot;yes&quot;, &quot;--save&quot;, &quot;60&quot;, &quot;1000&quot;]\n    volumes:\n      - redis_data:\/data\n    restart: unless-stopped\n\n  wordpress:\n    image: wordpress:php8.2-fpm\n    container_name: wp_php\n    environment:\n      - WORDPRESS_DB_HOST=db:3306\n      - WORDPRESS_DB_NAME=${DB_NAME}\n      - WORDPRESS_DB_USER=${DB_USER}\n      - WORDPRESS_DB_PASSWORD=${DB_PASSWORD}\n      - WORDPRESS_CONFIG_EXTRA=define('WP_REDIS_HOST','redis');n define('WP_MEMORY_LIMIT','256M');n define('AUTOMATIC_UPDATER_DISABLED', false);\n    volumes:\n      - wp_data:\/var\/www\/html\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_started\n    restart: unless-stopped\n\n  nginx:\n    image: nginx:alpine\n    container_name: wp_nginx\n    ports:\n      - &quot;80:80&quot;\n    volumes:\n      - wp_data:\/var\/www\/html:ro\n      - .\/nginx\/conf.d:\/etc\/nginx\/conf.d\n      - .\/nginx\/nginx.conf:\/etc\/nginx\/nginx.conf:ro\n      - nginx_logs:\/var\/log\/nginx\n    depends_on:\n      - wordpress\n    restart: unless-stopped\n\n  backup:\n    image: alpine:3.20\n    container_name: wp_backup\n    entrypoint: [&quot;\/bin\/sh&quot;,&quot;-c&quot;]\n    command: |\n      apk add --no-cache bash mariadb-client restic tzdata ca-certificates tar pigz &amp;&amp; \n      mkdir -p \/scripts &amp;&amp; \n      echo &quot;0 3 * * * \/bin\/bash \/scripts\/backup.sh &gt;&gt; \/var\/log\/backup.log 2&gt;&amp;1&quot; &gt; \/etc\/crontabs\/root &amp;&amp; \n      crond -f -L \/var\/log\/cron.log\n    environment:\n      - RESTIC_REPOSITORY=${RESTIC_REPOSITORY}\n      - RESTIC_PASSWORD=${RESTIC_PASSWORD}\n      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}\n      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}\n      - TZ=Europe\/Istanbul\n      - DB_HOST=db\n      - DB_USER=${DB_USER}\n      - DB_PASSWORD=${DB_PASSWORD}\n      - DB_NAME=${DB_NAME}\n    volumes:\n      - wp_data:\/var\/www\/html:ro\n      - .\/backup:\/scripts\n    depends_on:\n      db:\n        condition: service_healthy\n    restart: unless-stopped\n\nvolumes:\n  wp_data:\n  db_data:\n  redis_data:\n  nginx_logs:\n<\/code><\/pre>\n<h3><span id=\"env_Dosyasi\">.env Dosyas\u0131<\/span><\/h3>\n<p>Ayn\u0131 klas\u00f6rde basit bir <strong>.env<\/strong> dosyas\u0131, parolalar\u0131 ve isimleri ortam de\u011fi\u015fkeni olarak verir. Kodun g\u00f6vdesinde gizlemekten iyidir. \u0130sterseniz Docker secrets veya kasada saklama y\u00f6ntemleriyle daha da sertle\u015ftirebilirsiniz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">DB_NAME=wordpress\nDB_USER=wpuser\nDB_PASSWORD=degistir-lutfen\nDB_ROOT_PASSWORD=degistir-ama-sakince\n\nRESTIC_REPOSITORY=s3:s3.amazonaws.com\/sizin-bucketiniz\/wordpress-yedek\nRESTIC_PASSWORD=uzun-bir-sifre-secin\nAWS_ACCESS_KEY_ID=AKIAXXXXX\nAWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxx\n<\/code><\/pre>\n<h3><span id=\"Yedek_Scripti\">Yedek Script\u2019i<\/span><\/h3>\n<p>Geceleri saat 03:00\u2019te \u00e7al\u0131\u015facak minik bir script. Veritaban\u0131n\u0131 d\u0131\u015fa aktar\u0131r, wp-content\u2019i bir ar\u015five al\u0131r, ikisini <strong>restic<\/strong> ile uzak depoya yollar. Geri d\u00f6n\u00fc\u015f yolunu da haz\u0131rlad\u0131k, birazdan anlataca\u011f\u0131m.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># backup\/backup.sh\n#!\/usr\/bin\/env bash\nset -euo pipefail\n\nSTAMP=$(date +&quot;%Y%m%d-%H%M%S&quot;)\nWORK=\/tmp\/backup-${STAMP}\nmkdir -p &quot;$WORK&quot;\n\n# 1) Veritaban\u0131 dump\nmysqldump -h &quot;$DB_HOST&quot; -u &quot;$DB_USER&quot; -p&quot;$DB_PASSWORD&quot; &quot;$DB_NAME&quot; \n  --single-transaction --routines --events --triggers \n  | pigz -9 &gt; &quot;$WORK\/db-${STAMP}.sql.gz&quot;\n\n# 2) wp-content ar\u015fivi (\u00e7ekirdek ve eklentiler ayn\u0131 volume'da, isterseniz t\u00fcm\u00fcn\u00fc al\u0131n)\ncd \/var\/www\/html\nif [ -d wp-content ]; then\n  tar -I &quot;pigz -9&quot; -cf &quot;$WORK\/wp-content-${STAMP}.tar.gz&quot; wp-content\nelse\n  echo &quot;wp-content yok gibi, yine de devam&quot; &gt;&amp;2\nfi\n\n# 3) restic init (ilkse) ve yedekleme\nrestic snapshots || restic init\nrestic backup --host wordpress \n  &quot;$WORK\/db-${STAMP}.sql.gz&quot; \n  &quot;$WORK\/wp-content-${STAMP}.tar.gz&quot; || true\n\n# 4) Eski yedekleri budama: 7 g\u00fcnl\u00fck, 4 haftal\u0131k, 6 ayl\u0131k\nrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune\n\nrm -rf &quot;$WORK&quot;\necho &quot;Yedek tamam: ${STAMP}&quot;\n<\/code><\/pre>\n<h3><span id=\"Ilk_Calistirma\">\u0130lk \u00c7al\u0131\u015ft\u0131rma<\/span><\/h3>\n<p>Komutlar sade. \u00d6nce klas\u00f6r yap\u0131s\u0131n\u0131 haz\u0131rlay\u0131n: nginx dizini, backup dizini, .env dosyas\u0131. Sonra \u00e7al\u0131\u015ft\u0131r\u0131n ve \u00e7ay\u0131 koyun.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">docker compose pull\ndocker compose up -d\n<\/code><\/pre>\n<p>\u0130lk kurulumda WordPress sizden site ad\u0131 ve y\u00f6netici hesab\u0131 isteyecek. Nginx ayarlar\u0131n\u0131 da ekleyelim ki vitrinimiz derli toplu olsun.<\/p>\n<h2 id=\"section-5\"><span id=\"Nginx_ve_Redis_Vitrini_Parlatmak_Icerigi_Hizlandirmak\">Nginx ve Redis: Vitrini Parlatmak, \u0130\u00e7eri\u011fi H\u0131zland\u0131rmak<\/span><\/h2>\n<h3><span id=\"Nginx_Yapilandirmasi\">Nginx Yap\u0131land\u0131rmas\u0131<\/span><\/h3>\n<p>Basit ama i\u015f g\u00f6ren bir Nginx, trafi\u011fi WordPress\u2019in PHP-FPM\u2019ine aktar\u0131r, statik dosyalar\u0131 h\u0131zl\u0131 yeniler ve gereksiz y\u00fck\u00fc azalt\u0131r. A\u015fa\u011f\u0131daki iki dosya ile ba\u015flamak rahatlat\u0131r.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># nginx\/nginx.conf\nuser  nginx;\nworker_processes  auto;\nerror_log  \/var\/log\/nginx\/error.log warn;\npid        \/var\/run\/nginx.pid;\n\nevents {\n  worker_connections  1024;\n}\n\nhttp {\n  include       \/etc\/nginx\/mime.types;\n  default_type  application\/octet-stream;\n  sendfile        on;\n  tcp_nopush      on;\n  tcp_nodelay     on;\n  keepalive_timeout  65;\n  client_max_body_size 64m;\n\n  log_format  main  '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '\n                     '$status $body_bytes_sent &quot;$http_referer&quot; '\n                     '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';\n  access_log  \/var\/log\/nginx\/access.log  main;\n\n  include \/etc\/nginx\/conf.d\/*.conf;\n}\n<\/code><\/pre>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\"># nginx\/conf.d\/site.conf\nupstream php {\n  server wordpress:9000;\n  keepalive 16;\n}\n\nserver {\n  listen 80;\n  server_name _;\n  root \/var\/www\/html;\n  index index.php index.html;\n\n  location ~* .(png|jpg|jpeg|gif|svg|webp|css|js|ico|woff|woff2)$ {\n    expires 7d;\n    add_header Cache-Control &quot;public, max-age=604800&quot;;\n    try_files $uri $uri\/ =404;\n  }\n\n  location \/wp-content\/cache\/ { # plugin cache klas\u00f6rleri olursa\n    expires 10m;\n    add_header Cache-Control &quot;public, max-age=600&quot;;\n  }\n\n  location \/ {\n    try_files $uri $uri\/ \/index.php?$args;\n  }\n\n  location ~ .php$ {\n    include fastcgi_params;\n    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n    fastcgi_pass php;\n    fastcgi_read_timeout 120s;\n  }\n\n  location ~* \/(.git|.env|wp-config.php|readme.html|license.txt) {\n    deny all;\n  }\n}\n<\/code><\/pre>\n<p>\u00dcstteki yap\u0131, yeni ba\u015flayanlar i\u00e7in yeterli bir zemin. Zamanla mikro \u00f6nbellekleme ya da ek g\u00fcvenlik ba\u015fl\u0131klar\u0131 eklemek isteyebilirsiniz. Daha derine inmek isterseniz, sitemizdeki <a href=\"https:\/\/www.dchost.com\/blog\/docker-ile-wordpressi-vpste-nasil-yasatiriz-nginx-mariadb-redis-ve-lets-encrypt-ile-kalici-depolama-macerasi\/\">Docker ile WordPress\u2019i VPS\u2019te ya\u015fatman\u0131n s\u0131cak hikayesi<\/a> bu d\u00fczenin akrabas\u0131 gibi; pratik dokunu\u015flarla \u00e7ok \u015fey netle\u015fiyor.<\/p>\n<h3><span id=\"Redisi_WordPresse_Tanitmak\">Redis\u2019i WordPress\u2019e Tan\u0131tmak<\/span><\/h3>\n<p>WordPress ile Redis konu\u015fsun diye genelde k\u00fc\u00e7\u00fck bir eklenti yeter. \u201cRedis Object Cache\u201d gibi pop\u00fcler olanlar\u0131 kurup etkinle\u015ftirin. Ayarlarda \u201chost\u201d olarak redis konteyner ad\u0131n\u0131 yazman\u0131z genelde yetiyor. Biz zaten WORDPRESS_CONFIG_EXTRA ile &#8216;WP_REDIS_HOST&#8217; tan\u0131mlad\u0131k. Aktivasyon sonras\u0131 y\u00f6netim panelinde \u201cConnected\u201d g\u00f6r\u00fcrseniz i\u015fler yolunda demektir. Bazen sayfa olu\u015fturucular veya a\u011f\u0131r eklentiler ilk y\u00fcklemede \u00fc\u015fenge\u00e7 davran\u0131r, o anlarda \u00f6nbelle\u011fi bir kere temizlemek rahatlat\u0131r.<\/p>\n<h2 id=\"section-6\"><span id=\"Otomatik_Yedek_ve_Geri_Yukleme_ile_Guncelleme_Akisi_Once_Emniyet_Sonra_Cesaret\">Otomatik Yedek ve Geri Y\u00fckleme ile G\u00fcncelleme Ak\u0131\u015f\u0131: \u00d6nce Emniyet, Sonra Cesaret<\/span><\/h2>\n<h3><span id=\"Yedek_Akisi\">Yedek Ak\u0131\u015f\u0131<\/span><\/h3>\n<p>Haz\u0131rlad\u0131\u011f\u0131m\u0131z backup servisi her gece 03:00\u2019te \u00e7al\u0131\u015f\u0131yor. Veritaban\u0131 dump al\u0131n\u0131yor, wp-content ar\u015fivleniyor, <strong>restic<\/strong> ile uzak depoya g\u00f6nderiliyor. Bu uzak depo bir S3 uyumlu nesne depolama olabilir. Restic\u2019in incelikleri i\u00e7in <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/\" rel=\"nofollow noopener\" target=\"_blank\">restic ile yedekleri S3&#8217;e g\u00f6ndermek<\/a> belgesine g\u00f6z atmak iyi gelir. Benim sahada en sevdi\u011fim detay, \u201cforget\/prune\u201d ile ar\u015fivi ya\u015fland\u0131rabilmek; d\u00fcn\u00fcn, ge\u00e7en haftan\u0131n ve ayl\u0131k foto\u011fraflar\u0131n\u0131z birlikte duruyor.<\/p>\n<p>Geri y\u00fckleme provas\u0131 ba\u015ftan yap\u0131l\u0131nca, kriz an\u0131nda titreme olmuyor. Provay\u0131 \u015f\u00f6yle d\u00fc\u015f\u00fcnebilirsiniz: Temiz bir klas\u00f6re ayn\u0131 Compose\u2019u kurup, yedekten \u00e7ekiyorsunuz. \u0130lk geri y\u00fcklemeyi g\u00f6rmeden \u201ctamam yedekliyiz\u201d demek havada kal\u0131r. Ben provalar\u0131 k\u00fc\u00e7\u00fck bir alt ortamda yapmay\u0131 seviyorum; verinin bir k\u0131sm\u0131yla bile olsa kas haf\u0131zas\u0131 kazan\u0131l\u0131yor.<\/p>\n<h3><span id=\"Geri_Yukleme_Komutlari\">Geri Y\u00fckleme Komutlar\u0131<\/span><\/h3>\n<p>Prova zaman\u0131 geldi\u011finde, backup konteynerine girip restic ile dosyalar\u0131 indirirsiniz. Ard\u0131ndan veritaban\u0131n\u0131 i\u00e7e aktar\u0131r, wp-content\u2019i geri a\u00e7ars\u0131n\u0131z.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># son snapshot'\u0131 listeleyin\ndocker exec -it wp_backup restic snapshots\n\n# istedi\u011finiz an\u0131n ar\u015fivini bir klas\u00f6re \u00e7\u0131kar\u0131n\nRESTORE=\/tmp\/restore-$(date +%s)\ndocker exec -e RESTORE=${RESTORE} -it wp_backup \n  sh -lc &quot;mkdir -p $RESTORE &amp;&amp; restic restore latest --target $RESTORE&quot;\n\n# wp-content'i geri koymak (nginx\/wordpress durdurmay\u0131 unutmay\u0131n)\ndocker compose stop nginx wordpress\nHOST_RESTORE=$(docker exec -it wp_backup sh -lc &quot;echo $RESTORE&quot; | tr -d 'r')\n# Host'a kopyalamak i\u00e7in (Linux\/Mac):\n# docker cp wp_backup:${HOST_RESTORE}\/tmp\/backup-*\/wp-content-*.tar.gz .\/\n# sonra uygun klas\u00f6re a\u00e7\u0131p wp_data volume'a yerle\u015ftirin\n\ndocker compose start db\n# Veritaban\u0131 geri y\u00fckleme (dosyay\u0131 host'a al\u0131p i\u00e7e aktar\u0131n)\ngzip -dc db-YYYYMMDD-HHMMSS.sql.gz | docker exec -i wp_db sh -lc \n  &quot;mysql -u$DB_USER -p$DB_PASSWORD $DB_NAME&quot;\n\ndocker compose start wordpress nginx\n<\/code><\/pre>\n<p>Buradaki ad\u0131mlar\u0131n bir kez i\u015fledi\u011fini g\u00f6rmek, ak\u015famlar\u0131 \u00e7ok daha rahat uyutuyor. K\u00fc\u00e7\u00fck bir not: \u0130\u00e7erik canl\u0131yken geri y\u00fckleme yap\u0131lacaksa, \u201c\u00f6nce bak\u0131m sayfas\u0131, sonra i\u015flem\u201d s\u0131ras\u0131n\u0131 bozmamak laz\u0131m.<\/p>\n<h3><span id=\"Guncelleme_Akisi\">G\u00fcncelleme Ak\u0131\u015f\u0131<\/span><\/h3>\n<p>G\u00fcncelleme en \u00e7ok yanl\u0131\u015f anla\u015f\u0131lan konu. Asl\u0131nda \u00fc\u00e7 par\u00e7adan olu\u015fur: \u201c\u00f6nce yedek\u201d, \u201csonra imajlar\u0131 g\u00fcncelle\u201d, \u201cen sonda WordPress \u00e7ekirde\u011fi\/eklenti\/tema\u201d. Benim pratik ak\u0131\u015f\u0131m \u015f\u00f6yle ak\u0131yor: \u00d6nce bir <strong>manuel yedek<\/strong> tetikleyip tamamland\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcyorum. Sonra Compose imajlar\u0131n\u0131 \u00e7ekiyorum. Ard\u0131ndan WordPress\u2019i WP-CLI ile g\u00fcncelliyorum. Her ad\u0131m k\u00fc\u00e7\u00fck, ama bir araya gelince sa\u011flam.<\/p>\n<h3><span id=\"WP-CLI_ile_Guncelleme\">WP-CLI ile G\u00fcncelleme<\/span><\/h3>\n<p>WP-CLI, WordPress y\u00f6netiminde komut sat\u0131r\u0131n\u0131 sevmek i\u00e7in g\u00fc\u00e7l\u00fc bir bahane. Kurulumla u\u011fra\u015fmadan bir konteyner olarak \u00e7a\u011f\u0131rabiliriz. Resmi d\u00f6k\u00fcmana g\u00f6z atmak isterseniz <a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/\" rel=\"nofollow noopener\" target=\"_blank\">WP-CLI komutlar\u0131<\/a> ba\u015fl\u0131\u011f\u0131n\u0131 seversiniz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># Tek seferlik WP-CLI konteyneri ile komut \u00f6rnekleri\n# \u00c7ekirde\u011fi min\u00f6r g\u00fcncelle: (temkinli)\ndocker run --rm -it \n  --network $(docker network ls --filter name=_default --format {{.Name}}) \n  -v $(pwd)\/html:\/var\/www\/html \n  -e WORDPRESS_DB_HOST=db:3306 \n  -e WORDPRESS_DB_NAME=${DB_NAME} \n  -e WORDPRESS_DB_USER=${DB_USER} \n  -e WORDPRESS_DB_PASSWORD=${DB_PASSWORD} \n  wordpress:cli-php8.2 \n  wp core update --minor --path=\/var\/www\/html\n\n# Eklentileri g\u00fcncelle\ndocker run --rm -it \n  --network $(docker network ls --filter name=_default --format {{.Name}}) \n  -v $(pwd)\/html:\/var\/www\/html \n  -e WORDPRESS_DB_HOST=db:3306 \n  -e WORDPRESS_DB_NAME=${DB_NAME} \n  -e WORDPRESS_DB_USER=${DB_USER} \n  -e WORDPRESS_DB_PASSWORD=${DB_PASSWORD} \n  wordpress:cli-php8.2 \n  wp plugin update --all --path=\/var\/www\/html\n<\/code><\/pre>\n<p>\u00dcstteki \u00f6rnekler, WordPress dosyalar\u0131n\u0131n host\u2019ta <em>.\/html<\/em> alt\u0131nda oldu\u011fu bir d\u00fczeni varsay\u0131yor. Biz named volume kulland\u0131k. Bu durumda en kolay\u0131, k\u0131sa s\u00fcreli\u011fine volume\u2019\u0131 bir yard\u0131mc\u0131 konteynere mount edip \/var\/www\/html\u2019i o konteynerden kullanmak. Alternatif olarak WordPress servisinde WP-CLI \u00e7al\u0131\u015ft\u0131rmak da m\u00fcmk\u00fcn. Yani y\u00f6ntem \u00e7ok; \u00f6nemli olan, \u00f6nce yedek, sonra g\u00fcncelle prensibini bozmamak.<\/p>\n<h3><span id=\"Uygulama_Imajlarini_Guncellemek\">Uygulama \u0130majlar\u0131n\u0131 G\u00fcncellemek<\/span><\/h3>\n<p>Compose taraf\u0131nda g\u00fcncelleme genellikle iki komutla biter. \u00d6nce yeni imajlar\u0131 \u00e7ekersiniz, sonra konteynerleri yeniden yarat\u0131rs\u0131n\u0131z. Her \u015fey named volume\u2019larda durdu\u011fu i\u00e7in veri yerinden k\u0131p\u0131rdamaz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">docker compose pull\ndocker compose up -d\n<\/code><\/pre>\n<p>Nginx, PHP-FPM veya Redis imajlar\u0131ndaki g\u00fcncellemeleri b\u00f6ylece alm\u0131\u015f olursunuz. B\u00fcy\u00fck versiyon ge\u00e7i\u015flerinde k\u00fc\u00e7\u00fck bir test ortam\u0131 kurmak i\u00e7 rahatlat\u0131r. Ayn\u0131 Compose dosyas\u0131n\u0131 ba\u015fka bir a\u011f ve port ile aya\u011fa kald\u0131r\u0131p g\u00f6z atmak, s\u00fcrprizleri azalt\u0131r.<\/p>\n<h3><span id=\"Ince_Ayarlar_ve_Kucuk_Taktikler\">\u0130nce Ayarlar ve K\u00fc\u00e7\u00fck Taktikler<\/span><\/h3>\n<p>G\u00fcncelleme \u00f6ncesi \u201cbak\u0131m modunu\u201d k\u0131sa bir eklentiyle ya da Nginx\u2019te basit bir kural ile a\u00e7\u0131p, i\u015flem biter bitmez kapatmak i\u015fi p\u00fcr\u00fczs\u00fcz yapar. Redis \u00f6nbelle\u011fini g\u00fcncellemelerden sonra temizlemek \u00e7o\u011fu sitede \u201ceski par\u00e7a kalm\u0131\u015f sanki\u201d duygusunu yok eder. Ve tabii ki otomatik yedek ak\u0131\u015f\u0131n\u0131 bir <em>healthcheck<\/em> gibi d\u00fc\u015f\u00fcn\u00fcn; yedeklerin boyutu, say\u0131s\u0131 ve geri d\u00f6n\u00fc\u015f testi takvimini bir not defterine yaz\u0131p, ay sonunda bir bak\u0131\u015f at\u0131n.<\/p>\n<h3><span id=\"Compose_Referanslarina_Bakmak_Iyi_Gelir\">Compose Referanslar\u0131na Bakmak \u0130yi Gelir<\/span><\/h3>\n<p>\u0130\u015fin taban\u0131 Compose oldu\u011fu i\u00e7in, yeni bir \u00f6zellik veya ufak bir p\u00fcf arad\u0131\u011f\u0131n\u0131zda <a href=\"https:\/\/docs.docker.com\/compose\/\" rel=\"nofollow noopener\" target=\"_blank\">Docker Compose referanslar\u0131<\/a> hayat kurtar\u0131yor. Orada g\u00f6rd\u00fc\u011f\u00fcn\u00fcz bir ayar\u0131 k\u00fc\u00e7\u00fck k\u00fc\u00e7\u00fck denemek, bu yap\u0131y\u0131 tam size g\u00f6re hale getiriyor.<\/p>\n<h2 id=\"section-7\"><span id=\"Kapanis_Bir_Kez_Kur_Hep_Guven\">Kapan\u0131\u015f: Bir Kez Kur, Hep G\u00fcven<\/span><\/h2>\n<p>Toparlayal\u0131m. WordPress\u2019i Docker Compose ile Nginx, MariaDB ve Redis\u2019in aras\u0131na yerle\u015ftirdi\u011fimizde, asl\u0131nda bir d\u00fczen kurduk. Par\u00e7alar ayr\u0131; dokunurken birbirini rahats\u0131z etmiyorlar. <strong>Kal\u0131c\u0131 hacimler<\/strong> sayesinde verinin omurgas\u0131 sa\u011flam. <strong>Otomatik yedek<\/strong> ak\u0131\u015f\u0131 her gece bir foto\u011fraf \u00e7ekiyor, siz de rahat uyuyorsunuz. <strong>G\u00fcncelleme ak\u0131\u015f\u0131<\/strong> ise cesaret veriyor; \u00f6nce emniyet kemeri, sonra yolculuk.<\/p>\n<p>Pratik bir \u00f6neri seti b\u0131rakay\u0131m: \u0130lk haftay\u0131 g\u00f6zlem haftas\u0131 yap\u0131n. Log\u2019lara arada bir bak\u0131n, Redis ba\u011flant\u0131s\u0131n\u0131n ger\u00e7ekten aktif oldu\u011fundan emin olun, yedeklerin ger\u00e7ekten uzak depoya akt\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcn. Haftan\u0131n sonunda k\u00fc\u00e7\u00fck bir geri y\u00fckleme provas\u0131 yap\u0131n; birka\u00e7 ad\u0131m\u0131 yeniden ya\u015famak kaslar\u0131n\u0131z\u0131 \u0131s\u0131t\u0131yor. Ve unutmay\u0131n, k\u00fc\u00e7\u00fck iterasyonlar b\u00fcy\u00fck d\u00fczenlerin anahtar\u0131. Bug\u00fcn bir ayar\u0131 d\u00fczeltirsiniz, yar\u0131n imaj\u0131 g\u00fcncellersiniz, \u00f6b\u00fcr g\u00fcn yedeklerin saklama politikas\u0131n\u0131 g\u00fczelle\u015ftirirsiniz.<\/p>\n<p>Umar\u0131m bu rehber elinizi rahatlatt\u0131. Bir g\u00fcncelleme sabah\u0131nda yine bulu\u015fur, \u201cbak bunu da ekledim, hayat kolayla\u015ft\u0131\u201d deriz. Sorular\u0131n\u0131z olursa, \u00fczerinde konu\u015fmak her zaman keyif. Bir dahaki yaz\u0131da g\u00f6r\u00fc\u015fmek \u00fczere.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0130&ccedil;indekiler1 Hikaye Gibi Bir Giri\u015f: K\u00fc\u00e7\u00fck Bir T\u0131kan\u0131kl\u0131k, B\u00fcy\u00fck Bir Ak\u0131\u015f2 Resmi Netle\u015ftirelim: WordPress, Nginx, MariaDB ve Redis Nas\u0131l Konu\u015fur?3 Kal\u0131c\u0131 Hacimler: Dosyalar Nerede, Neden Bu Kadar \u00d6nemli?4 docker-compose.yml: \u00c7al\u0131\u015f\u0131r Bir \u00d6rnek ve K\u00fc\u00e7\u00fck S\u0131rlar4.1 Compose Dosyas\u01314.2 .env Dosyas\u01314.3 Yedek Script\u2019i4.4 \u0130lk \u00c7al\u0131\u015ft\u0131rma5 Nginx ve Redis: Vitrini Parlatmak, \u0130\u00e7eri\u011fi H\u0131zland\u0131rmak5.1 Nginx Yap\u0131land\u0131rmas\u01315.2 Redis\u2019i WordPress\u2019e Tan\u0131tmak6 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1651,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1650","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1650","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/comments?post=1650"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1650\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1651"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}