This Terraform module deploys a Restate server on Hetzner Cloud with Tailscale integration.
This module creates:
- A Hetzner Cloud server with Ubuntu 22.04
- Tailscale integration for secure networking
- Docker Compose setup with Restate and etcd
- Automated deployment and health checking
-
Copy the example configuration:
cp examples/basic/terraform.tfvars.example examples/basic/terraform.tfvars
-
Edit
examples/basic/terraform.tfvarswith your values:- Hetzner Cloud API token
- Tailscale API key and tailnet
- SSH key name and path
- Server configuration
-
Deploy:
cd examples/basic terraform init terraform plan terraform apply
hcloud_token: Hetzner Cloud API tokentailscale_api_key: Tailscale API keytailscale_tailnet: Your Tailscale tailnet namessh_key_name: SSH key name in Hetzner Cloudserver_name: Name for the server instanceuser_name: Administrative user nameprivate_ssh_key: Path to SSH private key
deploy_docker_compose: Whether to deploy Docker Compose (default: true)docker_compose_path: Deployment path on server (default: "/opt/restate")ssh_private_key_path: SSH private key path (default: "~/.ssh/id_rsa")ingress_endpoint: The ingress endpoint URL for Restate server (default: "http://{server_name}:8080")
Problem: Restate server fails to connect to etcd metadata store.
Symptoms:
- Logs show "Failed to join the cluster 'single-node'"
- Connection errors to
127.0.0.1:5122or similar - Server keeps restarting
Solution: The module includes several fixes:
- Proper service dependency management
- Health checks for etcd before starting Restate
- Explicit configuration file to override defaults
- Extended startup timeouts
A troubleshooting script is automatically deployed to /opt/restate/troubleshoot-restate.sh:
# Check service status
./troubleshoot-restate.sh status
# View recent logs
./troubleshoot-restate.sh logs
# Check service health
./troubleshoot-restate.sh health
# Restart services
./troubleshoot-restate.sh restart
# Run all checks
./troubleshoot-restate.sh full
# Attempt automatic fix
./troubleshoot-restate.sh fixIf the automatic fixes don't work:
-
Check Docker Compose status:
cd /opt/restate sudo docker compose ps -
View logs:
sudo docker compose logs etcd sudo docker compose logs restate
-
Restart services:
sudo docker compose down sudo docker compose up -d
-
Check etcd health:
sudo docker compose exec etcd etcdctl --endpoints=http://localhost:2379 endpoint health -
Check Restate health:
curl http://localhost:9070/health
If services can't communicate:
-
Check Docker network:
sudo docker network ls sudo docker network inspect restate_restate-network
-
Verify container connectivity:
sudo docker compose exec restate ping etcd
The module deploys a custom restate.toml configuration file that:
- Explicitly sets the etcd address
- Configures proper timeouts
- Sets cluster parameters
- Configures the ingress endpoint based on server name
If you need to modify the configuration:
- Edit
/opt/restate/restate.toml - Restart services:
sudo docker compose restart restate
┌─────────────────┐ ┌─────────────────┐
│ Restate │ │ etcd │
│ Server │◄──►│ (Metadata) │
│ :8080, :9070 │ │ :2379 │
└─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Tailscale │
│ Network │
└─────────────────┘
- Restate Server: Main application server
- Port 8080: Ingress API
- Port 9070: Admin API
- etcd: Metadata store for cluster coordination
- Port 2379: Client API
- Tailscale: Secure networking overlay
docker-compose.yml: Service definitionsrestate.toml: Restate configurationtroubleshoot-restate.sh: Troubleshooting script
- Server is accessible via Tailscale network
- SSH access with key-based authentication
- Docker containers run with restart policies
- Health checks ensure service availability
Check service health:
# Restate health endpoint
curl http://your-server:9070/health
# Via Tailscale
curl http://your-tailscale-hostname:9070/healthFor issues:
- Run the troubleshooting script
- Check the logs
- Verify network connectivity
- Review the configuration files
This module is provided as-is for educational and development purposes.