A production-ready CI/CD pipeline with high availability and automatic failover capabilities. Deploy to any infrastructure - AWS, Azure, local servers, or any cloud provider.
- Automatic Failover: Primary server goes down? Backup takes over automatically
- Database Replication: Continuous sync between primary and backup servers
- Safe Deployments: Automatic backup before deploy, rollback on failure
- CI/CD Pipeline: Automated testing and deployment via GitHub Actions
- Cloud Agnostic: Works on AWS, Azure, GCP, VPS, or bare metal servers
Users
│
┌───────┴───────┐
│ │
[Load Balancer] [GitHub Actions]
│ CI/CD Pipeline
│
┌──────┴──────┐
│ │
[PRIMARY] [BACKUP]
App + DB Standby
│ │
└─────────────┘
DB Replication
git clone https://github.com/smitraval24/high-availability-failover.git
cd high-availability-failover
# Copy the example configuration
cp config/config.env.example config/config.env
# Edit with your server details
nano config/config.envEdit config/config.env with your infrastructure:
# Required: Primary server (where app runs normally)
PRIMARY_HOST=your-primary-server-ip
PRIMARY_USER=your-ssh-username
# Required: Backup server (takes over if primary fails)
BACKUP_HOST=your-backup-server-ip
BACKUP_USER=your-ssh-username
# Optional: Load balancer
LB_HOST=your-loadbalancer-ip
LB_USER=your-ssh-usernameRun from your local machine to set up SSH keys between servers:
cd scripts
bash local-bootstrap.shSSH into your primary server and run the setup:
ssh your-user@your-primary-ip
cd high-availability-failover/ansible
bash SETUP.shIn your GitHub repository settings, add:
Secrets (Settings → Secrets and variables → Actions → Secrets):
PRIMARY_SSH_PRIVATE_KEY: SSH private key for primary serverBACKUP_SSH_PRIVATE_KEY: SSH private key for backup server
Variables (Settings → Secrets and variables → Actions → Variables):
PRIMARY_HOST: IP/hostname of primary serverPRIMARY_USER: SSH username for primary serverBACKUP_HOST: IP/hostname of backup serverBACKUP_USER: SSH username for backup server
Optional Variables:
RUNNER: Set toself-hosted, linux, x64for self-hosted runner (defaults toubuntu-latest)PROJECT_DIR: Project directory name (default:high-availability-failover)APP_PORT: Application port (default:3000)
high-availability-failover/
├── config/
│ ├── config.env.example # Template - copy to config.env
│ └── defaults.env # Default values
├── coffee_project/ # Sample Node.js application
│ ├── app.js # Express API
│ ├── docker-compose.yml # Container orchestration
│ └── test/ # Test suite
├── ansible/ # Infrastructure automation
│ ├── inventory.yml # Server definitions
│ ├── site.yml # Main playbook
│ └── *.yml # Individual playbooks
├── scripts/ # Operational scripts
│ ├── local-bootstrap.sh # Initial SSH setup
│ ├── monitor-primary-health.sh # Failover monitor
│ ├── replicate-db.sh # Database replication
│ ├── backup-container.sh # Pre-deploy backup
│ └── rollback-container.sh # Rollback on failure
├── load_balancer/ # Nginx configuration
└── .github/workflows/ # CI/CD pipelines
├── deploy.yml # Production deployment
├── pr-test.yml # PR testing
└── sync-dev.yml # Branch sync
- Pull Request: Runs linting and tests automatically
- Merge to main: Triggers deployment workflow
- Deployment:
- Creates backup of current container
- Pulls latest code
- Builds and starts new containers
- Runs health checks
- Rolls back automatically if health checks fail
- Post-deploy: Syncs code to backup server
-
Monitor (runs on backup server):
- Pings primary server every 30 seconds
- After 3 consecutive failures, triggers failover
-
Failover:
- Starts application on backup server
- Restores database from latest replication
- Traffic automatically routes to backup
-
Recovery:
- When primary recovers, syncs database back
- Backup returns to standby mode
- Runs every 30 minutes (configurable)
pg_dumpon primary → SCP → restore on backup- Ensures minimal data loss during failover
| Variable | Required | Default | Description |
|---|---|---|---|
PRIMARY_HOST |
Yes | - | Primary server IP/hostname |
PRIMARY_USER |
Yes | - | SSH username for primary |
BACKUP_HOST |
Yes | - | Backup server IP/hostname |
BACKUP_USER |
Yes | - | SSH username for backup |
LB_HOST |
No | - | Load balancer IP (optional) |
APP_NAME |
No | coffee |
Application name |
APP_PORT |
No | 3000 |
Application port |
DB_NAME |
No | coffee_dev |
Database name |
HEALTH_CHECK_INTERVAL |
No | 30 |
Seconds between health checks |
FAIL_THRESHOLD |
No | 3 |
Failures before failover |
DOMAIN_NAME |
No | - | Domain name (optional) |
| Variable | Required | Default | Description |
|---|---|---|---|
PRIMARY_HOST |
Yes | - | Primary server IP |
PRIMARY_USER |
Yes | - | Primary SSH user |
BACKUP_HOST |
Yes | - | Backup server IP |
BACKUP_USER |
Yes | - | Backup SSH user |
RUNNER |
No | ubuntu-latest |
Runner type |
PROJECT_DIR |
No | high-availability-failover |
Project directory |
APP_PORT |
No | 3000 |
Application port |
- Primary server: Runs application + database
- Backup server: Standby for failover
- Load Balancer: Nginx reverse proxy
- Primary server: Main application
- Backup server: Failover standby
Works with any cloud that supports:
- Linux VMs with SSH access
- Docker and Docker Compose
- Outbound internet (for GitHub Actions)
Tested on:
- AWS EC2
- Azure VMs
- Google Cloud Compute
- DigitalOcean Droplets
- Linode
- VCL (Virtual Computing Lab)
- Replace
coffee_project/with your application - Update
docker-compose.ymlfor your stack - Modify health check endpoint in
config/config.env:HEALTH_ENDPOINT=/your-health-endpoint
- Update container names if different:
APP_CONTAINER=your_app DB_CONTAINER=your_db
- Check GitHub Actions logs
- Verify SSH keys are correctly configured
- Ensure servers are reachable from GitHub runner
- Check monitor logs:
journalctl -u monitor-primary -f - Verify backup server can reach primary
- Check database replication status
- Verify application is running:
docker-compose ps - Test endpoint manually:
curl http://localhost:3000/coffees - Check application logs:
docker-compose logs app
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
cd coffee_project && npm test - Submit a pull request
ISC License
Originally developed as a DevOps course project demonstrating CI/CD, high availability, and infrastructure automation.