PanelicaDocs
panelica.com
Docs / App Hosting / Git Deploy

Git Deploy

Panelica 1.0.439 Verified 2026-08-04 App Hosting

Git Deploy turns "push to deploy" into a panel feature: connect a repository, point it at a domain's document root, and every deploy is pulled, snapshotted and synced with a one-click rollback waiting if it goes wrong. Webhooks close the loop so a push to GitHub or GitLab deploys automatically.

Panel locationGit Deployhttps://YOUR-SERVER-IP:8443/git/manager

This page walks through every screen and every switch, in the order you meet them.

Before you start

Git Deploy is a licensed feature (git) delivered as a package. If the server does not have it yet, the page offers a one-click install to ROOT; other roles see a note asking them to contact an administrator. Once installed it is available to every role, filtered by the permission set described under Permissions below.

Your hosting plan caps how many repositories an account may own. The manager shows the current figure; an unlimited plan reports no ceiling.

Where everything lives: each owner gets a .panelica-git tree inside their home — repos/ for working copies, snapshots/ for deploy snapshots, keys/ for deploy keys, logs/ for git output. Every git, rsync and pipeline command runs as that owner's Linux user, never as root, so a repository can never touch another account.

The Git Manager

 Git Manager
Overview Repositories (3) Deployments Pipelines Settings
RepositoryBranchStatusAuto-deployLast commitActions
company-site
github.com/acme/site
mainactiveONfeat: new pricingview · pull · delete

The manager has five tabs:

Tab What it shows
Overview Repository count against your quota, deployments in the last 24 hours, how many pipelines are active, and the most recent deployments across all repositories.
Repositories Every repository you may see, with status, branch, last commit and an auto-deploy switch. Row actions: open, pull, fetch, delete.
Deployments A server-wide deployment history, newest first, with status and the repository each belongs to.
Pipelines Every pipeline defined across your repositories, with its trigger branch and step count.
Settings Saved provider credentials — see Saved credentials below.

Adding a repository

Adding a repository is a three-step wizard.

Step 1 — source. Choose GitHub, GitLab, Bitbucket, a custom remote, or a local repository: an empty repository created on the server that you push to over SSH. A local repository has no remote, so pull and fetch are disabled for it and the panel says so instead of failing.

Step 2 — identity and access. Enter the clone URL, a name and the branch to track. Private repositories need an auth method:

  • Personal access token — stored encrypted, injected into the remote URL only for the duration of a pull, and scrubbed from every log line.
  • OAuth connection — a credential you saved once under Settings and reuse across repositories.
  • Deploy key — an ed25519 keypair the panel generates for the repository; you register the public half at your provider. See Deploy keys below.

Step 3 — deploy target. Pick one of:

  • None — just a repository on the server; nothing is deployed anywhere.
  • A domain or subdomain — the document root, with one-click /app and /public variants for frameworks that serve from a subdirectory.
  • A custom path — any directory inside the owner's home. Paths outside /home/<user>/ are refused, and a symlink that resolves outside is refused too.

Administrators and resellers pick the owning customer first; the repository, its files and every command it runs belong to that customer's Linux user.

Cloning happens in the background with live status. If the requested branch does not exist upstream, the panel detects it and corrects the tracked branch rather than leaving the repository broken.

The repository view

Opening a repository gives you nine tabs.

Overview

A facts table — local path, tracked branch, type (remote or local), owner, linked domain, deploy target and the preserve list — plus the last commit, and the action buttons Pull, Fetch, Deploy and Deploy settings. Local repositories additionally show a push-over-SSH cheat sheet with the exact git remote add line to run on your machine.

Branches

Lists every branch with the current one marked. You can create a branch from a base, check out a branch (which switches the working copy the next deploy will use), and delete a branch. The repository's default branch is protected: deleting it is refused with cannot delete the repository's default branch.

Commits

The commit history with author, date and message. Selecting a commit opens a diff viewer in the style of a code host: per-file collapse, syntax highlighting and keyboard navigation.

Files

A read-only browser of the working copy. Files open with syntax highlighting and can be downloaded individually. Nothing here writes to the repository — use git for that.

Deployments

