A single build.zip
make release-compat && make dist # → deploy/build.zip (~25 MB)
The binary cross-compiles for glibc 2.17 via cargo zigbuild — works on CentOS 7+ and any modern Linux.
systemd
deploy/blog.service — user blog-server (system, no-login), directory /opt/blog-server/, security hardening (NoNewPrivileges, ProtectSystem=strict), LimitNOFILE=65536. Port 80 via AmbientCapabilities=CAP_NET_BIND_SERVICE.
HAProxy reverse proxy
deploy/install_haproxy.sh + deploy/haproxy.cfg: :80 → 301 → :443, :443 → TCP passthrough → 127.0.0.1:8080 (blog-server with TLS+ACME). Stats :8404 — localhost only.
Phusion Passenger
Compatible with Passenger 6 (Generic Language Support). Passengerfile.json with max_instances: 1 (stateful app). Secure cookie via X-Forwarded-Proto — correct behavior behind a reverse proxy. Hot reload (file watcher) should not be used with Passenger.
Docker
Three compose files: dev / prod / runtime.
# Dev (build inside the container)
docker compose -f docker/docker-compose.yml up
# Prod (zigbuild under glibc 2.17 inside the container)
docker compose -f docker/docker-compose.prod.yml up --build
# Runtime (pre-built binary is mounted)
make release-compat && docker compose -f docker/docker-compose.runtime.yml up --build
For local debugging — docker/Dockerfile.debug + docker-compose.debug.yml (host-side remote debugging via gdbserver and CodeLLDB).