From e8c791dcdeb644f9307e791f71c48d428ec0e345 Mon Sep 17 00:00:00 2001 From: Phillip Michelsen Date: Mon, 13 Jul 2026 01:53:09 +0800 Subject: [PATCH] Simplify and validate Docker deployment --- Dockerfile | 27 +++++++++++++++++++-------- README.md | 13 ++++++------- compose.yml | 22 +++------------------- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/Dockerfile b/Dockerfile index 72c656e..a5cdfa0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,28 @@ FROM golang:1.26 AS build + WORKDIR /src COPY go.mod ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /preface-tools ./cmd/preface-tools -RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /healthcheck ./cmd/healthcheck +RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/preface-tools ./cmd/preface-tools +RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/healthcheck ./cmd/healthcheck + +FROM alpine:3.21 + +RUN apk add --no-cache ca-certificates \ + && addgroup -S -g 10001 preface \ + && adduser -S -D -H -u 10001 -G preface preface -FROM gcr.io/distroless/static-debian12:nonroot WORKDIR /app -COPY --from=build /preface-tools /usr/local/bin/preface-tools -COPY --from=build /healthcheck /usr/local/bin/healthcheck -COPY --from=build /src/prompts /app/prompts -VOLUME ["/app/data"] +COPY --from=build /out/preface-tools /usr/local/bin/preface-tools +COPY --from=build /out/healthcheck /usr/local/bin/healthcheck +COPY --chown=preface:preface prompts /app/prompts +RUN mkdir -p /app/data/comic-animator/uploads /app/data/comic-animator/outputs \ + && chown -R preface:preface /app/data + +USER preface EXPOSE 8080 -HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 CMD ["/usr/local/bin/healthcheck", "http://127.0.0.1:8080/readyz"] +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD ["/usr/local/bin/healthcheck", "http://127.0.0.1:8080/readyz"] + ENTRYPOINT ["/usr/local/bin/preface-tools"] diff --git a/README.md b/README.md index 3c4b5f8..8c23708 100644 --- a/README.md +++ b/README.md @@ -149,14 +149,13 @@ running process immediately. docker compose logs -f preface-tools ``` -4. Put a TLS reverse proxy in front of `127.0.0.1:8080`. The Compose file binds - only to loopback deliberately. If TLS is terminated by an ingress on another - host, adjust the `ports` mapping or use an external Docker network while - keeping the application container otherwise private. +4. Put a TLS reverse proxy in front of port `8080`. The Compose file publishes + that port on the host. Restrict it with the host firewall if the server is on + an untrusted network, or change the mapping to `127.0.0.1:8080:8080` after + confirming loopback Docker forwarding works on the deployment host. -The container runs as a non-root user with all Linux capabilities dropped, a -read-only root filesystem, `no-new-privileges`, and a named volume for runtime -data. It exposes: +The container runs as a dedicated non-root user and stores runtime data in a +named volume. It exposes: - `GET /healthz` for liveness; - `GET /readyz` for readiness. diff --git a/compose.yml b/compose.yml index c064be5..c901d46 100644 --- a/compose.yml +++ b/compose.yml @@ -1,12 +1,9 @@ services: preface-tools: - build: - context: . + build: . image: preface-tools:local restart: unless-stopped - init: true - env_file: - - .env + env_file: .env environment: APP_ENV: production HTTP_ADDRESS: :8080 @@ -14,23 +11,10 @@ services: COMIC_ANIMATOR_UPLOAD_DIR: /app/data/comic-animator/uploads COMIC_ANIMATOR_OUTPUT_DIR: /app/data/comic-animator/outputs ports: - - "127.0.0.1:8080:8080" + - "8080:8080" volumes: - preface-data:/app/data - ./prompts:/app/prompts:ro - read_only: true - tmpfs: - - /tmp:size=64m,mode=1777 - cap_drop: - - ALL - security_opt: - - no-new-privileges:true - healthcheck: - test: ["CMD", "/usr/local/bin/healthcheck", "http://127.0.0.1:8080/readyz"] - interval: 30s - timeout: 3s - start_period: 10s - retries: 3 volumes: preface-data: