This directory contains Butane configuration examples for Flatcar Container Linux on Hetzner Cloud.
| Example | Description | Use Case |
|---|---|---|
| basic.yaml | Minimal Flatcar setup | Base system, manual configuration |
| docker-container.yaml | Docker containers as systemd services | Single container workloads |
| docker-compose.yaml | Docker Compose stack | Multi-container applications |
| k3s.yaml | Single K3s server | Development, small workloads |
| k3s-internal.yaml | K3s in private network | Private cluster setup |
These configs can be used directly with Packer:
# Build with custom config
packer build -var "user_data=$(cat examples/k3s.yaml)" .Use the ct provider to transpile Butane to Ignition:
data "ct_config" "example" {
content = file("${path.module}/examples/k3s.yaml")
strict = true
}Transpile with the butane CLI:
# Install butane
brew install butane
# Transpile to Ignition
butane --strict < examples/k3s.yaml > ignition.jsonMinimal Flatcar setup with SSH access and hostname from Hetzner metadata.
Features:
- SSH key configuration
- Hostname from metadata API
Use for:
- Base system setup
- Manual service configuration
- Testing
Run Docker containers as systemd services.
Features:
- Docker enabled
- Nginx example container
- PostgreSQL example (disabled)
- Traefik reverse proxy example (disabled)
- Registry authentication template
Use for:
- Single container deployments
- Simple web applications
- Database servers
- Reverse proxies
Example services:
# Start Nginx
sudo systemctl start nginx-container
# Enable PostgreSQL
sudo systemctl enable --now postgres-container
# Check status
sudo systemctl status nginx-containerRun a complete Docker Compose stack.
Features:
- Docker Compose setup
- Example stack (Nginx + Redis + PostgreSQL)
- Daily automatic updates
- Persistent volumes
Use for:
- Multi-container applications
- Full application stacks
- Development environments
Manage the stack:
# Check status
docker-compose -f /opt/docker-compose.yml ps
# View logs
docker-compose -f /opt/docker-compose.yml logs -f
# Restart services
sudo systemctl restart docker-compose-appSingle K3s server with automatic installation.
Features:
- K3s installed on first boot
- Daily automatic updates
- Docker/Containerd disabled (K3s brings its own)
- Optional cluster mode
Use for:
- Development clusters
- Small production workloads
- Single-node Kubernetes
Access the cluster:
# Get kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
# Check nodes
kubectl get nodesEnable cluster mode: Uncomment in the file:
Environment="K3S_TOKEN=your-secret-token"
Environment="INSTALL_K3S_EXEC=server --cluster-init"K3s server in a private network with custom routing.
Features:
- Private network configuration
- Custom routing setup
- K3s bound to private interface
- Flannel configuration for private networks
Use for:
- Private clusters
- Multi-server setups with private networking
- High-security deployments
Network setup:
- Bind address:
192.168.240.2 - Gateway:
192.168.240.1 - DNS: Cloudflare (1.1.1.1, 1.0.0.1)
Replace the placeholder in each file:
ssh_authorized_keys:
- ssh-rsa AAAAB3... user@example.com # Your actual SSH public keyFor private images, add credentials to docker-container.yaml:
- path: /home/core/.docker/config.json
mode: 0600
user:
name: core
contents:
inline: |
{
"auths": {
"registry.example.com": {
"auth": "base64-encoded-username:password"
}
}
}Generate auth token:
echo -n "username:password" | base64Add environment variables to services:
ExecStart=/usr/bin/docker run \
-e DATABASE_URL=postgres://... \
-e API_KEY=secret \
my-app:latest- Always use SSH keys - Never use passwords
- Pin container versions - Use
nginx:1.25-alpineinstead ofnginx:latest - Use volumes for data - Keep data persistent across restarts
- Enable automatic updates - For security patches
- Test configurations - Transpile with
butane --strictbefore deploying - Use secrets management - Don't hardcode passwords in configs
sudo systemctl status service-namesudo journalctl -u service-name -fsudo systemctl restart service-namedocker logs -f container-nameMIT