Run docker container as non-root user - #12760
Conversation
SchrodingersGat
commented
Sep 1, 2026
- Closes [Docker] Container permissions #6589
✅ Deploy Preview for inventree-web-pui-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR aims to address docker bind-mount permission issues by running the InvenTree application processes (server/worker) as a dedicated non-root user in the production container image, while still performing required setup steps at startup.
Changes:
- Add a fixed
inventreeuser/group (uid=1000,gid=1000) and usegosuto drop privileges at container startup. - Update the container entrypoint to adjust ownership before launching the main command.
- Document the non-root behavior and directory ownership expectations in the Docker setup docs.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| docs/docs/start/docker.md | Documents non-root execution and external volume ownership behavior. |
| docs/docs/start/docker_install.md | Links install guidance to the directory ownership notes. |
| contrib/container/init.sh | Adds startup-time chown + gosu privilege drop logic. |
| contrib/container/Dockerfile | Installs gosu, adds inventree user, and adjusts Python userbase behavior for non-root runtime. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # 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 |
| @@ -153,6 +169,14 @@ RUN bash -c "cd '${INVENTREE_HOME}' && invoke int.backend-compilemessages" | |||
| 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} \ | |||
| && chmod 755 /root \ | |||
| && chmod -R o+rX /root/.local | |||
| !!! 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. |
|
Looks good in general; have you tested this starting up on an existing setup? |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #12760 +/- ##
==========================================
- Coverage 87.14% 87.13% -0.01%
==========================================
Files 1483 1483
Lines 100534 100526 -8
Branches 11524 11605 +81
==========================================
- Hits 87606 87597 -9
+ Misses 12866 12865 -1
- Partials 62 64 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Not yet. Still have to perform testing |
