microsoft / vscode-remote-release

Visual Studio Code Remote Development: Open any folder in WSL, in a Docker container, or on a remote machine using SSH and take advantage of VS Code's full feature set.
https://aka.ms/vscode-remote
Other
3.67k stars 292 forks source link

Buildkit support at devcontainer.json level #1409

Closed darkvertex closed 1 year ago

darkvertex commented 5 years ago

This is technically a dupe of https://github.com/microsoft/vscode-remote-release/issues/87 but since the other issue was closed and further commenting disallowed, I could not continue there.

Buildkit is great and very useful and right now if my Dockerfile absolutely needs it to build, it's great that I can control the runArgs in the devcontainer.json but it won't set DOCKER_BUILDKIT=1 for me at build time, so I need to remember to export that env var prior to launching vscode or my dev container won't build. It's not very ergonomic.

I found this doc page that suggests adding env vars by modifying the runArgs but from what I can tell that's only good for passing env vars to docker run, not setting them for docker build: https://code.visualstudio.com/docs/remote/containers-advanced#_adding-environment-variables

In the devcontainer.json, I would love either:

a) "use_buildkit": true or similar. b) or something to set the env for the docker build call, maybe:

"buildEnv": {
  "DOCKER_BUILDKIT": "1"
}

Thoughts?

chrmarti commented 5 years ago

Does "runArgs": [ "-e", "DOCKER_BUILDKIT=1" ] work for your case? (https://github.com/microsoft/vscode-remote-release/issues/1201 will address having something like you suggest in b)).

darkvertex commented 5 years ago

Sorry, I made a typo repeatedly... Everywhere I wrote about docker run I meant docker build. Buildkit adds fancy features at build time; it does nothing for running the containers.

I've edited my original text; apologies for the confusion.

My request still stands though. I need an env to be set before running docker build.

chrmarti commented 5 years ago

You can make buildkit the default: https://github.com/docker/buildx#setting-buildx-as-default-builder-in-docker-1903

Does that work for you?

darkvertex commented 5 years ago

That's a valid temporary workaround though I'm not a huge fan of having wrappers wrap builtin commands.

Sometimes I want the classic builder and it's nice to have the choice to decide when to use Buildkit or not inline without having to permanently edit my config by installing an alias.

eedwards-sk commented 4 years ago

I would like to use docker build secrets and cannot with the current devcontainer support for buildkit.

Forcing the entire system to use buildkit is not a solution or valid workaround -- the impact is too great to other projects.

mrmachine commented 4 years ago

You can make buildkit the default: https://github.com/docker/buildx#setting-buildx-as-default-builder-in-docker-1903

Does that work for you?

I believe this workaround does not work with:

    "dockerComposeFile": [
        "docker-compose.yml"
    ],

We need to set DOCKER_BUILDKIT=1 and COMPOSE_DOCKER_CLI_BUILD=1 env vars before VScode builds our image with compose.

noedlm commented 4 years ago

I'm running into this same issue. For now I just build the image then start the container in vscode. Having this feature would be nice for sure.

chrmarti commented 4 years ago

@mrmachine You can place a .env file with these environment variables in your project folder. Does that work?

noedlm commented 4 years ago

I got pulled to work on something else, I'll try it out as soon as I can and update whether it worked or not.

agners commented 4 years ago

Place DOCKER_BUILDKIT=1 in .env does work for me, the container gets built using BuildKit.

However, the build output looks a bit messy since BuildKit seems to assume a full terminal. Using --progress=plain in docker build does help but I did not found a way to pass extra arguments using devcontainer.json. There is also the environment variable BUILDKIT_PROGRESS=plain which does the same, and it seems to be working when using docker build on the command line. For some reason that environment variable does not work with .env, I assume it's related to how Visual Studio code starts the container build process.

mrmachine commented 4 years ago

Adding to .env file (read by compose) did not work for me, but adding to my ~/.zshenv file did work.

The output looks fine for me. I'm using zsh and zprezto on macOS.

UPDATE: Adding COMPOSE_DOCKER_CLI_BUILD=1 to .env is respected by docker-compose (CLI and vscode) because it is a Docker Compose var. But adding DOCKER_BUILDKIT=1 is ignored by docker-compose (CLI and vscode), presumably because it is a Docker var.

I don't know why adding it to my .zshenv file suddenly started working. I thought it was not working before. I had assumed that vscode would only inherit my env if started from CLI with code. But it seems ~/.zshenv is used even when vscode is launched directly from the macOS dock.

agners commented 4 years ago

@mrmachine you are indeed right .env also did not work for me. It seems I got confused during testing where I exactly added the variable already :-)

