Caddy, the Serverpod server and PostgreSQL 16 in deploy/. Only Caddy publishes ports; the server and Postgres are reachable only inside the Compose network (Docker bypasses ufw, and the server listens on every interface). Secrets come from deploy/.env as environment variables; there is no production passwords.yaml, and .dockerignore keeps local secrets out of the build context. The server image builds on Serverpod's template with an Ubuntu 24.04 runtime: complete glibc incl. libgcc_s for the SQLite libraries Serverpod 4 bundles, CA certificates, a non-root user, and exec so SIGTERM reaches the server. The scaffold's dev-only docker-compose.yaml is removed. Verified locally: image builds, all native libraries resolve, no passwords.yaml in the image, migrations apply at start, Caddy serves 200, port 8080 unreachable from the host, Postgres in UTC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
64 lines
2.8 KiB
Docker
64 lines
2.8 KiB
Docker
# The server image. Built from the repository root (the build context), because the
|
|
# workspace lockfile lives there:
|
|
#
|
|
# docker build -f halkyon_learn_server/Dockerfile .
|
|
#
|
|
# Based on Serverpod's template, with three changes: Dart 3.13 (our SDK floor), an
|
|
# Ubuntu 24.04 runtime instead of alpine + Dart's minimal glibc runtime (same
|
|
# distribution as our servers; complete glibc, which Serverpod 4's bundled SQLite
|
|
# libraries need), and a start command that passes Docker's stop signal on.
|
|
|
|
# ── Build stage: compile the server to a native executable ────────────────────────
|
|
FROM dart:3.13.4 AS build
|
|
WORKDIR /app
|
|
COPY pubspec.lock .
|
|
COPY halkyon_learn_server halkyon_learn_server
|
|
|
|
# A workspace root containing only the server package: the client package and the
|
|
# Flutter app aren't needed to build the server.
|
|
RUN printf '%s\n' \
|
|
'name: _' \
|
|
'environment:' \
|
|
' sdk: ^3.13.0' \
|
|
'workspace:' \
|
|
' - halkyon_learn_server' \
|
|
> pubspec.yaml
|
|
RUN dart pub get
|
|
WORKDIR /app/halkyon_learn_server
|
|
RUN dart build cli --target bin/main.dart --output build
|
|
RUN mv build/bundle/bin/main build/bundle/bin/server
|
|
RUN mkdir -p config migrations
|
|
|
|
# ── Runtime stage ─────────────────────────────────────────────────────────────────
|
|
# Ubuntu 24.04: glibc 2.39 (the bundled binaries need at most 2.34, measured) and
|
|
# libgcc_s (needed by libsqlite3_connection_pool, a Rust library; a server running
|
|
# against Postgres never loads it, but a future code path might). CA certificates
|
|
# for outgoing TLS, e.g. GitHub sign-in.
|
|
FROM ubuntu:24.04
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
WORKDIR /app
|
|
|
|
ENV runmode=production
|
|
ENV serverid=default
|
|
ENV logging=normal
|
|
ENV role=monolith
|
|
|
|
COPY --from=build /app/halkyon_learn_server/build/bundle/ ./
|
|
COPY --from=build /app/halkyon_learn_server/config/ config/
|
|
COPY --from=build /app/halkyon_learn_server/migrations/ migrations/
|
|
COPY --from=build /app/halkyon_learn_server/lib/src/generated/protocol.yaml lib/src/generated/protocol.yaml
|
|
|
|
# The server needs no root rights (it listens on 8080 and writes nothing to the
|
|
# image), so it runs as an unprivileged system user.
|
|
RUN useradd --system --no-create-home --shell /usr/sbin/nologin app
|
|
USER app
|
|
|
|
# Only the API server runs in production (no Insights, no web server).
|
|
EXPOSE 8080
|
|
|
|
# `exec` makes the server PID 1, so it receives Docker's SIGTERM and shuts down
|
|
# cleanly; extra arguments (e.g. --apply-migrations) come from the container command.
|
|
ENTRYPOINT ["/bin/sh", "-c", "exec ./bin/server --mode=$runmode --server-id=$serverid --logging=$logging --role=$role \"$@\"", "--"]
|
|
CMD []
|