Remote containers: Support target of multi-stage Dockerfile, buildArgs
stffabi opened this issue · 13 comments
It would be awesome if one could specify the target
of a multi-stage Dockerfile to be used for developing. This makes it possible to have one Dockerfile which first creates the build-image and afterwards the runtime container. This central Dockerfile can either be used from the buildserver to create the final container or by VSCode with a target to build only the dev container.
For example the following Dockerfile could be used to build the final container.
FROM golang:1.7.3 as builder
# Here one could install more needed developer tools
FROM builder as build
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=build /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
On the other hand vscode could use the builder
target to build the development container:
$ docker build --target builder .
Furthermore this would make the adaption of projects to Dev-Containers especially smooth and easy...
hi,
as this ticket is referenced by another which requests buildArgs, i'd also vote for buildArgs. atm a remote container runs as root, so all files do belong to root and not the user i want. in your doc you mention a solution like this:
ARG USERNAME=user-name
ARG USERUID=1000
ARG USERGROUP=user-group
ARG USERGID=1000
RUN groupadd -g $USERGID $USERGROUP
RUN useradd -m $USERNAME -u $USERUID -g $USERGID
ENV HOME /home/$USERNAME
...
USER $USERNAME
this helps to create a remote container which uses my UID/GID and so all files have the correct rights on the mounted filesystem.
but as you see, the USERNAME
,... are build-arg's which cannot be set with generic environment-values. if i set the USERNAME
(and the others) in this dockerfile to my concrete username (and uid,gid,group), other members of the team cannot use this devcontainer, because they have other values.
so it would be great to specify build-arg
s for the docker build and so one can extract the current user (or other environment-variables) and pass them to the build of the remote container. this will help to build containers which run as the same user and UID/GID as the one executing vscode.
at the moment i use the docker-compose solution, because in a compose file one can reference environment values (and use these values as build-args for a dockerfile). but here i have other problems ... i'd personally would like to use a pure container solution instead of a compose file.
@ulrichSchreiner What are the issues you see when using a docker-compose file? I have so far considered that an alternative for when the devcontainer.json does not support all the required options.
@chrmarti i want my directory name to be the mountpoint on the remote container. when using a compose file with the mount option
- "..:/workspace"
the thing on the remote side is called workspace
. but i normally have multiple roots in my workspace and i want it to be named as my directory. but how should i mount it, within the compose file?
perhaps i have a different look as you to remote containers. i see them as a clean-room environment, for specific types of project. so i would like to attach the .devcontainer
to a xx.code-workspace
file and not to a single project. when opening the workspace, all projects will be opend in the container.
at the momemt this works, by opening one project and than adding folders to the workspace (on the remote side). as i mount my $HOME to the container (but not as the HOME on the remote), this works. but i always have to reopen the workspace when i disconnect, because the connection is always initiated by a Open folder in remote container
i think you see the .devcontainer
as an addon to a single workspace/folder, so the recommended way for mounting the workspace with ..
is ok. and this works with a compose file.
but this is my personal opinion which is a little off-topic here i think ...
@ulrichSchreiner Thanks for clarifying. (Related: #278)
@chrmarti I think pretty much all commands should be extensible and also support environment variable injection otherwise it's so easy to run into a rabbit hole over small details like this.
As with have runArgs
, which should have buildArgs
.
For my case docker compose might work and I'll give it a go but I would have preferred to stick to a simple container approached
From @eedwards-sk #1857
I seem to be unable to specify build args during the dev container build process.
https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg
I want to perform an npm install during the build process, but this requires providing an environment variable for npm private registry authentication.
a build arg would be the way to accomplish this (an env var)
I would like a way to provide build args during the build process, from file (so e.g. an .env
file), e.g. "build_arg_file": "npmjs.env",
:
{
"name": "foo",
"context": "..",
"dockerFile": "Dockerfile",
"build_arg_file": "npmjs.env",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"extensions": [
"dbaeumer.vscode-eslint"
]
}
We also need to inject user/pass at container build time and --build-args
support would be great!
What are the issues you see when using a docker-compose file? I have so far considered that an alternative for when the devcontainer.json does not support all the required options.
@chrmarti how would you use docker-compose.yml
with vscode to solve the build time, developer dependent, username and password argument to docker?
Adding "target"
and "buildArgs"
(a key/value-pairs map to be passed with --build-arg
) properties to the devcontainer.json.
I wonder if we should place these together with "dockerFile"
and "context"
into a top-level "build"
property. Similar to what the docker-compose.yml
does.
So with all the build related properties it would make sense to group them in a top-level "build"
property similar to what the docker-compose.yml
does:
{
"build": {
"dockerFile": "...",
"context": "...",
"target": "...",
"args": {
"FOO": "BAR"
}
},
"preBuildCommand": "..."
}
This clarifies their use while avoiding the build
prefix on each. (Also: the existing top-level "context"
lacks that prefix and it can be unclear what it stands for.)
"preBuildCommand"
(#1045) is a bit lengthy when in the "build"
bag and "preCommand"
doesn't seem to work well. We can keep this one top-level like "postCreateCommand"
.
Renaming preBuildCommand
to initializeCommand
, see #1045 (comment).
dockerFile
and context
will remain supported as top-level properties.
hi,
as this ticket is referenced by another which requests buildArgs, i'd also vote for buildArgs. atm a remote container runs as root, so all files do belong to root and not the user i want. in your doc you mention a solution like this:
ARG USERNAME=user-name ARG USERUID=1000 ARG USERGROUP=user-group ARG USERGID=1000 RUN groupadd -g $USERGID $USERGROUP RUN useradd -m $USERNAME -u $USERUID -g $USERGID ENV HOME /home/$USERNAME ... USER $USERNAME
this helps to create a remote container which uses my UID/GID and so all files have the correct rights on the mounted filesystem.
but as you see, the
USERNAME
,... are build-arg's which cannot be set with generic environment-values. if i set theUSERNAME
(and the others) in this dockerfile to my concrete username (and uid,gid,group), other members of the team cannot use this devcontainer, because they have other values.so it would be great to specify
build-arg
s for the docker build and so one can extract the current user (or other environment-variables) and pass them to the build of the remote container. this will help to build containers which run as the same user and UID/GID as the one executing vscode.at the moment i use the docker-compose solution, because in a compose file one can reference environment values (and use these values as build-args for a dockerfile). but here i have other problems ... i'd personally would like to use a pure container solution instead of a compose file.
I'm not sure I fully understand everything in this thread, but I was looking for a solution to this problem as well. When I create new files inside a devcontainer they all belong to root
which causes some problems. Has this been solved? If so, can someone provide an example of a solution? Thanks!
@ajschmidt8 I assume you're on Linux. This works for single containers (not Docker Compose): Make sure your image has a regular user (non-root) and set "remoteUser"
in the devcontainer.json to that user's name. If that doesn't work, check if your local user's UID and GID are already taken by a different user/group in the image.