Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading