Automated Git Deployment on Web Hosting — Beginner CI/CD Guide

Developers using shared hosting often find themselves manually uploading files via FTP every time they make code changes — time-consuming and error-prone. The good news is that hosting with SSH support can be configured to deploy automatically on every git push using a Git bare repository and a post-receive hook. This guide walks through the full setup on DirectAdmin hosting.

Prerequisites: Hosting with SSH access enabled, Git installed locally (check with git --version), a GitHub or GitLab repository.

1. What Is CI/CD on Hosting?

CI/CD (Continuous Integration / Continuous Deployment) automates the process of getting code changes onto a live server. For shared hosting, the practical approach is a Git bare repository on the server combined with a post-receive hook — a shell script that runs automatically whenever code is pushed.

The flow is: push code from your local machine to the hosting server → the post-receive hook runs git checkout automatically → updated files appear in public_html instantly.

2. What You Need

AsiaGB Hosting: SSH access can be enabled by submitting a Support Ticket with your hosting username. Our team will activate it within 24 hours.

3. Create a Git Bare Repository on the Server

Connect via SSH and create a bare repository outside public_html:

# Connect via SSH
ssh [email protected]

# Create a folder for the bare repo (outside public_html)
mkdir ~/repos
cd ~/repos
git init --bare mysite.git

A bare repository has no working directory — it acts purely as a receiving endpoint for pushes, not as a place to store editable files.

4. Create the post-receive Hook Script

A hook script is a shell script Git runs automatically after receiving a push. Create the hook file:

nano ~/repos/mysite.git/hooks/post-receive

Paste the content below, replacing /home/username/public_html with your actual path:

#!/bin/bash
# post-receive hook — deploy to public_html
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE

GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR

git checkout -f main

echo "Deploy complete: $(date)"

Save the file, then make it executable:

chmod +x ~/repos/mysite.git/hooks/post-receive

⚠️ Check your branch name: If your repository uses master instead of main, change git checkout -f main to git checkout -f master.

5. Add the Remote on Your Local Machine

In your local project directory, add the hosting server as a Git remote:

# Navigate to your local project
cd ~/myproject

# Add the hosting server as a remote named "hosting"
git remote add hosting ssh://[email protected]/home/username/repos/mysite.git

# Test with your first push
git push hosting main

If everything is configured correctly, you'll see the "Deploy complete" message from the hook, and your updated files will appear in public_html immediately.

6. GitHub/GitLab Webhook (Advanced)

To trigger a deploy automatically whenever you push to GitHub or GitLab, create a PHP webhook receiver in public_html:

# Create deploy.php in public_html
<?php
$secret = 'YOUR_WEBHOOK_SECRET';
$payload = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($sig, $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '')) {
    http_response_code(403); exit;
}

exec('cd /home/username/repos/mysite.git && git fetch && GIT_WORK_TREE=/home/username/public_html git checkout -f main 2>&1', $out);
echo implode("\n", $out);

Then add a webhook in GitHub under Settings → Webhooks, set the Payload URL to https://yourdomain.com/deploy.php, and enter the same secret string.

7. Test the Automatic Deployment

Make any change locally and push:

git add .
git commit -m "test: auto deploy"
git push hosting main

Open your website — the change should appear immediately after a successful push.

8. Hosting vs VPS Limitations

CapabilityShared HostingVPS
Git bare repository✅ Yes✅ Yes
post-receive hook✅ Yes✅ Yes
Run npm install / composer⚠️ Limited (server-dependent)✅ Full control
Docker / Containers❌ Not supported✅ Yes
GitHub Actions self-hosted runner❌ Not supported✅ Yes
Starting price500 THB/yearHigher

For standard PHP, HTML, and CSS websites, Git hook deployment on shared hosting is perfectly sufficient and extremely affordable. For full CI/CD pipelines that include build and test steps, a VPS is a better fit.

Tip: Add a .gitignore file to exclude unnecessary files from being pushed: node_modules/, .env, *.log. This prevents secrets from accidentally ending up on your server.

9. Secure SSH Key Authentication

