nickjj / flask-static-digest

Flask extension to help make your static files production ready by md5 tagging and gzipping them.
MIT License
157 stars 27 forks source link

Getting Permission Error on flask digest compile (Ubuntu 20.4) #13

Closed leonardoschwartz closed 4 years ago

leonardoschwartz commented 4 years ago

Hey Nick, I just moved my dev environment to Ubuntu 20.4 from Mac and I'm not able to used flask digest compile from a the app's docker container as usual.

This is the traceback I'm seeing:

Traceback (most recent call last): File "/usr/local/bin/flask", line 8, in sys.exit(main()) File "/usr/local/lib/python3.8/site-packages/flask/cli.py", line 966, in main cli.main(prog_name="python -m flask" if as_module else None) File "/usr/local/lib/python3.8/site-packages/flask/cli.py", line 586, in main return super(FlaskGroup, self).main(args, kwargs) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 782, in main rv = self.invoke(ctx) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke return ctx.invoke(self.callback, ctx.params) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke return callback(args, kwargs) File "/usr/local/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func return f(get_current_context(), *args, *kwargs) File "/usr/local/lib/python3.8/site-packages/flask/cli.py", line 426, in decorator return __ctx.invoke(f, args, kwargs) File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke return callback(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/flask_static_digest/cli.py", line 20, in compile _compile(current_app.static_folder, File "/usr/local/lib/python3.8/site-packages/flask_static_digest/digester.py", line 35, in compile manifest = _generate_manifest(files, gzip_files, output_path) File "/usr/local/lib/python3.8/site-packages/flask_static_digest/digester.py", line 113, in _generate_manifest _write_to_disk(file, digested_file_path, gzip_files, output_path) File "/usr/local/lib/python3.8/site-packages/flask_static_digest/digester.py", line 141, in _write_to_disk shutil.copy2(file, full_digested_file_path) File "/usr/local/lib/python3.8/shutil.py", line 426, in copy2 copyfile(src, dst, follow_symlinks=follow_symlinks) File "/usr/local/lib/python3.8/shutil.py", line 259, in copyfile with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: PermissionError: [Errno 13] Permission denied: '/app/APP_NAME/../public/js/app-350139f5b599102893ae61f5dbd798f3.js'

For the look of it, the container doesn't have proper permission to modify files on my host, but this should be managed automatically by Docker, shouldn't it?

As I mentioned above, same code works perfectly on Mac, but is giving me this permission error on Ubuntu 20.4.

Thanks in advance Nick!

nickjj commented 4 years ago

Hi,

When you install Docker on native Linux you typically end up giving your user access rights to execute Docker commands as your user without needing root privileges.

Have you done this? https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user

leonardoschwartz commented 4 years ago

Thanks Nick. Nope, that doesn't solve the issue. I re-did the steps just in case but same error.

I should have mentioned before that the error happens even as a root/sudo

nickjj commented 4 years ago

What does your Dockerfile look like?

leonardoschwartz commented 4 years ago

As I said, this is working right now on my Mac setup. I don't know why my dockerfile would be relevant.

I created a non-root user and usergroup for the app in the dockerfile.

I'm using a bind volume from the app folder in the container to a folder in my host, and I understand that the user in the container is not the user who owns the folder in the host, but shouldn't manage the bind volumes making sure the container can write to the matching directory on host?

nickjj commented 4 years ago

I don't know why my dockerfile would be relevant.

It's relevant because Docker Desktop on MacOS and Windows do a little bit of magic to write files out as your current user instead of root, but this behavior doesn't apply to Linux.

This seems out of scope for Flask Static Digest. If you're using a non-root user in your Dockerfile you'll want to ensure any commands that write out files from the container to the host have proper user permissions. You would likely run into this issue if you ran a database migration too, because that would produce a volume mounted file back to your host.

Ultimately this becomes related to "how do I deal with Docker volume mounts and running containers as users who are not root".

If you're looking for a working example of how to run Docker as a non-root user and have your output files be owned by your Docker host's user (on any OS), I open sourced this recently: https://github.com/nickjj/docker-flask-example

If you run the digest command in that app it will produce digested files as the correct user both inside the container and the bind mount back on the Docker host and now you can serve those files with nginx or however you see fit.