VS Code の Remote Container で複数のコンテナを起動して作業を切り替える

# はじめに
VSCode の Remote Container って便利ですよね。
ローカルPCの環境を汚さずにいろいろな言語を試すことのできるのが最高。

ただ、サクッと試したいだけなのに、いちいち言語別に設定するのが面倒だったりしますよね。

この投稿では、1回起動するだけで複数のコンテナに接続できる設定を紹介します。

公式ドキュメントにも書かれているので、詳しく知りたい方はこちらを。
https://code.visualstudio.com/docs/remote/containers-advanced#_connecting-to-multiple-containers-at-once


# デモコードの概要
ここでは、golang と python のコンテナを扱うこととします。
`.
├── golang
│   ├── .devcontainer.json
│   └── Dockerfile
├── python
│   ├── .devcontainer.json
│   └── Dockerfile
└── docker-compose.yml
`
## 設定ファイルの詳細
### 1. docker-compose.yml
remote-containerで管理するコードの親元を docker-compose.yml に記載します。

build.context でディレクトリを指定し、そこから Dockerfile までの相対パスを dockerfile に書いておけば大丈夫です。

ディレクトリ構成が気に入らなければ、自由に変えることもできます。

```yml:docker-compose.yml
version: "3"
services:
  golang-container:
    build:
      context: golang 
      dockerfile: Dockerfile
    volumes:
      - .:/workspace:cached
    environment:
      TZ: "Asia/Tokyo"
    command: sleep infinity

  python-container:
    build:
      context: python 
      dockerfile: Dockerfile
    volumes:
      - .:/workspace:cached
    environment:
      TZ: "Asia/Tokyo"
    command: sleep infinity
```

### 2. .devcontainer.json
コンテナごとの設定を .devcontainer.json に記載します。

親子関係をつなぐために、 dockerComposeFile と service の名前は docker-compose.yml で定義したものと一致させています。

workspaceFolder で言語ごとに区分けたディレクトリを指定してやることにより、VS Code のウィンドウ上に他言語が表示されないようにできます。（表示していると警告が出てきたりしてうるさい）

extensions は調べたらいろいろあるので、好きにカスタマイズしたらいいです。

```json:.devcontainer.json
{
    "name": "Dev Container Golang Env",
    "dockerComposeFile": "../docker-compose.yml",
    "service": "golang-container",
    "workspaceFolder": "/workspace/golang",
    "extensions": [
      "golang.go",
      "donjayamanne.githistory",
      "eamodio.gitlens",
      "codezombiech.gitignore",
      "mhutchie.git-graph",
      "esbenp.prettier-vscode",
      "coenraads.bracket-pair-colorizer",
      "ionutvmi.path-autocomplete"
    ],
    "terminal.integrated.shellArgs.linux": [
        "-l"
    ],
    "shutdownAction": "stopCompose"
}
```

### 3. Dockerfile
コンテナごとに使いたい設定を記載します。

普通のDockerfileと同じようにかけるので、ライブラリのインストールもしておくと便利です。

ここでは、みんな大好き git の補完ツールをインストールさせています。

```docker:Dockerfile
FROM golang:buster

WORKDIR /

RUN apt-get update \
 && apt-get install -y --no-install-recommends \
      git \
      openssh-client \
      procps \
      ca-certificates \
      curl \
      unzip \
      gnupg \
      vim \
      wget \
 && rm -rf /var/lib/apt/lists/*

# git
RUN wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -O ~/.git-completion.bash
RUN chmod a+x ~/.git-completion.bash
RUN echo "source ~/.git-completion.bash" >> ~/.bashrc
RUN wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/.git-prompt.sh
RUN chmod a+x ~/.git-prompt.sh
RUN echo "source ~/.git-prompt.sh" >> ~/.bashrc
```

# 複数コンテナの起動方法
1. VS Code のコマンドパレットを開いて、`Remote-Containers: Open Folder in Container...` を選択する
2. 開きたいディレクトリを選択する（今回は golang か python のディレクトリ）

上記のように普通にRemoteContainerを起動する要領で操作したら、選択したコンテナだけでなく、設定に記載されている他のコンテナも作成してくれます。

切り替えるには、1. 2. の手順と同様に、開きたいディレクトリを選択するだけです。
1回目の起動時にコンテナは立ち上がっているので、ウィンドウが切り替えられてすぐに操作できます。

もし別ウィンドウにしたければ、VS Code で新規ウィンドウを作成して、そこから 1. 2. の手順を実行したらいいです。

# まとめ
VS Code の Remote Container で複数のコンテナを起動する方法を紹介しました。
ここでは golang と python の2つのコンテナでしたが、自由に追加できます。

複数言語を git のプライベートレポジトリで管理するときなんかに役立つのではないでしょうか。
言語のバージョン違いの動作検証なんかにも使えそうですね。

ソースコードは github で公開しています。
https://github.com/fumiyakk/demo-multiple-remote-containers


python は poetry を使うために手のこんだ作りになってます。
そのうち poetry と black を組み合わせた python の開発環境について紹介します。