`n

Deployment with Git - Complete Guide

Published: September 25, 2024 | Reading time: 20 minutes

Git Deployment Overview

Git-based deployment strategies for automated releases:

Deployment Benefits
# Git Deployment Benefits
- Automated deployments
- Version control integration
- Rollback capabilities
- Environment consistency
- Team collaboration
- Deployment tracking
- Zero-downtime deployments

Git Hooks Deployment

Post-Receive Hook Setup

Git Hooks Deployment
# Git Hooks Deployment

# 1. Create post-receive hook
# On server: /var/repo/myapp.git/hooks/post-receive
#!/bin/bash
WORK_TREE=/var/www/myapp
GIT_DIR=/var/repo/myapp.git

# Deploy to production
git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f

# Run build commands
cd $WORK_TREE
npm install --production
npm run build

# Restart services
sudo systemctl restart nginx
sudo systemctl restart myapp

# 2. Pre-receive hook validation
#!/bin/bash
# Validate deployment
while read oldrev newrev refname; do
    if [[ $refname = "refs/heads/main" ]]; then
        # Run tests
        git --work-tree=/tmp/test --git-dir=/var/repo/myapp.git checkout -f $newrev
        cd /tmp/test
        npm test
        if [ $? -ne 0 ]; then
            echo "Tests failed, deployment rejected"
            exit 1
        fi
    fi
done

# 3. Update hook for staging
#!/bin/bash
# Deploy to staging
WORK_TREE=/var/www/staging
GIT_DIR=/var/repo/myapp.git

git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f staging

cd $WORK_TREE
npm install
npm run build:staging

# 4. Branch-based deployment
#!/bin/bash
while read oldrev newrev refname; do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    
    case $branch in
        main)
            deploy_production
            ;;
        staging)
            deploy_staging
            ;;
        develop)
            deploy_development
            ;;
    esac
done

# 5. Environment-specific deployment
deploy_production() {
    WORK_TREE=/var/www/production
    GIT_DIR=/var/repo/myapp.git
    
    git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f main
    
    cd $WORK_TREE
    npm install --production
    npm run build:production
    
    # Health check
    curl -f http://localhost:3000/health || exit 1
    
    # Restart services
    sudo systemctl restart myapp
}

deploy_staging() {
    WORK_TREE=/var/www/staging
    GIT_DIR=/var/repo/myapp.git
    
    git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f staging
    
    cd $WORK_TREE
    npm install
    npm run build:staging
}

CI/CD Integration

GitHub Actions Deployment

CI/CD Deployment
# GitHub Actions Deployment

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run tests
      run: npm test
    
    - name: Build application
      run: npm run build

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Build application
      run: npm run build
    
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.5
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /var/www/myapp
          git pull origin main
          npm install --production
          npm run build
          sudo systemctl restart myapp

# 2. Multi-environment deployment
name: Multi-Environment Deployment

on:
  push:
    branches: [ main, staging, develop ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Determine environment
      id: env
      run: |
        if [[ $GITHUB_REF == 'refs/heads/main' ]]; then
          echo "environment=production" >> $GITHUB_OUTPUT
        elif [[ $GITHUB_REF == 'refs/heads/staging' ]]; then
          echo "environment=staging" >> $GITHUB_OUTPUT
        else
          echo "environment=development" >> $GITHUB_OUTPUT
        fi
    
    - name: Deploy to ${{ steps.env.outputs.environment }}
      uses: appleboy/ssh-action@v0.1.5
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /var/www/${{ steps.env.outputs.environment }}
          git pull origin ${{ github.ref_name }}
          npm install
          npm run build:${{ steps.env.outputs.environment }}
          sudo systemctl restart myapp-${{ steps.env.outputs.environment }}

Deployment Strategies

Advanced Deployment Patterns

Deployment Strategies
# Deployment Strategies

# 1. Blue-Green Deployment
#!/bin/bash
# Blue-Green deployment script

CURRENT_COLOR=$(cat /var/www/current_color)
if [ "$CURRENT_COLOR" = "blue" ]; then
    NEW_COLOR="green"
    OLD_COLOR="blue"
else
    NEW_COLOR="blue"
    OLD_COLOR="green"
fi

# Deploy to new environment
git --work-tree=/var/www/$NEW_COLOR --git-dir=/var/repo/myapp.git checkout -f main
cd /var/www/$NEW_COLOR
npm install --production
npm run build

# Health check
curl -f http://localhost:3001/health || exit 1

# Switch traffic
sudo ln -sf /var/www/$NEW_COLOR /var/www/current
echo $NEW_COLOR > /var/www/current_color

# Restart services
sudo systemctl restart nginx
sudo systemctl restart myapp

# 2. Rolling Deployment
#!/bin/bash
# Rolling deployment script

SERVERS=("server1" "server2" "server3")

for server in "${SERVERS[@]}"; do
    echo "Deploying to $server..."
    
    ssh $server "cd /var/www/myapp && git pull origin main"
    ssh $server "cd /var/www/myapp && npm install --production"
    ssh $server "cd /var/www/myapp && npm run build"
    ssh $server "sudo systemctl restart myapp"
    
    # Health check
    ssh $server "curl -f http://localhost:3000/health" || exit 1
    
    echo "Deployment to $server completed"
done

# 3. Canary Deployment
#!/bin/bash
# Canary deployment script

# Deploy to canary server
git --work-tree=/var/www/canary --git-dir=/var/repo/myapp.git checkout -f main
cd /var/www/canary
npm install --production
npm run build

# Route 10% traffic to canary
sudo nginx -s reload

# Monitor canary for 10 minutes
sleep 600

# Check metrics
CANARY_ERROR_RATE=$(curl -s http://localhost:3001/metrics | grep error_rate)
if [ "$CANARY_ERROR_RATE" -lt "0.01" ]; then
    # Deploy to production
    deploy_production
else
    # Rollback canary
    sudo nginx -s reload
    exit 1
fi

# 4. Feature Flag Deployment
#!/bin/bash
# Feature flag deployment

# Deploy with feature flags
git --work-tree=/var/www/myapp --git-dir=/var/repo/myapp.git checkout -f main
cd /var/www/myapp
npm install --production

# Set feature flags
export FEATURE_NEW_UI=true
export FEATURE_BETA_API=false

npm run build
sudo systemctl restart myapp

# 5. Database Migration Deployment
#!/bin/bash
# Database migration deployment

# Backup database
mysqldump -u root -p myapp > /backup/myapp_$(date +%Y%m%d_%H%M%S).sql

# Run migrations
cd /var/www/myapp
npm run migrate:up

# Deploy application
git --work-tree=/var/www/myapp --git-dir=/var/repo/myapp.git checkout -f main
npm install --production
npm run build

# Health check
curl -f http://localhost:3000/health || {
    # Rollback migration
    npm run migrate:down
    exit 1
}

sudo systemctl restart myapp

Deployment Best Practices

Production Guidelines

Deployment Best Practices

  • Automate all deployments
  • Use environment-specific configs
  • Implement health checks
  • Monitor deployment metrics
  • Have rollback procedures
  • Test in staging first
  • Use feature flags

Common Mistakes

  • Manual deployments
  • No health checks
  • Missing rollback plans
  • Deploying to production directly
  • Not monitoring deployments
  • Ignoring environment differences
  • Poor error handling

Summary

Git-based deployment involves several key components:

  • Git Hooks: Automated deployment triggers
  • CI/CD Integration: GitHub Actions and automation
  • Deployment Strategies: Blue-green, rolling, canary deployments
  • Best Practices: Guidelines and common mistakes

Need More Help?

Struggling with Git deployment setup or need help implementing automated deployment strategies? Our deployment experts can help you set up robust deployment pipelines.

Get Deployment Help