# Builder stage FROM golang:1.26-alpine AS builder # Install C compiler and musl headers required for CGO + go-sqlite3 RUN apk add --no-cache gcc musl-dev # Enable CGO (required by github.com/mattn/go-sqlite3) ENV CGO_ENABLED=1 # Cache build and module caches for faster rebuilds ENV GOCACHE=/go-cache ENV GOMODCACHE=/go/pkg/mod # Set working directory WORKDIR /build # Copy dependency manifests first and download modules (cache layer) COPY go.mod go.sum ./ RUN go mod download # Copy the rest of the source code COPY . . # Build a static-ish binary (C code for SQLite is compiled in; musl libc stays dynamic) RUN go build -o /app/server ./cmd/server/ # Runtime stage FROM alpine:3.20 # ca-certificates for TLS, tzdata for timezone support RUN apk add --no-cache ca-certificates tzdata # Create non-root user for better security RUN addgroup -S app && adduser -S app -G app # Set working directory WORKDIR /app # Copy the binary from the builder stage COPY --from=builder /app/server /app/server # Copy static and template assets from the project source COPY --from=builder /build/static /app/static COPY --from=builder /build/templates /app/templates # Ensure the app user owns the working dir (DB file created here at runtime) RUN chown -R app:app /app USER app # Expose the HTTP port EXPOSE 8080 # Default command CMD ["./server", "-addr", ":8080"]