May 12, 2026
Tutorials

Using Git for Automatic Deployments: Real-World Examples

Automatic Deployments Real-World Examples

One mistake in deployment, one forgotten environment variable, one misplaced file can take down a live application and cause thousands of dollars in downtime for businesses every minute. That is why automatic deployments using Git have become the norm in every startup, enterprise, and in between.

Git is a lot more than a version control system. Combined with the appropriate automation tools and processes, Git is the event that kicks off your full deployment process, automatically triggering tests, builds, and shipping code to production when a developer pushes a commit or merges a pull request.

Throughout this guide, you’ll learn how automated deployments work using Git, check out deployment examples from real-world developers, and create a deployment process that automates the deployment of your applications without any manual processes.

Table of Content

What Is Git-Based Automatic Deployment?

Automatic deployment using Git is a software delivery technique that involves performing a series of steps automatically when code is pushed to a particular branch of a Git repository. These steps may include running tests, building the application, and deploying it to a testing or production server, without the need to manually trigger any of these steps by a developer or operations team.

This is the foundation of most CI/CD pipelines, otherwise known as Continuous Integration and Continuous Deployment. The entire deployment process is version-controlled and codified and takes place automatically every time code changes are introduced into the repository, rather than a developer having to SSH into a server and run deployment scripts. This means you’ll enjoy quicker release cycles, fewer human mistakes, identical deployment environments, and a complete record of all changes made to production.

There are three popular ways to use Git automatic deployments: Git hooks, GitHub Actions / GitLab CI, and webhook-based deployment servers. Each of them has its own use, and depending on the complexity of their infrastructure, professional teams will use them together.

Method 1: Git Hooks for Automatic Deployment

The first method is to use Git Hooks for automatic deployment. Scripts that are run by Git before or after particular events, like a commit, push, or merge, are known as Git hooks. They reside in the .git/hooks/ directory of your repository and may be written in any scripting language, such as Bash, Python, Ruby, or Node.js.

The most powerful hook for automatic deployment is the post-receive one, which is executed on the remote (server-side) repository after it has been pushed by a developer’s local repository.

Real-World Example: Deploying a PHP Website with a Post-Receive Hook

In this example, we will create a PHP website that uses a Post-Receive Hook that is deployed in the real world. This is one of the most popular Git deployment patterns for small to medium-sized web applications deployed on a VPS or dedicated server.

Step 1: Create the Deployment Directories

Create the bare Git repository on your server, and the deployment directory where your application files will reside:

sudo mkdir -p /var/www/html/myapp

sudo mkdir -p /var/repo/myapp.git

cd /var/repo/myapp.git

sudo git init –bare

make directory mkdir

Step 2: Create the post-receive Hook

Now, create the post-receive hook script that will automatically deploy your code every time a push is received:

nano /var/repo/myapp.git/hooks/post-receive

Add the following deployment script:

#!/bin/bash

TARGET=”/var/www/html/myapp”

GIT_DIR=”/var/repo/myapp.git”

BRANCH=”main”

while read oldrev newrev ref; do

