Non-root user using gosu in app container. closes #1102#1106
Non-root user using gosu in app container. closes #1102#1106regulartim merged 3 commits intointelowlproject:developfrom
Conversation
- install gosu in Dockerfile alongside existing runtime dependencies - add mkdir -p /run/gunicorn and chown -R 2000:82 /var/log/greedybear /run in entrypoint_gunicorn.sh to pre-create socket directory and fix ownership of any root-owned files from previous deployments - replace exec "$@" with exec gosu www-data "$@" at the end of entrypoint_gunicorn.sh so gunicorn runs as www-data (uid 2000) instead of root the entrypoint still starts as root so chown, migrations and collectstatic continue to work correctly. gosu drops privileges to www-data right before gunicorn starts, ensuring gunicorn and all its workers run as non-root for their entire lifetime. existing deployments with log files owned by root are automatically fixed by the chown step on every restart — no manual migration needed.
|
Hi @regulartim , I have implemented non-root user! please take look when you get a chance. happy to make any changes based on your review! |
regulartim
left a comment
There was a problem hiding this comment.
Looks solid! 👍 @mlodic any concerns from your side?
docker/entrypoint_gunicorn.sh
Outdated
|
|
||
| # Fix log file ownership (manage.py commands above run as root and may create new log files) | ||
| chown -R 2000:82 /var/log/greedybear | ||
| chown -R 2000:82 /var/log/greedybear /run |
There was a problem hiding this comment.
Why not "/run/guincorn" ? There isn't really much else in "/run" but that might change...
There was a problem hiding this comment.
Good catch! you are 100% correct. In default.yml file, docker volume(gunicorn_sockets) is mounted at /run/gunicorn specifically. so www-data needs ownership only run/gunicorn not whole 'run' folder.
docker/entrypoint_gunicorn.sh
Outdated
| echo "------------------------------" | ||
|
|
||
| exec "$@" | ||
| exec gosu www-data "$@" |
There was a problem hiding this comment.
I had some problems when running the django dev server: watchfiles does not have the permission to read some of my folders. Maybe we should skip gosu in dev mode?
if [ "$DJANGO_TEST_SERVER" = "True" ]; then
exec "$@"
else
exec gosu www-data "$@"
fi
There was a problem hiding this comment.
yeah definitively not needed in dev mode
There was a problem hiding this comment.
Yes, I will write the code to skip gosu in dev mode!
docker/entrypoint_gunicorn.sh
Outdated
| echo "------------------------------" | ||
|
|
||
| exec "$@" | ||
| exec gosu www-data "$@" |
There was a problem hiding this comment.
yeah definitively not needed in dev mode
… into feature/non-root-user-docker
|
Hi @regulartim , I have made changes! Could you please verify? |
Description
gosuin Dockerfile alongside existing runtime dependencies (libgomp1,curl)mkdir -p /run/gunicornandchown -R 2000:82 /var/log/greedybear /runinentrypoint_gunicorn.shto pre-create the gunicorn socket directory and fix ownership of any root-owned files from previous deploymentsexec "$@"withexec gosu www-data "$@"at the end ofentrypoint_gunicorn.shso gunicorn runs aswww-data(uid 2000) instead of rootThe entrypoint still starts as root so
chown, migrations andcollectstaticcontinue to work correctly.gosudrops privileges towww-dataright before gunicorn starts, ensuring gunicorn and all its workers run as non-root for their entire lifetime.Existing deployments with log files owned by root are automatically fixed by the
chownstep on every restart — no manual migration needed.Tested with both
default.yml(production) andlocal_override.yml(development) — all working correctly.Related issues
Closes #1102
Type of change
Checklist
Formalities
<feature name>. Closes #999develop.develop.Docs and tests
Ruff) gave 0 errors.