Every deployment, newest first, with its status (pending, running, success, failed, cancelled), what triggered it (manual, pipeline, webhook), the branch, the commit and the full log. A running deployment can be cancelled; a finished one offers Rollback. See Deploying below for the mechanics.

Environments

Additional deploy targets — a staging directory, a second document root — each with its own name, branch, target path and environment variables. A pipeline deploy step can point at an environment instead of the repository's own target, and you can deploy to one by hand at any time.

Two switches decide how an environment behaves when nobody is watching:

  • Auto deploy — a webhook push also deploys to this environment, after the repository's own target. An environment pinned to a branch only follows pushes on that branch.
  • Protected — the environment refuses automatic deploys and cannot be deleted while the switch is on. Manual deploys and pipeline runs still work, because those are deliberate actions; the switch exists so an unattended push can never overwrite production. Turn protection off first if you really mean to delete the environment.

Pipelines

See Pipelines below.

Deploy keys

The panel generates an ed25519 keypair for the repository and shows you the public half to register at your provider as a deploy key. The private half stays in the owner's .panelica-git/keys directory and is never displayed or downloadable. Keys are listed by name and can be deleted; deleting one does not remove it at the provider, so revoke it there too.

Webhooks

See Webhooks below.

Deploying

Deploy runs a fixed, transparent five-phase sequence, and every phase writes to the deployment log:

  1. Pull the tracked branch (skipped, and said so, for local repositories).
  2. Snapshot the current contents of the target as a tar.gz under the owner's snapshots/ directory.
  3. Sync the repository over the target with rsync --delete.
  4. Fix permissions — directories 755, files 644, so the web server can serve them.
  5. Finalize — record the deployed commit and close the deployment row.

The last five snapshots are retained per repository; older ones are pruned automatically.

Failure drill: a deploy ships broken CSS at noon. Open the deployment row, click Rollback, confirm: the target directory is back to the pre-deploy snapshot in seconds, and the bad deploy's log is still there to debug at leisure.

What a deploy never copies

.git, node_modules, vendor and .panelica-deploy.yml are excluded from every deploy regardless of settings — build inputs and dependency trees belong on the build side, not in the document root.

What a deploy never deletes

Two files in the document root belong to the panel and are protected from deletion, while a repository that ships its own copy may still overwrite them:

  • .user.ini — the starter file for per-domain PHP settings the panel writes when the domain is created.
  • .well-known/acme-challenge/ — the ACME challenge directory. The challenge root is the document root, so without this a deploy could delete a challenge mid-issuance and fail an SSL renewal.

Keeping files a deploy would otherwise delete

A deploy mirrors the repository into the target, so anything the repository does not contain is removed — including files the application writes at runtime: .env, storage, uploaded media. Deploy settings → Preserve on deploy names them, one path per line:

.env
storage
public/uploads

Those paths are left untouched, and the deployment log names them:

[3/5] Deploying files...
Preserved in target: .env, storage

Paths are relative to the deploy target. Absolute paths and .. are rejected, because an exclusion is meant to name something inside the target — the form tells you before you save. Pipeline deploy steps read the same list, so a manual deploy and a pipeline deploy cannot behave differently. A repository with an empty list keeps the plain mirror behaviour.

The field sits on the repository's Overview tab under Deploy settings, alongside the deploy target — available both when creating a repository and at any time afterwards.

Rollback

Rollback restores a chosen earlier deployment. It first snapshots the current state (so a rollback is itself reversible), then restores the target to exactly what the snapshot held: files the bad deploy added are removed, files it changed are put back. Your preserve list and the panel-owned files above are respected during the restore too, so a rollback never costs you the running application's .env or uploads.

Pipelines

Pipelines add custom automation: named steps you run on demand, each executing as the owner's Linux user with the same path protections as deploys. A pipeline records a trigger branch, which the run uses as the branch to work on — a push does not start a pipeline by itself.

Each step carries:

Field Meaning
Name Free text, shown as the step header in the log.
Type See the table below.
Command The shell command to run (for the notify type, the message text).
Working directory Relative to the repository root. Blank means the root itself — public runs the command inside public/.
Timeout Seconds before the step is killed. 300 by default.
Continue on error On: a failing step is logged and the pipeline carries on. Off: the pipeline stops there and is marked failed.

