Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions contrib/container/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
# Install basic system level packages
RUN apt-get update && apt-get install -y --no-install-recommends \
git gettext libldap2 wget curl ssh \
# Used by the entrypoint script to drop root privileges in the production image
gosu \
# Weasyprint requirements : https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#alpine-3-12
weasyprint libpango-1.0-0 libcairo2 poppler-utils \
# Database client libraries
Expand All @@ -83,6 +85,11 @@
# Fix invoke command path for InvenTree environment check
RUN python -m pip install --no-cache-dir -U invoke

# Dedicated non-root user for running InvenTree in the 'production' image.
# Fixed uid/gid so that operators can chown their host-mounted data volume to match.
RUN groupadd --gid 1000 inventree \
&& useradd --uid 1000 --gid inventree --home-dir ${INVENTREE_HOME} --shell /bin/bash inventree

RUN mkdir -p ${INVENTREE_HOME}
WORKDIR ${INVENTREE_HOME}

Expand Down Expand Up @@ -132,6 +139,10 @@

ENV INVENTREE_DEBUG=False

# Container starts as root, but init.sh drops to this user before launching the
# CMD (fixing up ownership of the mounted data volume along the way) - see init.sh
ENV INVENTREE_RUN_AS_USER="inventree"

# As .git directory is not available in production image, we pass the commit information via ENV
ENV INVENTREE_COMMIT_HASH="${commit_hash}"
ENV INVENTREE_COMMIT_DATE="${commit_date}"
Expand All @@ -141,6 +152,11 @@
COPY src/backend/requirements.txt ${INVENTREE_BACKEND_DIR}/requirements.txt

# Copy compiled dependencies from prebuild image
# PYTHONUSERBASE must be pinned explicitly: pip installed these packages as --user
# under root, and Python resolves the user site-packages dir relative to the *running*
# user's home directory unless overridden - without this, imports break once we
# switch away from root below.
ENV PYTHONUSERBASE=/root/.local
ENV PATH=/root/.local/bin:$PATH

COPY --from=builder_stage ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web
Expand All @@ -153,6 +169,14 @@
RUN pip-licenses --format=json --with-license-file --no-license-path > "${INVENTREE_BACKEND_DIR}/InvenTree/InvenTree/licenses.txt" \
&& test -s "${INVENTREE_BACKEND_DIR}/InvenTree/InvenTree/licenses.txt"

# Fix up ownership of the application code/static files, and open up read access to
# the --user installed python packages under /root/.local (not readable by other users
# by default) - init.sh drops to the non-root 'inventree' user before launch, and
# additionally fixes up ownership of the (host-mounted) data volume at that point.
RUN chown -R inventree:inventree ${INVENTREE_HOME} \

Check warning on line 176 in contrib/container/Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Surround this variable with double quotes; otherwise, it can lead to unexpected behavior.

See more on https://sonarcloud.io/project/issues?id=inventree_InvenTree&issues=AaBckByvdQhJpfo5ayNg&open=AaBckByvdQhJpfo5ayNg&pullRequest=12760
&& chmod 755 /root \
&& chmod -R o+rX /root/.local
Comment on lines 155 to +178

# Launch the production server
CMD ["sh", "-c", "exec gunicorn -c ./gunicorn.conf.py InvenTree.wsgi -b ${INVENTREE_WEB_ADDR}:${INVENTREE_WEB_PORT} --chdir ${INVENTREE_BACKEND_DIR}/InvenTree"]

Expand Down
9 changes: 9 additions & 0 deletions contrib/container/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,14 @@ fi

cd ${INVENTREE_HOME}

# If requested (production image only), drop root privileges before launching the CMD.
# This lets the external data volume be bind-mounted with any host ownership -
# we fix it up here rather than requiring the operator to chown it in advance.
if [[ "$(id -u)" = "0" && -n "$INVENTREE_RUN_AS_USER" ]]; then
echo "Setting ownership of ${INVENTREE_DATA_DIR} to '${INVENTREE_RUN_AS_USER}'"
chown -R "${INVENTREE_RUN_AS_USER}:${INVENTREE_RUN_AS_USER}" "${INVENTREE_DATA_DIR}"
exec gosu "${INVENTREE_RUN_AS_USER}" "$@"
fi
Comment on lines +58 to +65

# Launch the CMD *after* the ENTRYPOINT completes
exec "$@"
3 changes: 3 additions & 0 deletions docs/docs/start/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ InvenTree stores any persistent data (e.g. uploaded media files, database data,
!!! info "Data Directory"
Make sure you change the path to the local directory where you want persistent data to be stored.

!!! info "Directory Ownership"
The `inventree-server` and `inventree-worker` containers run application code as a non-root user (`uid=1000`, `gid=1000`), rather than as `root`. On startup, each container automatically takes ownership of the directory mapped to `INVENTREE_EXT_VOLUME` (equivalent to `chown -R 1000:1000`) before dropping root privileges - no manual setup of this directory is required.
Comment on lines +118 to +119

### Database Connection

The `inventree-db` container is configured to use the `postgres:{{ config.extra.docker_postgres_version }}` docker image.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/start/docker_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Download these files to a directory on your local machine.
The first step is to edit the environment variables, located in the `.env` file.

!!! warning "External Volume"
You must define the `INVENTREE_EXT_VOLUME` variable - this must point to a directory *on your local machine* where persistent data is to be stored.
You must define the `INVENTREE_EXT_VOLUME` variable - this must point to a directory *on your local machine* where persistent data is to be stored. See [directory ownership](./docker.md#data-volume) for notes on how this directory's permissions are managed.

!!! warning "Database Credentials"
You must also define the database username (`INVENTREE_DB_USER`) and password (`INVENTREE_DB_PASSWORD`). You should ensure they are changed from the default values for added security
Expand Down
Loading