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

Docker Feature: preCreateCommand just like postCreateCommand #1045

Closed
Ciantic opened this issue Jul 27, 2019 · 17 comments
Closed

Docker Feature: preCreateCommand just like postCreateCommand #1045

Ciantic opened this issue Jul 27, 2019 · 17 comments
Assignees
Labels
containers Issue in vscode-remote containers plan-item A plan item
Milestone

Comments

@Ciantic
Copy link

Ciantic commented Jul 27, 2019

I want to have preCreateCommand just like there is postCreateCommand, e.g.

devcontainer.json

{
    "preCreateCommand": ["..."]
}

Which is ran before building or rebuilding the docker container.

I could use this e.g. to build the dependencies (bunch of other docker files) etc.

Edit Maybe better name would be preBuildCommand but there is already postCreateCommand so I named it preCreateCommand.

@egamma egamma added feature-request Request for new features or functionality containers Issue in vscode-remote containers labels Jul 29, 2019
@jabbera
Copy link

jabbera commented Jul 31, 2019

How is this not a thing already?!?:-)

I have a runtime image, and a development image that builds ontop of that. Right now I have no way to build both so I can make my dev image depend on my runtime image. I’m basically maintaining 2 docker files, one which wholly includes the other. Please help! (Or tell me I’m missing something obvious)

@Ciantic
Copy link
Author

Ciantic commented Aug 5, 2019

Yes you are right @jabbera, that's the problem I ran in to myself too. I guess we can open up the use case a little here if it's not clear:

Imagine there is Dockerfile for the main application:

FROM debian:buster-slim
RUN apt-get update -qq -y && apt-get -y install \
   ....

Then I build this locally like docker build -t mainapp .. This in turn should be the dependency for the development environment Dockerfile

.devcontainer/Dockerfile

FROM mainapp
...

To get this working it's required to run docker build -t mainapp . every time the vscode container is booted or rebuilt, which is tedious.

If there were preCreateCommand it would be possible to just build the deps, e.g.

{
    "preCreateCommand": ["docker", "build", "-t", "mainapp", "."]
}

@chrmarti
Copy link
Contributor

As a workaround, you could have production and development setups in the same Dockerfile (and make development the default because we don't support passing in build arguments yet): moby/moby#735 (comment)

@Ciantic
Copy link
Author

Ciantic commented Aug 15, 2019

@chrmarti we are not asking build arguments here, we are asking a preCreateCommand that is called in host computer before building. This would allow to build the depedencies among other things.

Sure if your deps are pure docker you can just concate them to devcontainer dockerfile but that is just awful.

@jabbera
Copy link

jabbera commented Aug 15, 2019

This works as a workaround! Thanks! Learn something new every day:-)

@Ciantic
Copy link
Author

Ciantic commented Aug 15, 2019

Edit Oh now I see, the moby/moby#735 (comment) allows to use staged builds in sense.

@byzhang
Copy link

byzhang commented Nov 21, 2019

How about using Jinja2 to generate Dockerfile as preCreateCommand?

@aniongithub
Copy link

👍 I use this plugin to do development and would love to run commands on the host to prepare things for the docker-compose or build step that devcontainer.json would execute.

For example download any prerequisites, mount directories or run any kernel mod commands needed for the container to function and MILLION things more!

@ob
Copy link

ob commented Feb 4, 2020

In our case, we generate the Dockerfile using a custom tool, so preCreateCommand would be really useful to avoid having to check-in the generated Dockerfile into the repository.

@diricxbart
Copy link

diricxbart commented Feb 12, 2020

I have another use case for this change, which might interest other people...

We have a Docker image which has a custom user with user ID and group ID 2000. We then typically launch this Docker as root user and switch the user ID and group ID to match our own ID's. Next we attach VSCode to this running container. All file permissions are at this point working well, even those via volume mounts.

Up til now I haven't been able to get this setup fully working based on the devcontainer approach. When I start the Docker as root and use the postCreateCommand to change the user ID and group ID, then I can switch users from root to the custom user and all works well, with the correct permissions, but only in that post create shell. However the VSCode <-> Docker connection is still with the root user, so changes made to files in VSCode on volume mounts are no longer accessible outside this Docker, since VSCode makes these changes as root user...

If I make the VSCode <-> Docker connection as the custom user, then I can't change the user ID and group ID, since there's still a proces in use by that user (of course, the VSCode <-> Docker connection). So the custom users keeps having ID's 2000 and file edits on the volume mounts are not accessible outside of the Docker container, where my user has different ID's.

So there are two solutions to this problem (I think):

  1. Setup a VSCode <-> Docker connection as root, change the custom user ID's, disconnect, reconnect but as the custom user. However, this flow is not supported AFAIK.
  2. Use the preCreateCommand to create a user which has the same user ID and group ID as used by the volume mounts and next establish the VSCode <-> Docker connection based on that user.

I'm looking forward to give this second option a try ;-)

@chrmarti
Copy link
Contributor

@diricxbart On Linux we update the UID/GID of the container user to the local user's UID/GID if the container user is not root and the target UID/GID are not already in use. Can you give that a try?

@chrmarti chrmarti self-assigned this Feb 19, 2020
@chrmarti chrmarti added plan-item A plan item and removed feature-request Request for new features or functionality labels Feb 19, 2020
@chrmarti chrmarti added this to the February 2020 milestone Feb 19, 2020
@chrmarti
Copy link
Contributor

Adding "preBuildCommand" as a new property to the devcontainer.json. This supports values as strings or array of strings. A string will be run in a shell (cmd.exe or /bin/sh), an array of strings will be run as command with arguments without a shell.

@aniongithub
Copy link

I needed this feature and a few others, so I built a dotnet global CLI tool that manages multiple devcontainer configurations, allows pass-though user access and mounts local source on remote containers running on different machines.

Check it out here. It's likely this might become irrelevant when these features are added into the core plugin, but it's available now 😄

@chrmarti
Copy link
Contributor

Making it "initializeCommand" instead of "preBuildCommand" after more discussion in the team. This will always run first before anything else is runs (which should be more flexible than preBuildCommand).

@guillemglez
Copy link

@diricxbart On Linux we update the UID/GID of the container user to the local user's UID/GID if the container user is not root and the target UID/GID are not already in use. Can you give that a try?

Is there a workaround for this if the Linux machine hosting the Docker Daemon is accessed via SSH from a Windows machine?

@chrmarti
Copy link
Contributor

chrmarti commented Mar 4, 2020

@guillemglez No, could you open a feature request for this?

@guillemglez
Copy link

@chrmarti Already mentioned in #20

@vscodebot vscodebot bot locked and limited conversation to collaborators Apr 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
containers Issue in vscode-remote containers plan-item A plan item
Projects
None yet
Development

No branches or pull requests

9 participants