Steps can be reordered with the up/down buttons; the order shown is the order they run.

The type decides what the step actually does:

Type What it does
Shell command Runs your command in the working directory.
Build Same execution as a shell command — the label groups build stages in the log.
Test Same execution as a shell command — the label groups test stages in the log.
Deploy Syncs the repository into the deploy target, honouring the preserve list. Bind the step to an environment to deploy to that environment's path instead.
Notify Writes a panel notification. The command field is the message; leave it blank for a default one naming the pipeline and step.

Shell, build and test execute identically — the distinction is for reading the log, not for behaviour.

A run writes one log covering every step, for example:

=== Pipeline: full-pipeline ===
--- Step 1: install (shell) ---
--- Step 2: build assets (build) ---
--- Step 3: unit tests (test) ---
--- Step 4: publish (deploy) ---
--- Step 5: tell me (notify) ---
Working directory catches people out: a test step with working directory public and command test -f public/build.txt fails, because the command already runs inside public. Write the path relative to the working directory, not to the repository root.

Webhooks

Webhooks make deployment hands-free. Create one per provider; the panel shows the endpoint URL and a secret exactly once — copy it then, it is never shown again.

Register the URL at your provider with that secret. Pushes are verified before anything runs: HMAC-SHA256 for GitHub, a constant-time token comparison for GitLab. A push that fails verification is rejected and nothing is deployed.

A verified push deploys when the repository's auto-deploy switch is on, using the repository's auto-deploy branch. Environments with auto deploy enabled are then deployed in turn, skipping any that are protected and any pinned to a different branch.

Saved credentials

The manager's Settings tab holds provider credentials you want to reuse instead of pasting a token into every repository. Each of GitHub, GitLab and Bitbucket can hold one connection, shown as connected or not connected, with the token masked. Connections can be added and removed at any time; removing one does not break repositories already cloned, but their next pull will need credentials again.

Security and isolation

  • Every git, rsync and pipeline command runs as the owner's Linux user through sudo -u, never as root.
  • Deploy targets must resolve inside /home/<owner>/. Symlinks are resolved before the check, so a link pointing outside is refused rather than followed.
  • Tokens are encrypted at rest, injected only for the duration of an operation, and scrubbed from logs.
  • Deploy key private halves are never displayed, downloadable or logged.
  • An environment id from another repository cannot be used to select a deploy target.

Permissions

Git Deploy carries the panel's most granular permission set — 34 keys, so you can grant browsing without granting deploying, or deploying without granting rollback:

git.access · git.repos.view · git.repos.create · git.repos.edit · git.repos.delete · git.repos.pull · git.repos.browse · git.branches.view · git.branches.create · git.branches.delete · git.commits.view · git.commits.diff · git.deploy.view · git.deploy.trigger · git.deploy.rollback · git.deploy.cancel · git.deploy.logs · git.envs.view · git.envs.create · git.envs.edit · git.envs.delete · git.pipelines.view · git.pipelines.create · git.pipelines.edit · git.pipelines.delete · git.pipelines.run · git.keys.view · git.keys.create · git.keys.delete · git.webhooks.view · git.webhooks.create · git.webhooks.delete · git.oauth.view · git.oauth.manage

Data visibility follows the roles and permissions chain: a USER sees only their own repositories, while ADMIN and RESELLER create on behalf of a chosen customer and see their chain.

Troubleshooting

Symptom Cause and fix
A deployment is already running for this repository Deploys are serialised per repository. Wait, or cancel the running one from the Deployments tab.
No deploy target path configured The repository was created with target None. Set one under Deploy settings.
Deploy target must be within user home directory The path is outside /home/<owner>/, or a symlink in it resolves outside.
Cannot delete the repository's default branch Check out another branch and make it the default first.
Environment is protected Turn the Protected switch off before deleting the environment.
Files the application created keep disappearing They are not in the preserve list. Add them under Deploy settings.
Pull fails on a local repository Local repositories have no remote. Push to them over SSH instead.
A push does not deploy Check three things: the repository's auto-deploy switch, the webhook secret at the provider, and that the pushed branch matches the auto-deploy branch.
Panelica Documentation · Written and verified against the live panel. · Last verified 2026-08-04 on Panelica 1.0.439