--- phase: 01-foundation plan: 01 type: execute wave: 1 depends_on: [] files_modified: - go.mod - go.sum - cmd/server/main.go - internal/health/handler.go - docker/Dockerfile - .dockerignore autonomous: true must_haves: truths: - "Go module initializes without errors" - "Go server compiles to a single binary" - "Docker image builds successfully for linux/amd64" - "Built image is less than 150MB (debian slim + static binary)" artifacts: - path: "go.mod" provides: "Go module definition" contains: "module" - path: "cmd/server/main.go" provides: "Application entry point" contains: "func main()" - path: "internal/health/handler.go" provides: "Health check endpoint handler" contains: "func Handler" - path: "docker/Dockerfile" provides: "Multi-stage build definition" contains: "FROM golang" - path: ".dockerignore" provides: "Build context exclusions" contains: ".git" key_links: - from: "cmd/server/main.go" to: "internal/health" via: "import statement" pattern: "internal/health" - from: "docker/Dockerfile" to: "cmd/server" via: "go build command" pattern: "go build.*cmd/server" --- Create Go project structure and multi-stage Dockerfile for isolated container builds. Purpose: Establishes the foundational artifacts needed to build and run the Pirate Station backend. This plan creates the Go module with a minimal HTTP server and the multi-stage Dockerfile that produces a portable ARM64/x86_64 binary. Output: Buildable Go project with Dockerfile that produces a slim container image. @/home/acty/.claude/get-shit-done/workflows/execute-plan.md @/home/acty/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/01-foundation/01-CONTEXT.md @.planning/phases/01-foundation/01-RESEARCH.md Task 1: Initialize Go project with HTTP server go.mod go.sum cmd/server/main.go internal/health/handler.go 1. Initialize Go module: ```bash go mod init github.com/acty/pirate-station ``` (Use github.com path even though pushing to Gitea - conventional Go module naming) 2. Create cmd/server/main.go with: - Import net/http and internal/health - http.HandleFunc for "/" returning "Pirate Station API" - http.HandleFunc for "/health" using health.Handler - ListenAndServe on :32768 - log.Fatal on server error - Log startup message with port number 3. Create internal/health/handler.go with: - package health - Handler(w http.ResponseWriter, r *http.Request) function - Check os.Stat("/data") - return 503 if not exists - Return 200 with {"status":"healthy"} JSON if /data exists - Return 503 with {"status":"unhealthy","reason":"data volume not mounted"} if not 4. Run `go mod tidy` to create go.sum Keep it minimal - no frameworks, no external dependencies, pure stdlib. ```bash go build -o /tmp/server ./cmd/server && echo "Build successful" ``` - go.mod exists with module path - cmd/server/main.go compiles - internal/health/handler.go provides health check - No external dependencies (only stdlib) Task 2: Create multi-stage Dockerfile docker/Dockerfile .dockerignore 1. Create docker/Dockerfile with multi-stage build: Build stage: - FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS builder - WORKDIR /build - COPY go.mod go.sum ./ (cache dependencies separately) - RUN go mod download - COPY . . - ARG TARGETOS TARGETARCH - RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-w -s" -o /server ./cmd/server Runtime stage: - FROM debian:bookworm-slim - RUN useradd -u 10001 -m appuser - USER appuser - COPY --from=builder /server /usr/local/bin/server - VOLUME /data - EXPOSE 32768 - CMD ["server"] 2. Create .dockerignore at project root: ``` .git .gitignore README.md *.md .env .env.local .DS_Store .air.toml docker-compose.yml .planning/ tmp/ ``` Key points: - Use --platform=$BUILDPLATFORM for native build speed - CGO_ENABLED=0 for static binary (no libc dependency) - -ldflags="-w -s" strips debug symbols (smaller binary) - Non-root user (appuser) for security - VOLUME /data declares mount point - Port 32768 as per user decision ```bash docker build -f docker/Dockerfile -t pirate-station:test . && docker images pirate-station:test --format "{{.Size}}" ``` Image should build and be under 150MB. - docker/Dockerfile exists with multi-stage build - .dockerignore excludes non-essential files - Image builds successfully - Image size under 150MB (debian slim + Go binary) 1. Go project compiles: `go build ./...` 2. Docker image builds: `docker build -f docker/Dockerfile -t pirate-station:test .` 3. Container starts: `docker run --rm -v /tmp/test-data:/data pirate-station:test &` then `curl localhost:32768/health` 4. Container cannot access host filesystem outside /data mount - Go module initialized with github.com/acty/pirate-station - HTTP server listens on :32768 - /health endpoint returns JSON status - Dockerfile produces working image under 150MB - Image runs as non-root user - No external Go dependencies (stdlib only) After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`