# ============================================================================= # 3E Eğitim — Horizon (kuyruk süpervizörü) # ============================================================================= # Kurulum: # sudo cp deployment/systemd/3eegitim-*.{service,timer} /etc/systemd/system/ # sudo systemctl daemon-reload # sudo systemctl enable --now 3eegitim-horizon 3eegitim-schedule.timer 3eegitim-backup.timer # # ⛔ NEDEN VAR (uçtan uca denetim §9): Horizon ve Reverb için servis birimi # YOKTU. Sunucu yeniden başladığında kuyruk sessizce durur — bildirim gitmez, # audit mühürlenmez, sertifika üretilmez. Hiçbir ekran hata vermez; işler # yalnızca olmaz. # ============================================================================= [Unit] Description=3E Egitim — Horizon # ⛔ `docker.service`, `redis.service` DEĞİL (OPS-5, 12.08.2026). Bu birim uzun # süre var olmayan bir birimi bekledi: `After=redis.service` yazıyordu ve o birim # sistemde YOK — Redis docker'da koşuyor. Var olmayan bir birim `After=` içinde # sessizce yok sayılır, yani "önce Redis" sırası hiç işlemiyordu. After=network-online.target docker.service Wants=network-online.target Requires=docker.service # ⛔ Start limiti KAPALI, ve `ExecStartPre` yüzünden zorunlu. Hazırlık kontrolü # birkaç kez üst üste düşerse systemd varsayılanı (10 sn'de 5 deneme) devreye # girer ve unit KALICI olarak vazgeçer — korunmak istediğimiz hâlin ta kendisi, # bu kez systemd eliyle. Beklemenin kendisi zaten süreli. StartLimitIntervalSec=0 [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/var/www/html/3e-egitim/current # ⚠ `--environment` açıkça: systemd'nin ortamı kabuğunkinden farklıdır ve # APP_ENV okunmazsa Horizon local varsayar. # ⛔ Container'lar hazır olana kadar beklenir. `After=docker.service` yalnız # daemon'un başladığını söyler; container'lar ondan SONRA, asenkron kalkar. Bu # satır olmadan reboot'ta kuyruk Redis'ten önce ayağa kalkar ve # `Connection refused` ile döner (OPS-2/OPS-3'ün reboot'taki eşi). ExecStartPre=/var/www/html/3e-egitim/current/deployment/scripts/wait-for-services.sh redis postgres ExecStart=/usr/bin/php8.5 artisan horizon --environment=production # ⛔ `horizon:terminate` ile durur, SIGKILL ile değil. Çalışan bir işin # ortasında öldürmek, yarım yazılmış bir audit satırı bırakır. ExecStop=/usr/bin/php8.5 artisan horizon:terminate Restart=always RestartSec=5 # ⚠ Bellek tavanı: bir worker sızdırırsa systemd onu yeniden başlatır ve # sunucu takas alanına düşmez. MemoryMax=1G StandardOutput=append:/var/log/3eegitim/horizon.log StandardError=append:/var/log/3eegitim/horizon-error.log [Install] WantedBy=multi-user.target