Git Push to Deploy: Automating Server Deployment with Post-Receive Hooks and Docker Compose

🔐 Secure Git Push-Based Deployment

This guide explains how to securely deploy a Docker-based application using Git push, with two users:

  • sshuser – non-root user responsible for pushing code.
  • myrootuser – root-privileged user responsible for executing deployment.

✅ Deployment Flow Summary

ActorActionRuns As
sshuserPushes code to bare Git reposshuser
post-receiveTriggers deploy scriptvia sudo -u myrootuser
deploy.shRuns Docker Composeas myrootuser

🧭 Step-by-Step Setup


🔹 1. On Server: Create Bare Git Repo (as sshuser)

ssh sshuser@your-server
mkdir -p ~/repos/myapp.git
cd ~/repos/myapp.git
git init --bare

🔹 2. Create post-receive Hook (as sshuser)

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

Paste this:

#!/bin/bash
sudo -u myrootuser /home/myrootuser/deploy-scripts/deploy.sh

Make it executable:

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

🔹 3. Allow sshuser to Run Only This Script as myrootuser

Run as root or myrootuser:

sudo visudo -f /etc/sudoers.d/sshuser-deploy

Add this line:

sshuser ALL=(myrootuser) NOPASSWD: /home/myrootuser/deploy-scripts/deploy.sh

🔹 4. Create the deploy.sh Script (as myrootuser)

mkdir -p /home/myrootuser/deploy-scripts
nano /home/myrootuser/deploy-scripts/deploy.sh

Paste this:

#!/bin/bash

DEPLOY_DIR="/home/myrootuser/myapp"
REPO_DIR="/home/sshuser/repos/myapp.git"
LOG_FILE="$DEPLOY_DIR/deploy.log"

echo "[$(date)] Deployment triggered by git push." >> "$LOG_FILE"

# Checkout code
GIT_WORK_TREE=$DEPLOY_DIR git --git-dir=$REPO_DIR checkout -f >> "$LOG_FILE" 2>&1

cd "$DEPLOY_DIR" || exit 1

# Docker Compose actions
docker compose build >> "$LOG_FILE" 2>&1
docker compose down >> "$LOG_FILE" 2>&1
docker compose up -d >> "$LOG_FILE" 2>&1

echo "[$(date)] Deployment finished." >> "$LOG_FILE"

Make it executable:

chmod +x /home/myrootuser/deploy-scripts/deploy.sh

Ensure ownership of target directory:

mkdir -p /home/myrootuser/myapp
chown -R myrootuser:myrootuser /home/myrootuser/myapp

🔹 5. On Your Local Machine: Push Code to Server

git remote add production ssh://your-server-alias/home/sshuser/repos/myapp.git
git push production master
How to configure GIT_SSH_COMMAND for one-off pushes or set a permanent ~/.ssh/config alias with IdentityFile Using Custom SSH Keys with Git Push: How to Deploy Securely with -i



✅ Final Flow Recap

ActorActionRuns As
sshuserPushes code via Gitsshuser
post-receiveTriggers deploy scriptvia sudo -u myrootuser
deploy.shRuns Docker Composemyrootuser

🔐 Security Considerations

  • sshuser can only run the deploy script, not arbitrary sudo commands.
  • All Docker and sensitive actions are isolated under myappuser.
  • Logs are stored per deployment in /home/myrootuser/myapp/deploy.log.


Comments

Popular posts from this blog

Mount StorageBox to the server for backup

psql: error: connection to server at "localhost" (127.0.0.1), port 5433 failed: ERROR: failed to authenticate with backend using SCRAM DETAIL: valid password not found

Keeping Your SSH Connections Alive: Configuring ServerAliveInterval and ServerAliveCountMax