# ============================================================================== # STAGE 1: Build # ============================================================================== FROM rust:1.85-alpine AS builder # Install the minimal C toolchain required by the `ring` crate (a dependency of `rustls`). RUN apk add --no-cache musl-dev gcc WORKDIR /app # 1. Create a dummy binary project for dependency caching. RUN mkdir src RUN echo "fn main() {}" > src/main.rs # 2. Copy the dependency manifests. COPY Cargo.toml Cargo.lock ./ # 3. Build the dependencies. RUN cargo build --release # 4. Now, copy the actual application source code. COPY src ./src # 5. Build the real application. RUN cargo build --release # ============================================================================== # STAGE 2: Create the final production image # ============================================================================== FROM alpine:3.22 AS final # Set default environment variables ENV CRON_SCHEDULE="10 2 * * *" ENV PUID=1000 ENV PGID=1000 # Install runtime dependencies. RUN apk add --no-cache ca-certificates tzdata su-exec busybox # Create a non-root user and group for the application to run as RUN addgroup -S -g ${PGID} app && \ adduser -S -u ${PUID} -G app -h /app app # Copy the compiled binary from the builder stage COPY --from=builder /app/target/release/sbrs /usr/local/bin/ruleset-sync # Copy the entrypoint script COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # Create necessary directories and set ownership for volumes RUN mkdir -p /config /rules && \ chown -R app:app /config /rules # Set the entrypoint for the container ENTRYPOINT ["entrypoint.sh"]