Skip to content

Non-root user using gosu in app container. closes #1102#1106

Merged
regulartim merged 3 commits intointelowlproject:developfrom
SupRaKoshti:feature/non-root-user-docker
Mar 25, 2026
Merged

Non-root user using gosu in app container. closes #1102#1106
regulartim merged 3 commits intointelowlproject:developfrom
SupRaKoshti:feature/non-root-user-docker

Conversation

@SupRaKoshti
Copy link
Contributor

Description

  • Install gosu in Dockerfile alongside existing runtime dependencies (libgomp1, curl)
  • Add mkdir -p /run/gunicorn and chown -R 2000:82 /var/log/greedybear /run in entrypoint_gunicorn.sh to pre-create the gunicorn 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.

Tested with both default.yml (production) and local_override.yml (development) — all working correctly.

Related issues

Closes #1102

Type of change

  • Bug fix (non-breaking change which fixes an issue).
  • New feature (non-breaking change which adds functionality).
  • Breaking change (fix or feature that would cause existing functionality to not work as expected).
  • Chore (refactoring, dependency updates, CI/CD changes, code cleanup, docs-only changes).

Checklist

Formalities

  • I have read and understood the rules about how to Contribute to this project.
  • I chose an appropriate title for the pull request in the form: <feature name>. Closes #999
  • My branch is based on develop.
  • The pull request is for the branch develop.
  • I have reviewed and verified any LLM-generated code included in this PR.

Docs and tests

  • I documented my code changes with docstrings and/or comments.
  • I have checked if my changes affect user-facing behavior that is described in the docs. If so, I also created a pull request in the docs repository.
  • Linter (Ruff) gave 0 errors.
  • I have added tests for the feature/bug I solved.
  • All the tests gave 0 errors.

- 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.
@SupRaKoshti
Copy link
Contributor Author

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!

Copy link
Collaborator

@regulartim regulartim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid! 👍 @mlodic any concerns from your side?


# 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not "/run/guincorn" ? There isn't really much else in "/run" but that might change...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

echo "------------------------------"

exec "$@"
exec gosu www-data "$@"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah definitively not needed in dev mode

Copy link
Contributor Author

@SupRaKoshti SupRaKoshti Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will write the code to skip gosu in dev mode!

Copy link
Member

@mlodic mlodic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's good finding

echo "------------------------------"

exec "$@"
exec gosu www-data "$@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah definitively not needed in dev mode

- Scope chown to /var/log/greedybear /run/ginucorn only (least privilege)
- Skip gosu in dev mode (DJANGO_TEST_SERVER=True)
@SupRaKoshti
Copy link
Contributor Author

Hi @regulartim , I have made changes! Could you please verify?

Copy link
Collaborator

@regulartim regulartim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you! :)

@regulartim regulartim merged commit 03855bf into intelowlproject:develop Mar 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants