# Runbook: Deploy Hetznertreehouse

Hetznertreehouse runs ONLY on `land-shared-one` (178.104.70.180) as a Docker container.
It subscribes to `tap.hetzner.provision` and `tap.hetzner.teardown` via NATS queue group
`hetznertreehouse` to ensure exactly-once processing.

## Prerequisites

- SSH access to `root@178.104.70.180`
- Go toolchain for cross-compilation
- Git push access to `github.com/nimsforest/hetznertreehouse`

## Deploy

### 1. Build and tag

```bash
cd ~/hetznertreehouse
git tag vX.Y.Z
git push origin master --tags
# CI builds binaries and creates GitHub release
```

### 2. Cross-compile locally

```bash
cd ~/hetznertreehouse
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
  -ldflags "-X github.com/nimsforest/hetznertreehouse/internal/cli.Version=vX.Y.Z" \
  -o /tmp/hetznertreehouse-linux-amd64 ./cmd/hetznertreehouse
```

### 3. Upload and build Docker image

```bash
scp /tmp/hetznertreehouse-linux-amd64 root@178.104.70.180:/tmp/hetznertreehouse

ssh root@178.104.70.180 'cat > /tmp/Dockerfile.hetznertreehouse <<EOF
FROM alpine:3.21
RUN apk add --no-cache ca-certificates
COPY hetznertreehouse /usr/local/bin/hetznertreehouse
RUN chmod +x /usr/local/bin/hetznertreehouse
ENTRYPOINT ["hetznertreehouse", "serve"]
EOF
cd /tmp && docker build -f Dockerfile.hetznertreehouse \
  -t registry.nimsforest.com/hetznertreehouse:vX.Y.Z . && \
  docker tag registry.nimsforest.com/hetznertreehouse:vX.Y.Z \
  registry.nimsforest.com/hetznertreehouse:latest'
```

### 4. Replace container

```bash
ssh root@178.104.70.180 "docker stop hetznertreehouse && docker rm hetznertreehouse"

ssh root@178.104.70.180 'docker run -d \
  --name hetznertreehouse \
  --network host \
  --restart unless-stopped \
  -e NATS_URL=nats://127.0.0.1:4222 \
  -e HETZNER_TOKEN=<token> \
  -v /opt/hetznertreehouse/config.yaml:/root/.hetznertreehouse/config.yaml:ro \
  registry.nimsforest.com/hetznertreehouse:vX.Y.Z'
```

### 5. Verify

```bash
ssh root@178.104.70.180 "docker logs hetznertreehouse --tail 5"
# Expected:
#   [Wind] connected to nats://127.0.0.1:4222 as hetznertreehouse
#   [Wind] Catching leaves on subject tap.hetzner.provision with queue hetznertreehouse
#   [Wind] Catching leaves on subject tap.hetzner.teardown with queue hetznertreehouse
#   hetznertreehouse vX.Y.Z ready (catching tap.hetzner.*)
```

## Config

Config file on server: `/opt/hetznertreehouse/config.yaml`

```yaml
nats_url: "nats://127.0.0.1:4222"
dns_zone: "mynimsforest.com"
server_type: "cx23"
location: "nbg1"
ssh_keys:
  - main
  - neoremote
```

## Rollback

```bash
# Stop current
ssh root@178.104.70.180 "docker stop hetznertreehouse && docker rm hetznertreehouse"

# Run previous version
ssh root@178.104.70.180 'docker run -d \
  --name hetznertreehouse \
  --network host \
  --restart unless-stopped \
  -e NATS_URL=nats://127.0.0.1:4222 \
  -e HETZNER_TOKEN=<token> \
  -v /opt/hetznertreehouse/config.yaml:/root/.hetznertreehouse/config.yaml:ro \
  registry.nimsforest.com/hetznertreehouse:<previous-version>'
```

## Troubleshooting

```bash
# Check logs
ssh root@178.104.70.180 "docker logs hetznertreehouse --tail 50"

# Check NATS connectivity
ssh root@178.104.70.180 "docker exec hetznertreehouse nats sub 'tap.hetzner.>' --count 1"

# Check container status
ssh root@178.104.70.180 "docker inspect hetznertreehouse --format '{{.State.Status}}'"
```
