Git Projects & Zero-Downtime Deployments
PanelOps connects directly to your GitHub repositories, allowing you to deploy full-stack web applications, microservices, and APIs with automatic framework detection, zero-downtime blue/green rollouts, and automatic continuous integration.
🛠️ Supported Frameworks & Autodetection
PanelOps automatically inspects your repository and configures optimized Docker container stacks for:
- Node.js: Next.js, Express, NestJS, Remix, Nuxt, Vite, Fastify, Astro.
- Python: Django, FastAPI, Flask, Tornado, Gunicorn/Uvicorn.
- PHP: Laravel, Symfony, WordPress, Composer packages.
- Go: Gin, Fiber, Echo, standard Go binaries.
- Rust: Actix-web, Axum, Rocket.
- Ruby: Ruby on Rails, Sinatra, Puma.
- Static Sites: HTML5, React SPA, Vue SPA, Tailwind outputs (served via Nginx alpine).
- Dockerfile: Custom multi-stage Docker builds.
🔄 Deployment Pipeline
GitHub Push / Manual Trigger
│
▼
1. Source Clone / Fetch (shallow git clone)
│
▼
2. Build Engine (Docker containerized build with caching)
│
▼
3. Zero-Downtime Rollout (spins up new container on alternate port)
│
▼
4. Health Check Verification (verifies HTTP 200 on /healthz or /)
│
▼
5. Live Promotion (updates each configured proxy route and verifies it before committing the active deployment pointer)
⚡ Key Features
- Blue/Green Candidate Deployments: Each run receives a unique deployment ID, isolated source workspace, image tag, container name, and Docker-assigned host port. The active project and proxy are not switched until the candidate passes its health check.
- Rollback Retention: The previous container is given time to drain, then stopped but retained with its image so it remains available for rollback.
DEPLOYMENT_RETAIN_PREVIOUScontrols how many prior successful deployments are retained (default1, clamped to1–100); older containers and images are pruned after promotion. - GitHub Webhooks (Continuous Deployment): Webhook signatures are checked against the raw request body. Delivery IDs are unique, repository identity and configured branches are checked, and deployments are placed in the persistent Agenda queue.
- GitHub Commit Statuses: Connected GitHub accounts receive pending, success, or failure statuses for the deployed commit and environment.
- Environment Variables & Secrets: Manage production
.envvariables securely with AES-256 encryption. - Live Streaming Build Logs: Stream terminal build steps and container logs in real time over WebSockets.
- Instant Rollbacks: Revert to any prior successful deployment with 1 click.
- Deployment Terminal: Open a read-only, deployment-scoped live log stream from deployment history. Recent sanitized output is persisted for reconnect/replay; the terminal does not control the deployment process.
- Node.js Defaults: Node.js builds default to the current Node 22 LTS line when a repository does not declare a runtime version. A repository's detected
engines.nodeversion or an explicit project runtime setting takes precedence.
Docker BuildKit and npm may write normal progress and warnings to stderr. The deployment terminal reports that output as informational or warning-level; a failed Docker build is reported as an error when the build command exits unsuccessfully.
Operational limitations
Blue/green promotion is conditional, not an absolute zero-downtime guarantee. It depends on the configured health-check endpoint accurately representing readiness, the target server's Docker/Nginx availability, and backward-compatible database changes. The candidate must pass its own HTTP/process check and each configured domain route must return a 2xx/3xx response after the proxy switch before the active deployment pointer is committed. Nginx reloads gracefully and existing connections are allowed to drain for five seconds before the old container receives a 30-second graceful stop; unusually long-lived connections may still be interrupted. A proxy configuration or activation failure prevents promotion and attempts to restore the prior upstream.
Each web candidate is assigned a host port by Docker to avoid check-then-bind port races. The firewall allow rule is applied only after promotion; domains continue to route through the configured reverse proxy. The configured retention count applies to prior successful deployments, not the active deployment. GitHub statuses require a connected account token with repository status access; webhook-based deployment requires a publicly reachable PanelOps URL. Before a branch-triggered candidate is promoted, PanelOps verifies that its commit is still the branch head; superseded builds fail without changing production traffic.
Deployment slots isolate build workspaces and containers, but currently use the project's shared environment variables and runtime configuration. Configure slot-specific secrets only after adding a separate per-slot environment configuration surface. Candidate host ports are not exposed through firewall rules until promotion; host firewall defaults still determine whether an unapproved port is reachable.
Deployment numbers are allocated with the project's atomic counter. Before upgrading a database that may contain duplicate or invalid historical numbers, stop deployment workers and run node installer/migrate-deployment-sequences.js from either the Cloud checkout or Customer Node directory; the migration repairs old numbers and installs the unique project/number index. Live log history is bounded to the latest 1,200 events per deployment and 256 KiB of legacy plain-text log output. Socket log subscriptions and the HTTP replay endpoint both require an authenticated project owner or admin. Log output is redacted and rendered as text, not HTML. App Store job log rooms are likewise restricted to the job owner, and their persisted and streamed output is sanitized with job-specific environment and admin-password values redacted.
The application source and installed JavaScript dependencies were checked for Node's deprecated util.isArray() API. The apparent lodash/fp util.isArray reference is to Lodash's own helper, which resolves to Array.isArray; no dependency update or warning suppression is required.
Automatic pushes are currently branch-based (with optional tags). Queue processing is durable through Agenda, but deployment execution still requires the Customer Node's configured SSH/Docker access. Secrets needed to clone private repositories remain controlled through the existing encrypted GitHub account integration. This does not make application database migrations automatically backward-compatible.