Skip to content

Commit f648be7

Browse files
authored
Merge pull request #57 from febus982/docker_not_root
Run container as non root user
2 parents f222aa6 + ee4ec41 commit f648be7

File tree

2 files changed

+46
-25
lines changed

2 files changed

+46
-25
lines changed

Dockerfile

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,45 @@
1-
# Install shared system requirements (e.g. libmysql)
21
FROM python:3.11-slim as base
2+
ARG UID=2000
3+
ARG GID=2000
4+
RUN addgroup --gid $GID nonroot && \
5+
adduser --uid $UID --gid $GID --disabled-password --gecos "" nonroot
6+
WORKDIR /app
7+
38
# Creating a separate directory for venvs allows to easily
49
# copy them from the builder and to mount the application
510
# for local development
6-
RUN mkdir /poetryvenvs
7-
WORKDIR /app
11+
RUN mkdir /poetryvenvs && chown nonroot:nonroot /poetryvenvs
12+
13+
# Install necessary runtime libraries (e.g. libmysql)
814
RUN apt-get update \
915
&& apt-get install -y --no-install-recommends \
1016
make \
1117
&& rm -rf /var/lib/apt/lists/*
1218

13-
RUN pip install -U pip
14-
RUN pip install poetry
15-
RUN poetry config virtualenvs.path /poetryvenvs
19+
# Update pip and install poetry
20+
RUN pip install --no-cache-dir -U pip
21+
RUN pip install --no-cache-dir -U poetry
1622

17-
# Install shared build system requirements (gcc, library headers, etc.)
1823
FROM base as base_builder
24+
# Install build system requirements (gcc, library headers, etc.)
25+
# for compiled Python requirements like psycopg2
1926
RUN apt-get update \
2027
&& apt-get install -y --no-install-recommends \
2128
build-essential gcc git \
2229
&& rm -rf /var/lib/apt/lists/*
2330

24-
COPY pyproject.toml .
25-
COPY poetry.lock .
31+
# From here we shouldn't need anymore a root user
32+
# Switch to nonroot and config poetry
33+
USER nonroot
34+
RUN poetry config virtualenvs.path /poetryvenvs
35+
36+
COPY --chown=nonroot:nonroot pyproject.toml .
37+
COPY --chown=nonroot:nonroot poetry.lock .
2638

2739
# Test image, contains all files and dependencies
2840
FROM base_builder as test
29-
RUN poetry install --no-root --with http,grpc,dev
30-
COPY . .
41+
RUN poetry install --with http,grpc,dev
42+
COPY --chown=nonroot:nonroot . .
3143

3244
# Installs requirements to run production http application
3345
FROM base_builder as http_builder
@@ -39,25 +51,31 @@ RUN poetry install --no-root --with grpc
3951

4052
# Copy the shared python packages
4153
FROM base as base_app
42-
COPY pyproject.toml .
43-
COPY poetry.lock .
44-
COPY alembic ./alembic
45-
COPY domains ./domains
46-
COPY storage ./storage
47-
COPY config.py .
48-
COPY di_container.py .
49-
COPY alembic.ini .
50-
COPY Makefile .
54+
USER nonroot
55+
RUN poetry config virtualenvs.path /poetryvenvs
56+
COPY --chown=nonroot:nonroot pyproject.toml .
57+
COPY --chown=nonroot:nonroot poetry.lock .
58+
COPY --chown=nonroot:nonroot alembic ./alembic
59+
COPY --chown=nonroot:nonroot domains ./domains
60+
COPY --chown=nonroot:nonroot storage ./storage
61+
COPY --chown=nonroot:nonroot config.py .
62+
COPY --chown=nonroot:nonroot di_container.py .
63+
COPY --chown=nonroot:nonroot alembic.ini .
64+
COPY --chown=nonroot:nonroot Makefile .
5165
ENTRYPOINT ["poetry", "run"]
5266

5367
# Copy the http python package and requirements from relevant builder
5468
FROM base_app as http_app
5569
COPY --from=http_builder /poetryvenvs /poetryvenvs
56-
COPY http_app ./http_app
57-
CMD exec opentelemetry-instrument uvicorn http_app:create_app --host 0.0.0.0 --port 8000 --factory
70+
COPY --chown=nonroot:nonroot http_app ./http_app
71+
# opentelemetry-instrument will spawn a subprocess, therefore we use exec
72+
# to make sure the app runs on PID 1 and receives correctly system signals
73+
CMD opentelemetry-instrument uvicorn http_app:create_app --host 0.0.0.0 --port 8000 --factory
5874

5975
# Copy the grpc python package and requirements from relevant builder
6076
FROM base_app as grpc_app
6177
COPY --from=grpc_builder /poetryvenvs /poetryvenvs
62-
COPY grpc_app ./grpc_app
78+
COPY --chown=nonroot:nonroot grpc_app ./grpc_app
79+
# opentelemetry-instrument will spawn a subprocess, therefore we use exec
80+
# to make sure the app runs on PID 1 and receives correctly system signals
6381
CMD exec opentelemetry-instrument python3 -m grpc_app

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
containers:
2+
# Use local UID to avoid files permission issues when mounting directories
3+
# We could do this at runtime, by specifying the user, but it's easier doing it
4+
# at build time, so no special commands will be necessary at runtime
5+
docker compose build --build-arg UID=`id -u` dev
26
# To build shared container layers only once we build a single container before the other ones
3-
docker compose build dev
4-
docker compose build
7+
docker compose build --build-arg UID=`id -u`
58

69
dev:
710
poetry run uvicorn http_app:create_app --host 0.0.0.0 --port 8000 --factory --reload

0 commit comments

Comments
 (0)