Phase 01: Foundation - 2 plans in 2 waves - Plan 01: Go project + Dockerfile (wave 1) - Plan 02: Dev environment + verification (wave 2) - Ready for execution Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.7 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-foundation | 01 | execute | 1 |
|
true |
|
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.
<execution_context> @/home/acty/.claude/get-shit-done/workflows/execute-plan.md @/home/acty/.claude/get-shit-done/templates/summary.md </execution_context>
@.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)-
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
-
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
-
Run
go mod tidyto 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)
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"]
- 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
Image should build and be under 150MB.
docker build -f docker/Dockerfile -t pirate-station:test . && docker images pirate-station:test --format "{{.Size}}"- docker/Dockerfile exists with multi-stage build
- .dockerignore excludes non-essential files
- Image builds successfully
- Image size under 150MB (debian slim + Go binary)
<success_criteria>
- 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) </success_criteria>