Keep cover volume aligned with configured path
This commit is contained in:
+1
-2
@@ -26,8 +26,7 @@ POSTGRES_PASSWORD=changeme-generate-a-long-random-password
|
||||
# DATABASE_URL=postgres://user:pass@host:5432/bookmarks?sslmode=require
|
||||
|
||||
# Directory inside bookmark-api for immutable, content-addressed Cover bytes.
|
||||
# Compose seeds and mounts its named volume at /covers, so keep this value
|
||||
# /covers in this deployment. Standalone backend runs may choose another path.
|
||||
# Compose builds the image and mounts its named volume at this path.
|
||||
COVER_DIR=/covers
|
||||
|
||||
# --- Prod override (Traefik) only ---
|
||||
|
||||
@@ -53,8 +53,8 @@ POSTGRES_PASSWORD=<paste output of: openssl rand -hex 24>
|
||||
# not run; it then replaces the URL built from POSTGRES_PASSWORD above.
|
||||
# DATABASE_URL=postgres://user:pass@host:5432/bookmarks?sslmode=require
|
||||
|
||||
# Required path inside bookmark-api. Compose seeds and mounts the named
|
||||
# cover-data volume at /covers, so keep this value /covers.
|
||||
# Required path inside bookmark-api. Compose builds the image and mounts the
|
||||
# named cover-data volume at this path.
|
||||
COVER_DIR=/covers
|
||||
|
||||
# Required for the Traefik override. Both have no fallback — compose refuses
|
||||
|
||||
@@ -42,7 +42,7 @@ covers are stored, so the library renders in full with the browser switched off.
|
||||
| `OWNER_DISCORD_ID` | *(required)* | Discord user ID of the owner: seeded as the first Reader, owns every pre-registration bookmark, and is the only Reader who can revoke another's sessions. |
|
||||
| `ALLOWED_ORIGINS` | Asura + Demonic + Comix + Kagane origins | Comma-separated CORS allowlist. |
|
||||
| `DATABASE_URL` | *(required)* | Postgres connection URL, e.g. `postgres://bookmarks:…@postgres:5432/bookmarks?sslmode=disable`. Compose builds it from `POSTGRES_PASSWORD`. |
|
||||
| `COVER_DIR` | *(required)* | Filesystem volume for immutable, content-addressed Cover bytes. Compose requires `/covers` and mounts `cover-data` there; standalone runs may choose another writable durable path. |
|
||||
| `COVER_DIR` | *(required)* | Filesystem volume for immutable, content-addressed Cover bytes. Compose builds the image and mounts `cover-data` at this path; standalone runs may choose another writable durable path. |
|
||||
| `PORT` | `8080` | Plain HTTP; TLS terminated by the proxy. |
|
||||
| `BROWSER_WS_URL` | empty | CDP endpoint of the remote browser (`ws://<tailnet IP>:9222`), used to poll Kagane/Novelfull past their JS challenge and to fetch uncached Kagane covers. Must be an IP or `localhost` — Chrome's DevTools handler 500s any other Host header, MagicDNS names included. Unset disables both; stored covers still serve. |
|
||||
| `DISCORD_CLIENT_ID` | *(required)* | Discord application credentials for the browser sign-in (ADR-0002). |
|
||||
|
||||
+4
-2
@@ -2,6 +2,7 @@
|
||||
|
||||
# --- build stage: compile a static, CGO-free binary ---
|
||||
FROM golang:1.26-alpine AS build
|
||||
ARG COVER_DIR=/covers
|
||||
WORKDIR /src
|
||||
|
||||
# Dependencies first for layer caching (changes rarely).
|
||||
@@ -20,12 +21,13 @@ COPY internal/ ./internal/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/server .
|
||||
|
||||
# Create the source directory; runtime COPY sets ownership for the named volume.
|
||||
RUN mkdir -p /covers
|
||||
RUN mkdir -p "$COVER_DIR"
|
||||
|
||||
# --- runtime stage: distroless static, non-root ---
|
||||
FROM gcr.io/distroless/static:nonroot
|
||||
ARG COVER_DIR=/covers
|
||||
WORKDIR /
|
||||
COPY --from=build --chown=65532:65532 /covers /covers
|
||||
COPY --from=build --chown=65532:65532 ${COVER_DIR} ${COVER_DIR}
|
||||
COPY --from=build /out/server /server
|
||||
EXPOSE 8080
|
||||
USER nonroot:nonroot
|
||||
|
||||
+7
-4
@@ -11,7 +11,10 @@
|
||||
|
||||
services:
|
||||
bookmark-api:
|
||||
build: ./backend
|
||||
build:
|
||||
context: ./backend
|
||||
args:
|
||||
COVER_DIR: ${COVER_DIR:?set COVER_DIR in .env}
|
||||
image: bookmarkmanager-backend:latest
|
||||
container_name: bookmark-api
|
||||
restart: unless-stopped
|
||||
@@ -26,8 +29,8 @@ services:
|
||||
# The bookmarks database. Host is the compose service name; the password
|
||||
# comes from .env so it is never committed.
|
||||
DATABASE_URL: ${DATABASE_URL:-postgres://bookmarks:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}@postgres:5432/bookmarks?sslmode=disable}
|
||||
# Required path inside the API. The image seeds ownership at /covers and
|
||||
# the named volume below mounts there; keep COVER_DIR=/covers in .env.
|
||||
# Required path inside the API. The build seeds ownership at this path
|
||||
# and the named volume below mounts there.
|
||||
COVER_DIR: ${COVER_DIR:?set COVER_DIR in .env}
|
||||
PORT: "8080"
|
||||
# Log timestamps only. Go's `log` stamps lines in local time, and this
|
||||
@@ -84,7 +87,7 @@ services:
|
||||
# is why a redeploy always ships the repo's script.
|
||||
- ./userscript:/userscript:ro
|
||||
# Content-addressed cover bytes survive API restarts and redeploys.
|
||||
- cover-data:/covers
|
||||
- cover-data:${COVER_DIR:?set COVER_DIR in .env}
|
||||
# Bound to loopback only: the proxy (or curl during smoke test) reaches it,
|
||||
# the public internet does not.
|
||||
ports:
|
||||
|
||||
Reference in New Issue
Block a user