mirror of
https://github.com/Xevion/dynamic-preauth.git
synced 2026-01-31 00:24:07 -06:00
refactor(docker): optimize multi-stage build with cargo-chef and layer caching
Improves Docker build performance and security through better layer caching, dependency pre-building, and a minimal non-root runtime container. - Add cargo-chef for Rust dependency caching across demo and server builds - Separate planner and builder stages for optimal layer reuse - Use pnpm with frozen lockfile for reproducible frontend builds - Switch to debian:12-slim runtime with non-root user (uid 1000) - Add health check endpoint monitoring - Strip release binaries to reduce image size - Pre-compress frontend assets during build
This commit is contained in:
+112
-39
@@ -1,60 +1,133 @@
|
||||
# Build the demo application
|
||||
FROM rust:latest AS builder-demo
|
||||
# syntax=docker/dockerfile:1
|
||||
ARG RUST_VERSION=1.86.0
|
||||
|
||||
WORKDIR /build/demo
|
||||
RUN apt update && apt install -y g++-mingw-w64-x86-64
|
||||
ARG RAILWAY_PUBLIC_DOMAIN
|
||||
# --- Chef Base Stage ---
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-${RUST_VERSION} AS chef
|
||||
WORKDIR /app
|
||||
|
||||
RUN rustup target add x86_64-pc-windows-gnu
|
||||
RUN rustup target add x86_64-unknown-linux-gnu
|
||||
# TODO: Add support for macOS
|
||||
# RUN rustup target add x86_64-apple-darwin
|
||||
# --- Demo Planner Stage ---
|
||||
FROM chef AS demo-planner
|
||||
COPY demo/Cargo.toml demo/Cargo.lock* demo/build.rs ./
|
||||
COPY demo/src ./src
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
COPY ./demo ./
|
||||
# --- Demo Builder Stage ---
|
||||
FROM chef AS demo-builder
|
||||
|
||||
RUN cargo build --release --target x86_64-pc-windows-gnu
|
||||
RUN cargo build --release --target x86_64-unknown-linux-gnu
|
||||
# RUN cargo build --release --target x86_64-apple-darwin
|
||||
# Install cross-compilation toolchain for Windows
|
||||
RUN apt-get update && apt-get install -y \
|
||||
g++-mingw-w64-x86-64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Build the server application
|
||||
FROM rust:alpine AS builder-server
|
||||
# Add cross-compilation targets
|
||||
RUN rustup target add x86_64-pc-windows-gnu x86_64-unknown-linux-gnu
|
||||
|
||||
RUN apk update && apk add musl-dev
|
||||
WORKDIR /build/server
|
||||
# Copy recipe and cook dependencies
|
||||
COPY --from=demo-planner /app/recipe.json recipe.json
|
||||
RUN cargo chef cook --release --target x86_64-unknown-linux-gnu --recipe-path recipe.json
|
||||
RUN cargo chef cook --release --target x86_64-pc-windows-gnu --recipe-path recipe.json
|
||||
|
||||
COPY ./src ./src
|
||||
COPY ./Cargo.toml ./Cargo.lock ./
|
||||
RUN cargo build --release
|
||||
|
||||
# Build the Astro frontend
|
||||
FROM node:lts AS builder-astro
|
||||
|
||||
WORKDIR /build/astro
|
||||
|
||||
COPY ./frontend/ ./
|
||||
# Copy source and build
|
||||
COPY demo/Cargo.toml demo/Cargo.lock* demo/build.rs ./
|
||||
COPY demo/src ./src
|
||||
|
||||
ARG RAILWAY_PUBLIC_DOMAIN
|
||||
ENV RAILWAY_PUBLIC_DOMAIN=${RAILWAY_PUBLIC_DOMAIN}
|
||||
|
||||
RUN npm install pnpm -g
|
||||
RUN pnpm install
|
||||
RUN pnpm build
|
||||
RUN ./compress.sh
|
||||
RUN cargo build --release --target x86_64-unknown-linux-gnu
|
||||
RUN cargo build --release --target x86_64-pc-windows-gnu
|
||||
|
||||
# Run the server application
|
||||
FROM alpine:latest
|
||||
# Strip binaries
|
||||
RUN strip target/x86_64-unknown-linux-gnu/release/demo
|
||||
|
||||
# --- Server Planner Stage ---
|
||||
FROM chef AS server-planner
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src ./src
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
# --- Server Builder Stage ---
|
||||
FROM chef AS server-builder
|
||||
|
||||
# Copy recipe and cook dependencies
|
||||
COPY --from=server-planner /app/recipe.json recipe.json
|
||||
RUN cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
# Copy source and build
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src ./src
|
||||
RUN cargo build --release
|
||||
|
||||
# Strip binary
|
||||
RUN strip target/release/dynamic-preauth
|
||||
|
||||
# --- Frontend Builder Stage ---
|
||||
FROM node:22-slim AS frontend-builder
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder-astro /build/astro/dist/ ./public/
|
||||
COPY --from=builder-demo /build/demo/target/x86_64-pc-windows-gnu/release/demo.exe ./demo.exe
|
||||
COPY --from=builder-demo /build/demo/target/x86_64-unknown-linux-gnu/release/demo ./demo-linux
|
||||
COPY --from=builder-server /build/server/target/release/dynamic-preauth ./dynamic-preauth
|
||||
# Install pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@9 --activate
|
||||
|
||||
# Copy package files for layer caching
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source and build
|
||||
COPY frontend/ ./
|
||||
|
||||
ARG RAILWAY_PUBLIC_DOMAIN
|
||||
ENV RAILWAY_PUBLIC_DOMAIN=${RAILWAY_PUBLIC_DOMAIN}
|
||||
|
||||
RUN pnpm build
|
||||
|
||||
# Pre-compress static assets
|
||||
RUN ./compress.sh
|
||||
|
||||
# --- Runtime Stage ---
|
||||
FROM debian:12-slim
|
||||
|
||||
ARG APP=/app
|
||||
ARG APP_USER=appuser
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG TZ=Etc/UTC
|
||||
ENV TZ=${TZ}
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup --gid $GID $APP_USER \
|
||||
&& adduser --uid $UID --disabled-password --gecos "" --ingroup $APP_USER $APP_USER \
|
||||
&& mkdir -p ${APP}
|
||||
|
||||
WORKDIR ${APP}
|
||||
|
||||
# Copy built artifacts
|
||||
COPY --from=frontend-builder --chown=$APP_USER:$APP_USER /app/dist/ ./public/
|
||||
COPY --from=demo-builder --chown=$APP_USER:$APP_USER /app/target/x86_64-pc-windows-gnu/release/demo.exe ./demo.exe
|
||||
COPY --from=demo-builder --chown=$APP_USER:$APP_USER /app/target/x86_64-unknown-linux-gnu/release/demo ./demo-linux
|
||||
COPY --from=server-builder --chown=$APP_USER:$APP_USER /app/target/release/dynamic-preauth ./dynamic-preauth
|
||||
|
||||
# Set proper permissions
|
||||
RUN chmod +x ${APP}/dynamic-preauth
|
||||
|
||||
USER $APP_USER
|
||||
|
||||
# Build-time arg for PORT, default to 5800
|
||||
ARG PORT=5800
|
||||
# Runtime environment var for PORT, default to build-time arg
|
||||
ENV PORT=${PORT}
|
||||
EXPOSE ${PORT}
|
||||
|
||||
CMD ["/app/dynamic-preauth"]
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT}/session || exit 1
|
||||
|
||||
CMD ["./dynamic-preauth"]
|
||||
|
||||
Reference in New Issue
Block a user