Git deploy
Deploy from a Git repository with automatic framework detection, sandboxed builds, health-checked zero-downtime releases, push webhooks and one-click rollback.
Git deploy builds and runs your code straight from a repository. ZoPanel detects the framework, proposes install, build and start commands, builds in a sandbox limited to the account's CPU and memory, and only switches traffic to the new release after it passes a health check. If anything fails, the previous release keeps running.
Create a website from Git
- Open Websites → New website and choose the Git deploy type.
- Enter the Repository URL, the Branch (default
main) and, for monorepos, the Root directory (for exampleapps/web). - Keep Free SSL (Let's Encrypt) on and click Create website.
The first deployment starts immediately. When it has finished, ZoPanel issues the SSL certificate in the same task, so the two never collide.
You can also deploy into an existing website from its Deploy tab.
Repository URLs
| Form | Example |
|---|---|
| Public HTTPS | https://github.com/owner/repo |
| SSH (private repositories) | git@github.com:owner/repo.git or ssh://git@git.example.com:2222/owner/repo |
The repository host must be a public address. For a private repository, open Deploy → Deploy key (private repositories), click Show deploy key, add that public key to the repository as a read-only deploy key, and use the git@… URL.
Other sources in the Source list: Uploaded files (File Manager), where you upload the project to domains/<domain>/source with the File Manager or SFTP, and Ready-made Docker image.
Framework detection
On every deploy (unless you turn Auto-detect off), ZoPanel inspects the repository and fills in the build settings. The first match wins:
| Found in the repository | Detected as |
|---|---|
composer.json (and no Node server framework) |
Laravel (artisan or laravel/framework), Symfony, or PHP (Composer). Front-end assets are built with npm when package.json has a build script. |
package.json |
Next.js, Nuxt, Remix / React Router, SvelteKit, Astro, NestJS, Gatsby, Angular, Create React App, Docusaurus, VitePress, Vite (React/Vue/Svelte), or a Node.js server (Express, Fastify, Koa, Hono…) |
wp-config-sample.php + wp-login.php |
WordPress |
Gemfile |
Ruby on Rails, Rack (Sinatra, Hanami…) or Ruby |
pom.xml, build.gradle |
Java / Spring Boot |
*.csproj |
.NET / ASP.NET Core |
manage.py, requirements.txt, pyproject.toml, Pipfile |
Django, FastAPI, Flask or Python |
go.mod |
Go |
index.php / index.html |
PHP / static HTML |
Dockerfile only |
Dockerfile (container) |
A few details worth knowing:
- Package manager:
pnpm-lock.yaml→pnpm install --frozen-lockfile,yarn.lock→yarn install --frozen-lockfile,package-lock.json→npm ci, otherwisenpm install. - Node.js version: taken from
.nvmrc,.node-versionorengines.node. If that major version is not installed, the newest installed one is used. - Static exports: Next.js with
output: 'export', Astro without@astrojs/node, SvelteKit withadapter-static, Vite, Angular and similar builds are served as static sites from their output folder. - Procfile: a
web:line always provides the start command. - Laravel: an
APP_KEYis generated if missing,storageand.envare kept between releases, and sessions and cache use the account's Redis when it is available.
Click Analyze repository to see the detection before you deploy, then Use these settings and customize if you want to change them.
Build and run settings
The Build & run card shows what will run:
| Field | Notes |
|---|---|
| Runtime / Version | node, python, go, php, ruby, java, dotnet, static or docker. Latest installed uses the newest version on the server. |
| Type | Server app (process), Static site, PHP (PHP-FPM) or Container (Dockerfile). |
| Install command | For example npm ci or composer install --no-dev --optimize-autoloader --no-interaction. |
| Build command | For example npm run build. Chain several commands with && on a single line. |
| Start command | Server apps only. The app must listen on 127.0.0.1:$PORT. |
| Output directory / Document root | Folder served for static and PHP sites, such as dist or public. |
| Persistent paths | Kept between releases, such as storage, uploads or .env. |
| Health check path | Must answer with a status below 500 before the release goes live. Default /. |
Environment variables are available during the build and at runtime; PORT is set automatically. Use Paste .env to add many at once (up to 200 variables, single-line values).
Container (Dockerfile) mode must first be enabled once on the server by an administrator:
zopanel ctl feature enable custom-docker
How a deployment runs
- The code is fetched into a new release folder:
domains/<domain>/releases/<timestamp>/. - Install and build commands run as the hosting account through systemd, inside the account's CPU and memory limits, unable to write outside its home.
- Server apps start in the idle slot on their own port. ZoPanel waits up to 90 seconds for the health check path to answer.
- nginx switches to the new release (a graceful reload), then the previous process is stopped.
currentpoints to the live release.
Each deployment is listed under Deployments with its commit, trigger (Manual, Git push or Created) and status. If a deployment fails, the owner gets a Deployment failed notification.
Automatic deploys on push
- On the Deploy tab, turn on Deploy when main is pushed in the Automatic deploys card.
- Copy the Payload URL (
https://<panel-domain>:8888/api/hooks/deploy/<id>) and the Secret. - Add the webhook in your Git host:
- GitHub: Settings → Webhooks → paste the URL, content type
application/json, and the secret. - GitLab / Gitea: paste the URL and put the secret in Secret token.
- GitHub: Settings → Webhooks → paste the URL, content type
ZoPanel verifies the signature (GitHub's X-Hub-Signature-256) or the token header (GitLab, Gitea); the secret is never accepted in the URL. Only pushes to the configured branch deploy. Duplicate deliveries are ignored, and at most one webhook deploy starts per 15 seconds, never while another deployment is running. GitHub's ping event answers pong.
Regenerate secret replaces the secret; update the webhook in your Git host afterwards.
Deploy from CI with an API token
With a Pro license, create an API token in My account → API tokens and trigger a deployment from any CI system:
curl -X POST \
-H "Authorization: Bearer zpat_..." \
https://panel.example.com:8888/api/sites/<site-id>/app/deploy
Rollback
The Releases card keeps the last 5 builds. Click Rollback on any of them: server apps are started in the idle slot and switched over after the health check, exactly like a deployment, so rolling back causes no downtime.
Logs
- Deploy tab → Application output shows the latest output of the running app; turn on Live to follow it.
- Each deployment's build log is kept in Tasks.
- The website's Logs tab shows the nginx access and error logs, and Run diagnostics explains recent errors.