AdminsForum
Guide CyberPanel Git Deployment: Deploy from GitHub (and the Option That Deleted Our Site) - Printable Version

+- AdminsForum (https://adminsforum.com)
+-- Forum: Free & open-source control panels (https://adminsforum.com/Forum-free-open-source-control-panels)
+--- Forum: CyberPanel (https://adminsforum.com/Forum-cyberpanel)
+---- Forum: CyberPanel Guides & Tutorials (https://adminsforum.com/Forum-cyberpanel-guides-tutorials)
+----- Forum: CyberPanel Websites & OpenLiteSpeed Guides (https://adminsforum.com/Forum-cyberpanel-websites-openlitespeed-guides)
+----- Thread: Guide CyberPanel Git Deployment: Deploy from GitHub (and the Option That Deleted Our Site) (/Thread-guide-cyberpanel-git-deployment-deploy-from-github-and-the-option-that-deleted-our-site)



CyberPanel Git Deployment: Deploy from GitHub (and the Option That Deleted Our Site) - JAY - 10-26-2026

CyberPanel Git Deployment: Deploy from GitHub (and the Option That Deleted Our Site)

Deploying from Git means your website's files come from a repository (GitHub, GitLab, Bitbucket) instead of FTP uploads. You push a change, the server pulls it, done. CyberPanel has a Manage Git page for this. We tested it on our test subdomain
Code:
blog.cyber.adminslab.com
with a small public demo repo (
Code:
octocat/Spoon-Knife
on GitHub, three files:
Code:
index.html
,
Code:
styles.css
,
Code:
README.md
). It worked in the end, but one option deleted the whole site folder on the way. Read the warning in Step 2 before you click anything.

Step 1: Open Manage Git
Websites > List Websites > Manage (or List Child Domains > Manage for a subdomain), then Manage Git at the top. The address is
Code:
https://YOUR-SERVER-IP:8090/websites/yourdomain.com/manageGIT
.

Pick the folder (for us
Code:
/home/cyber.adminslab.com/blog
, the subdomain's document root). Without a repository in it you get two buttons: Init Repo (start a new, empty repo here) and Attach Existing Repo (clone one from GitHub/GitLab). We wanted the second.

Step 2: Attach Existing Repo, and what went wrong
The dialog asks for Git Host, Username (the repo owner) and Repo Name, and shows a Deployment Key (an SSH public key CyberPanel generates for the site user).
In the dialog we filled in github.com, the owner and the repo name, and clicked Attach:
[Image: attachment.php?aid=567]

First try:
Code:
fatal: destination path '/home/cyber.adminslab.com/blog' already exists and is not an empty directory.
The folder only had CyberPanel's default
Code:
index.html
, but Git can only clone into an empty folder.

With Override Data ticked we tried again:
[Image: attachment.php?aid=568]

Second try:
Code:
[email protected]: Permission denied (publickey).
CyberPanel always clones over SSH (
Code:
[email protected]:owner/repo.git
), and GitHub only accepts SSH from a key it knows, even for a public repo. The deployment key in the dialog has to be added to the repository first (see Step 4).

And then we looked at the server:
[Image: attachment.php?aid=569]

The folder was gone. Override Data deleted the site's document root before cloning; the clone then failed, and nothing was put back. The subdomain answered 404 until we fixed it.

So, before you use Attach Existing Repo:
  • Add the deployment key to the repo first (Step 4), so the clone actually succeeds.
  • Take a backup of the folder, or better, don't tick Override Data at all. Move the old files away yourself.
  • Never try this on the main document root of a live site without a backup (CyberPanel backups).

Step 3: The simple way that worked: git clone over HTTPS
For a public repo you don't need any key: clone over HTTPS from SSH. The target folder must not exist yet (or be empty), so move the old document root away first:
Code:
cd /home/yourdomain.com mv public_html public_html.old sudo -u SITEUSER git clone https://github.com/owner/repo.git public_html
Run it as the site user (
Code:
sudo -u SITEUSER
, ours is
Code:
cyber2602
), not as root. Then the files belong to the site user and OpenLiteSpeed can serve them without a permission fix.
As the site user, from the parent folder of the document root:
[Image: attachment.php?aid=570]

The site came back right away with the repo's
Code:
index.html
(
Code:
<title>Spoon-Knife</title>
).

Two things we checked afterwards:
  • Is
    Code:
    .git
    reachable from the web?
    No:
    Code:
    /.git/config
    and
    Code:
    /.git/HEAD
    answered 403,
    Code:
    /README.md
    200. The 403 came from OpenLiteSpeed itself, not from our ModSecurity rules (nothing in the audit log). Test your own site anyway:
    Code:
    curl -I https://yourdomain.com/.git/config
    must not return 200. An exposed
    Code:
    .git
    folder gives away your whole source code.
  • Root can't use the repo. Running
    Code:
    git log
    as root in the site user's repo gave
    Code:
    fatal: detected dubious ownership in repository
    . That's a Git safety check. Don't "fix" it with
    Code:
    safe.directory
    ; just always run Git as the site user.

Step 4: Private repositories: the deploy key
For a private repo, HTTPS needs a token. The cleaner way is the deploy key CyberPanel already made. It's the site user's SSH key:
Code:
cat /home/yourdomain.com/.ssh/SITEUSER.pub
(on our server
Code:
/home/cyber.adminslab.com/.ssh/cyber2602.pub
, created the moment we opened the Attach dialog). On GitHub open the repository's Settings > Deploy keys > Add deploy key, paste it, and leave Allow write access off. A deploy key gives access to that one repository only, read-only, which is exactly what a web server needs. After that, Attach Existing Repo or a clone over SSH as the site user works:
Code:
sudo -u SITEUSER git clone [email protected]:owner/private-repo.git public_html
(We tested with a public repo and didn't add the key to a GitHub account, so we saw the "Permission denied" side of this, not the success.)

Step 5: Deploy updates
Once the folder is a Git repo, Manage Git recognises it no matter how it was cloned: our HTTPS clone showed up with its 3 commits and the buttons Pull, Push, Commit, Create New Branch, Edit .gitignore, Git Logs and Remove.

To test an update we pushed a new commit with one new file,
Code:
hello.txt
.
Then Pull in Manage Git:
[Image: attachment.php?aid=571]

Changes applied: a fast-forward to the new commit. On the server the new file belonged to the site user (
Code:
-rw-r--r-- cyber2602 cyber2602 hello.txt
), so the panel runs the pull as the site user, not as root. The file was live at once.

One oddity: when there's nothing new, the panel shows it as a failure:
[Image: attachment.php?aid=572]

Operation Failed! Pull not required. with
Code:
Already up to date.
underneath. Nothing is wrong; there was just nothing to pull.

From SSH the same update is one line:
Code:
cd /home/yourdomain.com/public_html && sudo -u SITEUSER git pull --ff-only
Code:
--ff-only
refuses to merge if someone edited files on the server, instead of creating a mess. If you want updates to arrive on their own, you can put that line in the site user's crontab (cron guide), for example every 5 minutes. For PHP projects, run your build steps after the pull (
Code:
composer install --no-dev
,
Code:
php artisan migrate --force
for Laravel).

Good habits
  • Keep secrets out of the repo:
    Code:
    .env
    ,
    Code:
    wp-config.php
    and uploads belong in
    Code:
    .gitignore
    , and stay only on the server.
  • Don't edit files on the server in a deployed folder. The next pull will refuse or overwrite them. Change the repo instead.
  • For a framework with a
    Code:
    public/
    folder, clone the repo one level up and point the document root at
    Code:
    public
    , like in our Laravel guide. Then
    Code:
    .git
    ,
    Code:
    .env
    and the source code are outside the web root anyway.
  • Test a deployment on a subdomain or a staging copy first.

More CyberPanel guides
Tested on CyberPanel 3.0 (build 8, OpenLiteSpeed edition) on Ubuntu 24.04, October 2026. Menu names can change slightly between versions.