Using SSH keys instead of passwords is not just more convenient — it is significantly more secure. Keys cannot be brute-forced the way passwords can, and they enable seamless passwordless deployment from your local machine to the hosting server.

Generate an SSH Key Locally

# Generate an Ed25519 key (recommended — fast and secure)
ssh-keygen -t ed25519 -C "[email protected]"

# Print the public key to copy to your hosting server
cat ~/.ssh/id_ed25519.pub

Add the Public Key to Your Hosting Server

# Connect with password for the first time
ssh [email protected]

# Create the authorized_keys file
mkdir -p ~/.ssh && chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
# Paste your public key, save, then set permissions
chmod 600 ~/.ssh/authorized_keys

After this, SSH connections use the key automatically. Running git push hosting main will deploy without any password prompt, making the workflow faster and suitable for scripted automation.

⚠️ Security reminder: Never commit your private key file (~/.ssh/id_ed25519) to any repository. Keep it only on your local machine and never share it.

10. Multi-Branch Deployments — Development, Staging, Production

Real-world projects typically separate code into multiple environments. You can support this on hosting by modifying the post-receive hook to check which branch was pushed before deciding where to deploy.

#!/bin/bash
# post-receive hook supporting multiple branches
while read oldrev newrev refname; do
  BRANCH=$(git rev-parse --symbolic --abbrev-ref "$refname")

  if [ "$BRANCH" = "main" ]; then
    GIT_WORK_TREE=/home/username/public_html git checkout -f main
    echo "Deployed to PRODUCTION: $(date)"

  elif [ "$BRANCH" = "staging" ]; then
    GIT_WORK_TREE=/home/username/staging git checkout -f staging
    echo "Deployed to STAGING: $(date)"
  fi
done

Pushing to main deploys to public_html for live visitors. Pushing to staging deploys to a separate subdirectory, letting you review changes before releasing to production.

Branch Deploy Target Purpose
mainpublic_html/Production — visible to all visitors
stagingstaging/Pre-release testing
developdev/Active development environment

11. Adding Rollback to the Hook Script

Every reliable deployment pipeline needs a rollback mechanism. You can add this logic directly to the post-receive hook so that if the deployment fails, the server automatically reverts to the last known good commit.

#!/bin/bash
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE
GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR

# Record the current commit before deploying
PREV_COMMIT=$(git -C /home/username/public_html rev-parse HEAD 2>/dev/null || echo "none")

# Deploy new code
if git checkout -f main; then
  echo "Deploy successful: $(date)"
  echo "Commit: $(git rev-parse HEAD)"
else
  echo "Deploy failed — rolling back..."
  git checkout -f "$PREV_COMMIT"
  echo "Rolled back to $PREV_COMMIT"
fi

You should also maintain a deploy log for auditing purposes. Add this line to your hook script:

# Append deploy record to log file
echo "$(date): branch=main commit=$(git rev-parse HEAD)" >> /home/username/deploy.log

12. Comparing Deployment Methods on Shared Hosting

Developers use several approaches to deploy code to shared hosting. Each has distinct trade-offs in terms of speed, reliability, and complexity, as shown in the comparison below.

Method Ease of Use Error Risk Best For
Manual FTP UploadLowHigh (human error)Complete beginners
Git Hook (bare repo)HighLowMost PHP/HTML projects
PHP Webhook receiverVery highLow (if secret set)Teams using GitHub/GitLab
GitHub Actions + SCPMediumLowProjects requiring CI steps

For small to medium PHP projects, the Git bare repository with a post-receive hook offers the best balance of simplicity and reliability — especially on hosting plans that already support SSH access. The setup takes about 20 minutes and delivers a workflow developers at any skill level can maintain confidently.

Tip: Add a .gitignore file to exclude unnecessary files from being pushed: node_modules/, .env, *.log. This prevents secrets from accidentally ending up on your server.

Hosting with SSH Access for Git Deployment

AsiaGB Hosting starts at 500 THB/year with SSD storage, DirectAdmin, PHP 7.4/8.2/8.3, and SSH access available on request.

View Hosting Plans