Single-binary self-hosted Markdown blog on Rust axum: no database, live search, Typst PDF export, and strong SEO.
axumblogdockermarkdownminijinjarustself-hostedtypstvite
1# syntax=docker/dockerfile:1
2# ----- builder -----
3FROM rust:alpine AS builder
4
5RUN apk add --no-cache musl-dev
6
7COPY --from=oven/bun:alpine /usr/local/bin/bun /usr/local/bin/bun
8
9WORKDIR /app
10
11COPY Cargo.toml Cargo.lock ./
12COPY src ./src
13COPY frontend ./frontend
14
15RUN cd frontend && bun install --frozen-lockfile && bun run build
16RUN --mount=type=cache,target=/usr/local/cargo/registry \
17 --mount=type=cache,target=/app/target \
18 cargo build --release && \
19 cp target/release/blog /app/blog
20
21# ----- runtime -----
22FROM alpine:3.23
23
24RUN apk add --no-cache \
25 font-jetbrains-mono ttf-dejavu ttf-liberation fontconfig
26
27WORKDIR /app
28
29COPY --from=builder /app/blog ./blog
30COPY --from=builder /app/dist ./dist
31COPY templates ./templates
32COPY content ./content
33
34RUN addgroup -S -g 1000 app && \
35 adduser -S -h /app -s /sbin/nologin -u 1000 -G app app && \
36 chown -R app:app /app
37USER app
38
39ENV PORT=8000
40EXPOSE 8000
41
42CMD ["./blog"]