lemonsaurus / django-simple-bulma

Django application to add the Bulma CSS framework and its extensions
MIT License
136 stars 16 forks source link

collectstatic permissions issue #101

Open mfoulds opened 2 months ago

mfoulds commented 2 months ago

TLDR;

I get a permission error when running collectstatic. I have a workaround, but wondering if there's a more fundamental fix I can apply?

Details

I'm running a dockerised django project. I've installed django-simple-bulma and added to settings as required.

STATICFILES_FINDERS = [
    # Default finders
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    # Bulma finder
    "django_simple_bulma.finders.SimpleBulmaFinder",
]

If I run manage.py collectstatic as root user, then everything works fine. However when running in development mode as a regular user (I don't have root access inside the development container), I get the error below. Same problem when running on the production VPS server:

$ ./manage.py collectstatic
BASE_DIR = /home/devuser/navapps/src

You have requested to collect static files at the destination
location as specified in your settings:

    /home/devuser/navapps/src/staticfiles

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes
Found another file with the destination path 'admin/js/cancel.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'admin/js/popup_response.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'admin/js/collapse.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Traceback (most recent call last):
  File "/home/devuser/navapps/src/./manage.py", line 21, in <module>
    main()
  File "/home/devuser/navapps/src/./manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 209, in handle
    collected = self.collect()
                ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 126, in collect
    for path, storage in finder.list(self.ignore_patterns):
  File "/usr/local/lib/python3.11/site-packages/django_simple_bulma/finders.py", line 215, in list
    files = self._get_bulma_css()
            ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_simple_bulma/finders.py", line 149, in _get_bulma_css
    with open(css_path, "w", encoding="utf-8") as bulma_css:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.11/site-packages/django_simple_bulma/css/bulma.css'

Inside the container:

🐳 [] devuser: /usr/local/lib/python3.11/site-packages/django_simple_bulma
$ ls -l
total 40
-rw-r--r--  1 root root    0 Jul  4 03:36 __init__.py
-rw-r--r--  1 root root  338 Jul  4 03:36 apps.py
drwxr-xr-x  3 root root 4096 Jul  4 03:36 bulma
drwxr-xr-x  2 root root 4096 Jul  4 03:41 css
drwxr-xr-x 25 root root 4096 Jul  4 03:36 extensions
-rw-r--r--  1 root root 8585 Jul  4 03:36 finders.py
-rw-r--r--  1 root root  243 Jul  4 03:36 settings.py
drwxr-xr-x  2 root root 4096 Jul  4 03:36 templatetags
-rw-r--r--  1 root root 3080 Jul  4 03:36 utils.py

Workaround

If I change permissions by running the following as root, then everything is ok:

chown -R devuser:1001 /usr/local/lib/python3.11/site-packages/django_simple_bulma/css
chmod -R 775 /usr/local/lib/python3.11/site-packages/django_simple_bulma/css

Question

But I would prefer not do have to do this. Is there a configuration setting in django-simple-bulma that I can change, or something else I can do?

lemonsaurus commented 1 month ago

Hi @mfoulds!

I think this kind of problem is typically addressed by adding your user to the docker group so that it can access those docker fileshares as if it was root.

Have you tried something like sudo usermod -aG docker devuser ? (you may also need to do sudo groupadd docker if it doesn't exist)

Note that this may have security implications. A more modern and possibly more secure solution may be to run the daemon in rootless mode - see this article: https://docs.docker.com/engine/security/rootless/

lemonsaurus commented 1 month ago

Either way I'm fairly sure there's nothing django-simple-bulma could do to get around this for you, as it's just related to the fact that your docker daemon is running as root and you're executing commands that need access to the inside of those containers from non-root users. 🐴

mfoulds commented 1 month ago

Thanks @lemonsaurus. I'll try adding the user to the docker group and will definitely check out rootless mode. In the meantime, I found that changing the permission of the specific directory also works:

RUN if [ -d "/usr/local/lib/python3.11/site-packages/django_simple_bulma/css" ]; then \
    chown -R ${USER}:1001 /usr/local/lib/python3.11/site-packages/django_simple_bulma/css && \
    chmod -R 775 /usr/local/lib/python3.11/site-packages/django_simple_bulma/css; \
    fi

Either way you're right, it's not to do with the django-simple-bulma package. Thanks again!