📝

みんながきっと1万回は聞いている、VS Code Remoteでコンテナ開発をやる方法

2021/04/18に公開

こんにちは皆さん。

いやね、皆さんこう言いますよ。
「それもう何番煎じやねん!前も聞いたわ!」
ってね。

でも、こうも思うじゃないですか。
「たくさん記事があるってことは、ひょっとしてめっちゃくちゃ大事なことなのでは?」
とね。

とういうわけで、毎回まるで前提のごとく使っていたVS Code Remote Containerによるコンテナ開発について、自分が使っているやり方について簡潔に書いてみます。
マニュアルなぞっても面白くないですしね。

VS Code Remote

VSCではリモート環境に入ってエディタを起動することができます。
イメージ的にはこんな感じで、リモート環境上で立ち上げたエディタを、外部から遠隔操作するようなイメージですね。
VSC Remote
VS Code Remote自体は随分前からあったのですが、WindowsのDocker開発の環境が整うまでに結構かかったのですよね。
私のプライベートマシンがWindowsであることもあって、完全にRemote Containersができるようになったときは、無駄に感動したものです。

このエクステンションは、このリモート環境をどこに用意するかで、3つに分かれています。
普通の外部サーバで実行しSSHでアクセスするもの、WindowsのWSL上で実行するもの、そして、立ち上げたコンテナ上で実行するものです。
今回解説するのは、コンテナにアクセスするものです。

VS Code Remote Containers

VSCをコンテナ上で実行できるパッケージですが、その実行方法がいくつかあります。各々について解説していきます。

パッケージインストール

何をやるにもVSCの Remote Containerが必要です。さっさと入れちゃいましょう。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
入れるのは一瞬ですが、前提として、docker for mac もしくは docker for windowsが必要です。
私の環境ではdocker for windows の WSL2ホスティングを使っています。

attatch container

まずは手っ取り早くコンテナ上でVSCを実行してみましょう。
例として私の環境でPHP8の開発をしたいと考えたとき、まぁ、PHP8をそもそも入れていないわけですよ。Windowsですし。

> php
php : 用語 'php' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前
が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ php
+ ~~~
    + CategoryInfo          : ObjectNotFound: (php:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

ただ、dockerはあるので、そいつでphpを立ち上げてみます。

docker run -it --rm --name php-testing php:8 bash

終わったら、後でexitして落とします。

さて、コンテナが立ち上がってい状況で、VSCで以下のような手順を踏みます。

  1. 左下のアイコンを押す
  2. Remote-containers: Attatch to runnning container を選択する
  3. 立ち上がっているコンテナを選択する



これだけで、コンテナ上で実行するVSCが立ち上がります。
実際に見てみたのはこんな感じです。

(PHP古いな。。。更新しよう)
これでPHP8の入った環境中でのVSCを使った開発が始められるようになります。
もちろん、PHP intelephense などのエクステンションをインストールすることもできます。
しかし、注意すべきは、エクステンションのインストールは、環境ごとになるという点です。普段ホストで開発していると気にしないですが、コンテナ開発をする場合、基本的にコンテナは実行終了とともに破棄することが多いので、その場合、いちいちエクステンションをインストールしなおさなきゃいけない点に留意しましょう。
面倒な場合は、コンテナを破棄せず、使いまわすようにしましょう。

devcontainer

複数人での開発を考えると、構築する環境定義をプロダクトコードの中に入れておくのが楽です。
VSCのRemote Containerでは、動かしたいコンテナ環境を、docker-composeと少々に設定で定義することができます。
その方法を解説していきましょう。

.devcontainer

まず、プロダクトリポジトリのルート配下に以下のようにディレクトリとファイルを作ります。

.devcontainer
  ┗ devcontainer.json
  ┗ docker-compose.yml

超単純には、docker-compose.ymlがVSCで開発するうえで必要な環境を用意する部分で、devcontainer.jsonが実際にVSCをどこでどのように起動するかを定義する部分です。
docker-composeを使わないで、dockerのイメージを直接指定するやり方もありますが、今回はdocker-composeを使った方法の解説だけにします。

コンテナの定義

私がよくLaravelの記事を書くときに使っているテンプレを例にしてみましょう。
大体の場合、PHPを動かす環境とデータベースがあれば事足りますので、docker-compose.ymlは以下のようになる場合が多いです。

version: "3"

services:
    workspace:
        build: workspace
        command: sleep infinity
        volumes:
            - ../:/var/www/
        ports: 
            - 8000:8000

    db:
        image: mysql
        environment:
            - MYSQL_ROOT_PASSWORD=secret
            - MYSQL_USER=niisan
            - MYSQL_DATABASE=niisan
            - MYSQL_PASSWORD=secret

ここで、workspaceという未定義のコンテナが出てくるので、いつものdocker-composeで環境を立ち上げるのと同じやり方で、workspaceのコンテナを定義しておきます。

.devcontainer
  ┗ devcontainer.json
  ┗ docker-compose.yml
  ┗ workspace
    ┗ Dockerfile

仕事じゃないので、たいして派手な内容ではないですが、以下のようなDockerfileを使っています。

FROM php:8

RUN apt-get update && apt-get install -y git unzip libonig-dev libzip-dev && \
docker-php-ext-install mbstring pdo pdo_mysql zip && \
pecl install xdebug && docker-php-ext-enable xdebug

COPY --from=composer /usr/bin/composer /usr/bin/composer

とりあえず、composerとテストできる環境があればいいや的なやつですね。

devcontainer.json

最後に、devcontainer.jsonを定義しましょう。

{
    "name": "oauth-laravel",
    "dockerComposeFile": "docker-compose.yml",
    "service": "workspace",
    "workspaceFolder": "/var/www",
    "settings": {
        "editor.tabSize": 4
    },
    "shutdownAction": "stopCompose"
}

このなかで、dockerComposeFileserviceは必須で、どのcomposeファイルを使って、どのサービス上でVSCを動作させればいいかを判断します。
ここまでできれば、あとはVSCを再起動させるだけです。

左下のアイコンを押して、Remote Containers: Reopen in Container を選択します。これで、開発環境に入った状態で、VSCが再起動します。
ちょっとわかりにくいかもですが、コンテナ環境上でエディタが起動しています。

おまけ

エクステンションの指定

devcontainerで起動させる場合、エクステンションについては少しありがたい機能があります。上に挙げたdevcontainer.jsonでextensionsという項目があるので、ここにあらかじめ入れておきたいエクステンションを記録しておけばよいです。jsonに簡単に追加する機能もあります。

そうすると、こんな感じになります。

{
    "name": "oauth-laravel",
    "dockerComposeFile": "docker-compose.yml",
    "service": "workspace",
    "workspaceFolder": "/var/www",
    "settings": {
        "editor.tabSize": 4
    },
	"shutdownAction": "stopCompose",
	"extensions": [
		"felixfbecker.php-intellisense"
	]
}

とりあえず、PHPで必要そうなエクステンションはあらかじめ入れるようにしておきましょう。

デバッガ

デバッガもリモート環境中で動かせます。
...動かせているはず。
試しにPHPのxdebug動かしてみましょう。
とりあえず、以下のiniファイルを/usr/local/etc/php/conf.d/docker-php-ext-xdebug.iniに突っ込みます。

zend_extension=xdebug
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_port = 9000

自動でやるんならDockerfileで入れてあげればいいかなって思いますが、今回は普通に編集したのを突っ込みました。

普通に動きますね。

まとめ

というわけで、VS Code Remote Containersの自分流のやり方を書いてみました。
もし、もっと深く知りたいとかであれば、マニュアルサイトを見に行ってくれればと思います。

今回は今すぐに始めるとしたら、どういう感じで始められるかな?という観点でやってみました。
開発環境をリモートの隔離された環境に作り、ホストをきれいに保つというのは、私にとっては割と重要事項ですので、同じ考えを持つ方々にとって良い記事となっていれば幸いです。

今回はこんなところです。

参考

マニュアル
devcontainer.jsonの仕様

Discussion