Skip to content

Commit 1695f17

Browse files
authored
Use deterministic UID/GID in Dockerfile #1555 (#1569)
Signed-off-by: tdruez <[email protected]>
1 parent 944d960 commit 1695f17

File tree

3 files changed

+77
-23
lines changed

3 files changed

+77
-23
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ Changelog
44
v35.4.0 (unreleased)
55
--------------------
66

7+
- Use deterministic UID/GID in Dockerfile.
8+
A temporary ``chown`` service is now started in the ``docker-compose`` stack
9+
to fix the permissions. This process is only fully run once.
10+
You may manually run this process using the following:
11+
``$ chown -R 1000:1000 /var/scancodeio/``
12+
https://github.com/aboutcode-org/scancode.io/issues/1555
13+
714
- Resolve and load dependencies from SPDX SBOMs.
815
https://github.com/aboutcode-org/scancode.io/issues/1145
916

Dockerfile

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,23 @@ LABEL org.opencontainers.image.source="https://github.com/aboutcode-org/scancode
2626
LABEL org.opencontainers.image.description="ScanCode.io"
2727
LABEL org.opencontainers.image.licenses="Apache-2.0"
2828

29-
ENV APP_NAME scancodeio
30-
ENV APP_USER app
31-
ENV APP_DIR /opt/$APP_NAME
32-
ENV VENV_LOCATION /opt/$APP_NAME/.venv
29+
# Set default values for APP_UID and APP_GID at build-time
30+
ARG APP_UID=1000
31+
ARG APP_GID=1000
32+
33+
ENV APP_NAME=scancodeio
34+
ENV APP_USER=app
35+
ENV APP_UID=${APP_UID}
36+
ENV APP_GID=${APP_GID}
37+
ENV APP_DIR=/opt/$APP_NAME
38+
ENV VENV_LOCATION=/opt/$APP_NAME/.venv
3339

3440
# Force Python unbuffered stdout and stderr (they are flushed to terminal immediately)
35-
ENV PYTHONUNBUFFERED 1
41+
ENV PYTHONUNBUFFERED=1
3642
# Do not write Python .pyc files
37-
ENV PYTHONDONTWRITEBYTECODE 1
43+
ENV PYTHONDONTWRITEBYTECODE=1
3844
# Add the app dir in the Python path for entry points availability
39-
ENV PYTHONPATH $PYTHONPATH:$APP_DIR
45+
ENV PYTHONPATH=$PYTHONPATH:$APP_DIR
4046

4147
# OS requirements as per
4248
# https://scancode-toolkit.readthedocs.io/en/latest/getting-started/install.html
@@ -64,27 +70,24 @@ RUN apt-get update \
6470
&& apt-get clean \
6571
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
6672

67-
# Create the APP_USER group and user
68-
RUN addgroup --system $APP_USER \
69-
&& adduser --system --group --home=$APP_DIR $APP_USER \
70-
&& chown $APP_USER:$APP_USER $APP_DIR
71-
72-
# Create the /var/APP_NAME directory with proper permission for APP_USER
73-
RUN mkdir -p /var/$APP_NAME \
73+
# Create the APP_USER group, user, and directory with specific UID and GID
74+
RUN groupadd --gid $APP_GID --system $APP_USER \
75+
&& useradd --uid $APP_UID --gid $APP_GID --home-dir $APP_DIR --system --create-home $APP_USER \
76+
&& chown $APP_USER:$APP_USER $APP_DIR \
77+
&& mkdir -p /var/$APP_NAME \
7478
&& chown $APP_USER:$APP_USER /var/$APP_NAME
7579

7680
# Setup the work directory and the user as APP_USER for the remaining stages
7781
WORKDIR $APP_DIR
7882
USER $APP_USER
7983

84+
# Create static/ and workspace/ directories
85+
RUN mkdir -p /var/$APP_NAME/static/ /var/$APP_NAME/workspace/
86+
8087
# Create the virtualenv
8188
RUN python -m venv $VENV_LOCATION
8289
# Enable the virtualenv, similar effect as "source activate"
83-
ENV PATH $VENV_LOCATION/bin:$PATH
84-
85-
# Create static/ and workspace/ directories
86-
RUN mkdir -p /var/$APP_NAME/static/ \
87-
&& mkdir -p /var/$APP_NAME/workspace/
90+
ENV PATH=$VENV_LOCATION/bin:$PATH
8891

8992
# Install the dependencies before the codebase COPY for proper Docker layer caching
9093
COPY --chown=$APP_USER:$APP_USER pyproject.toml $APP_DIR/

docker-compose.yml

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ services:
88
- db_data:/var/lib/postgresql/data/
99
shm_size: "1gb"
1010
restart: always
11+
healthcheck:
12+
test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" ]
13+
interval: 10s
14+
timeout: 5s
15+
retries: 5
1116

1217
redis:
1318
image: docker.io/library/redis:latest
@@ -18,12 +23,45 @@ services:
1823
- redis_data:/data
1924
restart: always
2025

26+
# This service is responsible for ensuring the correct ownership of files
27+
# in the shared volumes used by the application (static and workspace).
28+
# It ensures that all files inside the `/var/scancodeio/` directory are owned
29+
# by the user and group with the UID and GID defined in the environment variables
30+
# APP_UID and APP_GID, which default to 1000 if not set.
31+
#
32+
# The service runs only once (due to "restart: no") and performs a `chown` operation
33+
# to change the ownership of the static and workspace directories, ensuring proper
34+
# file access rights for the running application containers.
35+
#
36+
# Volumes mounted:
37+
# - static: Ensures the ownership of static files in the /var/scancodeio/static directory
38+
# - media: Ensures the ownership of media files in the /var/scancodeio/workspace directory
39+
#
40+
# Notes: This service can be removed in future ScanCode.io release.
41+
chown:
42+
image: docker.io/library/alpine:latest
43+
restart: "no"
44+
command: sh -c "
45+
if [ ! -f /var/scancodeio/workspace/.chown_done ]; then
46+
chown -R ${APP_UID:-1000}:${APP_GID:-1000} /var/scancodeio/ &&
47+
touch /var/scancodeio/workspace/.chown_done;
48+
echo 'Chown applied!';
49+
else
50+
echo 'Chown already applied, skipping...';
51+
fi"
52+
env_file:
53+
- docker.env
54+
volumes:
55+
- static:/var/scancodeio/static/
56+
- workspace:/var/scancodeio/workspace/
57+
2158
web:
2259
build: .
23-
command: wait-for-it --strict --timeout=60 db:5432 -- sh -c "
60+
command: sh -c "
2461
./manage.py migrate &&
2562
./manage.py collectstatic --no-input --verbosity 0 --clear &&
26-
gunicorn scancodeio.wsgi:application --bind :8000 --timeout 600 --workers 8 ${GUNICORN_RELOAD_FLAG:-}"
63+
gunicorn scancodeio.wsgi:application --bind :8000 --timeout 600 \
64+
--workers 8 ${GUNICORN_RELOAD_FLAG:-}"
2765
env_file:
2866
- docker.env
2967
expose:
@@ -34,12 +72,17 @@ services:
3472
- workspace:/var/scancodeio/workspace/
3573
- static:/var/scancodeio/static/
3674
depends_on:
37-
- db
75+
db:
76+
condition: service_healthy
77+
redis:
78+
condition: service_started
79+
chown:
80+
condition: service_completed_successfully
3881

3982
worker:
4083
build: .
4184
# Ensure that potential db migrations run first by waiting until "web" is up
42-
command: wait-for-it --strict --timeout=120 web:8000 -- sh -c "
85+
command: wait-for-it --strict --timeout=600 web:8000 -- sh -c "
4386
./manage.py rqworker --worker-class scancodeio.worker.ScanCodeIOWorker
4487
--queue-class scancodeio.worker.ScanCodeIOQueue
4588
--verbosity 1"
@@ -53,6 +96,7 @@ services:
5396
- redis
5497
- db
5598
- web
99+
- chown
56100

57101
nginx:
58102
image: docker.io/library/nginx:alpine

0 commit comments

Comments
 (0)