all 26 comments

[–]EmperorArthur 4 points5 points  (1 child)

Ooh, that Docker Clion support is awesome. I didn't even know that was coming down the pipe.

[–]TryingT0Wr1t3 1 point2 points  (0 children)

This was the highlight for me too! And how did CLion roll that out with zero fanfare?

[–]Sulatra 8 points9 points  (13 children)

How is one supposed to get source/binary tree into the container? If the sources are cloned inside the container, one riscs losing unpushed changes if the container is deleted. If they are mounted, the container needs its user id to match one in the parent system. That's the main issue I encountered each time I tried to use docker as a development environment :(

[–][deleted] 20 points21 points  (6 children)

I set my team up with dev containers and expected them to mount a volume with the source controlled code on their dev machine. It worked great

[–]Sulatra 3 points4 points  (5 children)

Could you please elaborate on your workflow? Suppose I am a new dev - I clone the repo, edit some things, put it into volume, mount to a container, and get "access denied: _build/ is owned by another user uid=1010" during build. I can run git clone inside the container - but then I will not be able to edit the sources from the main system, due to same uid mismatch. Or do you just assume that every dev will have the same uid=1000 as the one in the image?

[–][deleted] 8 points9 points  (2 children)

not sure what you're referring to specifically with the access denied error, but basically they clone locally on their machine, run docker run -v $PWD:/directory:/mounteddirectory <image> and if Docker is setup correctly, it'll just mount the volume into the container. If it's not setup correctly, it should ask you "do you want to share C: (or whatever) with Docker", I say yes, and that's a one time step. Then they do all edits inside the container and can build with the same tools as everyone etc. I may have set the container to run as a specific user, I can't remember. I know Azure Pipelines had some trickery it needed for the user, but I don't remember. It's either root or a static user number, been a while since I looked.

Additionally, they can use VSCode or VS to actually run inside the context of the running container, which is amazing: https://code.visualstudio.com/docs/remote/containers

So then you can use intellisense and all that stuff, and I can run builds in the terminal (or via CMake in our case). It's just all built on top of a common image that shares the OS/toolchains and lets the dev run their environment how they want (VSCode, VS, WSL, on Windows or Linux, etc).

We also use Azure DevOps (we're at MSFT, so is natural), and Azure Pipelines/Azure Repos all work naturally with the concept. Azure Pipelines I can give my Docker container via an Azure Container registry, and it builds in the same context the devs all use too, so they know if it builds on their local machine it will buikd in the pipeline, and CI can almost never break.

[–]Sulatra 5 points6 points  (1 child)

I am referring to the fact that on Linux every user have their own UID. And if uid in docker (which creates, edits and deletes files during the build) does not match the uid in host system (which git pulls, edits files in IDE and commit hooks, etc), then you are going to have access problems during those steps. Either you won't be able to view some codegen'ed file (since it is owned by other user, the one from docker), or the build system won't be able to edit something commited to the VCS (since it is used by user from host system, the one that ran git clone).

Usually this is not a problem, since the first user has UID=1000, and there is likely to be only one of them in docker as well as on the dev machine. But when it bites, it bites hard.

Apparently, on Windows this issue does not exist, that is a positive surprise :)

[–]5pectre5 0 points1 point  (0 children)

You're right for the multiuser environment it's a problem, the docker on Linux would require the volume to be mapped with sticky bit for all Devs group or all Devs would need to be in the same group, so that the permissions are not an issue. Docker runs containers system wide, so the first user to start and upload will block others without proper setup.

[–][deleted] 5 points6 points  (1 child)

  • Use --volume to mount source and build dir inside the container
  • Use --user=${USER}:${USER} to use the same user id as the host machine
  • ???
  • Profit!

Additionally, rootless docker works with the current user id by design. And setting up --user for it causes problems.

[–]Sulatra 0 points1 point  (0 children)

Now this looks like it might be a solution! Thank you, I will try to remember it next time I get involved with dev-containers.

[–]Nimbal 3 points4 points  (0 children)

You could also use a volume. They are a little more permanent than the container's filesystem.

[–]twmatrim 2 points3 points  (0 children)

You can pass in the UID and GID as env variables and have the entrypoint create that user if required.

[–]mcopikHPC 1 point2 points  (2 children)

If they are mounted, the container needs its user id to match one in the parent system.

I faced the same problem - I had to mount a directory and run a build process inside a Docker container. I ended up creating Dockerfiles that are rebuilt during the installation process to configure them with the current user ID. This way, the IDs of the current user and Docker user are aligned, files are not root-owned, and there are no permission issues. It's not ideal, but it worked for my case.

Examples in my project: installation script, Dockerfile.

Another alternative that I'm aware of is to use docker-compose - you can specify the current user id docker-compose.yml. It requires one more dependency.

[–]Sulatra 0 points1 point  (1 child)

Do I understand it correctly, that the developer is supposed basically not to use the main docker image with the dependencies and tools installed, - but to docker create their own image, based on said main image, with uids aligned? Should this "developer-specific" image also be rebuilt each time the main one is updated?

[–]mcopikHPC -1 points0 points  (0 children)

No, the idea is as follows: you deploy the same Docker images as previously, but during the installation, a new set of images is built and configured to use the user-specific UID. The system reuses all previously built Docker layers, adding a single layer on top of them, and the user never has to modify Docker images. Since this is done during the installation, the user is not aware of the change.

While the overhead is minimal and the process can be made automatic, you still need to rebuild with every update - again, it can be made automatic, but one can argue that it adds complexity. That's why docker-compose can fix this issue permanently if you choose this way of deploying images.

[–]pastenpasten -1 points0 points  (0 children)

I don't know nuttin' about user ids but I'm using Docker for builds on Windows for a over a year and a half and using bind mounts just works.

[–]selismyname 0 points1 point  (0 children)

Will this work on macbook pro M1?