I assume you are using dockerComposeFile in .devcontainer/devcontainer.json then? I tested only with build.dockerfile so far. And indeed.

CarlosDomingues commented 4 years ago

Just adding to what others have said, my main use case for Remote - Containers is to share a ready-to-use, reproducible and isolated development environments with my team, so they can just git clone a project and start working right away.

Solutions that require manually configuring Docker or editing .env files (which often should not be checked) are cool workarounds, but greatly diminish the solution's value.

cgorski-vso commented 3 years ago

My team relies heavily on caching using cache_from in compositions to build containers on developer machines by using remote repositories as a cache. This requires BuildKit. Outside of VSCode, on the CLI, I can build a rather large composition rather quickly by first pulling the images and then running docker-compose using BuildKit.

Despite my best efforts (mostly around setting environment variables in every conceivable way I can think of, and installing the BuildKit CLI wrappers), I cannot get VSCode on Windows to use BuildKit. My compositions build, but the process is agonizingly slow. BuildKit reduces build times from 15 minutes to 2 minutes on some developer machines, so this is a big hit to productivity.

cgorski-vso commented 3 years ago

To follow up on my previous comment:

The current workaround is to create shell scripts to be run outside of VSCode that manually pull, build, and bring up the composition. I can then use "Open folder in container ..." in VSCode. This indeed allows me to build a large composition in dramatically reduced time.

However, as others have pointed out, this workaround defeats the purpose of some of the core principals around the docker and remote execution extensions. It requires manually running scripts outside of VSCode to control docker-compose. It also introduces the potential for errors into the build process due to human error, which I have already made several times (but despite that the workaround still beats waiting 15 minutes for a build).

PavelSosin-320 commented 3 years ago

The recent Docker Desktop versions support buildkit as a CLI plugin(!) - Docker Desktop buildx. It is enabled by env variable. Docker-compose is not perfect in the image build because its main purpose today is Docker stack deploy input. You can't expect too much from it. But there are numerous OCI Container builders like Podman's buildah. Kubernetes' kaniko. Maybe, it is not so bad that image building is done outside VSCode as a Task?DockerHub is not the only possible repository.

mrmachine commented 3 years ago

Circling back on this issue. I believe docker buildx install on the host works for regular projects checked out to the host mac and opened in a container via vscode, because the host docker environment is doing the build.

But it does NOT seem to work for the Clone Repository in Container Volume feature. Is it the case that Clone Repository in Container Volume is using docker in docker? Because it must build an image from a checkout that itself is only available from inside a container.

So, how can I:

  1. Ensure that the buildx plugin is actually installed in the docker in docker environment; and
  2. Ensure that docker buildx install is executed in the docker in docker environment BEFORE my image is built

I've been experimenting with "initializeCommand": [".devcontainer/init"] in devcontainer.json and the following inside that .devcontainer/init script:

...
# Is buildkit not installed?
if ! docker buildx install 2>/dev/null; then
    # Install plugin.
    mkdir -p ~/.docker/cli-plugins
    if [[ "$(arch)" = aarch64 ]]; then
        wget -nv -O ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.6.3/buildx-v0.6.3.linux-arm64
    else
        wget -nv -O ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.6.3/buildx-v0.6.3.linux-amd64
    fi
    chmod a+x ~/.docker/cli-plugins/docker-buildx
    # Enable buildkit.
    docker buildx install
fi

But, that still does not work...

[6427 ms] Start: Run: docker exec -it -w /workspaces/FOO -u root b36d1f2a72a6a8f8e5274d60ddb578b817e5fe7c79c97c01b4504e3f9d2cd5be .devcontainer/init
+ docker buildx install
+ mkdir -p /root/.docker/cli-plugins
+ arch
+ '[[' aarch64 '=' aarch64 ]]
+ wget -nv -O /root/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.6.3/buildx-v0.6.3.linux-arm64
Connecting to github.com (52.64.108.95:443)
Connecting to github-releases.githubusercontent.com (185.199.111.154:443)
saving to '/root/.docker/cli-plugins/docker-buildx'
docker-buildx        100% |************************************************************************************************************| 54.8M  0:00:00 ETA
'/root/.docker/cli-plugins/docker-buildx' saved
+ chmod a+x /root/.docker/cli-plugins/docker-buildx
+ docker buildx install
[10175 ms] Start: Run in container: docker-compose version --short
[10954 ms] Start: Run: docker ps -q -a --filter label=com.docker.compose.project=FOO-develop --filter label=com.docker.compose.service=django
[11065 ms] Start: Run in container: docker-compose -f /workspaces/FOO/docker-compose.yml -f /workspaces/FOO/.devcontainer/docker-compose.devcontainer.yml -f /tmp/docker-compose.repositoryContainer.yml config
...
[11535 ms] 
[11543 ms] Start: Run: docker events --format {{json .}} --filter event=start
[11544 ms] Start: Run in container: docker-compose --project-name FOO-develop -f /workspaces/FOO/docker-compose.yml -f /workspaces/FOO/.devcontainer/docker-compose.devcontainer.yml -f /tmp/docker-compose.repositoryContainer.yml build
postgres uses an image, skipping
elasticsearch uses an image, skipping
redis uses an image, skipping
Building django
Step 1/5 : ARG IMAGE_TAG=master
Step 2/5 : FROM "FOO/FOO:${IMAGE_TAG}"
 ---> dc75cbeffcbb
Step 3/5 : COPY requirements.txt .
 ---> Using cache
 ---> 1da6337b4921
Step 4/5 : RUN --mount="type=cache,id=FOO-pip,target=/home/container/.cache/pip" pip-install.sh
ERROR: Service 'django' failed to build : the --mount option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled
[21187 ms] Command failed: docker-compose --project-name FOO-develop -f /workspaces/FOO/docker-compose.yml -f /workspaces/FOO/.devcontainer/docker-compose.devcontainer.yml -f /tmp/docker-compose.repositoryContainer.yml build

FYI, just executing docker buildx install in an initializeCommand script DOES enable buildkit when run in Codespaces.

chrmarti commented 3 years ago

Could you give the latest Remote-Containers (0.205.0 or later) a try? This currently requires VS Code Insiders and comes with an updated Dockerfile using a new Docker Compose for building dev container images from volumes. I see the --mount option working with that (it failed with 0.202.5 as you report).

mrmachine commented 3 years ago

I've just tried the latest VS Code Insiders and Remote-Containers 0.205.0. On first run, my .devcontainer/init script returns a non-zero exit code intentionally, to give the user an opportunity (and instructions) to reopen in the recovery container and provide some secrets that are required to build the image.

