Some checks failed
CI Pipeline / Rust Format Check (push) Successful in 5s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Failing after 1m46s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
Three issues fixed in the multi-stage Docker build: 1. CRITICAL: Add COPY migrations/ to rust-builder stage - sqlx::migrate!(../../migrations) is a compile-time proc macro - Without migrations/ present, cargo build fails with 'no such file or directory' - Previously migrations/ was only copied in runtime stage (too late) 2. Copy individual crate Cargo.toml files for dependency caching - The dummy-build caching step only copied workspace Cargo.toml/Cargo.lock - Without crate-level manifests, cargo couldn't resolve the workspace - This meant the cache layer was ineffective (rebuilt everything on code changes) 3. Add openssl package to runtime stage - entrypoint.sh uses openssl rand, openssl genpkey, openssl pkey - Only libssl3t64 (shared library) was installed, not the CLI tool - Runtime would fail on first-run key generation All stages verified: Ubuntu 24.04 ✅ Rust via rustup (1.85+) ✅
142 lines
4.9 KiB
Docker
142 lines
4.9 KiB
Docker
# =============================================================================
|
|
# Linux Patch Manager — Multi-stage Docker Build
|
|
# =============================================================================
|
|
# Build: docker build -t linux-patch-manager .
|
|
# Run: docker compose up
|
|
# =============================================================================
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 1: Rust build (Ubuntu 24.04 + rustup)
|
|
# ---------------------------------------------------------------------------
|
|
FROM ubuntu:24.04 AS rust-builder
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
RUN apt-get update && apt-get install -y \
|
|
build-essential \
|
|
curl \
|
|
pkg-config \
|
|
libssl-dev \
|
|
libfontconfig1-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Rust via rustup (stable channel, provides 1.85+)
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
|
ENV PATH="/root/.cargo/bin:${PATH}"
|
|
|
|
WORKDIR /usr/src/app
|
|
|
|
# Cache dependencies by building a dummy project first
|
|
COPY Cargo.toml Cargo.lock ./
|
|
COPY crates/pm-web/Cargo.toml crates/pm-web/Cargo.toml
|
|
COPY crates/pm-worker/Cargo.toml crates/pm-worker/Cargo.toml
|
|
COPY crates/pm-core/Cargo.toml crates/pm-core/Cargo.toml
|
|
COPY crates/pm-agent-client/Cargo.toml crates/pm-agent-client/Cargo.toml
|
|
COPY crates/pm-auth/Cargo.toml crates/pm-auth/Cargo.toml
|
|
COPY crates/pm-ca/Cargo.toml crates/pm-ca/Cargo.toml
|
|
COPY crates/pm-reports/Cargo.toml crates/pm-reports/Cargo.toml
|
|
COPY crates/migrate-secrets/Cargo.toml crates/migrate-secrets/Cargo.toml
|
|
RUN mkdir -p crates/pm-web/src crates/pm-worker/src crates/pm-core/src \
|
|
crates/pm-agent-client/src crates/pm-auth/src crates/pm-ca/src \
|
|
crates/pm-reports/src crates/migrate-secrets/src
|
|
RUN echo 'fn main(){}' > crates/pm-web/src/main.rs \
|
|
&& echo 'fn main(){}' > crates/pm-worker/src/main.rs \
|
|
&& echo '' > crates/pm-core/src/lib.rs \
|
|
&& echo '' > crates/pm-agent-client/src/lib.rs \
|
|
&& echo '' > crates/pm-auth/src/lib.rs \
|
|
&& echo '' > crates/pm-ca/src/lib.rs \
|
|
&& echo '' > crates/pm-reports/src/lib.rs \
|
|
&& echo 'fn main(){}' > crates/migrate-secrets/src/main.rs
|
|
RUN cargo build --release 2>/dev/null || true
|
|
|
|
# Now build the real project
|
|
COPY crates/ crates/
|
|
COPY migrations/ migrations/
|
|
RUN cargo build --release
|
|
|
|
# Verify binaries exist
|
|
RUN ls -la target/release/pm-web target/release/pm-worker
|
|
|
|
# Strip debug symbols
|
|
RUN strip target/release/pm-web target/release/pm-worker
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 2: Frontend build (Ubuntu 24.04 + Node.js 20)
|
|
# ---------------------------------------------------------------------------
|
|
FROM ubuntu:24.04 AS frontend-builder
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
RUN apt-get update && apt-get install -y \
|
|
curl \
|
|
ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Node.js 20 via NodeSource
|
|
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
&& apt-get install -y nodejs \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /usr/src/app/frontend
|
|
COPY frontend/package.json frontend/package-lock.json ./
|
|
RUN npm ci --production=false
|
|
|
|
COPY frontend/ ./
|
|
RUN npm run build
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 3: Runtime
|
|
# ---------------------------------------------------------------------------
|
|
FROM ubuntu:24.04 AS runtime
|
|
|
|
RUN apt-get update && apt-get install -y \
|
|
ca-certificates \
|
|
libssl3t64 \
|
|
libfontconfig1 \
|
|
openssl \
|
|
postgresql-client-16 \
|
|
argon2 \
|
|
curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create service user
|
|
RUN useradd --system --no-create-home --shell /usr/sbin/nologin \
|
|
--comment "Linux Patch Manager service account" patch-manager
|
|
|
|
# Create directories
|
|
RUN mkdir -p /etc/patch-manager/ca /etc/patch-manager/certs \
|
|
/etc/patch-manager/jwt /etc/patch-manager/tls \
|
|
/var/log/patch-manager /opt/patch-manager \
|
|
/usr/share/patch-manager/frontend \
|
|
/usr/share/patch-manager/migrations
|
|
|
|
# Copy binaries
|
|
COPY --from=rust-builder /usr/src/app/target/release/pm-web /usr/local/bin/pm-web
|
|
COPY --from=rust-builder /usr/src/app/target/release/pm-worker /usr/local/bin/pm-worker
|
|
|
|
# Copy frontend
|
|
COPY --from=frontend-builder /usr/src/app/frontend/dist/ /usr/share/patch-manager/frontend/
|
|
|
|
# Copy migrations
|
|
COPY migrations/ /usr/share/patch-manager/migrations/
|
|
|
|
# Copy entrypoint
|
|
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
RUN chmod 755 /usr/local/bin/entrypoint.sh
|
|
|
|
# Copy config template
|
|
COPY config/config.example.toml /usr/share/patch-manager/config.example.toml
|
|
|
|
# Set ownership
|
|
RUN chown -R patch-manager:patch-manager \
|
|
/etc/patch-manager /var/log/patch-manager \
|
|
/opt/patch-manager /usr/share/patch-manager
|
|
|
|
# Expose HTTPS port
|
|
EXPOSE 443
|
|
|
|
# Volume for persistent data
|
|
VOLUME ["/etc/patch-manager", "/var/log/patch-manager", "/opt/patch-manager"]
|
|
|
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|