From 10a18d188d50df841c835c3c23b5657d43463d0c Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Thu, 3 Sep 2026 10:48:03 +0500 Subject: [PATCH 1/2] feat: dockerfile --- Dockerfile | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..95fba45 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +# build +FROM rust:1-slim-bookworm AS builder +WORKDIR /app + +# cache deps separately from source - build a throwaway main.rs +# against just the manifest first, so `cargo build` layer only +# reruns when Cargo.toml/Cargo.lock actually change. +COPY Cargo.toml Cargo.lock ./ +RUN mkdir src && echo "fn main() {}" > src/main.rs +RUN cargo build --release --bin mantle +RUN rm -rf src + +COPY src ./src +# touch so cargo doesn't skip the real build using the dummy's mtime +RUN touch src/main.rs +RUN cargo build --release --bin mantle + +# minimal runtime image +FROM debian:bookworm-slim AS runtime + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN groupadd --system mantle \ + && useradd --system --gid mantle --no-create-home --shell /usr/sbin/nologin mantle + +WORKDIR /app +COPY --from=builder /app/target/release/mantle /usr/local/bin/mantle +COPY migrations ./migrations + +USER mantle + +ENTRYPOINT ["/usr/local/bin/mantle"] From ac0d7bea03fd0c9f5a671656ec79e6af478d0fd4 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Thu, 3 Sep 2026 10:51:48 +0500 Subject: [PATCH 2/2] docs: update readme to add docker section --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 21590fa..1dff302 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,27 @@ cargo run --bin mantle Build, deploy, and release builds work the same as any other Cargo project — no extra steps beyond the usual `--release`, aside from the other `--bin` targets in the workspace (e.g. `generate-openapi`, mentioned above) +## Docker + +```bash +docker build -t mantle . +docker run --rm -p 5050:5050 -v ./config.toml:/app/config.toml:ro --name mantle mantle +``` + +Secrets can be passed via the same `APP_*` env vars instead of putting them in the mounted `config.toml`: + +```bash +docker run --rm -p 5050:5050 \ + -v ./config.toml:/app/config.toml:ro \ + -e APP_DATABASE_URL="postgres://user:password@host.docker.internal/mantle" \ + -e APP_DISCORD_CLIENT_SECRET="..." \ + -e APP_DISCORD_STATE_SECRET="..." \ + -e APP_API_SECRET="..." \ + mantle +``` + +If Postgres runs on the host rather than in a container, use `host.docker.internal` instead of `localhost` in `database.url` — the container has its own network namespace. + ## License MIT 2026 JerryImMouse - see LICENSE.TXT