-
Notifications
You must be signed in to change notification settings - Fork 288
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
feat: get host uid:gid and use in docker #576
Conversation
e88e579
to
4b8b9fc
Compare
I tested on mac and linux and it worked properly in a few basic cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you feel about using this as a case study for a bit until we're satisfied it works for everyone before we roll out to other projects?
Sounds pragmatic to me. I'd also like a bit more testing before merge. I'll put a call out on slack. @manueldelreal might you be able to test this branch? |
That's a good idea. I found myself confused by the mix of seemingly
prod-only stuff in there. I'll split them out. For the dev container, I'm
leaning toward keeping the container just for the execution environment,
but getting the repo root through the volume mount exclusively (not copying
the source into the image).
…On Fri, Sep 6, 2019 at 9:33 PM Eric Dobbertin ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In Dockerfile
<#576 (comment)>
:
> @@ -113,4 +119,6 @@ RUN if [ "$BUILD_ENV" = "production" ]; then \
yarn build; \
fi;
-CMD ["yarn", "start"]
+# hadolint ignore=DL3002
+USER root
This file is serving as dockerfile for both production and dev builds. The
things you’re adding shouldn’t be necessary for prod builds. So maybe we
should just split into two separate dockerfiles and get rid of the
BUILD_ENV stuff?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#576?email_source=notifications&email_token=AADVYSINKNZWDXYYCDF6BPTQIMOHZA5CNFSM4IUMRE72YY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCD7RXKY#pullrequestreview-285154219>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADVYSP36XD3ET6T7WQKKFTQIMOHZANCNFSM4IUMRE7Q>
.
|
OK I started implementing separate Dockerfiles but that got me thinking. I think duplicating the dockerfile will make things worse and the inevitable drift between them is something I want to avoid. I've made Dockerfile changes that ensure |
You can run commands based on environment variables. For example (ripped from some medium post so I wouldn't have to contrive one): RUN if [ "$NODE_ENV" = "development" ]; \
then npm install; \
else npm install --only=production; \
fi |
@focusaurus Yes there will always be a point at which maintaining the conditional logic correctly is more confusing than splitting to two files. We may not be at that point, but I just thought I'd float the idea. If you're sticking with one, then you'll need to keep I'm not particular about the exact mechanics of how we do it, but I do think the Dockerfile should be as minimal, dependency-free, and production-targeted as possible, since One other thing that I've wanted to try to do is to create a single published "development environment" image that most of our If there is a way to solve the USER/chown stuff without image changes, then we actually could use one of the official Node images directly for development. That would be my true goal. To be clear, what I mean is that in build:
context: . to this: image: node:10-alpine or at least to this: image: reactioncommerce/dev:node10v1 At which point |
I removed the docker-compose override. There's lots of ways this could work. My thought was "create a generic mechanism to solve the docker uid issue that we can eventually templatize to all projects that need volume mounts" so I was trying to keep it logically into a "prepare the mounts" phase prior to a "start the app" phase.
I was initially trying to limit scope of changes in this PR in hoping to get it to land without spending a full cycle on it. There's lots we can change about how we use docker. All I'm focused on in this PR is getting the volume mount permissions correct. You're other comment about not needing a Dockerfile for local dev I guess might be nice but it's beyond the scope I want to tackle here. |
@focusaurus tested with fresh installs for users with UID 1001 (my default one), 1000 and an entirely new user, all three scenarios yielded a running container with no permissions issues. I had a slight hiccup on the first run but it was unrelated to this branch's code changes. I say that this looks good for the scope that you trying to tackle here. |
Regarding "beyond the scope", 👍 . We so rarely touch the docker setup that it's tempting to do all of the things that have been building up whenever we do. |
OK |
Marking this WIP. We have a lot of stuff that's good and ready to go but we're considering more substantial changes to the prod Dockerfile. |
@manueldelreal Can you pull down the latest changes and run a few more quick tests please? |
Tested latest commits on my mac, all good:
|
Also tested on linux with uid 1001. Looks good. FYI this line of output is the new code:
|
- Grab the uid:gid of the repo root in docker - Use that for the node user we run as in the container - Check owner of all volume mounts, if not OK, fix them - this should avoid permission errors on linux - provide bin/fix-volumes to fix owner issues ad hoc - There is no more ../node_modules - 1 and only 1 place where modules go for local dev (and prod) - local dev it's a volume mount, prod it's baked in - We have no native add-ons at the moment, so it should be OK, but `npm rebuild` as needed - Also many docker and CI refactorings - split prod and dev dockerfiles - They are both small now - Use ci-scripts/docker-labels to reduce LABEL boilerplate - change lint CI task to run outside a docker container Signed-off-by: Peter Lyons <pete@reactioncommerce.com>
Signed-off-by: Peter Lyons <pete@reactioncommerce.com>
372d586
to
124aeaa
Compare
OK I think I'm good for someone to merge this after the next round of code re-review and testing. |
OK I'm going to merge this. The interesting change is a single commit we can revert later if any serious issues surface. |
Just noticed that this might not work in some case. After that, everything inside the reaction-next-satrterkit belongs to root and can't be edited by my normal user anymore. I wonder what is wrong here. After removing the existing volumes, and chowning back my folder I can't reproduce it anymore. |
Hmm. We some a little weirdness today too with some older versions of the docker-base dev images. Could you |
Impact: major
Type: feature|bugfix
Issue
On linux, the docker container runs as user
node
(uid 1000), which in many cases is not the same as the developer's host OS uid. This can cause mismatches in ownership of files that are shared between the host and the container via docker volume mounts. Ultimately this surfaces as filesystem errors (EACCESS
,permission denied
, etc) at various times including when trying to runyarn
, do builds, etc.Why doesn't bug affect all linux users?
On many linux distributions, the first non-system user is assigned uid 1000. That's why in our docker container the
node
user has uid 1000, it's just a default. That's also why many developer's have uid 1000 as well: it's the default for the first non-system user on their distribution and their user is the first one they add when doing their OS install. Because of that default and coincidence many users avoid this issue because their uid just happens to match the one we use. (This was the case for me personally and why it is harder for me to encounter/reproduce these issues)Why doesn't this affect macOS users?
Docker for Mac has automatic mapping that avoids this issue largely.
How does this apply to reaction core? Other repos?
If testing proves successful in storefront, I believe this pattern would apply to reaction core and essentially every docker-based service we have that makes use of volume mounts, which is probably most but not all of them. I started with core initially as a fix there would have the widest impact, but the docker setup there is significantly more complex and with the slow startup time I switched to storefront as an easier first project to tackle.
Related issues
Error creating Reaction config file: /opt/reaction/src/.reaction/config.json
Solution
The key elements of the solution are:
chown
volumes to fix them)stat
on the repo rootnode
user account in the container to have the matching uidstat
on each volume mount point and check if ownership is correct.su-exec
tonode
in the container then proceed to launch the application./bin/fix-volumes
script that can be run at any time that willchown
/chmod
all volume mount directories properly and should be a 1-stop fix to this entire category of errorsThere are a ton of unix heavy details in here we should scrutinize during code review.
Some things to note about the solution (pending QA testing)
fix-volumes
Breaking changes
I don't think anything here would count as "breaking" but the changed ownership/permission of host files could be surprising/unexpected as noted above.
Testing
git clone
of this example-storefront branch,./bin/setup
, anddocker-compose up
$HOME/.cache/yarn-offline-mirror
$HOME/.cache/yarn
example-storefront/node_modules
example-storefront/build
adduser
CLI) and once I didsudo adduser plyons2 docker
the new user could use docker. Then Isudo su - plyons2
to get a shell with that user for testing.docker-compose run web ps -ef
root
processes then a switch tonode
for thebin/start
Example good output
root
, that's a bug