Implementing GitLab Post-Receive Hooks for Automated Deployment to Production Server


3 views

When working with GitLab as your version control system, you can leverage post-receive hooks to automate deployment workflows. Unlike standard Git hooks, GitLab provides a more integrated approach through its webhook system and CI/CD pipelines.

First, prepare your production server to receive and process the Git push:


# On production server (assuming Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y git-core

# Create a bare repository
mkdir /var/www/website.git
cd /var/www/website.git
git init --bare

# Create post-receive hook
cat > hooks/post-receive << 'EOF'
#!/bin/bash
TARGET="/var/www/html"
GIT_DIR="/var/www/website.git"
BRANCH="master"

while read oldrev newrev refname
do
    if [[ $refname = "refs/heads/$BRANCH" ]];
    then
        echo "Ref $refname received. Deploying ${BRANCH} branch to production..."
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
        # Add any post-deploy commands here
        cd $TARGET && npm install && npm run build
    fi
done
EOF

# Make the hook executable
chmod +x hooks/post-receive

In your GitLab project:

  1. Navigate to Settings > Webhooks
  2. Add URL in format: ssh://user@production.server/var/www/website.git
  3. Set trigger to "Push events"
  4. Under "Secret token", generate and store a secure token
  5. Check "Enable SSL verification" if using HTTPS

For more control, consider using GitLab's built-in CI/CD:


# .gitlab-ci.yml example
stages:
  - deploy

deploy_production:
  stage: deploy
  only:
    - master
  script:
    - rsync -avz --delete -e ssh ./ user@production.server:/var/www/html/
    - ssh user@production.server "cd /var/www/html && npm install && npm run build"
  • Use SSH keys with restricted permissions
  • Implement webhook secret verification
  • Consider using a deployment token instead of personal accounts
  • Set proper file permissions on production server

If deployments aren't triggering:


# Check hook logs on production server
tail -f /var/log/auth.log

# Test SSH connection manually
ssh -T user@production.server

# Verify GitLab webhook deliveries
# (Project Settings > Webhooks > Edit > Recent Deliveries)

When working with GitLab, you can automate deployment to a production server using post-receive hooks. This is particularly useful for web projects where you want to update the live server whenever changes are pushed to the master branch.

First, you'll need to set up a bare repository on your production server:

mkdir /var/repo/website.git
cd /var/repo/website.git
git init --bare

Create a post-receive hook script in the hooks directory:

cat > /var/repo/website.git/hooks/post-receive << 'EOF'
#!/bin/bash
while read oldrev newrev ref
do
    if [[ $ref =~ .*/master$ ]];
    then
        echo "Deploying master branch to production..."
        GIT_WORK_TREE=/var/www/html git checkout -f
    fi
done
EOF

Make the script executable:

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

In your GitLab project settings, navigate to Webhooks and add a new webhook:

  • URL: http://your-production-server:8080/your-webhook-endpoint
  • Trigger: Push events
  • Secret token: [your-secure-token]

For a more robust solution, consider using GitLab's built-in CI/CD:

# .gitlab-ci.yml
deploy_production:
  stage: deploy
  script:
    - rsync -avz --delete ./ user@production-server:/var/www/html/
  only:
    - master

If you encounter permission problems, ensure:

chown -R git:git /var/repo/website.git
chown -R www-data:www-data /var/www/html

For debugging, add logging to your hook script:

echo "$(date): Received push to $ref" >> /var/log/git-hooks.log

Always use SSH keys for authentication and consider:

  • Restricting hook access to specific IPs
  • Using HTTPS with proper certificates
  • Implementing secret token verification