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.
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鈥檓 basically maintaining 2 docker files, one which wholly includes the other. Please help! (Or tell me I鈥檓 missing something obvious)
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", "."]
}
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): https://github.com/moby/moby/issues/735#issuecomment-493703188
@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.
This works as a workaround! Thanks! Learn something new every day:-)
Edit Oh now I see, the https://github.com/moby/moby/issues/735#issuecomment-493703188 allows to use staged builds in sense.
How about using Jinja2 to generate Dockerfile as preCreateCommand?
:+1: 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!
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.
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):
I'm looking forward to give this second option a try ;-)
@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?
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.
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 :smile:
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).
@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?
@guillemglez No, could you open a feature request for this?
@chrmarti Already mentioned in #20
Most helpful comment
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.