{"id":1516,"date":"2025-11-07T22:30:28","date_gmt":"2025-11-07T19:30:28","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/"},"modified":"2025-11-07T22:30:28","modified_gmt":"2025-11-07T19:30:28","slug":"node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/","title":{"rendered":"Node.js\u2019i Canl\u0131ya Al\u0131rken Panik Yapma: PM2\/Systemd, Nginx, SSL ve S\u0131f\u0131r Kesinti Deploy Nas\u0131l Kurulur?"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><h2 id=\"section-1\">Ofiste Gece Yar\u0131s\u0131: K\u00fc\u00e7\u00fck Bir Kesinti, B\u00fcy\u00fck Bir Ders<\/h2>\n<p>Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Uykunun en tatl\u0131 yerinde telefon \u00e7alar, bildirim sesi kula\u011f\u0131n\u0131z\u0131 deler, bir bakm\u0131\u015fs\u0131n\u0131z Node.js uygulamas\u0131 susmu\u015f. O gece ben de ayn\u0131 duyguyla telefona uzanm\u0131\u015ft\u0131m. Sunucuda hi\u00e7bir \u015fey yokmu\u015f gibi duran k\u00fc\u00e7\u00fck bir ayr\u0131nt\u0131, sanki hal\u0131n\u0131n alt\u0131na s\u00fcp\u00fcr\u00fclm\u00fc\u015f bir toz topa\u011f\u0131 gibi birikti birikti, sonra koca bir \u00f6ks\u00fcr\u00fckle kendini belli etti. Me\u011fer log dosyas\u0131 \u015fi\u015fmi\u015f, reverse proxy tamponu yanl\u0131\u015f ayarl\u0131ym\u0131\u015f, s\u00fcre\u00e7 de beklenmedik bir anda nefessiz kalm\u0131\u015f.<\/p>\n<p>O zaman d\u00fc\u015f\u00fcnd\u00fcm: \u201cBu i\u015f biraz mutfak i\u015fi. Malzemeler belli, do\u011fru s\u0131ralamayla ve do\u011fru \u0131s\u0131da pi\u015fince her \u015fey tad\u0131nda.\u201d \u0130\u015fte bu yaz\u0131da o s\u0131ralamay\u0131 birlikte kuraca\u011f\u0131z. <strong>PM2 ya da systemd<\/strong> ile s\u00fcre\u00e7leri ayakta tutmak, <strong>Nginx reverse proxy<\/strong> ile trafi\u011fi usulca y\u00f6nlendirmek, <strong>SSL<\/strong> ile g\u00fcveni sa\u011flamak ve en \u00f6nemlisi <strong>s\u0131f\u0131r kesintiyle<\/strong> da\u011f\u0131t\u0131m yapmak\u2026 Hepsi bir arada, ak\u0131\u015fkan ve anla\u015f\u0131l\u0131r bir yolculuk olsun istiyorum. Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: Kod sizin, sunucu sizin, ritmi de siz belirliyorsunuz. Biz de davulun tokmaklar\u0131n\u0131 do\u011fru yerlere vural\u0131m.<\/p>\n<h2 id=\"section-2\">Production Akl\u0131: Tek Bir Node S\u00fcreciyle D\u00fcnya D\u00f6nm\u00fcyor<\/h2>\n<p>Node.js tek bir olay d\u00f6ng\u00fcs\u00fcne dayan\u0131yor, bu y\u00fczden \u00fcretimde \u201ctek s\u00fcrece g\u00fcven\u201d yakla\u015f\u0131m\u0131 k\u0131r\u0131lgan. K\u00fc\u00e7\u00fck bir dosya okuma gecikmesi, beklenmeyen bir istisna, k\u0131sa s\u00fcreli CPU dalgalanmas\u0131\u2026 Hepsi trafi\u011fin \u00fcst\u00fcne dalga dalga biner. \u00dcretimde amac\u0131m\u0131z \u015fu: s\u00fcreci izlemek, yeniden ba\u015flatmak, ak\u0131\u015fa kald\u0131\u011f\u0131 yerden devam etmek. Burada PM2 ve systemd ikilisi devreye girer. \u0130kisi de s\u00fcreci ayakta tutar, loglar\u0131 kaydeder, \u00e7\u00f6k\u00fcnce aya\u011fa kald\u0131r\u0131r. Ama tarzlar\u0131 farkl\u0131; biri Node d\u00fcnyas\u0131na yak\u0131n duran bir yard\u0131mc\u0131, di\u011feri i\u015fletim sistemine g\u00f6m\u00fcl\u00fc, i\u015fini sessizce yapan bir servis y\u00f6neticisi.<\/p>\n<p>Bir de \u015fu k\u00fc\u00e7\u00fck ama \u00f6nemli ayr\u0131nt\u0131lar var: <strong>ortam de\u011fi\u015fkenleri<\/strong> okunabilir olmal\u0131, <strong>log<\/strong>lar d\u00f6nmeli, <strong>maksimum dosya tan\u0131t\u0131c\u0131<\/strong> say\u0131s\u0131 k\u00fc\u00e7\u00fck kalmamal\u0131, uygulama beklenmedik kapan\u0131nca kibarca yeniden ba\u015flat\u0131lmal\u0131. Ve elbette <strong>health check<\/strong>\u2026 Nginx\u2019e \u201cBen iyiyim\u201d diyecek minik bir u\u00e7 nokta, kimi zaman koca bir krizden d\u00f6nd\u00fcr\u00fcr.<\/p>\n<h2 id=\"section-3\">PM2 ile Ko\u015fmak: H\u0131zl\u0131 Kurulum, Kolay Kontrol<\/h2>\n<p>PM2, Node.js d\u00fcnyas\u0131nda bir nevi tur rehberi gibi. Komutlar\u0131 anla\u015f\u0131l\u0131r, g\u00fcnl\u00fck i\u015fleri kolayla\u015ft\u0131r\u0131yor. \u0130lk kez canl\u0131ya ge\u00e7ecekseniz PM2 ile ba\u015flamak, mutfa\u011fa yumu\u015fak bir giri\u015f gibi hissettirir. Kendi deneyimimde en \u00e7ok sevdi\u011fim \u015fey, tek komutla s\u00fcre\u00e7 ba\u015flat\u0131p kaydedebilmek, sonra sunucu yeniden a\u00e7\u0131ld\u0131\u011f\u0131nda kald\u0131\u011f\u0131 yerden devam ettirmesi.<\/p>\n<p>Basit bir ba\u015flang\u0131\u00e7 i\u00e7in \u00f6nce kurup temelini atal\u0131m:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">npm install -g pm2\npm2 start app.js --name myapp\npm2 save\npm2 startup  # \u00c7\u0131kt\u0131daki komutu sudo ile \u00e7al\u0131\u015ft\u0131r\u0131n<\/code><\/pre>\n<p>Sonras\u0131nda bir <strong>ecosystem<\/strong> dosyas\u0131yla d\u00fczen kurmak iyi olur. Ortam de\u011fi\u015fkenlerini, ka\u00e7 kopya \u00e7al\u0131\u015faca\u011f\u0131n\u0131, log yollar\u0131n\u0131 burada netle\u015ftirirsiniz. K\u00fc\u00e7\u00fck bir \u00f6rnek:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ ecosystem.config.js\nmodule.exports = {\n  apps: [\n    {\n      name: 'myapp',\n      script: 'app.js',\n      instances: 'max',\n      exec_mode: 'cluster',\n      env: {\n        NODE_ENV: 'production',\n        PORT: 3000\n      },\n      max_memory_restart: '512M',\n      error_file: '\/var\/log\/myapp\/error.log',\n      out_file: '\/var\/log\/myapp\/out.log',\n      merge_logs: true,\n      time: true\n    }\n  ]\n}<\/code><\/pre>\n<p>B\u00f6ylece uygulamay\u0131 \u015fu \u015fekilde y\u00f6netirsiniz: ba\u015flatmak i\u00e7in <strong>pm2 start ecosystem.config.js<\/strong>, g\u00fcncelleme sonras\u0131 zarif\u00e7e yeniden ba\u015flatmak i\u00e7in <strong>pm2 reload myapp<\/strong>. <strong>reload<\/strong> komutu \u00f6zellikle severim; anl\u0131k kesinti olmadan yeni s\u00fcr\u00fcm\u00fc devreye al\u0131r. Bir de loglar\u0131 tek pencerede g\u00f6rmek isterseniz <strong>pm2 logs<\/strong> rahatlat\u0131r.<\/p>\n<p>PM2 hakk\u0131nda akl\u0131n\u0131za tak\u0131lan her \u015fey i\u00e7in resmi sayfaya \u015f\u00f6yle b\u0131rakay\u0131m: <a href=\"https:\/\/pm2.keymetrics.io\/\" target=\"_blank\" rel=\"noopener nofollow\">PM2\u2019nin sade belgeleri ve pratik komutlar\u0131<\/a>. Orada kaybolmadan, ne ararsan\u0131z bulursunuz.<\/p>\n<h2 id=\"section-4\">systemd ile Ko\u015fmak: \u0130\u015fletim Sisteminin Omuzlar\u0131<\/h2>\n<p>systemd bir ba\u015fka d\u00fcnya. \u201cBenim uygulamam sistemin vatanda\u015f\u0131 olsun\u201d diyorsan\u0131z, en do\u011fal yol bu. Ayaklar\u0131 yere sa\u011flam basan bir servis tan\u0131m\u0131, beklenmedik durumlarda otomatik toparlanma ve temiz log ak\u0131\u015f\u0131yla sunucunuzun dilini konu\u015fur. Birka\u00e7 kez servis dosyas\u0131n\u0131 do\u011fru modelliyorsunuz, sonras\u0131 su gibi ak\u0131yor.<\/p>\n<p>K\u00fc\u00e7\u00fck bir servis birimi haz\u0131rlayal\u0131m. Uygulaman\u0131z\u0131n dizini \u00f6rne\u011fin <strong>\/var\/www\/myapp\/current<\/strong> olsun; bunu birazdan s\u0131f\u0131r kesinti da\u011f\u0131t\u0131mda kullanaca\u011f\u0131z:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \/etc\/systemd\/system\/myapp.service\n[Unit]\nDescription=My Node.js App\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=\/var\/www\/myapp\/current\nExecStart=\/usr\/bin\/node app.js\nRestart=always\nRestartSec=3\nEnvironment=NODE_ENV=production\nEnvironment=PORT=3000\n# Dosya tan\u0131t\u0131c\u0131 s\u0131n\u0131r\u0131n\u0131 art\u0131rmak iyi gelebilir\nLimitNOFILE=65536\n# Kibar kapatma i\u00e7in\nKillSignal=SIGINT\n\n[Install]\nWantedBy=multi-user.target<\/code><\/pre>\n<p>Servisi y\u00fckleyip ba\u015flatal\u0131m:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo systemctl daemon-reload\nsudo systemctl enable myapp\nsudo systemctl start myapp\nsudo systemctl status myapp<\/code><\/pre>\n<p>Loglar i\u00e7in <strong>journalctl -u myapp -f<\/strong> yeterli. E\u011fer servis g\u00fcncelleme sonras\u0131 nazik\u00e7e yenilensin isterseniz, uygulaman\u0131n SIGINT veya SIGTERM ile kibarca kapanabildi\u011finden emin olun. B\u00f6ylece <strong>systemctl restart myapp<\/strong> dedi\u011finizde isteklerinizi yar\u0131 yolda b\u0131rakmaz. Bir ipucu: Node taraf\u0131nda s\u00fcre\u00e7 kapan\u0131rken a\u00e7\u0131k ba\u011flant\u0131lar\u0131 bekleyen ufak bir <strong>graceful shutdown<\/strong> i\u015flevi eklemek, gece yar\u0131s\u0131 kalp k\u0131r\u0131kl\u0131klar\u0131n\u0131 \u00f6nler.<\/p>\n<h2 id=\"section-5\">Nginx Reverse Proxy: Trafi\u011fin \u015eefi, WebSocket\u2019in Dostu<\/h2>\n<p>Node\u2019u do\u011frudan 80 veya 443\u2019te dinletmek zorunda de\u011filsiniz. Hatta \u00e7o\u011fu zaman dinletmeyin. Nginx\u2019i \u00f6ne koyup Node\u2019unuzu i\u00e7eride saklamak hem g\u00fcvenlik, hem performans, hem de esneklik sa\u011flar. Mesela WebSocket ba\u011flant\u0131lar\u0131, b\u00fcy\u00fck header\u2019lar, s\u0131k\u0131\u015fan tamponlar\u2026 Nginx do\u011fru ayarlarla bu i\u015fleri ustaca s\u00fczer.<\/p>\n<p>Basit bir ters vekil ayar\u0131 \u015f\u00f6yle olabilir. WebSocket\u2019i unutmayal\u0131m, ba\u015fl\u0131klar\u0131 d\u00fczg\u00fcn iletelim, zaman a\u015f\u0131m\u0131yla gereksiz panik ya\u015famayal\u0131m:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">upstream myapp_upstream {\n    server 127.0.0.1:3000;\n    keepalive 64;\n}\n\nserver {\n    listen 80;\n    server_name example.com;\n\n    # \u0130leride 443'e alaca\u011f\u0131z, \u015fimdilik HTTP\n\n    location \/health {\n        access_log off;\n        return 200 'ok';\n    }\n\n    location \/ {\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection &quot;upgrade&quot;;\n\n        proxy_read_timeout 60s;\n        proxy_connect_timeout 5s;\n        proxy_send_timeout 60s;\n\n        proxy_pass http:\/\/myapp_upstream;\n    }\n}<\/code><\/pre>\n<p>Bu yap\u0131, WebSocket dahil \u00e7o\u011fu ak\u0131\u015f\u0131 sorunsuz ge\u00e7irir. \u201cNiye 80? SSL nerede?\u201d derseniz, hemen bir sonraki b\u00f6l\u00fcmde Let\u2019s Encrypt ile 443\u2019e ta\u015f\u0131y\u0131p tad\u0131n\u0131 \u00e7\u0131karaca\u011f\u0131z. Ayr\u0131ca Nginx taraf\u0131nda HTTP\/2 veya HTTP\/3 gibi modern protokollerle h\u0131z kazanmak, statik dosyalar\u0131 do\u011frudan Nginx\u2019ten sunmak g\u00fcnl\u00fck hayat\u0131 rahatlat\u0131r. Tabi, a\u015f\u0131r\u0131 kuruluma ka\u00e7madan, neye ihtiyac\u0131n\u0131z varsa onu a\u00e7mak en iyisi.<\/p>\n<h2 id=\"section-6\">SSL\u2019i Ba\u011flayal\u0131m: Let\u2019s Encrypt, HSTS ve Sa\u011flam Bir Tarife<\/h2>\n<p>G\u00fcvensiz bir trafik, g\u00fczel bir yeme\u011fin \u00fczerine d\u00f6k\u00fclen tuzlu su gibi. \u0130ster PM2, ister systemd, \u00f6ndeki kap\u0131 Nginx ise HTTPS\u2019i temiz kurmak \u00f6nemli. En pratik yol Let\u2019s Encrypt ve Certbot. Alan ad\u0131n\u0131z DNS\u2019te do\u011fru yere i\u015faret ediyorsa, Nginx i\u00e7in komutlar inan\u0131lmaz k\u0131sa s\u00fcr\u00fcyor.<\/p>\n<p>\u00d6nce sunucuda Certbot\u2019u \u00e7al\u0131\u015ft\u0131r\u0131n. Sunucunuzu ve web sunucunuzu se\u00e7ti\u011finizde, kurulum sizden bir iki onaydan sonra sertifikalar\u0131 al\u0131p Nginx\u2019e ekler:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># \u0130\u015fletim sistemi ve web sunucunuza g\u00f6re ad\u0131mlar i\u00e7in\n# bu sayfadan ba\u015flay\u0131n:\n# https:\/\/certbot.eff.org\/instructions<\/code><\/pre>\n<p>Bu i\u015flem bitti\u011finde Nginx konfig\u00fcrasyonuna 443 blo\u011fu eklenir, otomatik yenileme planlan\u0131r. Geriye birka\u00e7 ince ayar kal\u0131r: g\u00fc\u00e7l\u00fc \u015fifre k\u00fcmeleri, HSTS, OCSP stapling ve HTTP\u2019den HTTPS\u2019e temizlikle y\u00f6nlendirme. Detay\u0131 bir \u00e7\u0131rp\u0131da yazmak burada yorabilir; ama iyi bir ba\u015flang\u0131\u00e7 i\u00e7in \u015fu kayna\u011f\u0131 seviyorum: <a href=\"https:\/\/ssl-config.mozilla.org\/\" target=\"_blank\" rel=\"noopener nofollow\">Mozilla\u2019n\u0131n SSL yap\u0131land\u0131rma \u00f6nerileri<\/a>. Basit\u00e7e profil se\u00e7ip Nginx\u2019e uygun <strong>server<\/strong> blo\u011funu d\u00fczenleyebilirsiniz.<\/p>\n<p>Bu ad\u0131m\u0131 bitirdi\u011finizde <strong>server_name<\/strong> alan ad\u0131n\u0131z\u0131 kar\u015f\u0131layacak, 80\u2019den 443\u2019e y\u00f6nlendirme net olacak, sertifikalar otomatik yenilenecek. B\u00f6ylece taray\u0131c\u0131lar ye\u015fil kilidi g\u00f6sterecek, API \u00e7a\u011fr\u0131lar\u0131n\u0131z da g\u00fcvenle akacak. \u0130sterseniz HTTP\/2\u2019yi a\u00e7\u0131p isteklerin birer tren gibi ayn\u0131 hatta akmas\u0131n\u0131 sa\u011flay\u0131n; \u00e7o\u011fu modern taray\u0131c\u0131 destekliyor. Nginx\u2019in proxy ayarlar\u0131yla birle\u015fince performans tatl\u0131 bir seviyeye gelir.<\/p>\n<h2 id=\"section-7\">S\u0131f\u0131r Kesinti Deploy: PM2 Reload, Sembolik S\u00fcr\u00fcmler ve Mavi\/Ye\u015fil<\/h2>\n<p>As\u0131l heyecan burada ba\u015fl\u0131yor. Canl\u0131 trafi\u011fi kesmeden yeni s\u00fcr\u00fcm\u00fc devreye almak, \u00fcretim d\u00fcnyas\u0131nda \u00f6zg\u00fcven demek. \u0130ki g\u00fczel yol var: PM2\u2019nin <strong>reload<\/strong> sihri ve systemd taraf\u0131nda <strong>sembolik s\u00fcr\u00fcmlerle<\/strong> y\u00fcr\u00fcyen mavi\/ye\u015fil yakla\u015f\u0131m\u0131.<\/p>\n<p>PM2 ile yol almak isterseniz basit ak\u0131\u015f \u015fu: yeni kodu dizine al\u0131n, ba\u011f\u0131ml\u0131l\u0131klar\u0131 kurun, database \u015feman\u0131z varsa migrasyonlar\u0131 ko\u015fun, sonra <strong>pm2 reload myapp<\/strong>. Reload, eski s\u00fcre\u00e7 kapanmadan yenisini aya\u011fa kald\u0131rd\u0131\u011f\u0131 i\u00e7in kullan\u0131c\u0131 fark etmez. K\u00fc\u00e7\u00fck bir \u00f6rnek da\u011f\u0131t\u0131m ad\u0131m\u0131:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">git pull origin main\nnpm ci --only=production\nnpm run build\npm2 reload myapp<\/code><\/pre>\n<p>Biraz daha esnek, systemd\u2019e yak\u0131\u015fan bir yakla\u015f\u0131m ise s\u00fcr\u00fcml\u00fc klas\u00f6rlerdir. Uygulamay\u0131 <strong>\/var\/www\/myapp\/releases\/2024-11-07-1200<\/strong> gibi zaman damgal\u0131 klas\u00f6rlere koyars\u0131n\u0131z. <strong>current<\/strong> adl\u0131 sembolik link hangi s\u00fcr\u00fcm\u00fcn canl\u0131 oldu\u011funu s\u00f6yler. Da\u011f\u0131t\u0131mda yeni klas\u00f6r\u00fc rsync ile doldurur, ba\u011f\u0131ml\u0131l\u0131klar\u0131 kurar, <strong>current<\/strong> ba\u011flant\u0131s\u0131n\u0131 yeni s\u00fcr\u00fcme \u00e7evirir, sonra <strong>systemctl restart myapp<\/strong> dersiniz. Nginx \u00f6n\u00fcnde oldu\u011fu i\u00e7in kapatma-a\u00e7ma aras\u0131 \u00e7ok k\u0131sa kal\u0131r, ba\u011flant\u0131lar kesilmez. A\u015fa\u011f\u0131 yukar\u0131 \u015f\u00f6yle bir da\u011f\u0131t\u0131m beti\u011fi yeter:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">#!\/usr\/bin\/env bash\nset -euo pipefail\nAPP_DIR=\/var\/www\/myapp\nRELEASE=$(date +&quot;%Y-%m-%d-%H%M%S&quot;)\nTARGET=&quot;$APP_DIR\/releases\/$RELEASE&quot;\nmkdir -p &quot;$TARGET&quot;\n\n# Kodlar\u0131 getir\nrsync -a --delete .\/ &quot;$TARGET&quot;\/\n\n# Ba\u011f\u0131ml\u0131l\u0131klar ve build\ncd &quot;$TARGET&quot;\nnpm ci --only=production\nnpm run build || true\n\n# Sa\u011fl\u0131k kontrol\u00fc i\u00e7in portu localde \u00e7al\u0131\u015ft\u0131r\u0131p bir kez yoklama da ekleyebilirsiniz\n\n# Canl\u0131ya al\nln -sfn &quot;$TARGET&quot; &quot;$APP_DIR\/current&quot;\nsudo systemctl restart myapp\n\n# \u0130sterseniz eski s\u00fcr\u00fcmleri saklama politikas\u0131na g\u00f6re temizleyin<\/code><\/pre>\n<p>Bu y\u00f6ntem mavi\/ye\u015fil\u2019e g\u00f6z k\u0131rpar. \u0130sterseniz iki farkl\u0131 portta iki s\u00fcr\u00fcm\u00fc \u00e7al\u0131\u015ft\u0131r\u0131r, Nginx upstream\u2019i k\u00fc\u00e7\u00fck bir konfig\u00fcrasyon g\u00fcncellemesiyle birinden di\u011ferine ge\u00e7irirsiniz. Risksiz geri d\u00f6nmek de kolayla\u015f\u0131r, \u00e7\u00fcnk\u00fc eski s\u00fcr\u00fcm duruyor. Da\u011f\u0131t\u0131m ak\u0131\u015f\u0131n\u0131z\u0131 daha detayl\u0131 kurgulamak isterseniz, biz daha \u00f6nce <a href=\"https:\/\/www.dchost.com\/blog\/vpse-sifir-kesinti-ci-cd-nasil-kurulur-rsync-sembolik-surumler-ve-systemd-ile-sicak-bir-yolculuk\/\">VPS\u2019e s\u0131f\u0131r kesinti CI\/CD kurulumunu rsync ve sembolik s\u00fcr\u00fcmlerle ad\u0131m ad\u0131m<\/a> anlatm\u0131\u015ft\u0131k; oradaki mant\u0131\u011f\u0131 Node uygulamas\u0131na uyarlamak olduk\u00e7a do\u011fal.<\/p>\n<p>Son bir dokunu\u015f: da\u011f\u0131t\u0131m sonras\u0131 uygulaman\u0131n \u201ciyi misin?\u201d dedi\u011fimiz bir health endpoint\u2019ine yan\u0131t verdi\u011fini kontrol etmeyi al\u0131\u015fkanl\u0131k yap\u0131n. Nginx\u2019e k\u0131sa s\u00fcreli bir \u201cbekle, yeni s\u00fcr\u00fcm ayaklan\u0131yor\u201d sabr\u0131 tan\u0131mak, ufak gecikmelerde 502 paniklerinin \u00f6n\u00fcne ge\u00e7er.<\/p>\n<h2 id=\"section-8\">Loglar, \u0130zleme ve K\u00fc\u00e7\u00fck Dokunu\u015flar<\/h2>\n<p>Her \u015fey \u00e7al\u0131\u015f\u0131yor diye kenara yaslanmak yerine, kula\u011f\u0131n\u0131z\u0131 sahaya dayay\u0131n. Loglar\u0131n\u0131z d\u00f6ng\u00fcye girsin, boyutlar makul kals\u0131n. PM2 kullan\u0131yorsan\u0131z log d\u00f6n\u00fc\u015ft\u00fcrme i\u00e7in kendi ara\u00e7lar\u0131 var; systemd taraf\u0131nda ise <strong>journalctl<\/strong> zaten i\u015fin b\u00fcy\u00fck b\u00f6l\u00fcm\u00fcn\u00fc hallediyor. Uygulama loglar\u0131n\u0131 tek kanaldan ak\u0131tmak, sorun \u00e7\u00f6zmeyi be\u015f dakikada bitiren bir al\u0131\u015fkanl\u0131k.<\/p>\n<p>Bir s\u00fcre sonra izleme ihtiyac\u0131 kendini belli ediyor. CPU\u2019nun nabz\u0131, bellek t\u00fcketimi, 5xx oran\u0131, gecikmeler\u2026 Bunlar\u0131 ufak panolar halinde g\u00f6rmek, sorun \u00e7\u0131kmadan \u00f6nce size g\u00f6z k\u0131rpar. Sunucu taraf\u0131nda hafif bir s\u00fcre\u00e7 y\u00f6netimi, Nginx\u2019te kibar zaman a\u015f\u0131mlar\u0131, uygulama taraf\u0131nda \u00f6l\u00e7\u00fcm noktalar\u0131\u2026 Hepsi birlikte k\u00fc\u00e7\u00fck bir orkestra gibi \u00e7alar. Bu orkestray\u0131 kurarken belgeler bazen alt\u0131n de\u011ferinde oluyor; \u00f6rne\u011fin <a href=\"https:\/\/certbot.eff.org\/instructions\" target=\"_blank\" rel=\"noopener nofollow\">Certbot\u2019un basit y\u00f6nergeleri<\/a> tek sayfada yolu g\u00f6steriyor.<\/p>\n<p>Bir de k\u00fc\u00e7\u00fck bir pratik: \u00fcretimde <strong>npm install<\/strong> yerine <strong>npm ci<\/strong> kullanmak, ba\u011f\u0131ml\u0131l\u0131klar\u0131n tutarl\u0131 kurulmas\u0131n\u0131 sa\u011flar. Build ad\u0131m\u0131n\u0131 her seferinde temiz almak, yar\u0131n \u00f6b\u00fcr g\u00fcn \u201cbende \u00e7al\u0131\u015f\u0131yor\u201d c\u00fcmlesini tarihe kar\u0131\u015ft\u0131r\u0131r. Ortam de\u011fi\u015fkenlerini sistem taraf\u0131nda tan\u0131mlay\u0131p, yaln\u0131zca ihtiya\u00e7 duyduklar\u0131n\u0131z\u0131 uygulamaya verin; hem g\u00fcvenlik, hem ta\u015f\u0131nabilirlik i\u00e7in iyi gelir.<\/p>\n<h2 id=\"section-9\">Kapan\u0131\u015f: Ritmi Bulunca Gerisi Ak\u0131yor<\/h2>\n<p>Ba\u015fta g\u00f6z korkutucu g\u00f6r\u00fcnen \u00fcretim d\u00fczeni, birka\u00e7 do\u011fru ta\u015f yerini bulunca huzura kavu\u015fuyor. PM2 ile pratik bir ba\u015flang\u0131\u00e7 yapabilir, systemd ile k\u00f6k salm\u0131\u015f bir servis mimarisi kurabilir, Nginx\u2019i \u00f6ne al\u0131p trafi\u011fi yumu\u015fatabilir, SSL\u2019i temizce ba\u011flay\u0131p g\u00fcveni sa\u011flad\u0131ktan sonra s\u0131f\u0131r kesintili da\u011f\u0131t\u0131mla g\u00f6n\u00fcl rahatl\u0131\u011f\u0131yla \u201cdeploy\u201d diyebilirsiniz. \u0130\u015fin g\u00fczeli, bu par\u00e7alar bir kez elinize al\u0131\u015f\u0131nca art\u0131k her projede kendili\u011finden ak\u0131yor.<\/p>\n<p>Benim tavsiyem, \u00f6nce k\u00fc\u00e7\u00fck ad\u0131mlarla ilerleyin. Health endpoint\u2019i eklemek, loglar\u0131 tek yere toplamak, da\u011f\u0131t\u0131m beti\u011fini sadele\u015ftirmek gibi ufak dokunu\u015flar bile b\u00fcy\u00fck fark yarat\u0131yor. Sonra s\u0131ras\u0131yla reload veya sembolik s\u00fcr\u00fcm ak\u0131\u015f\u0131n\u0131 oturtun, SSL\u2019i s\u0131k\u0131la\u015ft\u0131r\u0131n, Nginx ayarlar\u0131n\u0131z\u0131 g\u00f6zden ge\u00e7irin. Bir noktada fark edeceksiniz: gece yar\u0131s\u0131 gelen telefonlar\u0131n say\u0131s\u0131 d\u00fc\u015fecek, hatta belki tamamen susacak. Umar\u0131m bu yaz\u0131 size o ritmi bulmada yard\u0131mc\u0131 olmu\u015ftur. Bir dahaki yaz\u0131da daha da ince ayarlarda bulu\u015furuz; i\u00e7iniz ferah olsun, \u00fcretim d\u00fcnyas\u0131 sand\u0131\u011f\u0131n\u0131z kadar sert de\u011fil, do\u011fru re\u00e7eteyle gayet uysal.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Ofiste Gece Yar\u0131s\u0131: K\u00fc\u00e7\u00fck Bir Kesinti, B\u00fcy\u00fck Bir Ders Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Uykunun en tatl\u0131 yerinde telefon \u00e7alar, bildirim sesi kula\u011f\u0131n\u0131z\u0131 deler, bir bakm\u0131\u015fs\u0131n\u0131z Node.js uygulamas\u0131 susmu\u015f. O gece ben de ayn\u0131 duyguyla telefona uzanm\u0131\u015ft\u0131m. Sunucuda hi\u00e7bir \u015fey yokmu\u015f gibi duran k\u00fc\u00e7\u00fck bir ayr\u0131nt\u0131, sanki hal\u0131n\u0131n alt\u0131na s\u00fcp\u00fcr\u00fclm\u00fc\u015f bir toz topa\u011f\u0131 gibi birikti birikti, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1517,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1516","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\/1516","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=1516"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1516\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1517"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}