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

Remote containers: Support target of multi-stage Dockerfile, buildArgs #46

Closed
stffabi opened this issue May 3, 2019 · 13 comments
Closed
Assignees
Labels
containers Issue in vscode-remote containers plan-item A plan item
Milestone

Comments

@stffabi
Copy link

stffabi commented May 3, 2019

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...

@chrmarti chrmarti self-assigned this May 3, 2019
@chrmarti chrmarti added containers Issue in vscode-remote containers feature-request Request for new features or functionality labels May 3, 2019
@ulrichSchreiner
Copy link

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-args 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.

@chrmarti
Copy link
Contributor

@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.

@ulrichSchreiner
Copy link

@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 ...

@chrmarti
Copy link
Contributor

@ulrichSchreiner Thanks for clarifying. (Related: #278)

@sandorfr
Copy link

sandorfr commented Jul 3, 2019

@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

@Chuxel
Copy link
Member

Chuxel commented Nov 16, 2019

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"
	]
}

@nomadster
Copy link

We also need to inject user/pass at container build time and --build-args support would be great!

@nomadster
Copy link

nomadster commented Jan 27, 2020

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?

@chrmarti
Copy link
Contributor

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.

@chrmarti
Copy link
Contributor

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".

@chrmarti
Copy link
Contributor

Renaming preBuildCommand to initializeCommand, see #1045 (comment).

dockerFile and context will remain supported as top-level properties.

@chrmarti chrmarti added plan-item A plan item and removed feature-request Request for new features or functionality labels Feb 23, 2020
chrmarti added a commit to microsoft/vscode that referenced this issue Feb 23, 2020
@chrmarti chrmarti added this to the February 2020 milestone Feb 23, 2020
@ajschmidt8
Copy link

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-args 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!

@chrmarti
Copy link
Contributor

@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.

@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

7 participants