hatch-surf/DEPLOYMENT.md
Chris Anderson 475fd95a59
Some checks are pending
CI / go (push) Waiting to run
CI / docker (push) Waiting to run
CI / lint-go (push) Waiting to run
CI / lint-docs (push) Waiting to run
CI / check-paperclip (push) Waiting to run
Update deployment: Go API backend with Docker Compose
- Update Dockerfile to golang:1.26-alpine (matching go.mod)
- Update deploy.sh for Docker Compose workflow
- Rewrite DEPLOYMENT.md for new API architecture
- Add env vars for face service and Redis configuration
2026-06-26 05:55:56 +02:00

5.8 KiB

Hatch API — Deployment Guide

Overview

The Hatch API (hatch.surf) is a Go backend deployed via Docker Compose on the production server.

Key principle: All changes MUST go through the git repository and automated deployment. Never edit files directly on the server.


Repository

Location: /home/nara/apps/web/

Git Remotes:

  • githubel-foundation/hatch-surf (Gitea, source of truth)
  • originel-foundation/hatch-surf (Gitea push-mirror)

Structure:

cmd/hatch/              # Go server entrypoint
internal/               # Go packages (handler, store, face, etc.)
Dockerfile              # Multi-stage Docker build (Go → scratch)
docker-compose.yml      # Container orchestration (hatch + caddy)
Caddyfile               # Caddy reverse proxy config
deploy.sh               # Deployment script

Deployment Flow

  1. Merge PR to main
  2. Gitea webhook triggers gitea-webhook.py
  3. Script runs deploy.sh automatically

Manual

cd /home/nara/apps/web
./deploy.sh

What deploy.sh does:

  1. git pull github main — fetches latest from GitHub (source of truth)
  2. git push origin main — syncs to Gitea (push-mirror)
  3. docker compose down — stops current containers
  4. docker compose build hatch — rebuilds the Go binary in a multi-stage build
  5. docker compose --profile with-caddy up -d — starts hatch + caddy
  6. Verifies health endpoint responds 200

Docker Setup

Services:

Service Image Port Purpose
hatch web-hatch 8080 Go API server
caddy caddy:2-alpine 80/443 Reverse proxy + TLS

Profiles:

  • Default: hatch only (API on port 8080)
  • with-caddy: hatch + caddy (full HTTPS via Let's Encrypt)

Check status:

docker compose ps
docker compose logs hatch
docker compose logs caddy

Environment Variables

Configure in .env or pass to Docker Compose:

Variable Default Description
HATCH_HOSTNAME localhost Public hostname for TLS cert
HATCH_BASE_URL http://localhost Base URL for SSE and self-references
FACE_SERVICE_ENABLED false Enable AWS Rekognition face search
AWS_REGION us-east-1 AWS region for Rekognition
REKOGNITION_COLLECTION hatch-faces Rekognition collection ID
REDIS_URL Redis URL (optional, for caching)

Making Changes

1. Edit Go source

cd /home/nara/apps/web
vim cmd/hatch/main.go       # Server entrypoint
vim internal/handler/       # HTTP handlers
vim internal/face/          # Face detection service
vim internal/store/         # Database layer

2. Build and test locally

go build ./cmd/hatch/
go test ./...

3. Commit and push

git add .
git commit -m "Description of changes"
git push origin main

4. Deploy

Either wait for webhook or run manually:

./deploy.sh

5. Verify

curl -s http://localhost:8080/healthz
curl -s http://localhost:8080/readyz

Common Mistakes to Avoid

DON'T: Edit files directly inside the Docker container
DON'T: Commit without testing
DON'T: Use go run in production

DO: Test with go test ./... before committing
DO: Use docker compose build for production builds
DO: Check health endpoints after deployment


Rollback

If a deployment causes issues:

cd /home/nara/apps/web

# Revert to previous version
git revert HEAD
git push origin main

# Redeploy
./deploy.sh

API Endpoints

Method Path Description
GET /healthz Liveness probe
GET /readyz Readiness probe (checks DB)
GET /api/v1/spaces List public spaces
POST /api/v1/spaces Create a space
GET /api/v1/spaces/{slug} Get space by slug
POST /api/v1/spaces/{slug}/photos Upload photo to space
POST /api/v1/face/search Search faces by image
GET /e/{endpointID} Inspect captured requests
GET /e/{endpointID}/events SSE stream for live updates

Troubleshooting

Container not starting:

docker compose logs hatch
docker compose logs caddy

Health check failing:

curl -v http://localhost:8080/healthz
docker compose exec hatch /bin/hatch  # Check binary exists

Database issues:

# SQLite database is persisted in a Docker volume
docker volume ls | grep hatch-data
docker run --rm -v hatch-data:/data alpine ls -la /data/

Port conflict:

sudo lsof -i :8080
# Kill conflicting process or change port in docker-compose.yml

Integration Tests

Integration tests require AWS credentials (build tag: integration):

export AWS_REGION=us-east-1
export REKOGNITION_COLLECTION=hatch-faces-test
go test -tags=integration ./internal/face/... -v

Performance benchmarks (build tag: performance):

go test -tags=performance -bench=. ./internal/face/...

Contact