This plan outlines the migration of the Torrust Tracker demo from Digital Ocean to Hetzner infrastructure. The migration prioritizes ease of updates over performance by maintaining Docker-based deployments, and follows a complete local development and testing approach before deploying to production.
- Docker-first approach: Continue using Docker for the tracker to simplify updates (just pull new images)
- Complete local testing: Finish all development and testing locally before creating any Hetzner VMs
- MySQL by default: Replace SQLite with MySQL for better production characteristics
- 12-Factor App compliance: Refactor the entire repository to follow modern deployment practices
Objective: Replace SQLite with MySQL as the default database
- Add MySQL service to
docker-compose.yaml - Update tracker configuration (
tracker.toml) to use MySQL connection - Create MySQL initialization scripts/schema
- Update environment variable templates (
.env.production) - Update documentation for MySQL setup
- Deploy locally using
make apply - Verify MySQL service starts successfully
- Make test announce request
- Confirm download counter increases in MySQL
torrentstable - Test tracker restart with persistent MySQL data
Deliverable: Working local deployment with MySQL backend
Objective: Refactor repository to follow 12-Factor App methodology
Reference: See detailed plan in infrastructure/docs/refactoring/twelve-factor-refactor/
- Configuration via environment: Move all config to environment variables
- Dependency isolation: Explicit dependency declaration in Docker
- Stateless processes: Ensure tracker processes are stateless
- Port binding: Clean service port configuration
- Logs as streams: Structured logging to stdout/stderr
- Environment parity: Dev/staging/prod environment consistency
- Implement configuration refactoring (see phase-1-implementation.md)
- Update Docker configurations
- Refactor environment variable management
- Update deployment scripts
- Update documentation
Deliverable: 12-Factor compliant repository structure
Objective: Fully automate tracker deployment including SSL certificates
- ✅ VM provisioning via cloud-init
- ✅ Basic app setup (copy files,
.envconfig,docker compose up) - ❌ SSL certificate generation
- ❌ Crontab setup for renewals
- ❌ Production hardening steps
- Automate SSL certificate generation with Certbot
- Set up automatic certificate renewal crontabs
- Implement production hardening automation
- Create comprehensive deployment validation script
- Handle edge cases and error recovery
- Integrate with existing cloud-init setup
- If Certbot automation requires manual interaction, document as the only manual step
- Follow production setup guide: https://torrust.com/blog/deploying-torrust-to-production
Deliverable: One-command deployment to production-ready state
Objective: Add Hetzner Cloud provider support and validate complete deployment
- Research and add Hetzner Cloud OpenTofu provider
- Create Hetzner-specific Terraform configurations
- Implement Hetzner cloud-init adaptations
- Test complete deployment pipeline on Hetzner
- Configure provider-level firewall (optional, complementing VM firewall)
- Validate tracker accessibility via IP (HTTP)
- VM firewall via cloud-init: ✅ Required
- Provider firewall: 🤔 Optional additional security layer
- Deploy test VM on Hetzner
- Verify all services start correctly
- Test tracker functionality (announce, scrape)
- Confirm firewall rules work correctly
- Performance and connectivity testing
Deliverable: Working Hetzner deployment with IP access
Objective: Migrate existing tracker data from Digital Ocean SQLite to Hetzner MySQL
- Export existing SQLite data from Digital Ocean instance
- Create data transformation scripts (SQLite → MySQL)
- Import data to new MySQL instance
- Validate data integrity and completeness
- Test tracker with migrated data
Note: This step is optional and can be skipped for a fresh start
Objective: Manually configure Grafana for monitoring the tracker.
- Log in to Grafana at
http://localhost:3100/with default credentials (admin/admin). - Change the default admin password.
- Configure the Prometheus data source to poll the tracker's API metrics endpoint.
- Optional: Import pre-built dashboards from the repository to visualize tracker metrics.
Note: An issue will be opened with more details when work on this phase begins.
Deliverable: A configured Grafana instance with a Prometheus data source and dashboards.
Objective: Comprehensive testing of the new Hetzner deployment
- Functional Testing: All tracker endpoints work correctly
- Performance Testing: Announce/scrape response times
- Integration Testing: Index ↔ Tracker communication
- Monitoring: Grafana dashboards show correct metrics
- SSL Testing: HTTPS certificate generation and renewal
- Backup Testing: Database backup and restore procedures
- Fresh torrent announce and scrape
- High-load announce testing
- Tracker restart with data persistence
- Certificate renewal simulation
- Firewall rule validation
Deliverable: Fully validated production deployment
Objective: Switch production traffic to Hetzner infrastructure
- Consider static IP allocation on Hetzner
- Prepare DNS change procedures
- Document rollback plan
- Update DNS records to point to new Hetzner IP
- Update Digital Ocean index configuration:
- Change tracker resolution from Docker service name to public domain
- Index will access tracker via public API instead of internal Docker network
- Monitor traffic and error rates
- Validate end-to-end functionality
- Monitor system stability for 24-48 hours
- Verify certificate auto-renewal works
- Confirm backup procedures
- Update documentation with new procedures
Deliverable: Production traffic on Hetzner infrastructure
Currently hardcoded in cloud-init:
- Number of tracker instances (e.g., 2 UDP trackers on ports 6868, 6969)
- Firewall port configurations
- Service scaling parameters
Future Enhancement: Inject dynamic configuration via template variables
This repository serves as a template for users deploying their own trackers. Current hardcoded configurations can be manually adapted, but future work could make this more dynamic.
- Keep Digital Ocean instance running until Hetzner deployment is fully validated
- Maintain DNS rollback capability
- Document emergency procedures
- All changes tested locally before Hetzner deployment
- Staged rollout with validation at each phase
- Comprehensive testing before DNS switch
- Tracker accessible via HTTPS on Hetzner
- MySQL database working with persistent data
- Grafana monitoring functional
- SSL certificates auto-renewing
- Index successfully communicating with tracker
- Performance equivalent to or better than Digital Ocean
- 12-Factor App compliance achieved
- One-command deployment working