PUSHED_BRANCH=$(echo $ref | sed -n ‘s/refs\/heads\///p’)

if [ “$PUSHED_BRANCH” = “$BRANCH” ]; then

echo “Deploying branch: $PUSHED_BRANCH to $TARGET”

git –work-tree=$TARGET –git-dir=$GIT_DIR checkout -f $BRANCH

echo “Deployment complete.”

fi

done

Save and close the file, then make it executable:

sudo chmod +x /var/repo/myapp.git/hooks/post-receive

sudo chmod +x /var/repo/myapp.git/hooks/post-receive

Step 3: Set Up Your Local Project Repository

On your local machine (or in a separate directory on the same Ubuntu machine for testing), create a new project and initialize it as a Git repository:

sudo mkdir -p /tmp/myapp-local

cd /tmp/myapp-local

sudo git init

mkdir

sudo git init

Set up a local project repository by configuring the email and name:

sudo git config user.email “dev@myapp.com”

sudo git config user.name “Developer”

sudo git checkout -b main

sudo git config user email

Create your application files:

cat > index.html << ‘EOF’

<!DOCTYPE html>

<html>

<head><title>My App</title></head>

<body><h1>Hello from Git Auto Deploy!</h1></body>

</html>

EOF

cat > deploy-info.txt << ‘EOF’

App: myapp

Version: 1.0.0

Deployed via: Git post-receive hook

EOF

Commit the files:

sudo git add .

sudo git commit -m “Initial commit: Add index.html and deploy-info”

sudo git add

Step 4: Add the Server as a Remote and Push

Add the bare repository on your server as a remote named production, then push your code:

sudo git remote add production /var/repo/myapp.git

sudo git push production main

sudo git push production main

The three remote: lines are the output from your post-receive hook executing on the server, confirming that the code was automatically deployed to /var/www/html/myapp the instant the push completed.

Verify the deployed files:

sudo ls -la /var/www/html/myapp/

sudo cat /var/www/html/myapp/index.html

sudo ls -la /var/www/html/myapp/

Your application files are now live in the deployment directory, deployed automatically by a single git push command.

Step 5: Test a Second Deployment (Version Update)

Update your application and push again to prove that automatic deployment works for every subsequent push, not just the first one:

cat > index.html << ‘EOF’

<!DOCTYPE html>

<html>

<head><title>My App v2</title></head>

<body>

<h1>Hello from Git Auto Deploy – Version 2!</h1>

<p>Updated automatically via Git push.</p>

</body>

</html>

EOF

cat > deploy-info.txt << ‘EOF’

App: myapp

Version: 2.0.0

Deployed via: Git post-receive hook

EOF

Add the bare repository on your server as a remote named production, then push your code:

sudo git add .

sudo git commit -m “v2.0: Update index.html with version info”

sudo git push production main

Verify the update was deployed:

sudo cat /var/www/html/myapp/deploy-info.txt

Every push to the main branch now automatically deploys to your server with zero manual steps.

View full Git commit history and remote info.

sudo git log –oneline –graph –all

sudo git remote -v

The git log confirms that two successful automated deployments are recorded in the version history, giving you a complete audit trail of every release.

Method 2: GitHub Actions for Automatic Deployment

GitHub Actions is a cloud-native CI/CD platform built directly into GitHub that defines automated workflows using YAML files stored inside .github/workflows/ in your repository. It is the most widely used Git automatic deployment tool for teams hosting code on GitHub.

Real-World Example: Create the GitHub Actions Workflow File

Inside your project, create the workflow directory and file:

sudo mkdir -p /tmp/myapp-local

sudo nano .github/workflows/deploy.yml

Add the following workflow configuration:

name: Deploy to Production

on:

push:

branches:

– main

jobs:

deploy:

runs-on: ubuntu-latest

steps:

– name: Checkout code

uses: actions/checkout@v3

– name: Set up Node.js

uses: actions/setup-node@v3

with:

node-version: ’20’

– name: Install dependencies

run: npm install

– name: Run tests

run: npm test

– name: Deploy to server via SSH

uses: appleboy/ssh-action@master

with:

host: ${{ secrets.SERVER_HOST }}

username: ${{ secrets.SERVER_USER }}

key: ${{ secrets.SSH_PRIVATE_KEY }}

script: |

cd /var/www/myapp

git pull origin main

npm install –production

pm2 restart myapp

Commit and push this workflow file to your GitHub repository:

sudo git add .github/

sudo git commit -m “Add GitHub Actions deployment workflow”

Finally, push this workflow file to your GitHub repository:

sudo git push production main

Once pushed, GitHub will automatically detect the workflow file and run the pipeline on every subsequent push to the main branch. Navigate to the Actions tab in your GitHub repository to watch the pipeline execute in real time.

Important: Before this workflow can deploy to your server, add three repository secrets in GitHub under Settings → Secrets and variables → Actions:

  • SERVER_HOST — Your server’s IP address or domain name
  • SERVER_USER — The SSH username (e.g., ubuntu)
  • SSH_PRIVATE_KEY — The private SSH key used to connect to your server

Method 3: GitLab CI/CD for Automatic Deployment

GitLab CI/CD is GitLab’s built-in pipeline system configured through a .gitlab-ci.yml file in the root of your repository. It is widely adopted in enterprise environments and teams that self-host their Git infrastructure.

Real-World Example: Create the GitLab CI/CD Pipeline File

In the root of your project, create the GitLab CI/CD configuration:

sudo nano .gitlab-ci.yml

Add the following pipeline configuration for a Python Django application:

stages:

– test

– deploy

test:

stage: test

image: python:3.11

script:

– pip install -r requirements.txt

– python manage.py test

deploy_production:

stage: deploy

only:

– main

script:

– apt-get update -qq && apt-get install -y openssh-client

– eval $(ssh-agent -s)

– echo “$SSH_PRIVATE_KEY” | ssh-add –

– ssh -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_HOST “

cd /var/www/djangoapp &&

git pull origin main &&

pip install -r requirements.txt &&

python manage.py migrate &&

sudo systemctl restart gunicorn”

Commit this file to your GitLab repository:

sudo git add .gitlab-ci.yml

sudo git commit -m “Add GitLab CI/CD pipeline configuration”

sudo git push production main

GitLab will automatically find .gitlab-ci.yml and run the pipeline. The test stage is executed first, and deployment can only take place when all tests are successful, so that broken code is never deployed to production.

Git Branching Strategy for Automatic Deployments

The base that enables automatic deployments to be safe and predictable is a clear Git branching strategy. The most common way to use automated deployments is to adhere to the GitFlow model or, more simply, the trunk-based development model:

  • main branch: The production code is always located here. Pushes or merges to main automatically deploy to the production environment.
  • staging branch: Automatically publishes to the staging environment, where the QA tests are done before code gets to production.
  • develop branch: automatically deploys to the development or integration environment for continuous testing while developing.

Only run automated tests, not deployments, on feature branches; never untested/untested code reaches any live environment automatically.

Security Best Practices for Git Automatic Deployments

When moving a deployment to production, new security risks arise that all DevOps engineers should consider before taking a deployment to production:

  • Never put credentials in your repository. Do not store SSH keys, API tokens, database passwords, or other sensitive values that your deployment pipeline needs in environment variables. Never use environment variables to store SSH keys, API tokens, database passwords, or other sensitive values that your deployment pipeline requires.
  • Don’t use personal SSH keys; use deploy keys. A deploy key is a repository-specific SSH key pair that can be used to access a repository with read-only or read-write access, so that the blast radius is minimised if that key should be compromised.
  • Limit the number of branches that cause deployments. Use protected branches like main and production for deploying changes, and have branch protection rules set up that require code reviews before the branch is merged.
  • Run your deployment pipeline as a non-root user. The deployment user on your server should not have full sudo/ root privileges, only the lowest possible privileges to restart the application and write to the deployment directory.

Real-World Deployment Workflow: End-to-End Example

Let’s have a look at an actual SaaS product team’s full Git automated deployment workflow:

  • The developer makes a feature branch off of main and submits a pull request to GitHub.
  • The test suite, linting, unit tests, and integration tests are automatically performed against the feature branch on GitHub Actions.
  • When all checks return a “pass”, the Pull Request is reviewed and approved by a senior developer.
  • The developer will merge the Pull Request into main.
  • When someone pushes to main, GitHub Actions will trigger the production deployment workflow.
  • The workflow executes the entire test suite once again, creates a production Docker image, pushes it to a Docker container registry, and directs the production server to retrieve and deploy the new image.
  • It takes less than three minutes to deploy with no manual steps, and the team receives an email notification in Slack when the deployment is successful.

In the typical workflow, this is the process that all companies, from startups to publicly traded tech companies, go through, and it’s completely dependent on Git as the hub for coordination.

Conclusion

Using Git for automatic deployments eliminates manual file transfers (like FTP) by triggering updates whenever you push code to a repository. Whether you implement simple Git post-receive hooks for a personal VPS, use GitHub Actions for a SaaS application, or adopt GitLab CI/CD for an enterprise environment, the core principle remains the same: every deployment should be a predictable, repeatable consequence of a Git push, not a manual operation that depends on a specific person following a checklist correctly.

The real-world examples in this guide give you working starting points that you can adapt to your specific technology stack and infrastructure. Start with the simplest implementation that solves your current deployment pain, and evolve the pipeline as your team and application grow in complexity.

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video