With 0.202.5 that works fine, and the build after providing secrets fails (because I can't enable buildkit for the build).

With 0.205.0, I cannot even reopen in recovery container. I just get this error at bottom right:

An unexpected error was thrown while attempting to change the workspace of the window (An unknown error occurred. Please consult the log for more details.).

The log doesn't indicate anything interesting except that .devcontainer/init failed (as expected):

[141 ms] Remote-Containers 0.205.0 in VS Code 1.62.0-insider (ff1e16eebb93af79fd6d7af1356c4003a120c563).
[141 ms] Start: Resolving Remote
[143 ms] Start: Check Docker is running
[143 ms] Start: Run: docker version --format {{.Server.APIVersion}}
[290 ms] Server API version: 1.41
[291 ms] Start: Run: docker volume ls -q
[403 ms] Start: Run: docker ps -q -a --filter label=vsch.local.repository=https://github.com/FOO/FOO/tree/codespaces --filter label=vsch.local.repository.volume=FOO-codespaces-671d92059284359413c7b6ee4ce7a1b8 --filter label=vsch.local.repository.folder=FOO --filter label=vsch.quality=insider
[512 ms] Start: Run: docker build -f /var/folders/2j/ymfzssrx66gg87hypqbw1ptr0000gn/T/vsch/volumeBootstrap.Dockerfile-0.205.0 -t vsc-volume-bootstrap /var/folders/2j/ymfzssrx66gg87hypqbw1ptr0000gn/T/vsch
[+] Building 1.2s (6/6) FINISHED                                                
 => [internal] load build definition from volumeBootstrap.Dockerfile-0.20  0.0s
 => => transferring dockerfile: 184B                                       0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/alpine:3.14.2           1.1s
 => [1/2] FROM docker.io/library/alpine:3.14.2@sha256:e1c082e3d3c45cccac8  0.0s
 => CACHED [2/2] RUN apk add --no-cache  nodejs  git  openssh-client  doc  0.0s
 => exporting to image                                                     0.0s
 => => exporting layers                                                    0.0s
 => => writing image sha256:83d8a321021f6a9492c80936eebd79c06a21cf09fc987  0.0s
 => => naming to docker.io/library/vsc-volume-bootstrap                    0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[2368 ms] Cloning Github repository: FOO/FOO into /workspaces/FOO

[2368 ms] Start: Run: docker run -d --mount type=volume,src=FOO-codespaces-671d92059284359413c7b6ee4ce7a1b8,dst=/workspaces -v /var/run/docker.sock:/var/run/docker.sock vsc-volume-bootstrap sleep infinity
[2878 ms] Start: Run in container: /bin/sh
[2880 ms] Start: Launching Remote-Containers helper.
[2880 ms] ssh-agent: SSH_AUTH_SOCK in container (/tmp/vscode-ssh-auth-63592ee66d5914093d224829efe71b99cb8e1a6e.sock) forwarded to host (/private/tmp/com.apple.launchd.2OqL7NJN6h/Listeners).
[2881 ms] Start: Run: gpgconf --list-dir agent-extra-socket
[2884 ms] Start: Run in container: cat <<'EOF-/tmp/vscode-remote-containers-63592ee66d5914093d224829efe71b99cb8e1a6e.js' >/tmp/vscode-remote-containers-63592ee66d5914093d224829efe71b99cb8e1a6e.js
[3071 ms] 
[3071 ms] 
[3071 ms] Start: Run in container: cat <<'EOF-/tmp/vscode-remote-containers-server-63592ee66d5914093d224829efe71b99cb8e1a6e.js' >/tmp/vscode-remote-containers-server-63592ee66d5914093d224829efe71b99cb8e1a6e.js
[3085 ms] 
[3085 ms] 
[3085 ms] Start: Run in container: node /tmp/vscode-remote-containers-server-63592ee66d5914093d224829efe71b99cb8e1a6e.js
[3088 ms] Start: Run in container: # Test for /root/.gitconfig and git
[3095 ms] 
[3096 ms] 
[3096 ms] Start: Run in container: # Copy /Users/tailee/.gitconfig to /root/.gitconfig
[3099 ms] 
[3099 ms] 
[3099 ms] Start: Run in container: command -v git >/dev/null 2>&1 && git config --global --replace-all credential.helper '!f() { node /tmp/vscode-remote-containers-63592ee66d5914093d224829efe71b99cb8e1a6e.js $*; }; f' || true
[3107 ms] 
[3107 ms] 
[3108 ms] Start: Run in container: # Test for /root/.ssh/known_hosts and ssh
[3111 ms] 
[3111 ms] 
[3112 ms] Start: Run in container: # Copy /Users/tailee/.ssh/known_hosts to /root/.ssh/known_hosts
[3116 ms] 
[3116 ms] 
[3328 ms] Start: Run in container: cat /workspaces/FOO/.devcontainer/devcontainer.json 2>/dev/null
[3330 ms] Start: Run in container: cat /workspaces/FOO/.devcontainer/devcontainer.json 2>/dev/null
[3332 ms] The options 'workspaceMount' or 'workspaceFolder' are ignored when cloning a repository into a volume.
Running the initializeCommand from devcontainer.json...

[3333 ms] Start: Run: docker exec -it -w /workspaces/FOO -u root 494c732910ad0d51b904a333cd6cd5e871230bf24a6d4631c17ac4a59b0af962 .devcontainer/init
+ git config --get --local transcrypt.version
+ '[' '!' ]
+ cat TRANSCRYPT_CIPHER
+ TRANSCRYPT_CIPHER=
+ cat TRANSCRYPT_PASSWORD
+ TRANSCRYPT_PASSWORD=
+ '[' -z  ]
+ cat

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!! MANUAL SETUP REQUIRED !!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Add 'TRANSCRYPT_CIPHER' (if required) and 'TRANSCRYPT_PASSWORD' repository
secrets in Codespaces OR save to disk, and rebuild.

        echo '...' > TRANSCRYPT_CIPHER  # If required. Default: aes-256-cbc
        echo '...' > TRANSCRYPT_PASSWORD

