Skip to main content

Building the image

From the project root:
docker build -t hagaki .

How the image is built

The Dockerfile uses a two-stage build to keep the final image small:
FROM rust:1.88-slim AS builder
WORKDIR /app
COPY . /app
RUN cargo build --release

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app/target/release/hagaki /usr/local/bin/hagaki
ENV RUST_LOG=info
CMD ["hagaki"]
StageBase imagePurpose
builderrust:1.88-slimCompiles the release binary
Runtimedebian:bookworm-slimRuns the binary; no Rust toolchain included
Only ca-certificates is installed in the runtime image. The final image contains only the binary and its minimal OS dependencies.

Volume mounts (required)

The service will not work without the asset directories. The binary running at /app inside the container resolves paths relative to its working directory. You must mount the asset directories at exactly these container paths:
Host path (example)Container pathPurpose
/data/asset/private/frame/asset/private/frameCard frame assets
/data/asset/private/idol/asset/private/idolCharacter images
/data/asset/public/render/asset/public/renderRendered output
The binary resolves ../asset/... relative to /app, which means it looks for /asset/... at the container root level.

Running the container

Replace the host paths below with the actual locations of your asset directories:
docker run -d \
  --name hagaki \
  -p 8899:8899 \
  -v /data/asset/private/frame:/asset/private/frame:ro \
  -v /data/asset/private/idol:/asset/private/idol:ro \
  -v /data/asset/public/render:/asset/public/render \
  -e RUST_LOG=info \
  hagaki
The frame and idol volumes are mounted read-only (:ro) since the service only reads from them. The render volume must be writable.

Docker Compose

services:
  hagaki:
    image: hagaki
    build: .
    ports:
      - "8899:8899"
    volumes:
      - /data/asset/private/frame:/asset/private/frame:ro
      - /data/asset/private/idol:/asset/private/idol:ro
      - /data/asset/public/render:/asset/public/render
    environment:
      RUST_LOG: info
    restart: unless-stopped
Build and start:
docker compose up -d

Overriding RUST_LOG

The image sets RUST_LOG=info by default. Override it at runtime:
docker run -e RUST_LOG=debug -p 8899:8899 ... hagaki
See Building from source for all valid RUST_LOG values.
The container exposes port 8899. Map it to a different host port (e.g., -p 80:8899) or place an Nginx reverse proxy in front of it. See the Nginx reverse proxy guide.

Build docs developers (and LLMs) love