# ── Build stage ──────────────────────────────────────────────────────────────── FROM golang:1.25-alpine AS builder WORKDIR /build # Cache dependency downloads separately from source compilation. COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -ldflags="-s -w" -o /scraper ./cmd/scraper # ── single-file binary stage ─────────────────────────────────────────────────── # Download the official pre-compiled single-file-cli binary (Deno-compiled, # statically linked for Linux x86_64 glibc). We pin to a specific version so # image builds are reproducible; bump this ARG to upgrade. FROM alpine:3.20 AS singlefile-downloader ARG SINGLEFILE_VERSION=2.0.83 RUN apk add --no-cache wget ca-certificates && \ wget -q -O /single-file \ "https://github.com/gildas-lormeau/single-file-cli/releases/download/v${SINGLEFILE_VERSION}/single-file-x86_64-linux" && \ chmod +x /single-file # ── Runtime stage ────────────────────────────────────────────────────────────── FROM alpine:3.20 # ca-certificates: HTTPS to novelfire.net # gcompat: glibc compatibility shim so the glibc-linked single-file binary # runs on musl/Alpine without needing a full glibc image. # libstdc++: required by the Deno runtime embedded in single-file RUN apk add --no-cache ca-certificates tzdata gcompat libstdc++ WORKDIR /app COPY --from=builder /scraper /app/scraper COPY --from=singlefile-downloader /single-file /usr/local/bin/single-file # Create the default static output directory. RUN mkdir -p /app/static/books # Non-root user. RUN addgroup -S scraper && adduser -S scraper -G scraper RUN chown -R scraper:scraper /app USER scraper # ── Configuration ───────────────────────────────────────────────────────────── ENV BROWSERLESS_URL=http://browserless:3030 ENV BROWSERLESS_STRATEGY=content ENV SCRAPER_WORKERS=0 ENV SCRAPER_STATIC_ROOT=/app/static/books ENV SCRAPER_HTTP_ADDR=:8080 ENV SINGLEFILE_PATH=/usr/local/bin/single-file EXPOSE 8080 # Default: run as an HTTP server. Override CMD to use "run" for one-shot. ENTRYPOINT ["/app/scraper"] CMD ["serve"]