From 3206b10bd96f78cd1831ab9a95e91ac0a6644404 Mon Sep 17 00:00:00 2001 From: Vladimir Zagainov Date: Wed, 20 May 2026 09:41:54 +0300 Subject: [PATCH] feat: add Docker setup with multi-stage build and docker-compose - Add Dockerfile with golang:1.25-alpine build stage + alpine runtime stage - Add docker-compose.yml with naviwatcher service and data volume - Add .dockerignore for build context cleanup - Add .gitignore for build artifacts and data directory - Update plan: mark Task 7 checkboxes as complete Co-Authored-By: Claude Opus 4.6 --- .dockerignore | 10 ++++++++ .gitignore | 6 +++++ Dockerfile | 29 +++++++++++++++++++++++ docker-compose.yml | 11 +++++++++ docs/plans/2026-05-20-foundation-layer.md | 14 +++++------ 5 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..336dd5a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.gitignore +.DS_Store +naviwatcher +naviwatcher-linux +naviwatcher-mac +naviwatcher.exe +data/ +.claude/ +.ralphex/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd480e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +naviwatcher +naviwatcher-linux +naviwatcher-mac +naviwatcher.exe +data/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..79b825a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +RUN apk add --no-cache gcc musl-dev + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN CGO_ENABLED=1 GOOS=linux go build -o naviwatcher ./cmd/naviwatcher + +# Runtime stage +FROM alpine:latest + +RUN apk add --no-cache ca-certificates sqlite-libs + +WORKDIR /app + +COPY --from=builder /app/naviwatcher . + +EXPOSE 8080 + +VOLUME ["/app/data"] + +ENTRYPOINT ["./naviwatcher"] +CMD ["-config=/app/data/config.yaml"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..474105a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +services: + naviwatcher: + build: + context: . + dockerfile: Dockerfile + container_name: naviwatcher + ports: + - "8080:8080" + volumes: + - ./data:/app/data + restart: unless-stopped diff --git a/docs/plans/2026-05-20-foundation-layer.md b/docs/plans/2026-05-20-foundation-layer.md index c4156b0..0d7f1e5 100644 --- a/docs/plans/2026-05-20-foundation-layer.md +++ b/docs/plans/2026-05-20-foundation-layer.md @@ -115,13 +115,13 @@ Build the foundation layer of NaviWatcher: a greenfield Go project with zero exi - [x] run tests — must pass before task 7 ### Task 7: Docker setup -- [ ] create `Dockerfile` with multi-stage build: build stage (golang:1.21-alpine) + runtime stage (alpine:latest) -- [ ] configure Dockerfile to copy config, build binary, expose port, set entrypoint -- [ ] create `docker-compose.yml` with naviwatcher service, volume for SQLite DB and config -- [ ] create `.dockerignore` file -- [ ] verify Docker image builds: `docker compose build` -- [ ] verify container starts and health check passes (if implemented) -- [ ] run full test suite — must pass before task 8 +- [x] create `Dockerfile` with multi-stage build: build stage (golang:1.25-alpine) + runtime stage (alpine:latest) +- [x] configure Dockerfile to copy config, build binary, expose port, set entrypoint +- [x] create `docker-compose.yml` with naviwatcher service, volume for SQLite DB and config +- [x] create `.dockerignore` file +- [x] verify Docker image builds: `docker compose build` +- [x] verify container starts and health check passes (container starts, loads config, runs successfully) +- [x] run full test suite — must pass before task 8 ### Task 8: Verify acceptance criteria - [ ] verify Go module builds cleanly with `go build`