Use this checklist to ensure a smooth production deployment.
- Server provisioned with adequate resources (2+ GB RAM, 2+ CPU cores recommended)
- Docker and Docker Compose installed and updated
- Git installed for code updates
- Firewall configured with the following ports:
- Port 22 (SSH) - restricted to your IP
- Port 80 (HTTP) - open for Let's Encrypt
- Port 443 (HTTPS) - open for production traffic
- Port 5432 (PostgreSQL) - closed or restricted to internal network only
- Domain name registered
- DNS A record pointing to server IP address
- DNS propagated (check with
dig your-domain.comornslookup your-domain.com) - Wait 24-48 hours after DNS changes for full propagation
- Copy
.env.prod.templateto.env.prod - Set
DOMAINto your domain name - Set
CERTBOT_EMAILto your email address - Generate and set strong
DB_PASSWORD(use password manager) - Generate and set
JWT_ACCESS_SECRET(useopenssl rand -base64 32) - Generate and set
JWT_REFRESH_SECRET(useopenssl rand -base64 32) - Generate and set
ZERO_AUTH_SECRET(useopenssl rand -base64 32) - Update
CORS_ORIGINtohttps://your-domain.com - Update
VITE_API_URLtohttps://your-domain.com/api - Update
VITE_ZERO_SERVERtowss://your-domain.com/zero - Review all other configuration values
- All secrets are unique and randomly generated
- Secrets are at least 32 characters long
-
.env.prodis added to.gitignore -
.env.prodhas restricted permissions (chmod 600 .env.prod) - SSH key authentication enabled
- SSH password authentication disabled
- Root login disabled
- Non-root user created for deployment
- Fail2ban or similar intrusion prevention installed
- Clone repository to server
git clone <repository-url> /path/to/grocery cd /path/to/grocery
- Checkout production branch or tag
git checkout main # or your production branch - Copy environment file
cp .env.prod.template .env.prod # Edit .env.prod with your values
- Start PostgreSQL container
docker-compose -f docker-compose.prod.yml up -d postgres
- Wait for database to be healthy
docker-compose -f docker-compose.prod.yml ps postgres
- Verify database schema applied
docker-compose -f docker-compose.prod.yml exec postgres psql -U grocery -d grocery_db -c "\dt"
- Build application images
docker-compose -f docker-compose.prod.yml build --pull
- Start backend services
docker-compose -f docker-compose.prod.yml up -d auth-server zero-cache
- Verify backend services are healthy
docker-compose -f docker-compose.prod.yml ps
- Start frontend service
docker-compose -f docker-compose.prod.yml up -d frontend
- Verify all services are running
./deploy.sh status
- Start nginx service
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml up -d nginx
- Obtain SSL certificate
./deploy.sh ssl-cert --ssl
- Verify certificate obtained successfully
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml exec certbot certbot certificates - Restart nginx to use certificate
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml restart nginx
- Start certbot renewal service
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml up -d certbot
- Access application at
https://your-domain.com - Verify SSL certificate is valid (lock icon in browser)
- Test user registration
- Test user login
- Test creating a grocery list
- Test adding items to list
- Test real-time sync (open in two browsers)
- Test API endpoints at
https://your-domain.com/api/health - Verify WebSocket connection for Zero-cache
- Run SSL Labs test: https://www.ssllabs.com/ssltest/
- Aim for A or A+ rating
- Test from different devices (desktop, mobile, tablet)
- Test from different browsers (Chrome, Firefox, Safari, Edge)
- Test from different networks (mobile data, different WiFi)
- Load testing with expected user load
- Test error scenarios (database down, invalid credentials, etc.)
- Create directory for logs
mkdir -p logs/nginx logs/certbot
- Set up log rotation
- Configure monitoring for:
- Server CPU and memory usage
- Disk space usage
- Container health status
- Application errors
- SSL certificate expiry
- Set up alerting for critical issues
- Create backup directory
mkdir -p backups
- Test database backup
./deploy.sh backup-db
- Verify backup file created
ls -lh backups/
- Set up automated daily backups (cron job)
# Add to crontab 0 2 * * * cd /path/to/grocery && ./deploy.sh backup-db
- Test backup restoration on separate system
./deploy.sh restore-db
- Set up off-site backup storage
- Review Docker resource limits
- Monitor database query performance
- Check nginx access logs for slow requests
- Enable database query logging if needed
- Review and adjust rate limits based on usage
- Document server access procedures
- Document deployment procedures for updates
- Document backup and restore procedures
- Document emergency rollback procedures
- Document monitoring and alerting setup
- Create runbook for common issues
- Check service health status
./deploy.sh health --ssl
- Review error logs
./deploy.sh logs --ssl | grep -i error - Check disk space usage
df -h
- Review backup success/failure
- Update Docker images
./deploy.sh update --ssl
- Review and rotate logs
- Review security advisories
- Test backup restoration
- Review SSL certificate expiry
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml exec certbot certbot certificates - Review and update dependencies
- Performance analysis and optimization
- Security audit
- Penetration testing
- Disaster recovery drill
- Review and update documentation
- Review and update monitoring thresholds
- Capacity planning review
- Announce maintenance window to users
- Create database backup
./deploy.sh backup-db
- Pull latest code
git fetch origin git checkout <version-tag>
- Review changelog for breaking changes
- Update environment variables if needed
- Build new images
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml build --pull
- Apply database migrations if needed
- Deploy update
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml up -d --force-recreate
- Verify services are healthy
./deploy.sh health --ssl
- Test critical functionality
- Monitor for errors
If deployment fails:
- Stop services
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml down
- Restore database backup if needed
./deploy.sh restore-db
- Checkout previous version
git checkout <previous-version>
- Rebuild and restart
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml build docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml up -d
- Verify services are healthy
- Investigate and document the issue
- Check service status
./deploy.sh status --ssl
- Check logs for errors
./deploy.sh logs --ssl | tail -100 - Restart specific service
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml restart <service-name>
- If restart fails, check Docker daemon
systemctl status docker
- Check PostgreSQL logs
docker-compose -f docker-compose.prod.yml logs postgres
- Check database connectivity
docker-compose -f docker-compose.prod.yml exec postgres pg_isready - If corrupted, restore from backup
./deploy.sh restore-db
- Check certificate status
docker-compose -f docker-compose.prod.yml -f docker-compose.ssl.yml exec certbot certbot certificates - Manually renew if expired
./deploy.sh ssl-renew --ssl
- If renewal fails, check DNS and port 80 accessibility
- Check disk usage
df -h
- Clean up old logs
find logs/ -name "*.log" -mtime +30 -delete - Remove old Docker images
docker system prune -a --volumes
- Remove old database backups
find backups/ -name "*.sql.gz" -mtime +90 -delete
- Server Administrator: _______________
- Database Administrator: _______________
- Application Developer: _______________
- Security Contact: _______________
- Domain Registrar: _______________
- Hosting Provider: _______________
- SSL Certificate: Let's Encrypt (automated)
- Production Site: https://your-domain.com
- SSL Labs Test: https://www.ssllabs.com/ssltest/
- Docker Hub: https://hub.docker.com/
Add any deployment-specific notes, quirks, or important information here: