# syntax=docker/dockerfile:1 # ── Build ────────────────────────────────────────────────────────────── # Runs on the builder's native platform; cross-compiles to the target arch. # CGO_ENABLED=0 works because the SQLite driver (modernc.org/sqlite) is pure # Go, so there is no cgo and no libc to match against. FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS build ARG TARGETOS=linux ARG TARGETARCH=amd64 ARG VERSION=dev WORKDIR /src # Cache the module layer separately from the source. COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" \ -o /out/vellum ./cmd/vellum # ── Runtime ──────────────────────────────────────────────────────────── FROM alpine:3.22 RUN apk add --no-cache ca-certificates tzdata su-exec COPY --from=build /out/vellum /usr/local/bin/vellum COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # /data persistent state (SQLite database) — back this up # /config regenerable cache (thumbnails, extracted pages) # /media the library, mounted read-only; Vellum never writes here VOLUME ["/data", "/config"] ENV VELLUM_DATA_DIR=/data \ VELLUM_CONFIG_DIR=/config \ VELLUM_LISTEN=:7788 # PUID/PGID are consumed by entrypoint.sh, which drops root privileges after # taking ownership of the data and cache directories. ENV PUID=1001 \ PGID=1001 EXPOSE 7788 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget -qO- http://127.0.0.1:7788/healthz || exit 1 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]