# syntax=docker/dockerfile:1 # ---- OpenFUT Core: offline FUT backend (Axum + bundled SQLite) ---- # Multi-stage: build with the Rust toolchain, ship a slim Debian runtime. # rustls + bundled SQLite mean no OpenSSL/system-sqlite at runtime. FROM rust:1-bookworm AS builder WORKDIR /build # Cache dependency compilation: copy manifests first, build a stub, then the # real sources. sqlx migrations are compiled in via sqlx::migrate!, so the # migrations/ dir must be present at build time. COPY Cargo.toml Cargo.lock* ./ RUN mkdir -p src \ && echo 'fn main() {}' > src/main.rs \ && echo '' > src/lib.rs \ && cargo build --release --bin openfut-core 2>/dev/null || true RUN rm -rf src COPY src ./src COPY migrations ./migrations # Touch so cargo rebuilds against the real sources rather than the stub. RUN touch src/main.rs src/lib.rs \ && cargo build --release --bin openfut-core # ---- Runtime ---- FROM debian:bookworm-slim AS runtime # curl is used by the compose/Docker healthcheck to hit /health. RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl \ && rm -rf /var/lib/apt/lists/* # Run unprivileged. RUN useradd --system --uid 10001 --create-home --home-dir /app openfut WORKDIR /app COPY --from=builder /build/target/release/openfut-core /usr/local/bin/openfut-core # data/ is read at runtime from DATA_DIR (moddable JSON content) — bundle it. COPY --chown=openfut:openfut data ./data # Persist the SQLite database on a named volume. RUN mkdir -p /app/db && chown openfut:openfut /app/db USER openfut ENV LISTEN_ADDR=0.0.0.0:8080 \ DATABASE_URL=sqlite:///app/db/openfut.db \ DATA_DIR=/app/data \ RUST_LOG=openfut_core=info,tower_http=info EXPOSE 8080 VOLUME ["/app/db"] HEALTHCHECK --interval=15s --timeout=4s --start-period=10s --retries=5 \ CMD curl -fsS http://127.0.0.1:8080/health || exit 1 ENTRYPOINT ["openfut-core"]