How to use Docker in VSCode DevContainer

Creating a DevContainer

First, execute > Remote-Containers: Add Development Container Configuration Files ... in the command palette to create the DevContainer configuration file. At this time, you can select a template, so select Docker from Docker (Docker from Docker Compose if you want to run DevContainer with docker-compose).

Now you can use Docker inside the container by running > Remote-Containers: Reopen in Container.

If you want to install some additional language etc., it is easy to edit .devcontainer / Dockerfile to change the base image. You can use any Debian or Ubuntu-based image. The following is an example based on the official DevContainer image for the Go language.

.devcontainer/Dockerfile


# Note: You can use any Debian/Ubuntu based image you want. 
FROM mcr.microsoft.com/vscode/devcontainers/go:1.15

#The following is omitted

Use Docker's bind mount within DevContainer

Be careful when using bind mount within DevContainer. If you mount it without thinking as below, you will not find the file you should have mounted in the container.

$ docker run --rm -it -v $(pwd):/app golang:1.15 /bin/bash

This is because Docker in DevContainer shares the Docker running on the host. Therefore, when performing bind mount, it is necessary to specify the path of the host instead of the path in DevContainer.

To solve this problem, the following environment variables are defined by default in .devcontainer/devcontainer.json.

json:.devcontainer/devcontainer.json


{
	// ...

	// Use this environment variable if you need to bind mount your local source code into a new container.
	"remoteEnv": {
		"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
	},

	// ...
}

$ {localWorkspaceFolder} is a variable available in devcontainer.json that means the host-side path of the open folder. This setting allows you to reference the host path from the environment variable LOCAL_WORKSPACE_FOLDER within DevContainer.

In other words, in order for the previous example to work correctly, do the following.

$ docker run --rm -it -v $LOCAL_WORKSPACE_FOLDER:/app golang:1.15 /bin/bash

Use docker-compose bind mount within DevContainer

Similarly for docker-compose, when using bind mount, it is necessary to specify the path on the host side.

The following settings do not work within DevContainer.

docker-compose.yml


version: "3"

services:
  app:
    image: ruby:2.7
    volumes:
      - .:/app
    working_dir: /app
    command: bundle exec rackup

It works by writing as follows.

docker-compose.yml


version: "3"

services:
  app:
    image: ruby:2.7
    volumes:
      - ${LOCAL_WORKSPACE_FOLDER}:/app
    working_dir: /app
    command: bundle exec rackup

However, if you write it like the above, you can not move it outside DevContainer. That is inconvenient, so it seems good to write the settings for DevContainer in docker-compose.override.yml [^ 1] etc. as follows.

[^ 1]: This is an optional configuration file that docker-compose loads by default. docker-compose.yml Overrides the settings in. See here for more information.

yaml:docker-compose.override.yml


services:
  app:
    volumes:
      - ${LOCAL_WORKSPACE_FOLDER}:/app

When the host OS is Windows

If the host OS is Windows, an error will occur even if you set using $ {LOCAL_WORKSPACE_FOLDER} as described above.

$ docker-compose up
ERROR: Named volume "c:\Users\frozenbonito\dev\docker-from-docker:/app" is used in service "app" but no declaration was found in the volumes section.

This is because if the host OS is Windows, the value of $ {localWorkspaceFolder} will be a Windows-style path and docker-compose will mistakenly recognize it as the Volume name.

There are two solutions.

Use the long syntax of volumes

Set the Windows path to docker-compose by using the long syntax in the volumes setting as shown below. It can be interpreted correctly.

yaml:docker-compose.override.yml


services:
  app:
    volumes:
      - type: bind
        source: ${LOCAL_WORKSPACE_FOLDER}
        target: /app

Set the environment variable COMPOSE_FORCE_WINDOWS_HOST

If the environment variable COMPOSE_FORCE_WINDOWS_HOST is set to true or 1, docker-compose looks like DevContainer. The HOST path in short syntax is now interpreted as a Windows path even if it is running in a Linux environment. Become.

It is a good idea to set it in devcontainer.json as follows.

json:.devcontainer/devcontainer.json


{
	// ...

	"remoteEnv": {
		"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}",
		"COMPOSE_FORCE_WINDOWS_HOST": "true"
	},

	// ...
}

Recommended Posts

How to use Docker in VSCode DevContainer
Understand in 5 minutes !! How to use Docker
How to use Lombok in Spring
How to use InjectorHolder in OpenAM
[Artifactory] How to use Docker repository
How to use classes in Java?
[Docker context] ~ How to access docker in remote environment from VScode ~
Multilingual Locale in Java How to use Locale
How to use custom helpers in rails
How to use named volume in docker-compose.yml
[Rails] How to use rails console with docker
How to use MySQL in Rails tutorial
How to use environment variables in RubyOnRails
How to use credentials.yml.enc introduced in Rails 5.2
How to use ExpandableListView in Android Studio
How to use Map
How to use rbenv
How to use letter_opener_web
How to use with_option
How to use fields_for
How to use java.util.logging
How to use map
How to use collection_select
How to use Twitter4J
How to use active_hash! !!
How to install Docker
How to use MapStruct
How to use hidden_field_tag
How to use TreeSet
[How to use label]
How to use identity
How to use hashes
How to use JUnit 5
How to use Dozer.mapper
How to use Gradle
How to use org.immutables
How to use java.util.stream.Collector
How to use VisualVM
How to use Map
How to check the logs in the Docker container
[Rails] How to use select boxes in Ransack
How to use "sign_in" in integration test (RSpec)
How to update pre-built files in docker container
How to use JQuery in js.erb of Rails6
How to use docker compose with NVIDIA Jetson
How to use nginx-ingress-controller with Docker for Mac
[Rails] How to use PostgreSQL in Vagrant environment
[Java] How to use Map
[Ruby] How to use standard output in conditional branching
How to use Chain API
[Java] How to use Map
How to use Priority Queuing
[Rails] How to use enum
How to use java Optional
How to use Ruby return
How to use Z3 library in Scala with Eclipse
[Rails] How to use enum
How to use @Builder (Lombok)
How to use java class
Understand how to use Swift's JSON Decoder in 3 minutes
How to use Swift UIScrollView