Adds a custom PocketBase binary (cmd/pocketbase) that embeds PocketBase as a Go framework with version-controlled migrations, replacing the fragile 419-line shell script. Migrations apply automatically on every `serve` startup. Migration 1 (20260414000001): full baseline schema — all 21 collections, both indexes on chapters_idx, and initial superuser creation from env vars. Migration 2 (20260414000002): adds three fields found in code but missing from the old script — books.rating, app_users.notify_new_chapters_push, book_comments.chapter. docker-compose: pocketbase service now uses the custom kalekber/libnovel-pocketbase image; pb-init one-shot container removed (migrations replace it entirely). Existing installs: run `migrate history-sync` once to mark migration 1 as done, then restart — migration 2 will apply the three previously missing fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
70 lines
3.1 KiB
Docker
70 lines
3.1 KiB
Docker
# syntax=docker/dockerfile:1
|
|
FROM golang:1.26.1-alpine AS builder
|
|
WORKDIR /app
|
|
|
|
# Download modules into the BuildKit cache so they survive across builds.
|
|
# This layer is only invalidated when go.mod or go.sum changes.
|
|
COPY go.mod go.sum ./
|
|
RUN --mount=type=cache,target=/root/go/pkg/mod \
|
|
go mod download
|
|
|
|
COPY . .
|
|
|
|
ARG VERSION=dev
|
|
ARG COMMIT=unknown
|
|
|
|
# Build all three binaries in a single layer so the Go compiler can reuse
|
|
# intermediate object files. Both cache mounts are preserved between builds:
|
|
# /root/go/pkg/mod — downloaded module source
|
|
# /root/.cache/go-build — compiled package objects (incremental recompile)
|
|
RUN --mount=type=cache,target=/root/go/pkg/mod \
|
|
--mount=type=cache,target=/root/.cache/go-build \
|
|
CGO_ENABLED=0 GOOS=linux go build \
|
|
-ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT}" \
|
|
-o /out/backend ./cmd/backend && \
|
|
CGO_ENABLED=0 GOOS=linux go build \
|
|
-ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT}" \
|
|
-o /out/runner ./cmd/runner && \
|
|
CGO_ENABLED=0 GOOS=linux go build \
|
|
-ldflags="-s -w" \
|
|
-o /out/healthcheck ./cmd/healthcheck && \
|
|
CGO_ENABLED=0 GOOS=linux go build \
|
|
-ldflags="-s -w" \
|
|
-o /out/pocketbase ./cmd/pocketbase
|
|
|
|
# ── backend service ──────────────────────────────────────────────────────────
|
|
# Uses Alpine (not distroless) so ffmpeg is available for on-demand voice
|
|
# sample generation via pocket-tts (WAV→MP3 transcoding).
|
|
FROM alpine:3.21 AS backend
|
|
RUN apk add --no-cache ffmpeg ca-certificates && \
|
|
addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
COPY --from=builder /out/healthcheck /healthcheck
|
|
COPY --from=builder /out/backend /backend
|
|
USER appuser
|
|
ENTRYPOINT ["/backend"]
|
|
|
|
# ── pocketbase service ───────────────────────────────────────────────────────
|
|
# Runs the custom PocketBase binary with Go migrations baked in.
|
|
# On every `serve` startup it applies any pending migrations automatically.
|
|
# Data is stored in /pb_data (mounted as a Docker volume in production).
|
|
FROM alpine:3.21 AS pocketbase
|
|
RUN apk add --no-cache ca-certificates && \
|
|
addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
COPY --from=builder /out/pocketbase /pocketbase
|
|
RUN mkdir -p /pb_data && chown appuser:appgroup /pb_data
|
|
VOLUME /pb_data
|
|
EXPOSE 8090
|
|
USER appuser
|
|
CMD ["/pocketbase", "serve", "--dir", "/pb_data", "--http", "0.0.0.0:8090"]
|
|
|
|
# ── runner service ───────────────────────────────────────────────────────────
|
|
# Uses Alpine (not distroless) so ffmpeg is available for WAV→MP3 transcoding
|
|
# when pocket-tts voices are used.
|
|
FROM alpine:3.21 AS runner
|
|
RUN apk add --no-cache ffmpeg ca-certificates && \
|
|
addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
COPY --from=builder /out/healthcheck /healthcheck
|
|
COPY --from=builder /out/runner /runner
|
|
USER appuser
|
|
ENTRYPOINT ["/runner"]
|