# Deploying a Site from Git

Source: https://support.kapsulehost.com/en-us/site-git-deploy

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 **Environment** group in the site's left menu, and choose **Git Deploy**. Two related pages sit nearby:

- **Deploys**, the full deploy history for this site, in the same **Environment** group.
- **Buildpack**, the detected build strategy, on Node.js sites, in the **Apps** group.

The Git Deploy page describes itself plainly: connect a repository and every push to your configured branch triggers a build and deploy.

![The Git Deploy page for a site in KPanel, where a repository is connected](https://support.kapsulehost.com/help/screenshots/site-git-deploy.4716f1a9.webp)

## Connecting a Repository

1. Pick your **Provider**: GitHub, GitLab or Bitbucket.
2. Enter the **Repository URL**. The SSH form is what you want, for example `git@github.com:user/repo.git`.
3. Set the **Branch** to deploy from. The field starts at `main`.
4. Optionally set a **Build command**, for example `npm run build`.
5. Optionally set an **Output directory**, for example `dist`, `public`, or `.` for a repository that is already built.
6. 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**.

> **Tip:** 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

KapsuleHost 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 KapsuleHost 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.

> **Warning:** 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 **Environment**, 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 **Apps** group shows how KapsuleHost 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](https://support.kapsulehost.com/en-us/site-preview) adds a per-PR URL on top of this setup.
- [Storing App Secrets For a Site](https://support.kapsulehost.com/en-us/site-secrets) for the credentials your build and runtime need.
- [Site Activity Log](https://support.kapsulehost.com/en-us/site-activity-log) records configuration changes made here.
