# OpenCrates Production Dockerfile
# Multi-stage build for optimized production deployment
# Build stage
FROM rust:1.75-slim-bullseye AS builder
# Set working directory
WORKDIR /app
# Install system dependencies required for building
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
libsqlite3-dev \
build-essential \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Copy dependency files first for better caching
COPY Cargo.toml Cargo.lock ./
# Create empty src directory and build dependencies
RUN mkdir src && \
echo "fn main() {}" > src/main.rs && \
echo "// Dummy lib.rs" > src/lib.rs && \
cargo build --release && \
rm -rf src
# Copy source code
COPY src ./src
COPY benches ./benches
COPY tests ./tests
COPY migrations ./migrations
COPY templates ./templates
COPY config ./config
COPY scripts ./scripts
COPY proptest-regressions ./proptest-regressions
# Build the application
RUN cargo build --release --bin opencrates
# Runtime stage
FROM debian:bullseye-slim AS runtime
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl1.1 \
libsqlite3-0 \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create opencrates user
RUN useradd -r -s /bin/false opencrates
# Create necessary directories
RUN mkdir -p /app/data /app/config /app/templates /app/logs && \
chown -R opencrates:opencrates /app
# Copy binary from builder stage
COPY --from=builder /app/target/release/opencrates /usr/local/bin/opencrates
# Copy configuration and templates
COPY --chown=opencrates:opencrates config/ /app/config/
COPY --chown=opencrates:opencrates templates/ /app/templates/
COPY --chown=opencrates:opencrates docker-compose.yml /app/
# Set permissions
RUN chmod +x /usr/local/bin/opencrates
# Switch to opencrates user
USER opencrates
# Set working directory
WORKDIR /app
# Environment variables with defaults
ENV RUST_LOG=info
ENV OPENCRATES_HOST=0.0.0.0
ENV OPENCRATES_PORT=8080
ENV OPENCRATES_DATABASE_URL=sqlite:///app/data/opencrates.db
ENV OPENCRATES_CONFIG_PATH=/app/config
ENV OPENCRATES_TEMPLATES_PATH=/app/templates
ENV OPENCRATES_DATA_PATH=/app/data
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:${OPENCRATES_PORT}/health || exit 1
# Expose port
EXPOSE 8080
# Default command
CMD ["opencrates", "serve", "--host", "0.0.0.0", "--port", "8080"]
# Development stage
FROM builder AS development
# Install development tools
RUN apt-get update && apt-get install -y \
vim \
less \
strace \
valgrind \
gdb \
&& rm -rf /var/lib/apt/lists/*
# Install cargo tools
RUN cargo install cargo-watch cargo-audit cargo-outdated
# Copy everything for development
COPY . .
# Build in debug mode
RUN cargo build
# Development environment variables
ENV RUST_LOG=debug
ENV RUST_BACKTRACE=1
# Default command for development
CMD ["cargo", "run", "--", "serve", "--host", "0.0.0.0", "--port", "8080", "--dev"]
# Testing stage
FROM builder AS testing
# Copy test files
COPY . .
# Install testing dependencies
RUN cargo install cargo-tarpaulin
# Run all tests
RUN cargo test --release
# Generate coverage report
RUN cargo tarpaulin --out Xml --output-dir ./target/coverage
# Production stage with minimal dependencies
FROM gcr.io/distroless/cc-debian11 AS production
# Copy CA certificates
COPY --from=runtime /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy binary
COPY --from=builder /app/target/release/opencrates /opencrates
# Copy configuration
COPY --from=runtime /app/config /app/config
COPY --from=runtime /app/templates /app/templates
# Environment variables
ENV RUST_LOG=info
ENV OPENCRATES_HOST=0.0.0.0
ENV OPENCRATES_PORT=8080
# User
USER 1000:1000
# Expose port
EXPOSE 8080
# Command
ENTRYPOINT ["/opencrates"]
CMD ["serve", "--host", "0.0.0.0", "--port", "8080"]