34 lines
1.8 KiB
Plaintext
34 lines
1.8 KiB
Plaintext
[supervisord]
|
|
nodaemon=true ; Run supervisord in the foreground
|
|
logfile=/dev/null ; Log supervisord output to stdout/stderr
|
|
logfile_maxbytes=0
|
|
|
|
[program:redis]
|
|
; Loopback-only and password-protected. REDIS_PASSWORD is exported by
|
|
; entrypoint.sh from the mounted secret; the app must supply it to connect.
|
|
command=/usr/bin/redis-server --loglevel notice --bind 127.0.0.1 ::1 --requirepass "%(ENV_REDIS_PASSWORD)s" --dir /var/lib/redis
|
|
user=appuser ; Run redis as our non-root user
|
|
autorestart=true
|
|
priority=10
|
|
stdout_logfile=/dev/stdout ; Redirect redis stdout to container stdout
|
|
stdout_logfile_maxbytes=0
|
|
stderr_logfile=/dev/stderr ; Redirect redis stderr to container stderr
|
|
stderr_logfile_maxbytes=0
|
|
|
|
[program:gunicorn]
|
|
; Bind is resolved by entrypoint.sh into GUNICORN_BIND: loopback unless a
|
|
; credential (CRAWL4AI_API_TOKEN) is present, in which case the operator may
|
|
; expose 0.0.0.0. gunicorn is the authoritative socket-level guard; the Python
|
|
; _resolve_auth() check is the in-process guard - both must agree.
|
|
command=/usr/local/bin/gunicorn --bind "%(ENV_GUNICORN_BIND)s" --workers 1 --threads 4 --timeout 1800 --graceful-timeout 30 --keep-alive 300 --log-level info --limit-request-line 8190 --limit-request-fields 100 --worker-class uvicorn.workers.UvicornWorker server:app
|
|
directory=/app ; Working directory for the app
|
|
user=appuser ; Run gunicorn as our non-root user
|
|
autorestart=true
|
|
priority=20
|
|
environment=PYTHONUNBUFFERED=1 ; Ensure Python output is sent straight to logs
|
|
stdout_logfile=/dev/stdout ; Redirect gunicorn stdout to container stdout
|
|
stdout_logfile_maxbytes=0
|
|
stderr_logfile=/dev/stderr ; Redirect gunicorn stderr to container stderr
|
|
stderr_logfile_maxbytes=0
|
|
|
|
# Optional: Add filebeat or other logging agents here if needed |