Aug 26 - Add gunicorn.conf.py
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled
This commit is contained in:
+21
-13
@@ -9,8 +9,8 @@
|
||||
#
|
||||
# Phase 5 additions vs original:
|
||||
# - Restart=on-failure: systemd restarts Gunicorn if the master exits non-zero
|
||||
# - Gunicorn --timeout: workers that don't respond within 25 s are replaced
|
||||
# - Gunicorn --graceful-timeout: allows in-flight requests to finish on reload
|
||||
# - Gunicorn settings live in gunicorn.conf.py (gthread workers, timeout
|
||||
# ordered above nginx proxy_read_timeout, /dev/shm heartbeat dir)
|
||||
# - PrivateTmp, NoNewPrivileges, ProtectSystem: basic systemd sandboxing
|
||||
# - StartLimitIntervalSec / StartLimitBurst: caps restart storm
|
||||
|
||||
@@ -29,19 +29,27 @@ Group=www-data
|
||||
WorkingDirectory=/home/spuser/PassKeeper
|
||||
EnvironmentFile=/home/spuser/PassKeeper/.env
|
||||
|
||||
# All tuning lives in gunicorn.conf.py (worker class, counts, timeouts,
|
||||
# logging) so it is versioned with the code and documented in one place.
|
||||
# Override any of it with GUNICORN_* variables in the EnvironmentFile above
|
||||
# rather than editing this line.
|
||||
# Absolute path — do not rely on WorkingDirectory for config lookup.
|
||||
ExecStart=/home/spuser/.venv/bin/gunicorn \
|
||||
--workers 4 \
|
||||
--bind 127.0.0.1:5000 \
|
||||
--timeout 25 \
|
||||
--graceful-timeout 20 \
|
||||
--keep-alive 5 \
|
||||
--access-logfile /home/spuser/logs/access.log \
|
||||
--error-logfile /home/spuser/logs/error.log \
|
||||
--log-level warning \
|
||||
-c /home/spuser/PassKeeper/gunicorn.conf.py \
|
||||
wsgi:app
|
||||
|
||||
# Reload (zero-downtime): send USR2 to Gunicorn master
|
||||
ExecReload=/bin/kill -s USR2 $MAINPID
|
||||
# Reload: HUP re-reads config and restarts workers in place under the
|
||||
# existing master.
|
||||
#
|
||||
# NOT USR2. USR2 forks a *second* master that inherits the listening socket,
|
||||
# and retiring the old one needs a follow-up WINCH + QUIT that this unit never
|
||||
# sent. The result was two masters competing for the port with systemd $MAINPID
|
||||
# tracking the stale one — a later stop/restart then signalled the wrong
|
||||
# process and the socket vanished, which Nginx reports as 502.
|
||||
#
|
||||
# HUP does not pick up changed Python source: use `systemctl restart` for code
|
||||
# deploys, reload only for config-only changes.
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
|
||||
# NO WatchdogSec here — deliberately.
|
||||
#
|
||||
@@ -52,7 +60,7 @@ ExecReload=/bin/kill -s USR2 $MAINPID
|
||||
# SIGKILLed it every ~30 s. Restart=on-failure then brought it back after RestartSec,
|
||||
# producing a repeating window of 502s from Nginx.
|
||||
#
|
||||
# Hung *workers* are already handled by Gunicorn's own --timeout above; a crashed
|
||||
# Hung *workers* are already handled by Gunicorn's own `timeout` in gunicorn.conf.py; a crashed
|
||||
# *master* is already handled by Restart=on-failure below. The watchdog added no
|
||||
# coverage, only outages.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user