98 lines
4.0 KiB
Docker
98 lines
4.0 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# KeepOrg synchronization server.
|
|
#
|
|
# The server is a static binary with no cgo — its only third-party code is
|
|
# the two pure-Go database drivers — so the runtime image carries the
|
|
# binary, a certificate bundle for talking to an OIDC provider or a
|
|
# PostgreSQL server over TLS, and nothing else. There is no shell in it: the binary
|
|
# probes its own health.
|
|
#
|
|
# podman build --format docker -t keeporgd:<version> --build-arg VERSION=<version> .
|
|
# docker build -t keeporgd:<version> --build-arg VERSION=<version> .
|
|
#
|
|
# podman needs --format docker, because the OCI image format has no
|
|
# HEALTHCHECK field and drops it silently.
|
|
#
|
|
# or `make docker`, which takes the version from versions.mk.
|
|
|
|
FROM golang:1.26-alpine AS build
|
|
|
|
ARG VERSION=dev
|
|
# The platform being built for, so `go build` cross-compiles to it rather than to
|
|
# the builder's own architecture.
|
|
ARG TARGETOS
|
|
ARG TARGETARCH
|
|
WORKDIR /src
|
|
|
|
# Only what the server is built from, so a change to the clients, the
|
|
# Android app or the docs does not invalidate this layer.
|
|
COPY go.mod go.sum ./
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
go mod download
|
|
COPY cmd/keeporgd ./cmd/keeporgd
|
|
COPY internal ./internal
|
|
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
--mount=type=cache,target=/root/.cache/go-build \
|
|
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -trimpath \
|
|
-ldflags="-s -w -X main.version=${APP_VERSION}" \
|
|
-o /out/keeporgd ./cmd/keeporgd
|
|
|
|
# Empty directories to copy into the scratch image with the right owner.
|
|
# There is no shell there to create them later.
|
|
RUN mkdir -p /out/var/lib/keeporg /out/etc/keeporg
|
|
|
|
|
|
FROM scratch
|
|
|
|
ARG VERSION=dev
|
|
LABEL org.opencontainers.image.title="KeepOrg server" \
|
|
org.opencontainers.image.description="Synchronization server for collaborative KeePass databases" \
|
|
org.opencontainers.image.version="${VERSION}" \
|
|
org.opencontainers.image.source="https://garage.rcmd.space/keeporg" \
|
|
org.opencontainers.image.licenses="AGPL-3.0-or-later" \
|
|
cc.tiredsysadmin.application="cc.tiredsysadmin.linux.keeporgd"
|
|
|
|
# Needed to reach an OIDC provider, or PostgreSQL, over TLS. Nothing else from the builder
|
|
# comes along.
|
|
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
|
|
|
# The data directory holds the SQLite database, unless KEEPORG_DATABASE_URL
|
|
# points at PostgreSQL. Every row in it is sealed under the master key. The
|
|
# configuration directory holds server.json and, unless the key is supplied
|
|
# otherwise, that master key. They are separate on purpose: whoever holds
|
|
# both can read everything, and either alone is useless.
|
|
#
|
|
# Give the master key somewhere durable, one of these three ways:
|
|
#
|
|
# --secret keeporg_master_key -e KEEPORG_MASTER_KEY_FILE=/run/secrets/keeporg_master_key
|
|
# -e KEEPORG_MASTER_KEY="$(head -c 32 /dev/urandom | base64)"
|
|
# -v keeporg-config:/etc/keeporg
|
|
#
|
|
# The first is preferred: the key is never in the process environment and
|
|
# never on a disk this container can write. The file may hold base64 or 32
|
|
# raw bytes. Neither environment variable is ever created by the server, so
|
|
# a secret that failed to mount is reported instead of being replaced.
|
|
#
|
|
# With none of the three, the server mints a key into the container's own
|
|
# layer on first start and loses it on the next `run`, after which it
|
|
# refuses to start: the database does not open with a new key. Nothing is
|
|
# overwritten; mount the original key and it starts.
|
|
COPY --from=build --chown=65532:65532 /out/var/lib/keeporg /var/lib/keeporg
|
|
COPY --from=build --chown=65532:65532 /out/etc/keeporg /etc/keeporg
|
|
VOLUME ["/var/lib/keeporg", "/etc/keeporg"]
|
|
|
|
COPY --from=build /out/keeporgd /keeporgd
|
|
|
|
# A fixed unprivileged id, matching the convention used by distroless.
|
|
USER 65532:65532
|
|
EXPOSE 8765
|
|
|
|
# The image has no shell, so the binary checks itself.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
|
CMD ["/keeporgd", "-healthcheck", "-addr", ":8765"]
|
|
|
|
ENTRYPOINT ["/keeporgd"]
|
|
CMD ["-addr", ":8765", "-data", "/var/lib/keeporg"]
|