+ exit 1
[3623 ms] Command failed: docker exec -it -w /workspaces/FOO -u root 494c732910ad0d51b904a333cd6cd5e871230bf24a6d4631c17ac4a59b0af962 .devcontainer/init
[11059 ms] Start: Run: docker version --format {{.Server.APIVersion}}
[11167 ms] 1.41
mrmachine commented 3 years ago

I temporarily stripped my .devcontainer/init script to avoid returning a non-zero exit code, and I also had to remove a bind mount volume from my docker-compose.yml file to avoid a Mounts denied error, but then finally I was able to build my image via buildkit with Clone Repository in Container Volume.

I am however now unable to edit any files because /workspace is owned by root and I am using containerUser in devcontainer.json. But that's a separate issue, as is being unable to reopen in the recovery container.

In any case, I still wonder if there might now be similar problems in the other direction. If the build environment is now hard coded to buildkit since 0.205.0, will others have issues if their image requires the standard builder?

Being able to specify in devcontainer.json whether or not builtkit is used, both for regular devcontainers and for Clone Repository in Container Volume, still seems ideal.

chrmarti commented 3 years ago

We chown the cloned repository once after cloning, but then leave the ownership as it is.

For my own understanding: What are the differences between classic and buildkit builds that makes you want to use a flag in the devcontainer.json to use the classic build? (buildkit seems to be largely backwards compatible.)

mrmachine commented 3 years ago

We have been bitten in the past when initially switching to buildkit. It was a long time ago now, but IIRC perhaps more a case of our misconfiguring build mounts for cache than a regression with buildkit itself, but I think the potential is there.

I am personally happy with buildkit, and came here looking for a way to enable buildkit.

But, if Docker can be configured to use two completely different builders outside of VS Code, I think VS Code should allow a choice between builders within for greater compatibility and interoperability with existing tooling and workflows that people might have. Especially for something like Clone Repository in Container Volume where the builder is being invoked inside a container, and therefore cannot easily be configured directly on the host.

EDIT: Adding on to that, I believe Docker Desktop itself still does not make buildkit the default. The plugin is bundled, but you still have to docker buildx install to make it the default. Other platforms don't even get the plugin bundled. If VS Code is forcing buildkit with Clone Repository in Container Volume, with no option to revert, that seems out of step with Docker.

chrmarti commented 3 years ago

I see it enabled in Docker Desktop by default and Alpine's docker-cli and docker-compose packages now also seem to enable it by default (we don't enable it for Clone Repository in Container Volume ourselves).

If enabling buildkit does not cause any issues, I would expect everyone to enable it over time since it is faster and comes with additional features. There seems to be some hesitancy towards enabling it in Linux packages because it moves the image layer cache around (and presumably changes its format), but maybe that will eventually change too. It seems to have changed for Alpine as we see.

AngellusMortis commented 3 years ago

Using docker-compose 2.0 or newer solved this for me. It looks like docker-compose uses Buildkit by default if it is enabled in your docker engine settings.

mccarthysean commented 2 years ago

