Alpha ZealPHP is early-stage and under active development. APIs may change between minor versions until v1.0. Feedback and bug reports welcome on GitHub.

Deploy

ZealPHP is a long-lived OpenSwoole server process. One process per port, N workers per process. Run behind a reverse proxy (nginx or Caddy) for TLS, static assets, and request logging.

systemd

A reference unit is shipped at deploy/zealphp.service. Copy it to /etc/systemd/system/zealphp.service, adjust User, WorkingDirectory, and ExecStart, then:

Enable and start the service
sudo systemctl daemon-reload
sudo systemctl enable zealphp
sudo systemctl start zealphp
sudo systemctl status zealphp

# Logs:
sudo journalctl -u zealphp -f

The unit is Type=simple — do not pass -d in ExecStart, systemd manages the lifecycle.

Environment variables

VariableDefaultPurpose
ZEALPHP_HOST0.0.0.0Bind address
ZEALPHP_PORT8080Listen port
ZEALPHP_WORKERSCPU countHTTP worker processes
ZEALPHP_TASK_WORKERS0Background task workers
ZEALPHP_SESSION_SECUREauto-detectForce Secure cookie flag (1/0). Auto-detects HTTPS via HTTPS, HTTP_X_FORWARDED_PROTO, or SERVER_PORT=443 headers.
ZEALPHP_COMPRESSION_MIDDLEWARE0Enable the reference PHP compression middleware (only if OpenSwoole's native http_compression is disabled).
ZEALPHP_HTTP_COMPRESSION1Enable OpenSwoole native HTTP compression.
ZEALPHP_SITE_URLrequest hostOverride the URL used in demo links rendered by the site.

nginx reverse proxy

/etc/nginx/sites-available/zealphp
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass         http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;

        # WebSocket upgrades on /ws/*
        proxy_set_header   Upgrade    $http_upgrade;
        proxy_set_header   Connection "upgrade";

        # SSE: disable response buffering and bump timeout
        proxy_buffering    off;
        proxy_read_timeout 86400;
    }
}

Caddy reverse proxy

Caddyfile
example.com {
    reverse_proxy 127.0.0.1:8080 {
        flush_interval -1   # streaming SSE / WebSocket
    }
}

Docker

The repo ships a Dockerfile and docker-compose.yml. For production:

docker-compose.yml (production sketch)
services:
  app:
    image: zealphp:0.2.0
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      ZEALPHP_HOST: 0.0.0.0
      ZEALPHP_PORT: 8080
      ZEALPHP_WORKERS: 8
      ZEALPHP_SESSION_SECURE: "1"
    volumes:
      - sessions:/var/lib/php/sessions
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/"]
      interval: 30s
      timeout: 5s
      retries: 3
volumes:
  sessions:

Production checklist

  • Run as a non-root user; bind to 8080, not 80.
  • Pin OpenSwoole + uopz extension versions in your Dockerfile.
  • Set ZEALPHP_WORKERS ≈ CPU cores.
  • Ensure the session save path (/var/lib/php/sessions) is writable by the service user and mode 0700.
  • Disable debug logging in production (ZEALPHP_DEBUG=0 or unset).
  • Rotate logs in /tmp/zealphp/ with logrotate.
  • Behind a TLS-terminating proxy, leave ZEALPHP_SESSION_SECURE unset — the framework auto-detects HTTPS from X-Forwarded-Proto.
  • Use php app.php restart for graceful, zero-downtime worker recycling.

More

Detailed write-up: docs/deployment.md on GitHub.