61 lines
2.5 KiB
Docker
61 lines
2.5 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# ---- deps: module download, cached until go.mod/go.sum change ----------------
|
|
FROM golang:1.25-alpine AS deps
|
|
WORKDIR /src
|
|
COPY go.mod go.sum ./
|
|
RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
|
|
|
# ---- test: `docker build --target test .` runs the test suite ----------------
|
|
FROM deps AS test
|
|
COPY . .
|
|
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \
|
|
go vet ./... && go test ./...
|
|
|
|
# ---- manual: an on-demand renderer for the PDF manual -----------------------
|
|
# Not part of the app image, so deploying the app never waits for it. Running
|
|
# this image renders docs/manual.md to /out/manual.pdf (typeset with WeasyPrint,
|
|
# then coffee-stained, hole-punched and photocopied; see docs/pdf/). The file is
|
|
# replaced atomically. Use scripts/render-manual.sh (compose volume) or
|
|
# scripts/manual-pdf.sh (a local file).
|
|
FROM alpine:3.20 AS manual
|
|
RUN apk add --no-cache weasyprint py3-markdown py3-pillow py3-numpy font-liberation poppler-utils
|
|
WORKDIR /manual
|
|
COPY docs/pdf ./pdf
|
|
COPY docs/manual.md .
|
|
ENTRYPOINT ["python3", "pdf/render.py", "manual.md", "/out/manual.pdf"]
|
|
|
|
# ---- build: static binaries (SQLite and Postgres drivers are pure Go) --------
|
|
FROM deps AS build
|
|
COPY . .
|
|
ENV CGO_ENABLED=0
|
|
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \
|
|
go build -trimpath -ldflags="-s -w" -o /out/ ./cmd/server ./cmd/daily ./cmd/asm
|
|
|
|
# ---- final: small runtime image ----------------------------------------------
|
|
FROM alpine:3.20
|
|
RUN addgroup -S -g 10001 halcyon && adduser -S -u 10001 -G halcyon halcyon \
|
|
&& mkdir /data && chown halcyon:halcyon /data
|
|
COPY --from=build /out/server /out/daily /out/asm /usr/local/bin/
|
|
|
|
USER halcyon
|
|
WORKDIR /data
|
|
|
|
# Where the world lives: "sqlite:<path>" or "postgres://user:pass@host/db".
|
|
# The default is a SQLite file on the /data volume; override it at run time,
|
|
# e.g. -e DATABASE_URL=postgres://... (the -db flag also overrides it).
|
|
ENV DATABASE_URL=sqlite:/data/halcyon.db
|
|
|
|
# The rendered PDF manual is read from here on every request. Compose mounts the
|
|
# volume the manual renderer writes to; if the file is absent /manual.pdf is a 404.
|
|
ENV MANUAL_PDF=/manual/manual.pdf
|
|
VOLUME /data
|
|
EXPOSE 8080
|
|
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
|
|
CMD wget -q -O /dev/null http://127.0.0.1:8080/info || exit 1
|
|
|
|
# Default: the API and website. Run one day of the belt with:
|
|
# docker run --rm -e DATABASE_URL=... <image> daily
|
|
CMD ["server"]
|