ADR 0017's step 1. Generic over group and hash (SrpGroup); production takes RFC 5054's 3072-bit group with SHA-256. k = H(N | PAD(g)), u = H(PAD(A) | PAD(B)), K = H(PAD(S)), M1 = H(H(N) xor H(g) | H(I) | s | PAD(A) | PAD(B) | K), M2 = H(PAD(A) | M1 | K). A and B must lie in 1..N-1 and u must not be 0; a and b are 256 bits from Random.secure(); proofs are compared in constant time. x comes from the caller (halkyon_keys makes it); RFC 5054's own x is there for the vectors only. - The register's half in halkyon_base_server (base.dart: srpChallenge, srpVerify), the device's written by hand in halkyon_base_client (srp.dart: SrpClient, srpVerifier). Serverpod's generator cleans and writes only a client's lib/src/protocol/ (serverpod_cli 4.0.4's _getDirectoriesRequiringCleaning; a generate leaves srp/ untouched). - Tests: RFC 5054 Appendix B on both halves; the client against the register, succeeding and every refusal. - The module's tests depend on its client, and pub resolves every member's dev dependencies, so Learn's server image takes the module's client into its workspace too. - The format check covers the hand-written half. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
71 lines
3.9 KiB
Docker
71 lines
3.9 KiB
Docker
# The server image. Built from the repository root (the build context), because the
|
|
# workspace's root pubspec and lockfile live there:
|
|
#
|
|
# docker build -f apps/learn/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.yaml pubspec.lock ./
|
|
COPY tool/workspace_only.sh tool/
|
|
COPY apps/learn/halkyon_learn_server apps/learn/halkyon_learn_server
|
|
COPY packages/halkyon_base_server packages/halkyon_base_server
|
|
COPY packages/halkyon_base_client packages/halkyon_base_client
|
|
|
|
# The workspace root with only the server and the module it builds on: neither the
|
|
# other apps nor Learn's client package are needed to build the server, and the Flutter
|
|
# packages would need Flutter. The module's client comes along only because the
|
|
# module's tests depend on it (SRP's two halves, held to each other), and pub resolves
|
|
# every member's dev dependencies; the server never imports it. Everything else stays
|
|
# as the repository has it, above all the dependency overrides, which bring the server
|
|
# our fork of the offline sync package (fetched with the git the Dart image has).
|
|
RUN sh tool/workspace_only.sh apps/learn/halkyon_learn_server packages/halkyon_base_server packages/halkyon_base_client
|
|
RUN dart pub get
|
|
WORKDIR /app/apps/learn/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. git for the published studysets' releases
|
|
# (ADR 0005, rule 3), which the server writes through the git command.
|
|
FROM ubuntu:24.04
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
WORKDIR /app
|
|
|
|
ENV runmode=production
|
|
ENV serverid=default
|
|
ENV logging=normal
|
|
ENV role=monolith
|
|
|
|
COPY --from=build /app/apps/learn/halkyon_learn_server/build/bundle/ ./
|
|
COPY --from=build /app/apps/learn/halkyon_learn_server/config/ config/
|
|
COPY --from=build /app/apps/learn/halkyon_learn_server/migrations/ migrations/
|
|
# Mozilla's Public Suffix List, for the Jellyfin server the instance suggests.
|
|
COPY --from=build /app/apps/learn/halkyon_learn_server/data/ data/
|
|
COPY --from=build /app/apps/learn/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 only into the
|
|
# repositories folder), so it runs as an unprivileged system user. The folder is the
|
|
# app user's, and a new volume mounted on it takes that over.
|
|
RUN useradd --system --no-create-home --shell /usr/sbin/nologin app \
|
|
&& mkdir repositories && chown app:app repositories
|
|
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 []
|