terainia/Dockerfile
Maximus Gorog f239a939ce Add Docker + Caddy deploy for voxel.mxvs.art
Multi-stage Dockerfile compiles wasm client + axum server in one Rust
builder and copies into a debian:bookworm-slim runtime (non-root uid).
docker-compose.yml binds localhost:8080 by default; docker-compose.prod.yml
replaces ports with a Caddy reverse proxy on host 80/443 that talks to
the voxel container over the internal network. Caddy auto-issues Let's
Encrypt certs.

DEPLOY.md covers the three deployment modes (local-only, VPS with
Cloudflare or Caddy, Cloudflare Tunnel from a workstation).
2026-05-23 18:45:05 -06:00

52 lines
1.8 KiB
Docker

# Multi-stage build: compile the wasm client + the server in one Rust
# image, then copy the artifacts into a tiny Debian runtime.
FROM rust:1-bookworm AS builder
# Pin wasm-bindgen-cli to the same version we use during development. If
# this number drifts from Cargo.lock the wasm load will fail.
ARG WASM_BINDGEN_VERSION=0.2.122
# Install the wasm32 target and wasm-bindgen-cli.
RUN rustup target add wasm32-unknown-unknown && \
cargo install wasm-bindgen-cli --version ${WASM_BINDGEN_VERSION} --locked
WORKDIR /build
# Copy the whole project. The .dockerignore keeps target/ out so we get
# a clean release build inside the container.
COPY . .
# Build the wasm client (release) and run wasm-bindgen to emit the
# JS glue + bg.wasm into web/.
RUN cargo build --target wasm32-unknown-unknown --release --lib && \
wasm-bindgen --target web --out-dir web --no-typescript \
target/wasm32-unknown-unknown/release/voxel_game.wasm
# Build the multiplayer server.
RUN cd server && cargo build --release
# ---- Runtime image ----
FROM debian:bookworm-slim AS runtime
# ca-certificates lets the server speak HTTPS if it ever needs to (it
# doesn't yet, but it's tiny and avoids surprises). tini handles signal
# forwarding so `docker stop` is clean.
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates tini && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /build/server/target/release/voxel-server /usr/local/bin/voxel-server
COPY --from=builder /build/web /app/web
ENV STATIC_DIR=/app/web
ENV PORT=8080
EXPOSE 8080
# Run as non-root for safety.
RUN useradd --create-home --shell /bin/false --uid 10001 voxel && \
chown -R voxel:voxel /app
USER voxel
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/local/bin/voxel-server"]