-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
93 lines (70 loc) · 3.19 KB
/
Dockerfile
File metadata and controls
93 lines (70 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# syntax=docker/dockerfile:1@sha256:b6afd42430b15f2d2a4c5a02b919e98a525b785b1aaff16747d2f623364e39b6
# Build arguments for versioning
ARG BUILD_TIME=unknown
ARG GIT_SHA=unknown
ARG VERSION=dev
ARG RELEASE_CHANNEL=dev
# Stage 1: Build frontend
# Pin to digest for reproducible builds (Dependabot will update this)
FROM node:24-alpine@sha256:cd6fb7efa6490f039f3471a189214d5f548c11df1ff9e5b181aa49e22c14383e AS frontend-builder
WORKDIR /app/frontend
# Copy package files
COPY frontend/package*.json ./
# Install dependencies
RUN npm ci
# Copy frontend source
COPY frontend/ ./
# Build frontend
RUN npm run build
# Stage 2: Build Python dependencies
# Use Chainguard's dev image which includes pip and build tools
# Pin to digest for reproducible builds (Dependabot will update this)
FROM cgr.dev/chainguard/python:latest-dev@sha256:16ef9480a72a9e1f422ade7c60c7d4d4a3ef258b676ecd223ae137972c3520fc AS python-builder
WORKDIR /app
# Copy requirements (PyPI packages with hashes + VCS packages)
COPY requirements/base.txt requirements/vcs.txt ./requirements/
# Install Python dependencies to a virtual environment
# This allows us to copy just the installed packages to the runtime image
# PyPI packages are hash-verified for supply chain security
# VCS packages (monarchmoney) are installed separately without hash verification
RUN python -m venv /app/venv && \
/app/venv/bin/pip install --no-cache-dir --upgrade pip && \
/app/venv/bin/pip install --no-cache-dir --require-hashes -r requirements/base.txt && \
/app/venv/bin/pip install --no-cache-dir --no-deps -r requirements/vcs.txt
# Stage 3: Runtime with minimal Chainguard image
# This image has 0-5 CVEs typically vs 800+ in python:3.12-slim
# Pin to digest for reproducible builds (Dependabot will update this)
FROM cgr.dev/chainguard/python:latest@sha256:90d81f1d75d9042571a6776b89763678f77fae44e399baf823466091bd494b02
# Re-declare build args for this stage
ARG BUILD_TIME=unknown
ARG GIT_SHA=unknown
ARG VERSION=dev
ARG RELEASE_CHANNEL=dev
# Set environment variables for the application
ENV BUILD_TIME=${BUILD_TIME}
ENV GIT_SHA=${GIT_SHA}
ENV APP_VERSION=${VERSION}
ENV RELEASE_CHANNEL=${RELEASE_CHANNEL}
# Chainguard images run as non-root by default (UID 65532)
# No need to create a user
WORKDIR /app
# Copy virtual environment from builder (owned by nonroot user)
COPY --from=python-builder --chown=65532:65532 /app/venv /app/venv
# Set PATH to use the virtual environment
ENV PATH="/app/venv/bin:$PATH"
# Copy Python source (owned by nonroot user)
COPY --chown=65532:65532 *.py ./
COPY --chown=65532:65532 blueprints/ ./blueprints/
COPY --chown=65532:65532 services/ ./services/
COPY --chown=65532:65532 core/ ./core/
# Copy state module with nonroot ownership (UID 65532) so app can write data files
# Note: /app/state should be mounted as a volume for persistent data
# Docker: docker run -v eclosion-data:/app/state ...
COPY --chown=65532:65532 state/ ./state/
# Copy built frontend from builder stage (owned by nonroot user)
COPY --from=frontend-builder --chown=65532:65532 /app/frontend/dist ./static
# Expose port
EXPOSE 5001
# Override Chainguard's default entrypoint to use venv Python with installed packages
ENTRYPOINT ["/app/venv/bin/python"]
CMD ["app.py"]