Try using simple environment variables, in addition to .env:

  dev_container:
    build:
      context: ..
      dockerfile: Dockerfile.dev
    env_file: 
      - ../.env
    environment:
      DOCKER_BUILDKIT: 1
      COMPOSE_DOCKER_CLI_BUILD: 1
jasonwilliams commented 2 years ago

Maybe this is a separate issue but i actually need DOCKER_BUILDKIT=0 and it seems impossible to set this as there's no hook for environment variables before the container starts.

Can we have a section for env vars which are ran before the docker-compose or docker is executed? So far the only hook is for setting envs within the remote container. This would fix the original issue also.

@chrmarti I can't imagine this is hard to implement? It has a lot of upvotes.

chrmarti commented 2 years ago

"localEnv" in the devcontainer.json similar to "containerEnv" and "remoteEnv"? 🤔

I'm hesitant to propose something specific to Buildkit since that seems to become enabled by default for everyone and any property in the devcontainer.json specific to that will be obsolete after this transition.

jasonwilliams commented 2 years ago

"localEnv" in the devcontainer.json similar to "containerEnv" and "remoteEnv"? 🤔

I'm hesitant to propose something specific to Buildkit since that seems to become enabled by default for everyone and any property in the devcontainer.json specific to that will be obsolete after this transition.

There is no ”localEnv” option when using DockerComposeFile, I only have remoteEnv. Also my solution would help in that it’s generic for any environment variable and not specific to buildkit

chrmarti commented 2 years ago

Sorry, I meant to say we could add "localEnv", but that does not exist today.

jasonwilliams commented 2 years ago

Sorry, I meant to say we could add "localEnv", but that does not exist today.

Oh right I see, yes please this would be very useful!

jimmcslim commented 2 years ago

Is there a comprehensive guide on how to set this up at all? My use case... wanting to start an x86 devcontainer on an Apple Silicon host - I have some code that has hard x86 dependencies and want devs with an M1 Mac the ability to work with it. I've had success running an x86 container emulated by Docker Desktop/qemu through the Vagrant Docker provider, but would like to translate this to VS Code Remote Containers.

chrmarti commented 2 years ago

@jimmcslim There is no guide at the moment. Not sure what your particular setup is, but if you are using a single container with a Dockerfile referenced in the devcontainer.json, you can try to add "runArgs": ["--platform", "linux/amd64"] to the devcontainer.json to control the platform docker run will use.

jimmcslim commented 2 years ago

@chrmarti I've had success with runArgs as you identified... to run an x86 container on an M1 Mac (with Docker Desktop using QEMU to do the x86->ARM translation). This works if the devcontainer.json uses image to identify an image.

But my understanding is that if devcontainer.json references a Dockerfile instead... there's no way to specify which platform to use for the build process so if the base image is available for both x86 and ARM then it will use the ARM image (which would then fail to run if you have specified linux/amd64 in the runArgs.

chrmarti commented 2 years ago

@jimmcslim There is a platform switch in the Dockerfile: https://docs.docker.com/engine/reference/builder/#from

jasonwilliams commented 2 years ago

hey @chrmarti just to clarify, is your resolution for this issue to provide a localEnvs field?

chrmarti commented 2 years ago

@jasonwilliams That seems like a good option, but I don't have a timeline for implementing it. Other issues have asked for an "envFile" property that would take a filepath to an "env" file listing environment variables like, e.g., Docker Compose supports. "localEnv" might be a better fit because we already have "containerEnv" and "remoteEnv".

moi90 commented 2 years ago

I included DOCKER_BUILDKIT=1 and COMPOSE_DOCKER_CLI_BUILD=1 in my ~/.bashrc. Still, traditional build is used. Any ideas why?

maciek16180 commented 2 years ago

Any updates to this issue? We are also waiting for it.

spirulence commented 2 years ago

I didn't have any luck with the workarounds and solutions mentioned here - my environment is a remote AWS EC2 arm64 machine (r6g.large) running Amazon Linux 2. (Codespaces can get prohibitively expensive!)

However, in this environment, I do have full control over the Docker daemon options via daemon.json (https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file) which on linux is located at /etc/docker/daemon.json.

The optional field features in daemon.json allows users to enable or disable specific daemon features. For example, {"features":{"buildkit": true}} enables buildkit as the default docker image builder.

The list of currently supported feature options:

buildkit: It enables buildkit as default builder when set to true or disables it by false. Note that if this option is not explicitly set in the daemon config file, then it is up to the cli to determine which builder to invoke.

After modifying the file I needed to reboot the service using sudo service docker restart.

For Docker Desktop users, this is also configurable by GUI, although it's easy to get the syntax wrong if you're typing by hand:

CleanShot 2022-05-16 at 12 54 14

I realize this won't work for users who need to pick at build-time between old and new builders - but in my case where I am provisioning the VM with user-data, and only need to support BuildKit build processes, which I suspect is a large cohort of users, this works really well. It makes a lot of sense to add something like this as a note to the VS Code documentation around requirements for Remote Containers as a callout for users who need BuildKit.

PS This enables you to use the target platform ARGs in your Dockerfile as in

ARG TARGETARCH
RUN curl -O https://releases.hashicorp.com/terraform/1.1.9/terraform_1.1.9_linux_${TARGETARCH}.zip
jasonwilliams commented 2 years ago

@chrmarti offering localEnv would solve a whole class of issues here, and is surely a quick-win as all you need to do is set the envs before launching the Docker process.

Any chance it could be prioritised? I’m sure people here would do it if it was open source.

bscott-machina commented 2 years ago

+1 for Buildkit support

Running into an issue where I have to alter the Build command to enable the SSH Mount so the users ssh key can be passed into the Devcontainer to checkout private repos.

DOCKER_BUILDKIT=1 docker build --ssh default . as an example

I don't see how https://github.com/devcontainers/cli, could of been released without support for this, cloning private repos is an important part of setting up a container for development and securing how SSH keys are passed in are also critical in my opinion.

chrmarti commented 2 years ago

Note that we are moving over to use docker buildx build by default. (That allows us to add the container features in the same build and that in turn simplifies handling of checkums for caching and multi-platform builds.) https://github.com/devcontainers/cli/blob/b7dc6fe5a406fda55e694ec126634c91d4a96198/src/spec-node/singleContainer.ts#L163

nahuel commented 2 years ago

Note, buildkit is also needed to build using an specific project/.devcontainer/Dockerfile.dockerignore instead of a general project/.dockerignore.

maciek16180 commented 2 years ago

Note that we are moving over to use docker buildx build by default. (That allows us to add the container features in the same build and that in turn simplifies handling of checkums for caching and multi-platform builds.) https://github.com/devcontainers/cli/blob/b7dc6fe5a406fda55e694ec126634c91d4a96198/src/spec-node/singleContainer.ts#L163

@chrmarti Is there an ETA on when the buildx build will be the default in vscode dev container? Or is it already / can already be set?

Aposhian commented 2 years ago

Are there any workarounds for how to get --ssh default support for buildkit builds?

chrmarti commented 2 years ago

We use buildx build by default and fall back to build when buildx is not installed. docker-compose v2 appears to use buildx build in its recent versions.

@Aposhian Not currently. Support for build CLI options is tracked as https://github.com/microsoft/vscode-remote-release/issues/3545.

Is there anything you were looking for getting from using BuildKit that would not be covered by adding build CLI options (https://github.com/microsoft/vscode-remote-release/issues/3545)? (Trying to find out if we can close this issue.)

YoniChechik commented 1 year ago

My best solution for this is enabling buildkit by default with: docker buildx install

scalpel4k commented 1 year ago

Could anyone entitled please explain why it is not possible to just have something like "runArgs" just for the compile/build stage? Buildkit is having so many options these days that I'd like to have some control over it and not having to hope for some vscode magic ....

crairs commented 1 year ago

The organization I work for is a very large organization; it's a big Microsoft customer and RedHat customer. Docker's use was supplanted by Podman years ago. We need to be able to disable the use of BuildKit.

chrmarti commented 1 year ago

@crairs We detect if BuildKit is available or not and do work without it.