Add AST JSON files for new documentation and scripts
- Created JSON representation for `collect-diagnostics.sh` including nodes and edges for its structure. - Added JSON for `ops-restarts.md` detailing various sections and their relationships. - Introduced JSON for `server-down-oom-diagnosis.md` capturing its content and connections.
This commit is contained in:
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/bin/sh
|
||||
# ClinicPro production diagnostics — run ON THE HOST as root (or a user with docker access).
|
||||
# Collects every piece of evidence needed to pin down why the service goes down
|
||||
# after hours of uptime (OOM vs full disk vs Redis growth). See docs/ops-restarts.md §7.
|
||||
#
|
||||
# Usage: sh collect-diagnostics.sh [container-name-or-id]
|
||||
set -u
|
||||
C="${1:-$(docker ps --format '{{.Names}}' | grep -i -m1 clinic || true)}"
|
||||
|
||||
echo "=== 1. OOM evidence (kernel, last 48h) ==="
|
||||
journalctl -k --since "48 hours ago" 2>/dev/null | grep -i -E "oom|killed process" | tail -20 \
|
||||
|| dmesg 2>/dev/null | grep -i -E "oom|killed process" | tail -20
|
||||
|
||||
echo ""
|
||||
echo "=== 2. Memory / swap now ==="
|
||||
free -h
|
||||
|
||||
echo ""
|
||||
echo "=== 3. Disk ==="
|
||||
df -h | head -10
|
||||
du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -h | tail -5
|
||||
|
||||
echo ""
|
||||
echo "=== 4. Container state ==="
|
||||
docker ps -a --format 'table {{.Names}}\t{{.Status}}'
|
||||
if [ -n "$C" ]; then
|
||||
docker inspect --format \
|
||||
'OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}} RestartCount={{.RestartCount}} StartedAt={{.State.StartedAt}} FinishedAt={{.State.FinishedAt}}' "$C"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 5. Live memory per container ==="
|
||||
docker stats --no-stream
|
||||
|
||||
echo ""
|
||||
echo "=== 6. php-fpm inside app container ==="
|
||||
if [ -n "$C" ]; then
|
||||
docker exec "$C" sh -c 'php -i 2>/dev/null | grep -E "^memory_limit"; ps -o rss,args 2>/dev/null | grep -E "php-fpm|messenger" | grep -v grep'
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 7. Redis memory ==="
|
||||
R="$(docker ps --format '{{.Names}}' | grep -i -m1 redis || true)"
|
||||
if [ -n "$R" ]; then
|
||||
docker exec "$R" redis-cli info memory 2>/dev/null | grep -E "used_memory_human|maxmemory_human|maxmemory_policy"
|
||||
docker exec "$R" redis-cli xlen messages 2>/dev/null && echo "(messages stream length above)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 8. Docker log driver config ==="
|
||||
docker info --format '{{.LoggingDriver}}' 2>/dev/null
|
||||
cat /etc/docker/daemon.json 2>/dev/null || echo "(no daemon.json — log rotation NOT configured)"
|
||||
|
||||
echo ""
|
||||
echo "=== done — paste this whole output back for diagnosis ==="
|
||||
+21
-2
@@ -108,7 +108,15 @@ GET /.well-known/acme-challenge/xxxx HTTP/1.1" 404 ... "Let's Encrypt validation
|
||||
|
||||
الگو: workerها چند بار recycle عادی میشوند و بعد از چند ساعت کل سرویس down میشود. مظنون اول: پر شدن حافظه سرور و کشته شدن پروسهها توسط OOM-killer.
|
||||
|
||||
### تأیید روی سرور
|
||||
### تأیید روی سرور — اسکریپت آماده
|
||||
|
||||
فایل [`docs/collect-diagnostics.sh`](collect-diagnostics.sh) را روی **هاست** کپی و اجرا کنید (همه شواهد را یکجا جمع میکند):
|
||||
|
||||
```bash
|
||||
scp docs/collect-diagnostics.sh root@SERVER:/tmp/ && ssh root@SERVER sh /tmp/collect-diagnostics.sh
|
||||
```
|
||||
|
||||
یا دستورهای کلیدی بهصورت دستی:
|
||||
|
||||
```bash
|
||||
# آیا کانتینر با OOM کشته شده؟
|
||||
@@ -124,7 +132,17 @@ docker stats --no-stream
|
||||
free -h
|
||||
```
|
||||
|
||||
اگر `OOMKilled=true` یا در journalctl خط `Out of memory: Killed process ... (php-fpm|mariadbd)` دیدید، تشخیص قطعی است.
|
||||
### جدول تفسیر خروجی اسکریپت
|
||||
|
||||
| شاهد در خروجی | تشخیص | اقدام |
|
||||
|---|---|---|
|
||||
| بخش ۱: `Out of memory: Killed process ... php-fpm` | نشت حافظه fpm | فیکسهای `pm.max_requests`/`memory_limit` این repo + redeploy کافی است |
|
||||
| بخش ۱: `Killed process ... mariadbd` یا `redis` | فشار کل RAM سرور | Redis `maxmemory` + Memory Limit در Coolify + swap |
|
||||
| بخش ۴: `OOMKilled=true` | سقف حافظه خود کانتینر | سقف را بالاتر ببرید یا مصرف را کم کنید |
|
||||
| بخش ۳: دیسک ≥ ۹۰٪ یا `*-json.log` چند GB | دیسک پر | log rotation در `daemon.json` + پاکسازی |
|
||||
| بخش ۷: `maxmemory: 0` و `used_memory` بزرگ/رشدکننده | Redis بیسقف | `maxmemory 256mb` + `maxmemory-policy volatile-lru` |
|
||||
| بخش ۶: `memory_limit` هنوز `1024M` | image قدیمی در حال اجراست | Redeploy نشده — دوباره deploy کنید |
|
||||
| هیچکدام | فرضیه حافظه/دیسک رد شد | خروجی کامل اسکریپت + ۵۰ خط آخر لاگ قبل از down را برای تحلیل بفرستید |
|
||||
|
||||
### چرا این اتفاق میافتاد (و فیکس اعمالشده)
|
||||
|
||||
@@ -134,6 +152,7 @@ free -h
|
||||
|
||||
### اقدامات تکمیلی روی سرور (خارج از repo)
|
||||
|
||||
0. **اول Redeploy** — همه فیکسهای این repo (php.ini، zz-pool.conf، supervisord.conf) فقط با build/deploy جدید اعمال میشوند؛ و در env واقعی Coolify به `MESSENGER_TRANSPORT_DSN` پارامتر `?stream_max_entries=20000` را اضافه کنید (نمونه در `.env.coolify.example`).
|
||||
1. در Coolify برای resource اپ **Memory Limit** بگذارید (مثلاً 1G) تا در بدترین حالت فقط همان کانتینر ریاستارت شود، نه کل سرور.
|
||||
2. اگر سرور swap ندارد، 1-2G swap اضافه کنید: `fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile`.
|
||||
3. اسکنهای بات (درخواستهای `GET /xxx.php → 404` پشتسرهم) توسط nginx مستقیم 404 میشوند و به Symfony نمیرسند — عامل مرگ نیستند، فقط نویز لاگ.
|
||||
|
||||
Reference in New Issue
Block a user