Implement complete Docker Compose CI/CD setup with optimized builds
- Add multi-stage Dockerfile with dependency caching for both frontend and backend - Implement Docker Compose configuration with separate frontend/backend services - Configure Caddy as reverse proxy with proper WASM and static file serving - Add volume mounting for frontend assets shared between containers - Optimize build process with staged compilation and workspace handling - Add debug logging and WASM initialization tracking for production deployment - Update README with project motivation and "vibe coded" disclaimer 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
125
Dockerfile
125
Dockerfile
@@ -1,67 +1,96 @@
|
||||
# Build stage
|
||||
# ---------------------------------------
|
||||
# -----------------------------------------------------------
|
||||
FROM rust:alpine AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache \
|
||||
musl-dev \
|
||||
pkgconfig \
|
||||
openssl-dev \
|
||||
nodejs \
|
||||
npm
|
||||
RUN apk add --no-cache musl-dev pkgconfig openssl-dev openssl-libs-static nodejs npm
|
||||
|
||||
# Install trunk for building Yew apps
|
||||
RUN cargo install trunk wasm-pack
|
||||
# Install trunk ahead of the compilation. This may break and then you'll have to update the version.
|
||||
RUN cargo install trunk@0.21.14 wasm-pack@0.13.1 wasm-bindgen-cli@0.2.100
|
||||
|
||||
# Add wasm32 target
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy dependency files
|
||||
COPY Cargo.toml ./
|
||||
COPY src ./src
|
||||
# Copy workspace files to maintain workspace structure
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY calendar-models ./calendar-models
|
||||
COPY frontend/Cargo.toml ./frontend/
|
||||
COPY frontend/Trunk.toml ./frontend/
|
||||
COPY frontend/index.html ./frontend/
|
||||
COPY frontend/styles.css ./frontend/
|
||||
|
||||
# Copy web assets
|
||||
COPY index.html ./
|
||||
COPY Trunk.toml ./
|
||||
# Create empty backend directory to satisfy workspace
|
||||
RUN mkdir -p backend/src && \
|
||||
printf '[package]\nname = "calendar-backend"\nversion = "0.1.0"\nedition = "2021"\n\n[dependencies]\n' > backend/Cargo.toml && \
|
||||
echo 'fn main() {}' > backend/src/main.rs
|
||||
|
||||
# Create dummy source files to build dependencies first
|
||||
RUN mkdir -p frontend/src && \
|
||||
echo "use web_sys::*; fn main() {}" > frontend/src/main.rs && \
|
||||
echo "pub fn add(a: usize, b: usize) -> usize { a + b }" > calendar-models/src/lib.rs
|
||||
|
||||
# Build dependencies (this layer will be cached unless dependencies change)
|
||||
RUN cargo build --release --target wasm32-unknown-unknown --bin calendar-app
|
||||
|
||||
# Copy actual source code and build the frontend application
|
||||
RUN rm -rf frontend
|
||||
COPY frontend ./frontend
|
||||
RUN trunk build --release --config ./frontend/Trunk.toml
|
||||
|
||||
|
||||
|
||||
|
||||
# Backend build stage
|
||||
# -----------------------------------------------------------
|
||||
FROM rust:alpine AS backend-builder
|
||||
|
||||
# Install build dependencies for backend
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache musl-dev pkgconfig openssl-dev openssl-libs-static
|
||||
|
||||
# Copy shared models
|
||||
COPY calendar-models ./calendar-models
|
||||
|
||||
# Create empty frontend directory to satisfy workspace
|
||||
RUN mkdir -p frontend/src && \
|
||||
printf '[package]\nname = "calendar-app"\nversion = "0.1.0"\nedition = "2021"\n\n[dependencies]\n' > frontend/Cargo.toml && \
|
||||
echo 'fn main() {}' > frontend/src/main.rs
|
||||
|
||||
# Create dummy backend source to build dependencies first
|
||||
RUN mkdir -p backend/src && \
|
||||
echo "fn main() {}" > backend/src/main.rs
|
||||
|
||||
# Build dependencies (this layer will be cached unless dependencies change)
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY backend/Cargo.toml ./backend/
|
||||
RUN cargo build --release
|
||||
|
||||
# Build the backend
|
||||
COPY backend ./backend
|
||||
RUN cargo build --release --bin backend
|
||||
|
||||
# Build the application
|
||||
RUN trunk build --release
|
||||
|
||||
|
||||
|
||||
# Runtime stage
|
||||
# ---------------------------------------
|
||||
FROM docker.io/nginx:alpine
|
||||
# -----------------------------------------------------------
|
||||
FROM alpine:latest
|
||||
|
||||
# Remove default nginx content
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
# Copy built application from builder stage
|
||||
COPY --from=builder /app/dist/* /usr/share/nginx/html/
|
||||
# Copy frontend files to temporary location
|
||||
COPY --from=builder /app/frontend/dist /app/frontend-dist
|
||||
|
||||
# Add nginx configuration for SPA
|
||||
RUN echo 'server { \
|
||||
listen 80; \
|
||||
server_name localhost; \
|
||||
root /usr/share/nginx/html; \
|
||||
index index.html; \
|
||||
location / { \
|
||||
try_files $uri $uri/ /index.html; \
|
||||
} \
|
||||
# Enable gzip compression \
|
||||
gzip on; \
|
||||
gzip_types text/css application/javascript application/wasm; \
|
||||
}' > /etc/nginx/conf.d/default.conf
|
||||
# Copy backend binary (built in workspace root)
|
||||
COPY --from=backend-builder /app/target/release/backend /usr/local/bin/backend
|
||||
|
||||
# Expose port
|
||||
EXPOSE 80
|
||||
# Create startup script to copy frontend files to shared volume
|
||||
RUN mkdir -p /srv/www
|
||||
RUN echo '#!/bin/sh' > /usr/local/bin/start.sh && \
|
||||
echo 'cp -r /app/frontend-dist/* /srv/www/' >> /usr/local/bin/start.sh && \
|
||||
echo 'echo "Starting backend server..."' >> /usr/local/bin/start.sh && \
|
||||
echo '/usr/local/bin/backend' >> /usr/local/bin/start.sh && \
|
||||
chmod +x /usr/local/bin/start.sh
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
|
||||
|
||||
# Start nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
# Start with script that copies frontend files then starts backend
|
||||
CMD ["/usr/local/bin/start.sh"]
|
||||
|
||||
Reference in New Issue
Block a user