Websites
Deploying a Site From Git
Git Deploy connects a repository to a site so that every push to your chosen branch clones the code, runs your build, and publishes the result. This guide covers the initial connection, the two repository-side steps that finish the setup, reading deploy history, and the buildpack detection that decides how a Node.js app is built.
Where Git Deploy Lives
Open Websites, click the site, open the Advanced menu in the site tab strip, and choose Git Deploy. Two related pages sit in the same menu:
- Deploys, the full deploy history for this site.
- Buildpack, the detected build strategy, on Node.js sites.
The Git Deploy page describes itself plainly: connect a repository and every push to your configured branch triggers a build and deploy.

Connecting a Repository
- Pick your Provider: GitHub, GitLab or Bitbucket.
- Enter the Repository URL. The SSH form is what you want, for example
git@github.com:user/repo.git. - Set the Branch to deploy from. The field starts at
main. - Optionally set a Build command, for example
npm run build. - Optionally set an Output directory, for example
dist,public, or.for a repository that is already built. - Click Connect repo.
Leave the build command and output directory empty if your repository is already deployable as it stands, which is the common case for a plain PHP or static site.
Advanced Scripts
Expanding Advanced reveals two extra fields:
- Pre-deploy script, which runs before the build.
- Post-deploy script, which runs after the deploy.
Use the post-deploy hook for the things that have to happen once new code is in place: clearing an application cache, running a database migration, restarting a worker.
Auto-Deploy On Push
The toggle at the bottom of the card controls whether pushes deploy at all. When it is on, every push to the configured branch triggers a deploy. When it is off, deploys only run when you trigger them manually with Deploy now.
Turn auto-deploy off during a code freeze or an incident rather than disconnecting the repository. Disconnecting throws away the deploy key and the webhook secret, so you have to redo both repository-side steps afterwards.
Finishing the Setup In Your Repository
Connecting the repository in KPanel is only the first of three steps. Until a deploy has run, the page shows a banner reading Complete setup: 2 steps remaining with everything you need.
Step 2: Add the Deploy Key
Kapsule needs read access to clone your repository. The banner shows a public key with a Copy key button.
Paste it into your repository's deploy keys. For GitHub the banner offers an Add to GitHub shortcut straight to the right settings page. Read access is enough; do not grant write.
Step 3: Add the Webhook
The webhook is what tells Kapsule a push has happened. The banner gives you three values:
| Field | Value |
|---|---|
| Payload URL | A URL ending in /api/git-deploy/webhook/ plus this site's ID |
| Secret | A generated signing secret, hidden until you click the eye icon |
| Content Type | application/json |
Copy each one into your repository's webhook settings. For GitHub there is an Add webhook to GitHub shortcut. Set the content type to JSON, not the form-encoded default, or the payload will not parse.
Treat the webhook secret like a password. Anyone who has it, plus the payload URL, can trigger a deploy of your site. Both values are only shown to people who can already administer the site, and the secret stays hidden behind the eye icon until you ask for it.
Deploying By Hand
Click Deploy now on the Git Deploy page to build and deploy the current head of the configured branch without pushing a commit. This works whether or not auto-deploy is on, which is what makes it the right tool during a freeze: pushes are ignored, but you can still ship the fix.
Reading Deploy History
Open Advanced, then Deploys. The page is titled Deploy history and lists every deployment triggered by webhook or by hand, newest first.
Each row carries:
- A status icon and the short commit SHA, with the branch as a pill.
- The commit message, or Manual deploy if there was no commit message to show.
- The author, how long ago it ran, how long it took, and what triggered it.
- A status pill.
The statuses are pending, building, deploying, success and failed. While anything is in flight the page refreshes itself every five seconds and shows a Refreshing automatically note underneath the table, so you can leave it open and watch a deploy land.
When a Deploy Fails
A failed row gets an Error button on the right. Click it to expand the captured error output inline, without leaving the page. That output is the build's own error text, so it usually names the file or the command that failed.
Work through it in this order: read the error, reproduce the same build command locally, fix, push. If the build works locally but not here, the difference is almost always an environment one, a missing dependency that is installed globally on your machine, or a file that is in your working directory but not committed.
Buildpack Detection
On Node.js sites, the Buildpack page in the Advanced menu shows how Kapsule has decided to build your app. Detection runs over the files at your repository root, and the first match wins:
| Detected | Trigger |
|---|---|
| Custom buildpack | kapsule.config.yaml or kapsule.config.yml at the root |
| Dockerfile buildpack | Dockerfile at the root |
| Node.js | package.json with a start, build or dev script |
| Python | requirements.txt or pyproject.toml |
| PHP | composer.json |
| Static | index.html at the root |
If nothing matches, the page says so and lists the supported triggers. Add a Dockerfile or a kapsule.config.yaml to take control of the build explicitly.
Running a Build
Click Run build to queue one. The page polls every three seconds while a run is in flight, and the Recent builds table shows the last runs with their start time, type, status, duration and resulting image reference. Click a row to see its log tail.
Only one build can be in flight at a time. Triggering a second while one is queued or running is refused with A build is already in progress, which is deliberate: two builds writing the same output at once is how you get a half-deployed site.
Disconnecting
Click Disconnect and confirm. The confirmation is explicit about the blast radius: the Git deploy configuration and the deploy key are removed, and your site files are not affected. The site keeps serving whatever was last deployed.
Tidy up afterwards by deleting the deploy key and the webhook in your repository settings. They will simply stop working, but leaving dead entries around makes the next audit harder.
Troubleshooting
Pushes do not trigger anything. Check the auto-deploy toggle first, then the webhook in your repository. Most providers show recent deliveries and their response codes, which tells you immediately whether the request left your repository at all.
Cloning fails. The deploy key is missing, was pasted with a line break in it, or was added to the wrong repository. Copy it again with the Copy key button rather than selecting the text by hand.
The deploy succeeds but the site does not change. The output directory is probably wrong. If your build writes to dist and the output directory is empty, the built files never reach the served root.
Everything says pending and never moves. The deploy was queued but never picked up. Trigger a manual Deploy now and check the Deploys page for an error row.
Where To Go Next
- Preview Deploys For Pull Requests adds a per-PR URL on top of this setup.
- Storing App Secrets For a Site for the credentials your build and runtime need.
- Site Activity Log records configuration changes made here.