Phase 8 plan: add Dockerfile step (Step 8.6)
- PROJECT_PLAN.md: insert Step 8.6 (Dockerfile) before the documentation step (renumbered to 8.7); acceptance criteria cover multi-stage build, non-root runtime user, EXPOSE ports, VOLUME /data, dist/mcias.conf.docker.example, Makefile docker target, and image size target (<50 MB) - ARCHITECTURE.md §18: add Dockerfile to artifact inventory table; add Dockerfile Design section covering build stages, security properties (no shell, non-root uid 10001, TLS inside container), operator workflow, and the new Makefile docker target
This commit is contained in:
@@ -842,12 +842,14 @@ neither depends on the other.
|
||||
| Environment template | `dist/mcias.env.example` | Master key and other secrets |
|
||||
| Reference config | `dist/mcias.conf.example` | Annotated production config |
|
||||
| Dev config | `dist/mcias-dev.conf.example` | Local development defaults |
|
||||
| Docker config | `dist/mcias.conf.docker.example` | Config template for container deployment |
|
||||
| Install script | `dist/install.sh` | First-time setup on a Linux host |
|
||||
| Dockerfile | `Dockerfile` | Multi-stage image for container deployment |
|
||||
| Man page: mciassrv | `man/man1/mciassrv.1` | Server binary reference |
|
||||
| Man page: mciasctl | `man/man1/mciasctl.1` | Admin CLI reference |
|
||||
| Man page: mciasdb | `man/man1/mciasdb.1` | DB tool reference |
|
||||
| Man page: mciasgrpcctl | `man/man1/mciasgrpcctl.1` | gRPC CLI reference |
|
||||
| Makefile | `Makefile` | Build, test, lint, install, release targets |
|
||||
| Makefile | `Makefile` | Build, test, lint, install, release, docker targets |
|
||||
|
||||
### systemd Unit Design
|
||||
|
||||
@@ -889,6 +891,57 @@ The unit does not start the service on install. Operators must run
|
||||
mciasgrpcctl.1.gz
|
||||
```
|
||||
|
||||
### Dockerfile Design
|
||||
|
||||
The image uses a two-stage build to keep the runtime image small and free of
|
||||
build toolchain:
|
||||
|
||||
```
|
||||
# Stage 1 — build
|
||||
FROM golang:1.26-bookworm AS builder
|
||||
CGO_ENABLED=1 (SQLite requires cgo)
|
||||
-trimpath -ldflags="-s -w" (strip DWARF and symbol table)
|
||||
Builds: mciassrv, mciasctl, mciasdb, mciasgrpcctl
|
||||
|
||||
# Stage 2 — runtime
|
||||
FROM debian:bookworm-slim
|
||||
Installs: ca-certificates, libc6
|
||||
Copies binaries from builder stage only
|
||||
Creates uid/gid 10001 (mcias:mcias)
|
||||
EXPOSE 8443 (REST/TLS) and 9443 (gRPC/TLS)
|
||||
VOLUME /data (SQLite database mount point)
|
||||
ENTRYPOINT ["mciassrv"]
|
||||
CMD ["-config", "/etc/mcias/mcias.conf"]
|
||||
```
|
||||
|
||||
Security properties of the runtime image:
|
||||
|
||||
- No shell, no package manager, no Go toolchain — minimal attack surface
|
||||
- Non-root user (`mcias`, uid 10001) — no escalation path
|
||||
- TLS termination happens inside the container (same cert/key as bare-metal
|
||||
deployment); the operator mounts `/etc/mcias/` as a read-only volume
|
||||
containing the config file, TLS cert, and TLS key
|
||||
- The SQLite database is on a named volume at `/data`; the operator is
|
||||
responsible for backup; no network storage is assumed
|
||||
|
||||
Operator workflow:
|
||||
|
||||
```
|
||||
# Build image
|
||||
docker build -t mcias:$(git describe --tags --always) .
|
||||
|
||||
# Run (example)
|
||||
docker run -d \
|
||||
--name mcias \
|
||||
-v /path/to/config:/etc/mcias:ro \
|
||||
-v mcias-data:/data \
|
||||
-p 8443:8443 \
|
||||
-p 9443:9443 \
|
||||
mcias:latest
|
||||
```
|
||||
|
||||
The Makefile `docker` target automates the build step with the version tag.
|
||||
|
||||
### Makefile Targets
|
||||
|
||||
| Target | Action |
|
||||
@@ -899,6 +952,7 @@ The unit does not start the service on install. Operators must run
|
||||
| `generate` | `go generate ./...` (re-generates proto stubs) |
|
||||
| `man` | Build man pages; compress to `.gz` in `man/` |
|
||||
| `install` | Run `dist/install.sh` |
|
||||
| `docker` | `docker build -t mcias:$(VERSION) .` |
|
||||
| `clean` | Remove `bin/`, `gen/`, compressed man pages |
|
||||
| `dist` | Cross-compile release tarballs for linux/amd64 and linux/arm64 |
|
||||
|
||||
|
||||
@@ -458,12 +458,36 @@ See ARCHITECTURE.md §18 for full design rationale and artifact inventory.
|
||||
- `make build` works from a clean checkout after `go mod download`
|
||||
- Tests: `make build` produces binaries; `make test` passes; `make lint` passes
|
||||
|
||||
### Step 8.6: Documentation
|
||||
### Step 8.6: Dockerfile
|
||||
**Acceptance criteria:**
|
||||
- `README.md` updated with: quick-start section referencing the install script,
|
||||
links to man pages, configuration walkthrough
|
||||
- ARCHITECTURE.md §18 written (operational artifact inventory, file locations,
|
||||
systemd integration notes)
|
||||
- `Dockerfile` at repository root using a multi-stage build:
|
||||
- Build stage: `golang:1.26-bookworm` — compiles all four binaries with
|
||||
`CGO_ENABLED=1` (required for SQLite via `modernc.org/sqlite`) and
|
||||
`-trimpath -ldflags="-s -w"` to strip debug info
|
||||
- Runtime stage: `debian:bookworm-slim` — installs only `ca-certificates`
|
||||
and `libc6`; copies binaries from the build stage
|
||||
- Final image runs as a non-root user (`uid=10001`, `gid=10001`; named `mcias`)
|
||||
- `EXPOSE 8443` (REST) and `EXPOSE 9443` (gRPC); both are overridable via env
|
||||
- `VOLUME /data` — operator mounts the SQLite database here
|
||||
- `ENTRYPOINT ["mciassrv"]` with `CMD ["-config", "/etc/mcias/mcias.conf"]`
|
||||
- Image must not contain the Go toolchain, source code, or build cache
|
||||
- `dist/mcias.conf.docker.example` — config template suitable for container
|
||||
deployment: `listen_addr = "0.0.0.0:8443"`, `grpc_addr = "0.0.0.0:9443"`,
|
||||
`db_path = "/data/mcias.db"`, TLS cert/key paths under `/etc/mcias/`
|
||||
- `Makefile` gains a `docker` target: `docker build -t mcias:$(VERSION) .`
|
||||
where `VERSION` defaults to the output of `git describe --tags --always`
|
||||
- Tests:
|
||||
- `docker build .` completes without error (run in CI if Docker available;
|
||||
skip gracefully if not)
|
||||
- `docker run --rm mcias:latest mciassrv --help` exits 0
|
||||
- Image size documented in PROGRESS.md (target: under 50 MB)
|
||||
|
||||
### Step 8.7: Documentation
|
||||
**Acceptance criteria:**
|
||||
- `README.md` updated with: quick-start section referencing both the install
|
||||
script and the Docker image, links to man pages, configuration walkthrough
|
||||
- ARCHITECTURE.md §18 updated to include the Dockerfile in the artifact
|
||||
inventory and document the container deployment model
|
||||
- `PROGRESS.md` updated to reflect Phase 8 complete
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user