Skip to content

Commit 2425520

Browse files
committed
CI: securing service image multi-stage build
1 parent 4dae2b6 commit 2425520

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
tests
22
__pycache__
3-
.venv
43
.env
4+
pytest.ini
5+
Dockerfile
6+
README.md
Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
1-
FROM python:3.10-slim
1+
FROM python:3.10-slim AS base
2+
3+
4+
RUN apt-get update && apt-get install -y --no-install-recommends \
5+
&& rm -rf /var/lib/apt/lists/*
6+
7+
8+
# Tweak Python to run better in Docker
9+
ENV PYTHONUNBUFFERED=1 \
10+
PYTHONDONTWRITEBYTECODE=1
11+
12+
13+
# Build stage: dev & build dependencies
14+
FROM base AS build
15+
216
COPY --from=ghcr.io/astral-sh/uv:0.7.19 /uv /uvx /bin/
317

4-
# Set environment variables
5-
ENV PYTHONDONTWRITEBYTECODE=1
6-
ENV PYTHONUNBUFFERED=1
7-
ENV BOKEH_ALLOW_WS_ORIGIN="*"
18+
# UV_COMPILE_BYTECODE=1 is an important startup time optimization
19+
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
20+
21+
WORKDIR /app
22+
23+
COPY uv.lock pyproject.toml ./
24+
RUN --mount=type=cache,target=/root/.cache/uv \
25+
uv sync --frozen --no-install-project --no-dev
26+
27+
COPY . .
28+
RUN --mount=type=cache,target=/root/.cache/uv \
29+
uv sync --frozen --no-dev
30+
31+
# Runtime stage: only venv
32+
FROM base AS runtime
33+
34+
WORKDIR /app
35+
36+
# Create user and group
37+
RUN addgroup --gid 1001 --system nonroot && \
38+
adduser --no-create-home --shell /bin/false \
39+
--disabled-password --uid 1001 --system --group nonroot
40+
41+
# Switch to non-root user
42+
USER nonroot:nonroot
843

9-
WORKDIR /usr/src/dashboard_service
10-
COPY ./pyproject.toml ./
11-
COPY ./uv.lock ./
12-
RUN uv sync --locked
44+
ENV VIRTUAL_ENV=/app/.venv \
45+
PATH="/app/.venv/bin:$PATH"
1346

14-
COPY src/nsdf_intersect_service/dashboard_service.py .
47+
COPY --from=build --chown=nonroot:nonroot /app ./
1548
COPY ./src/nsdf_intersect_service/config_dashboard.yaml /config/config_dashboard_default.yaml
1649
COPY ./src/nsdf_intersect_service/config_service.yaml /config/config_default.yaml
1750

1851
EXPOSE 10043
1952

20-
CMD ["uv", "run", "dashboard_service.py"]
53+
CMD ["python", "/app/src/nsdf_intersect_service/dashboard_service.py"]

0 commit comments

Comments
 (0)