Portable VPS Deployment with Ansible⚓︎
🚀 Cloud VPS Deployment Guide⚓︎
This guide deploys a standardized VPS configuration to any cloud provider (Hetzner, DigitalOcean, Linode, etc.) with monitoring, backups, and automation.
Prerequisites Checklist⚓︎
Before starting, ensure you have:
- Ubuntu 24.04 VPS deployed on any cloud provider
- Root or sudo access to VPS
- Synology NAS accessible via Tailscale
- VPS connected to Tailscale network
- Ntfy.sh server configured with authentication tokens
Phase 1: VPS Initial Setup⚓︎
Get VPS IP Address⚓︎
Write down the IP: _________________
Create User Account⚓︎
Deploy SSH Key⚓︎
# From your NAS, deploy the SSH key
cat /volume2/ansible-infrastructure/ssh-keys/ansible_key.pub | ssh unifiadmin@VPS_IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
Test SSH access:
Phase 2: Update Ansible Configuration⚓︎
Update VPS IP in Inventory⚓︎
Change the IP address:
all:
children:
vps_servers:
hosts:
portable-vps:
ansible_host: VPS_IP_HERE # ← Update this line
ansible_user: unifiadmin
ansible_ssh_private_key_file: ssh-keys/ansible_key
Phase 3: Deploy VPS Configuration with Ansible⚓︎
Test Connectivity⚓︎
docker run --rm -it \
-v /volume2/ansible-infrastructure:/ansible \
-w /ansible \
cytopia/ansible:latest \
sh -c "apk add --no-cache openssh-client && ansible -i inventory/portable-vps.yml all -m ping"
Expected output: portable-vps | SUCCESS => {"ping": "pong"}
Optional: Run Discovery⚓︎
docker run --rm -it \
-v /volume2/ansible-infrastructure:/ansible \
-w /ansible \
cytopia/ansible:latest \
sh -c "apk add --no-cache openssh-client && ansible-playbook -i inventory/portable-vps.yml playbooks/discover-server.yml --ask-become-pass -v"
Phase 3.5: Test Deployment (Recommended)⚓︎
Test Deployment First⚓︎
# Test deployment in check mode first
docker run --rm -it \
-v /volume2/ansible-infrastructure:/ansible \
-w /ansible \
cytopia/ansible:latest \
sh -c "apk add --no-cache openssh-client && ansible-playbook -i inventory/portable-vps.yml playbooks/vps-infrastructure.yml --check --diff --ask-become-pass -v"
Deploy Complete VPS Configuration⚓︎
# Deploy complete VPS configuration
docker run --rm -it \
-v /volume2/ansible-infrastructure:/ansible \
-w /ansible \
cytopia/ansible:latest \
sh -c "apk add --no-cache openssh-client && ansible-playbook -i inventory/portable-vps.yml playbooks/vps-infrastructure.yml --ask-become-pass -v"
When prompted for BECOME password: Enter the unifiadmin sudo password
Note: The deployment uses the vps-applications role with comprehensive defaults and bulletproof variable handling. Both local and VPS deployments are tested and working.
What Ansible Builds Automatically⚓︎
✅ Base System Configuration⚓︎
- SSH hardening (UFW firewall, Fail2Ban intrusion prevention)
- Essential packages (curl, wget, git, htop, vim, tree, cifs-utils, etc.)
- System package updates and security hardening
- User shell configuration with sudo and docker group access
- Service management and security policies
✅ Docker Environment⚓︎
- Docker v27.2.0+ installation with Compose
- Docker daemon configuration optimized for VPS
- Docker networks and volumes
- Docker Compose directory:
/home/unifiadmin/docker/compose - Container management and monitoring
✅ VPS-Specific Scripts (7 total)⚓︎
/usr/local/bin/unifi-backup.sh- Weekly Unifi controller backup/usr/local/bin/backup-golinks.sh- Daily Tailscale Golinks backup/usr/local/bin/internet-connectivity-check.sh- 5-minute connectivity monitoring/usr/local/bin/monitor-exit-node.sh- 5-minute Tailscale exit node monitoring/usr/local/bin/docker-maintenance.sh- Daily Docker updates and cleanup/usr/local/bin/backup-dotfiles.sh- Weekly dotfiles backup to GitHub/usr/local/bin/rclone-nas- NAS backup wrapper script
✅ NAS Integration⚓︎
- CIFS mount to
/mnt/Backupwith secure credentials - Automated backup destination configuration
- NAS connectivity verification and mounting
✅ Monitoring & Notifications⚓︎
- Ntfy.sh integration with separate authentication tokens:
- Server monitoring notifications
- Container update notifications
- Healthcheck notifications
- Healthcheck.io integration for critical services:
- Exit node monitoring
- Unifi backup verification
- Golinks backup verification
- Error handling with automatic notifications
✅ Scheduled Automation (6 cron jobs)⚓︎
- Unifi Backup: Sunday 1:00 AM with healthcheck
- Golinks Backup: Daily 4:00 AM with healthcheck
- Internet Connectivity: Every 5 minutes
- Exit Node Monitor: Every 5 minutes with healthcheck
- Docker Maintenance: Daily 2:30 AM
- Dotfiles Backup: Monday 3:00 AM
✅ Directory Structure⚓︎
/home/unifiadmin/.config/appdata- Application data/home/unifiadmin/docker/compose- Docker Compose files/home/unifiadmin/github/docker- Docker configurations/home/unifiadmin/github/configurations- Server configurations/home/unifiadmin/github/configurations/golink-backup- Golinks backup storage/mnt/Backup- NAS mount point
Phase 4: Post-Deployment Configuration⚓︎
Verify VPS Services⚓︎
# SSH to the VPS
ssh -i /volume2/ansible-infrastructure/ssh-keys/ansible_key unifiadmin@VPS_IP
# Check deployed scripts
ls -la /usr/local/bin/*.sh
# Verify cron jobs
crontab -l
# Check NAS mount
mount | grep /mnt/Backup
# Test connectivity monitoring
/usr/local/bin/internet-connectivity-check.sh
# Check Docker environment
docker --version
docker compose version
Configure Docker Applications⚓︎
# Navigate to Docker Compose directory
cd /home/unifiadmin/docker/compose
# Deploy your Docker applications
# (Place your docker-compose.yml files here)
# Start services
docker compose up -d
Phase 5: Monitoring Verification⚓︎
Test Notification System⚓︎
# Test ntfy notifications (replace with your actual token)
curl -H "Authorization: Bearer tk_8eaxrky4sbnki665w6m4aybokafi5" \
-H "Title: VPS Deployment Test" \
-d "VPS deployment completed successfully!" \
"https://ntfy.levine.io/server-monitoring"
Verify Healthchecks⚓︎
# Test healthcheck endpoints
curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/d48e3f5b-1ac3-42a8-87cb-382b55038a6b
Complete Deployment Timeline⚓︎
- VPS Provisioning: 5-10 minutes (cloud provider dependent)
- User Setup: 2-3 minutes
- Ansible Deployment: 8-12 minutes
- Application Deployment: 5-15 minutes (depending on containers)
- Verification: 3-5 minutes
VPS-Specific Configuration Details⚓︎
Security Hardening⚓︎
- UFW Firewall: Configured with essential ports only
- Fail2Ban: SSH brute force protection
- SSH Hardening: Key-only authentication, root login disabled
- User Management: Non-root user with minimal required privileges
Backup Strategy⚓︎
- NAS Integration: Direct CIFS mount to Synology NAS
- Automated Backups: Unifi, Golinks, and dotfiles
- Backup Verification: Healthcheck integration for critical backups
- Backup Destination:
/mnt/Backup(NAS mount)
Monitoring Architecture⚓︎
- Real-time Monitoring: Internet connectivity and Tailscale exit node
- Scheduled Monitoring: Docker maintenance and system backups
- Notification Channels: Ntfy.sh with topic-specific tokens
- Health Verification: Healthcheck.io integration for critical services
Common Issues & Solutions⚓︎
Variable Loading Issues⚓︎
Solution: The VPS role now has comprehensive defaults that ensure all variables are available, preventing undefined variable errors.
NAS Mount Issues⚓︎
Symptom: /mnt/Backup not accessible Solution:
# Check mount status
mount | grep /mnt/Backup
# Remount if needed
sudo mount -a
# Check credentials
sudo cat /etc/samba/credentials
Ntfy Notification Failures⚓︎
Symptom: Notifications not received Solution:
# Test ntfy connectivity
curl -v https://ntfy.levine.io/server-monitoring
# Verify token in script
grep -r "tk_" /usr/local/bin/
Docker Maintenance Issues⚓︎
Symptom: Docker maintenance script fails Solution:
# Check Docker Compose directory
ls -la /home/unifiadmin/docker/compose/
# Test Docker Compose manually
cd /home/unifiadmin/docker/compose
docker compose pull
docker compose up -d
Tailscale Connectivity Issues⚓︎
Symptom: Exit node monitoring fails Solution:
Emergency Commands Reference⚓︎
Quick VPS Info⚓︎
# System info
hostnamectl
df -h
free -h
docker --version
docker compose version
sudo tailscale status
Service Management⚓︎
# Check critical services
systemctl status docker
systemctl status cron
systemctl status ufw
systemctl status fail2ban
# Check logs
journalctl -u docker -f
tail -f /var/log/auth.log
Manual Script Execution⚓︎
# Test individual scripts
sudo -u unifiadmin /usr/local/bin/internet-connectivity-check.sh
sudo -u unifiadmin /usr/local/bin/monitor-exit-node.sh
sudo -u unifiadmin /usr/local/bin/docker-maintenance.sh
Dry Run Mode (Testing)⚓︎
# Test all changes without applying them
docker run --rm -it \
-v /volume2/ansible-infrastructure:/ansible \
-w /ansible \
cytopia/ansible:latest \
sh -c "apk add --no-cache openssh-client && ansible-playbook -i inventory/portable-vps.yml playbooks/vps-infrastructure.yml --check --diff --ask-become-pass -v"
Success Verification Checklist⚓︎
VPS is fully deployed when:
- SSH access works with key authentication
- UFW firewall is active and configured
- Fail2Ban is running and monitoring SSH
- Docker and Docker Compose are installed and running
- All 7 VPS scripts are deployed and executable
- All 6 cron jobs are scheduled and running
- NAS is mounted at
/mnt/Backup - Ntfy notifications are working
- Healthcheck endpoints are responding
- Internet connectivity monitoring is active
- Tailscale exit node monitoring is functional
Emergency Resources⚓︎
Ansible Project Location: /volume2/ansible-infrastructure
SSH Keys Location: /volume2/ansible-infrastructure/ssh-keys
VPS Inventory: /volume2/ansible-infrastructure/inventory/portable-vps.yml
VPS Playbook: /volume2/ansible-infrastructure/playbooks/vps-infrastructure.yml
NAS Backup Location: /mnt/Backup (on VPS)
VPS Architecture:
- Ansible: Infrastructure foundation with bulletproof variable handling
- Docker: Application containerization and orchestration
- Tailscale: Secure networking and connectivity
- NAS Integration: Centralized backup and storage
- Monitoring: Real-time alerts and health verification
Post-Deployment Tasks⚓︎
- Deploy Docker applications in
/home/unifiadmin/docker/compose - Test all monitoring and notification systems
- Verify backup operations are working correctly
- Update DNS records if needed for applications
- Document any provider-specific configurations
- Schedule regular maintenance and updates
Key Advantages of This VPS Approach⚓︎
✅ Complete Portability⚓︎
- Cloud-agnostic: Works on any Ubuntu 24.04 VPS
- Standardized configuration: Consistent across providers
- Automated deployment: No manual configuration required
✅ Comprehensive Monitoring⚓︎
- Real-time alerts: Connectivity and service monitoring
- Health verification: Automated backup and service checks
- Multi-channel notifications: Ntfy.sh and Healthcheck.io integration
✅ Robust Automation⚓︎
- Scheduled maintenance: Docker updates and cleanup
- Automated backups: Unifi, Golinks, and dotfiles
- Bulletproof variable handling: Prevents deployment failures
✅ Security Hardening⚓︎
- Firewall protection: UFW with minimal required ports
- Intrusion prevention: Fail2Ban monitoring
- Secure access: SSH key-only authentication
- Network security: Tailscale mesh networking
✅ Scalable Architecture⚓︎
- Multi-VPS support: Deploy to multiple cloud providers
- Centralized management: Single Ansible configuration
- Consistent monitoring: Unified notification system
VPS deployment completed successfully! 🚀