Rebuildable infrastructure project for restoring a Dockerized Sky control dashboard onto a fresh Hetzner VPS with Terraform and Ansible, then attaching a small observability stack beside it.
This project is intentionally structured around one operational goal:
- destroy the environment
- recreate it from code
- restore application state from backup
- verify the remote control path still works
- Terraform for infrastructure provisioning
- Ansible for server bootstrap and application restore
- Docker Compose for application runtime
- Tailscale for private connectivity to remote clients
- Prometheus, Loki, Promtail, Grafana, node-exporter, and cAdvisor for observability
- backup-and-restore workflow validation
High-level flow:
- Terraform creates a Hetzner server and firewall.
- Terraform generates Ansible handoff files.
- Ansible configures Ubuntu, Docker, and Tailscale.
- Ansible restores the saved
sky-dashboardstate. - Ansible starts:
sky-dashboardgrafanalokipromtailprometheusnode-exportercadvisor
- The rebuilt host connects to remote Sky clients over Tailscale.
terraform/Hetzner infrastructure definitions.ansible/Server configuration and restore playbook.apps/sky-dashboard/Maintained application source.apps/observability/Docker Compose monitoring stack.backups/Placeholder directory for private restore artifacts.docs/Runbook and restore notes.
This repository is a GitHub-safe copy.
It intentionally excludes:
- real API tokens
- real passwords
- Terraform state
- generated inventory files
- private backup archives
- live SQLite database files
Use these template files as your starting point:
terraform/terraform.tfvars.exampleansible/group_vars/all.yml.exampleansible/inventory.ini.example
See SECRETS.md for the local-only files that should never be committed.
From the repository root:
cd terraform
terraform init
terraform apply
cd ../ansible
ansible-galaxy collection install community.general community.docker ansible.posix
ansible-playbook -i inventory.ini playbook.ymlTerraform:
- creates the server
- creates the firewall
- generates:
ansible/inventory.iniansible/group_vars/sky_dashboard.yml
Ansible:
- updates Ubuntu
- installs Docker
- installs Tailscale
- joins the tailnet
- restores the Sky Dashboard backup
- overlays the maintained app source
- starts the application and observability containers
After deployment, verify:
ssh root@NEW_SERVER_IP
tailscale status
docker compose -f /opt/docker/sky-dashboard/docker-compose.yml ps
docker compose -f /opt/docker/observability/docker-compose.yml ps
curl http://127.0.0.1:3010
tailscale ping 100.120.120.88
curl http://100.120.120.88:3000/Then test in a browser:
http://NEW_SERVER_IP:3010http://NEW_SERVER_IP:3000
- The live working project keeps private restore artifacts locally and is not the same as this sanitized GitHub copy.
- Grafana provisioning was intentionally simplified during troubleshooting to keep the public version safe and easier to understand.
- This repository is best read as an infrastructure automation case study, not as a plug-and-play public deployment without private inputs.