mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-02 10:07:29 +09:00
Every open WebSocket and every long-polling agent holds one of the single process's 100 threads, so ~60 agents plus 40 tabs stalled the UI with no clear error. Read --threads from SERVERKIT_THREADS in the systemd unit and Docker image, and document the ceiling next to the single-worker constraint.
46 lines
1.8 KiB
Plaintext
46 lines
1.8 KiB
Plaintext
[Unit]
|
|
Description=ServerKit Backend API
|
|
After=network.target docker.service
|
|
Wants=docker.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=@USER@
|
|
Group=@USER@
|
|
WorkingDirectory=@SERVERKIT_DIR@/backend
|
|
# sbin dirs are mandatory, not cosmetic: the panel shells out to ufw, iptables
|
|
# and nft, all of which live in /usr/sbin. Without them a bare-name exec raises
|
|
# FileNotFoundError, which surfaced as "No Firewall Installed" on a host where
|
|
# ufw was installed and working. app/utils/system.py resolves such commands to
|
|
# an absolute path as a backstop; this keeps anything not routed through it
|
|
# working too.
|
|
Environment="PATH=@SERVERKIT_VENV_DIR@/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
Environment="FLASK_ENV=production"
|
|
Environment="SERVERKIT_INSTALL_DIR=@SERVERKIT_DIR@"
|
|
# Request threads; .env may override. See docs/ENVIRONMENT.md.
|
|
Environment="SERVERKIT_THREADS=100"
|
|
EnvironmentFile=@SERVERKIT_DIR@/.env
|
|
# Single PROCESS (-w 1) is mandatory: the agent gateway keeps connected-agent
|
|
# state in memory. Threaded worker (not GeventWebSocketWorker): the app runs
|
|
# async_mode='threading', where engineio serves WebSocket via simple-websocket
|
|
# on the raw socket — a gevent-websocket worker ALSO answers the upgrade,
|
|
# producing a double 101 handshake the browser reports as
|
|
# "Invalid frame header" (WS then silently degrades to polling).
|
|
ExecStart=@SERVERKIT_VENV_DIR@/bin/gunicorn -w 1 --threads ${SERVERKIT_THREADS} -b @BIND_HOST@:@PORT@ --timeout 120 --access-logfile @LOG_DIR@/access.log --error-logfile @LOG_DIR@/error.log run:app
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
# Security settings (while still allowing system management)
|
|
NoNewPrivileges=no
|
|
ProtectSystem=no
|
|
ProtectHome=no
|
|
|
|
# Logging
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=serverkit
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|