Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unmentioned problem accessing volumes as a non-root user #2724

Closed
TheYarin opened this issue Feb 14, 2021 · 16 comments · Fixed by #2785
Closed

Unmentioned problem accessing volumes as a non-root user #2724

TheYarin opened this issue Feb 14, 2021 · 16 comments · Fixed by #2785

Comments

@TheYarin
Copy link

I was having problems with the python Dockerfile template for running under a non-root user.
When mounting a volume to the container, that is pointing, say, on a folder, it's the host that is managing this folder's permissions, and thus, the internal appuser might not have access to it by default.

In the end, I managed to grant access to the folder on my linux host by specifying the user id inside the dockerfile when creating appuser, and granting permission using setfacl.

Here's a relevant snippet of my final version of the dockerfile:
image

This is very unintuitive, and should probably be mentioned somewhere, maybe to this page but I think this should be better emphasized in the dockerfile itself, since I didn't even think of opening the link that appeared in the dockerfile template at first.

@ucheNkadiCode
Copy link
Contributor

Hey @TheYarin,

Our team is trying to understand the scenario in which you are trying to set permissions on the host to give permissions to a userID that does not exist on the host. It seems that app user doesn't inherently have access to home/appuser since it was made during root access.

Could you give us the steps you were trying to take and when the error occured?

Did this section of Potential Errors When Running as a Non-Root User help solve your issue?

Document start:
To solve this issue, we need to correctly add permissions to the non-root user to gain access to this specific file or directory in the container.

Within your Dockerfile, add:

RUN useradd appuser && chown -R appuser /app

Adds permission to appuser (non-root) for access to the /extra folder
RUN chown -R appuser /extra

@TheYarin
Copy link
Author

The Potential Errors When Running as a Non-Root User section did not help me, unfortunately.

I'll try to explain the problem better:
Let's say I have a folder /share on the host that I want to access from within the container.
If inside the container my app runs as user appuser, it will not be able to access the mounted volume unless explicitly given access like I specified in the original post, that is: on the host side, running setfacl -m u:555:rwx /share where 555 is the uid of appuser within the container.
So you see, the problem is not permissions of folders created within the container, but permissions of a folder on the host.

@bwateratmsft
Copy link
Collaborator

bwateratmsft commented Feb 17, 2021

Are you sure about that? I was under the impression that the files on the host are accessed by the context of the Docker daemon (can't recall if it's root or the docker group). I'm certain that granting permission to the UID of the appuser should not work--that user is on a totally "separate", "untrusted" system.

The user doesn't exist on the host and the authentication system isn't anything federated, so the host would never trust appuser; it's the Docker daemon's context.

@karolz-ms
Copy link
Contributor

@bwateratmsft so apparently the UID/GID of the folder that is bind-mounted is propagated as-is to the container. So it is not so much that the docker daemon can't access the host folder, but instead what the container sees are the UID/GID from the host, unchanged. It is the (namespaced) kernel code running in the container context that refuses access to the folder based on its UID/GID--unless appropriate ACLs are set on the folder for the container user.

I think I agree with @TheYarin that this is far from obvious and that it would be worth mentioning in the docs 👍 BTW I could not find any mention of this behavior in the Docker docs, only learned about that after reading through some 5-year old StackOverflow posts.

@TheYarin
Copy link
Author

@bwateratmsft Turns out this is how permissions work on Linux, the gid/uid can be permitted access even if it does not exist on the system.

@karolz-ms Thanks for the more detailed explanation. I, too, could not find any proper official Docker documentation of this.

I don't think it's something that should be resolved from within the Dockerfile. If I recall correctly from my attempts, trying to set these permissions within the Dockerfile results in those being overwritten by the volume mount.

This problem is not specific to the Python Dockerfile template, it's relevant whenever you are trying to run as a non-root user within a container. (Unless that user happens to already exist in the host)

@bwateratmsft
Copy link
Collaborator

Interesting, good to know. I agree with @TheYarin then, we should probably point something out in the docs.

@ucheNkadiCode
Copy link
Contributor

This is great @TheYarin! Would you mind taking a screen shot of the error message or copying the terminal output? It'll be helpful to users like yourself if they can search for the exact wording and have a better chance of finding our docs.

Thanks for using our product and helping us add this scenario!

@TheYarin
Copy link
Author

This is the error I get when the permissions to the mounted folder (/app/logs) are not properly set:

Attaching to app_server_1
server_1  | Traceback (most recent call last):
server_1  |   File "/app/./app.py", line 16, in <module>
server_1  |     RotatingFileHandler(os.path.join(LOGS_FOLDER, "log.txt"), maxBytes=100 * 1024**2, backupCount=2), # 200MB
server_1  |   File "/usr/local/lib/python3.9/logging/handlers.py", line 153, in __init__
server_1  |     BaseRotatingHandler.__init__(self, filename, mode, encoding=encoding,
server_1  |   File "/usr/local/lib/python3.9/logging/handlers.py", line 58, in __init__
server_1  |     logging.FileHandler.__init__(self, filename, mode=mode,
server_1  |   File "/usr/local/lib/python3.9/logging/__init__.py", line 1142, in __init__
server_1  |     StreamHandler.__init__(self, self._open())
server_1  |   File "/usr/local/lib/python3.9/logging/__init__.py", line 1171, in _open
server_1  |     return open(self.baseFilename, self.mode, encoding=self.encoding,
server_1  | PermissionError: [Errno 13] Permission denied: '/app/logs/log.txt'

(When starting the app with docker-compose)

I think the last line (PermissionError: [Errno 13] Permission denied) is the one that's relevant.

Thank you!

@ucheNkadiCode
Copy link
Contributor

@TheYarin, thanks again for all of your suggestions! The Docs are currently in review and I'll make sure to follow up and send you a link to the new info when the link is active!

Have a great one! 🎈🎇

@TheYarin
Copy link
Author

TheYarin commented Mar 4, 2021

Glad to hear that, thanks!

@bwateratmsft
Copy link
Collaborator

Here's the PR: microsoft/vscode-docs#4369

@TheYarin
Copy link
Author

TheYarin commented Mar 5, 2021

@bwateratmsft Seems like I'm a little late but I had some feedback on this PR, probably worth considering.

@bwateratmsft
Copy link
Collaborator

Marking for 1.12, and based on @TheYarin's feedback here, we think it'd be a good idea to change our Python Dockerfile scaffolding to assign an explicit UID.

@bwateratmsft
Copy link
Collaborator

Thanks for all your great feedback @TheYarin. @ucheNkadiCode has updated the docs with your feedback to use an explicit UID (microsoft/vscode-docs#4391), and I also updated our Dockerfile scaffolding to do the same (#2785). Looks like those changes are live, too: https://code.visualstudio.com/docs/containers/python-configure-containers

@TheYarin
Copy link
Author

Great, thank you all!

@bwateratmsft
Copy link
Collaborator

This change is now released with Docker extension version 1.12.0.

@vscodebot vscodebot bot locked and limited conversation to collaborators Apr 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants