mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-23 03:27:43 +09:00
Drop gevent and the stale backend Dockerfile
The panel runs async_mode='threading' under a plain threaded gunicorn worker; nothing imports gevent. It was still installed everywhere, and on Python 3.14 (no wheel yet) its source build is what broke installs in issue #148. backend/Dockerfile was unreferenced and still launched the gevent-websocket worker that double-answers the WS handshake; the run.py hint recommended the same worker.
This commit is contained in:
1 parent
5e4ca2e8a1
commit
b739a6b17e
10 files changed
+14
-87
No files matched your search
+2
-4
@@ -44,7 +44,7 @@ RUN npm run build
|
||||
# Stage 2: Python dependency builder
|
||||
#
|
||||
# The compiler toolchain (gcc, *-dev headers) is needed to build wheels for
|
||||
# gevent / cryptography / lxml on platforms without a prebuilt wheel, but it is
|
||||
# cryptography / lxml / psutil on platforms without a prebuilt wheel, but it is
|
||||
# ~280 MB and has no business in a running panel. Building into a self-contained
|
||||
# venv here lets the runtime stage take the result and leave the toolchain behind.
|
||||
FROM python:3.11-slim-bookworm AS python-builder
|
||||
@@ -55,8 +55,6 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
python3-dev \
|
||||
# Required for gevent
|
||||
libevent-dev \
|
||||
# Required for cryptography
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
@@ -73,7 +71,7 @@ RUN pip install --no-cache-dir --upgrade pip \
|
||||
# surfaces as a failed image build, never as a half-installed panel on a host.
|
||||
#
|
||||
# 1. Bundled test suites. Third-party packages ship their own pytest trees
|
||||
# (gevent and passlib are the big ones) that no running panel imports.
|
||||
# (passlib is the big one) that no running panel imports.
|
||||
# 2. botocore API models. botocore carries JSON models for 400+ AWS services
|
||||
# (~15 MB); ServerKit constructs exactly three clients — s3
|
||||
# (storage_provider_service), route53 (dns_provider_service) and ses
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# Backend Dockerfile for ServerKit
|
||||
#
|
||||
# NOTE: A containerized backend CANNOT manage the host (no host Docker daemon,
|
||||
# nginx, systemctl, or real /var/serverkit/apps). The canonical deployment runs
|
||||
# the backend on the host via systemd (see install.sh + docker-compose.yml,
|
||||
# which is frontend-only). This image is only for local/dev or all-in-one demos.
|
||||
FROM python:3.11-slim-bookworm
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
FLASK_ENV=production \
|
||||
SERVERKIT_BACKEND_PORT=5000
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies including ClamAV for security scanning
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# Build dependencies
|
||||
gcc \
|
||||
python3-dev \
|
||||
libpq-dev \
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
libevent-dev \
|
||||
# ClamAV antivirus
|
||||
clamav \
|
||||
clamav-daemon \
|
||||
clamav-freshclam \
|
||||
# Utilities
|
||||
curl \
|
||||
procps \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get clean
|
||||
|
||||
# Create directories for ServerKit
|
||||
RUN mkdir -p /etc/serverkit /var/serverkit/apps /app/logs /var/quarantine /app/instance /var/backups/serverkit
|
||||
|
||||
# Copy requirements first for caching
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install --no-cache-dir -r requirements.txt \
|
||||
&& pip install --no-cache-dir gunicorn gevent gevent-websocket
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create non-root user and set permissions. /var/serverkit must be owned by
|
||||
# appuser too, otherwise the (dev/demo) backend cannot create app directories
|
||||
# under /var/serverkit/apps and fails with EACCES.
|
||||
RUN useradd --create-home appuser \
|
||||
&& chown -R appuser:appuser /app \
|
||||
&& chown -R appuser:appuser /app/instance \
|
||||
&& chown -R appuser:appuser /etc/serverkit \
|
||||
&& chown -R appuser:appuser /var/serverkit \
|
||||
&& chown -R appuser:appuser /var/quarantine \
|
||||
&& chown -R appuser:appuser /var/backups/serverkit
|
||||
|
||||
USER appuser
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f "http://localhost:${SERVERKIT_BACKEND_PORT:-5000}/api/v1/system/health" || exit 1
|
||||
|
||||
# Run with gunicorn + gevent for WebSocket support
|
||||
CMD ["sh", "-c", "exec gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 -b 0.0.0.0:${SERVERKIT_BACKEND_PORT:-5000} --timeout 120 --access-logfile - --error-logfile - run:app"]
|
||||
@@ -37,8 +37,6 @@ psutil==5.9.7
|
||||
# against async_mode='threading' (browser: "Invalid frame header").
|
||||
gunicorn==23.0.0
|
||||
simple-websocket==1.1.0
|
||||
gevent==25.4.2
|
||||
gevent-websocket==0.10.1
|
||||
|
||||
# Environment variables
|
||||
python-dotenv==1.2.2
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ if __name__ == '__main__':
|
||||
if env == 'production':
|
||||
print("ERROR: Do not run the development server in production!", file=sys.stderr)
|
||||
print("Use a production WSGI server like gunicorn instead:", file=sys.stderr)
|
||||
print(" gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 run:app", file=sys.stderr)
|
||||
print(" gunicorn -w 1 --threads 100 run:app", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Use SocketIO to run the app (supports WebSocket) - only in development
|
||||
|
||||
+1
-1
@@ -1460,7 +1460,7 @@ build_virtualenv() {
|
||||
else
|
||||
pip install -r "$INSTALL_DIR/backend/requirements.txt" --quiet
|
||||
fi
|
||||
pip install gunicorn gevent gevent-websocket --quiet
|
||||
pip install gunicorn --quiet
|
||||
|
||||
good "Python environment ready."
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ python3 -m venv --copies "$VENV_BUILD_DIR"
|
||||
source "$VENV_BUILD_DIR/bin/activate"
|
||||
pip install --upgrade pip --quiet
|
||||
pip install -r "$BUILD_DIR/backend/requirements.txt" --quiet
|
||||
pip install gunicorn gevent gevent-websocket --quiet
|
||||
pip install gunicorn --quiet
|
||||
|
||||
# Make the venv relocatable: rewrite absolute paths in activate scripts and
|
||||
# shebangs so the venv works at $TARGET_VENV_PATH on the target server.
|
||||
|
||||
@@ -368,7 +368,7 @@ sr_deploy() {
|
||||
( # shellcheck source=/dev/null
|
||||
source "$SR_VENV/bin/activate"
|
||||
pip install -q -r "$STAGE_DIR/backend/requirements.txt" \
|
||||
&& pip install -q gunicorn gevent gevent-websocket ) \
|
||||
&& pip install -q gunicorn ) \
|
||||
|| sr_die "pip install failed — previous staging deploy still running."
|
||||
else
|
||||
sr_step "Building the Python virtualenv"
|
||||
|
||||
@@ -199,8 +199,8 @@ The two modes deliberately make narrower claims than a full install:
|
||||
|
||||
- **quick** — shell syntax plus the source-level installer/update/lib/CLI suites.
|
||||
- **provision** — real repositories through `install.sh`, including supported
|
||||
Python, venv, pip, SSL, SQLite, ctypes, and a source build/import of the pinned
|
||||
gevent dependency. Ubuntu 26.04 also installs all backend requirements and
|
||||
Python, venv, pip, SSL, SQLite, ctypes, and a source build/import of gevent (a
|
||||
heavy C build that proves the toolchain). Ubuntu 26.04 also installs all backend requirements and
|
||||
runs `pip check`.
|
||||
|
||||
Neither mode proves systemd, nginx, firewall behavior, Docker-in-Docker,
|
||||
|
||||
@@ -167,12 +167,14 @@ else
|
||||
bad "it cannot create a virtualenv"
|
||||
fi
|
||||
# Force a source build: a cached/platform wheel would hide missing Python.h
|
||||
# and compilers, the exact gap behind issue #148. Use the production pin.
|
||||
native_requirement=$(grep '^gevent==' "$REPO_DIR/backend/requirements.txt")
|
||||
# and compilers, the exact gap behind issue #148. gevent is no longer a
|
||||
# panel dependency; it stays here as a heavy C build that proves the
|
||||
# toolchain works for whatever native dependency comes next.
|
||||
native_requirement='gevent==25.4.2'
|
||||
if /tmp/pp-venv/bin/python -m pip install --no-cache-dir --no-binary=gevent \
|
||||
"$native_requirement" >/tmp/pp-native.log 2>&1 \
|
||||
&& /tmp/pp-venv/bin/python -c 'import gevent' >/dev/null 2>&1; then
|
||||
ok "the pinned gevent dependency builds from source and imports"
|
||||
ok "a native C dependency (gevent) builds from source and imports"
|
||||
else
|
||||
bad "native dependency build failed"
|
||||
tail -40 /tmp/pp-native.log
|
||||
|
||||
+1
-1
@@ -696,7 +696,7 @@ rebuild_virtualenv() {
|
||||
source "$target_dir/bin/activate"
|
||||
pip install --upgrade pip --quiet
|
||||
pip install -r "$target_dir/../backend/requirements.txt" --quiet
|
||||
pip install gunicorn gevent gevent-websocket --quiet
|
||||
pip install gunicorn --quiet
|
||||
good "Virtual environment rebuilt at $target_dir"
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user