Docker shit

This commit is contained in:
2026-07-14 19:23:14 +02:00
parent 5585917eb1
commit b62bba0173
12 changed files with 334 additions and 7 deletions
+127
View File
@@ -0,0 +1,127 @@
# ============================================================
# Dockerfile — Full application (frontend + backend)
# ============================================================
# Multi-stage build:
# 1. chef install cargo-chef for dependency caching
# 2. planner generate recipe.json from the workspace
# 3. backend build the backend binary (release)
# 4. frontend build the frontend WASM bundle with Trunk
# 5. runtime minimal image: backend binary + static frontend + nginx
# ============================================================
# --------------- Stage 1: Chef base ---------------
FROM rust:1-bookworm AS chef
RUN cargo install cargo-chef
WORKDIR /app
# --------------- Stage 2: Planner ---------------
FROM chef AS planner
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
COPY backend/ backend/
COPY frontend/ frontend/
RUN cargo chef prepare --recipe-path recipe.json
# --------------- Stage 3: Backend builder ---------------
FROM chef AS backend-builder
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json -p backend
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
COPY backend/ backend/
COPY frontend/ frontend/
RUN cargo build --release -p backend
# --------------- Stage 4: Frontend builder ---------------
FROM chef AS frontend-builder
# Add the WASM target
RUN rustup target add wasm32-unknown-unknown
# Install Trunk (the WASM bundler used by the frontend) and sass (for SCSS)
RUN cargo install trunk
# Cache frontend dependencies
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --target wasm32-unknown-unknown --recipe-path recipe.json -p frontend
# Copy full workspace source for the build
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
COPY backend/ backend/
COPY frontend/ frontend/
# Build the frontend WASM bundle
# Trunk outputs to frontend/dist by default
WORKDIR /app/frontend
RUN trunk build --release
# --------------- Stage 5: Runtime ---------------
FROM debian:bookworm-slim AS runtime
# Install runtime dependencies:
# - ca-certificates & libssl3: TLS for PostgreSQL connections
# - nginx: serves the frontend static files and reverse-proxies /api to the backend
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates libssl3 nginx && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy the compiled backend binary
COPY --from=backend-builder /app/target/release/backend /app/backend
# Copy migrations
COPY backend/migrations/ /app/migrations/
# Copy the frontend static build output
COPY --from=frontend-builder /app/frontend/dist /var/www/html
# Nginx configuration: serve frontend + reverse-proxy /api to the backend
RUN cat > /etc/nginx/sites-available/default <<'EOF'
server {
listen 80;
server_name _;
root /var/www/html;
index index.html;
# Serve static frontend files, fall back to index.html for client-side routing
location / {
try_files $uri $uri/ /index.html;
}
# Reverse-proxy API requests to the Axum backend
location /api/ {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
# Startup script: launch backend in the background, then nginx in the foreground
RUN cat > /app/start.sh <<'SCRIPT'
#!/bin/bash
set -e
# Start the backend API server in the background
/app/backend &
# Start nginx in the foreground (keeps the container alive)
nginx -g 'daemon off;'
SCRIPT
RUN chmod +x /app/start.sh
EXPOSE 80
# Environment variables should be provided at runtime:
# DATABASE_URL PostgreSQL connection string
# TOKEN_SECRET JWT signing key
# ORIGIN Allowed CORS origin (should be the public URL of this container)
CMD ["/app/start.sh"]
+66
View File
@@ -0,0 +1,66 @@
# ============================================================
# Dockerfile.backend — Backend only
# ============================================================
# Multi-stage build:
# 1. chef install cargo-chef for dependency caching
# 2. planner generate a recipe.json from the workspace
# 3. builder build dependencies first (cached), then the backend binary
# 4. runtime minimal image with just the compiled binary
# ============================================================
# --------------- Stage 1: Chef base ---------------
FROM rust:1-bookworm AS chef
RUN cargo install cargo-chef
WORKDIR /app
# --------------- Stage 2: Planner ---------------
FROM chef AS planner
# Copy the full workspace so cargo-chef can resolve all dependencies
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
COPY backend/ backend/
COPY frontend/ frontend/
RUN cargo chef prepare --recipe-path recipe.json
# --------------- Stage 3: Builder ---------------
FROM chef AS builder
# Cache dependency compilation in its own layer
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json -p backend
# Now copy the real source and build
COPY Cargo.toml Cargo.lock ./
COPY src/ src/
COPY backend/ backend/
COPY frontend/ frontend/
RUN cargo build --release -p backend
# --------------- Stage 4: Runtime ---------------
FROM debian:bookworm-slim AS runtime
# Install TLS root certificates and PostgreSQL client libs (needed by sqlx
# at runtime for TLS connections via native-tls)
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates libssl3 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy the compiled binary
COPY --from=builder /app/target/release/backend /app/backend
# Copy migrations so they can be run at startup if needed
COPY backend/migrations/ /app/migrations/
EXPOSE 8001
# Environment variables should be provided at runtime via docker run --env
# or docker compose environment/env_file.
#
# Required:
# DATABASE_URL PostgreSQL connection string
# TOKEN_SECRET JWT signing key
# ORIGIN Allowed CORS origin (frontend URL)
CMD ["/app/backend"]
+46 -2
View File
@@ -6,9 +6,53 @@ services:
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=tickets
POSTGRES_PASSWORD: tickets
POSTGRES_DB: system_data
volumes:
- pg_data:/var/lib/postregsql/pg_data
- pg_data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
# Full application (frontend + backend + nginx)
# Usage: docker compose --profile full up --build
app:
profiles: ["full"]
build:
context: ..
dockerfile: docker/Dockerfile
container_name: ticketsystem
restart: unless-stopped
ports:
- 8080:80
environment:
DATABASE_URL: postgres://postgres:tickets@postgres:5432/system_data
TOKEN_SECRET: 160257c8c5ff2298363529e963a5901d2efa6d6ae67d634487c4d2bbc41c533f
ORIGIN: http://localhost:8080
depends_on:
postgres:
condition: service_healthy
# Backend only (API server)
# Usage: docker compose --profile backend up --build
backend:
profiles: ["backend"]
build:
context: ..
dockerfile: docker/Dockerfile.backend
container_name: ticketsystem-backend
restart: unless-stopped
ports:
- 8001:8001
environment:
DATABASE_URL: postgres://postgres:tickets@postgres:5432/system_data
TOKEN_SECRET: 160257c8c5ff2298363529e963a5901d2efa6d6ae67d634487c4d2bbc41c533f
ORIGIN: http://localhost:8000
depends_on:
postgres:
condition: service_healthy
volumes:
pg_data: