VSCodeのDev Containerを真面目にセットアップしてみる(Golang)

アプリケーション開発を行う上で、開発環境の構築は地味に煩わしい作業の一つである。 VSCodeの拡張機能「Dev Containers」を使うことで、 Dockerfileにより定義された一貫した開発環境を簡単に配布・利用することが可能となる。 今回はGolangを使った実際のアプリケーション開発を想定してDev Containerをセットアップしてみる。

はじめに

今回はGolang+PostgreSQLによるWebアプリケーション開発を想定し、 以下の要件を満たせるようにする。

  • PostgreSQLの開発用データベースが自動的にセットアップされる
  • Golangの言語ツール(補完等)を使えるようにする

なお、検証に用いた環境は以下のとおりである。

  • ArchLinux x86_64
  • Visual Studio Code (binary) 1.73.0
  • Dev Containers 0.262.3
  • Docker 20.10.21

Dev Container設定ファイルの作成

Dev Containerの設定ファイルはすべて.devcontainer/以下に作成していく。

今回作成するファイルは以下の通り。

1.devcontainer
2├── devcontainer.json
3├── docker-compose.yml
4└── Dockerfile

docker-compose.ymlの作成

今回は開発用のコンテナの他にDB用のコンテナも必要なので、 それらをまとめて立ち上げるためにdocker-compose.ymlを用意する。

 1version: '3'
 2
 3services:
 4  dev:
 5    build: .
 6    stdin_open: true
 7    volumes:
 8      - ../:/workspace
 9  psql:
10    image: postgres:15-alpine
11    volumes:
12      - pgdata:/var/lib/postgresql/data
13    environment:
14      - POSTGRES_PASSWORD=test
15      - POSTGRES_USER=test
16      - POSTGRES_DB=test
17
18volumes:
19  pgdata:

docker-composeを自前で用意する場合、ワークスペース(プロジェクトのディレクトリ)は自力でマウントする必要がある。 今回は../:/workspaceのようにして/workspaceにマウントしている。

ちなみに、開発用コンテナのstdin_open: trueは必須である。 これを省略した場合、開発用コンテナが即座に終了してしまう。

stdin_open: trueを省略した場合に起こるエラーについて

stdin_open: trueを省略すると以下のようなエラーが発生しDev Containerを起動できなくなる。

1[1096 ms] Start: Inspecting container
2[1097 ms] Start: Run: docker inspect --type container e62ecd75e1962b8d908c9890c383290d23af5c518c6378caa38c3c58f86a57f8
3[1143 ms] Start: Run in container: /bin/sh
4[1152 ms] Start: Run in container: uname -m
5[1170 ms] Shell server terminated (code: 1, signal: null)
6[1170 ms] Error response from daemon: Container e62ecd75e1962b8d908c9890c383290d23af5c518c6378caa38c3c58f86a57f8 is not running
7[1170 ms] Start: Run in container: cat /etc/passwd
8[1170 ms] Stdin closed!

Dockerfileの作成

Dockerfileでは、Go言語機能に必要なツールや、PostgreSQLクライアント等をインストールする。

 1FROM golang:1.19-bullseye
 2
 3# Postgresクライアントのインストール
 4RUN apt -y update \
 5 && apt -y install postgresql-client
 6
 7# Go言語ツールのインストール
 8RUN go install github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest \
 9  && go install github.com/ramya-rao-a/go-outline@latest \
10  && go install github.com/nsf/gocode@latest \
11  && go install github.com/acroca/go-symbols@latest \
12  && go install github.com/fatih/gomodifytags@latest \
13  && go install github.com/josharian/impl@latest \
14  && go install github.com/haya14busa/goplay/cmd/goplay@latest \
15  && go install github.com/go-delve/delve/cmd/dlv@latest \
16  && go install golang.org/x/lint/golint@latest \
17  && go install golang.org/x/tools/gopls@latest
18
19WORKDIR /workspace

ちなみに、go installは必ず一つずつ実行する必要がある。 これは一気にすべてをインストールしようとするとバージョンの解決に失敗するためである。

最後のWORKDIR /workspaceによって、ターミナルを開いたときにデフォルトでワークスペースに移動するようにしている。

devcontainer.json

最後にDev Container自体の設定ファイルであるdevcontainer.jsonを用意する。

 1{
 2  "dockerComposeFile": "docker-compose.yml",
 3  "service": "dev",
 4  "settings": {
 5    "terminal.integrated.shell.linux": "bash",
 6    "go.toolsManagement.checkForUpdates": "off",
 7    "go.useLanguageServer": true,
 8    "editor.formatOnSave": false,
 9    "[go]": {
10      "editor.formatOnSave": true
11    }
12  },
13  "workspaceFolder": "/workspace",
14  "extensions": [
15    "golang.go"
16  ]
17}

まず、dockerComposeFileによりカスタムのdocker-compose.ymlを使用することを示す。

次のserviceには、docker-compose内のどのサービスを開発用コンテナとして扱うかを指定する。

settingsには、Dev Containerを開いた際のVSCodeのコンフィグを書くことができる。 "terminal.integrated.shell.linux": "bash"は、指定しなかった場合shがシェルとして起動してしまったので記述している。

workspaceFolderにはVSCodeで開くコンテナ上のディレクトリを指定する。(必須)

extensionsには使用したい拡張機能を指定する。今回はGolangの機能のみがあればいいのでgolang.goを指定している。 なお、ここで指定する拡張機能名は、該当の拡張機能の詳細ページを開いた右下の「More Info」の中の「Identifier」を指定する。

Dev Containerの起動

まずはVSCodeでプロジェクトのディレクトリを開く。

1$ code .

次に、Dev Containersの拡張機能をまだ入れていない場合はインストールする。

インストールしたら、コマンドパレットを開き、「Dev Containers: Reopen in Container」を実行する。

初回はコンテナのビルドが走るため時間がかかる。

完了するとDev Container内のセッションに接続し、Golangの補完等が使えるようになる。

データベースへの接続

コンテナにpsqlコマンドをインストールしているので、普通に接続することが可能なはずである。

DBのホスト名はdocker-compose.ymlで指定したサービス名psqlとなる。

1root@0b39a3cf6d1a:/workspace# psql -h psql -U test
2Password for user test: 
3psql (13.8 (Debian 13.8-0+deb11u1), server 15.1)
4WARNING: psql major version 13, server major version 15.
5         Some psql features might not work.
6Type "help" for help.
7
8test=# 

まとめ

今回は開発用コンテナと一緒にDBサーバーを立ち上げる構成を試してみた。

Dockerさえ入っていればWindows, MacOS, Linuxで同じ開発環境を立ち上げられるのはなかなか魅力的である。

関連記事