morishitaです。
先日リリースされたVisual Studio Code May 2019で Stable でもRemote Developmentが使えるようになりました。
これはExtension Packで、次の3つの拡張を含んでいます。
- Remote - SSH - Visual Studio Marketplace
- Remote - Containers - Visual Studio Marketplace
- Remote - WSL - Visual Studio Marketplace
これらは、それぞれ個別にもインストール可能です。
最後のRemote - WSLはWindowsでしか使えないと思うので、macOSユーザの私はスルーなのですが、残りの2つはちょっと気になります。
今回はより利用する機会(=利用できれば便利な場面)が多そうなRemote - Containersを試してみました1。
Remote - Containersとは?
環境の構築・再現が容易で、他の環境から隔離させられるDockerコンテナを使った開発環境を使っている方も多いと思います。
Remote - Containersはそんな方々に便利そうな拡張です。
その名の通り、Dockerコンテナ上で動作している開発環境に接続して、あたかもコンテナ上でVSCodeを動作させてるかのようになります2。
使ってみる
では、実際に使ってみましょう。
動作確認するにあたり、次のようなdocker-compose.ymlをプロジェクトのルートディレクトリに持つ簡単なRailsアプリケーションを例にします。
version: "3" volumes: pgdata: gem_home: services: postgres: image: postgres:10.7 ports: - 35432:5432 volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: pgpassword rails: build: . image: rails-pg ports: - 33000:3000 volumes: - .:/rails-pg - gem_home:/usr/local/bundle - /rails-pg/.git depends_on: - postgres working_dir: /rails-pg command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
次の2つのコンテナ定義を含むシンプルな構成です。
- postgres:
- PostgreSQL 10.7
- rails
- Railsのコンテナ。Ruby 2.6.3、Rails 5.2.2
- プロジェクトルートを
/rails-pg
マウントしておりRailsを起動できる
docker-compose up
を実行すると次のとおりになります。
$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------- rails-pg_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:35432->5432/tcp rails-pg_rails_1 bash -c rm -f tmp/pids/ser ... Up 0.0.0.0:33000->3000/tcp
ブラウザでhttp://localhost:33000/を開くと、Railsアプリケーションにアクセスできます。
開発作業はrailsコンテナに入ってやりたいということになります。
インストール
VS Codeのインストールはできているという前提で進めます。
まずはRemote - Containers - Visual Studio Marketplaceをインストールします。
インストールが完了すると次のような表示がVSCodeのウィンドウの左下角に追加されます。
Railsプロジェクトを開いてみる
Remote - Containersを使う場合には、File
メニューからプロジェクトのルートディレクトリを開くのではなく、先程の左下の赤い角をクリックします。
すると次のメニューがコマンドパレットに表示されます3。
この中から、Remote-Containers: Open Folder in Containerを選択します。ファイル選択ダイアログが表示されるので、docker-compose.ymlのあるプロジェクトのルートディレクトリを選択します。
次にDockerfileやdocker-compose.yml、いずれを参照して起動するかを聞かれるので、docker-compose.ymlを選択します。
最後に、次の様にdocker-compose.yml内のどのコンテナかを聞かれるので、rails
を選択します。
すると、VSCodeが再起動して開き直します。
どんな状態で立ち上がっているのか?
ファイルツリーには次の様に表示されます。
rails-pg
ディレクトリにもともとのプロジェクトルートディレクトリをマウントしているので、この中だけ見えればいいのですが、/
が見えてしまっています。
docker-compose.ymlにworking_dir: /rails-pg
を設定していますが、効いてないようです。
コンテナの起動状態は次のとおりです。
$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------- rails-pg_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:35432->5432/tcp rails-pg_rails_1 bash -c rm -f tmp/pids/ser ... Up 0.0.0.0:33000->3000/tcp
docker-compose up
した時と全く同じ様に起動されているようです。
なので、http://localhost:33000/ を開くとRailsアプリケーションにアクセスできます。
VSCodeを閉じると、コンテナも停止されます。
.devcontainer.json
再度、普通にFile
メニューからVSCodeでプロジェクトのルートディレクトリを開くと、.devcontainer.jsonというファイルが追加されています4。
これはVSCodeが起動するコンテナの開発環境Dev Containerについての設定ファイルです5。
上記の操作の結果では次のような内容になっています。
// See https://aka.ms/vscode-remote/devcontainer.json for format details. { "dockerComposeFile": "docker-compose.yml", "service": "rails", "workspaceFolder": "/", "extensions": [] }
このファイルの中にworkspaceFolder
の設定項目があります。
この値を"rails-pg"
に書き換えて、VSCodeを開き直します。
すると、次のようなダイアログがウィンドウの右下に表示されます。
Reopen in Conrainer をクリックすると.devcontainer.jsonに従ってコンテナでプロジェクトを開いてくれます。
"workspaceFolder": "rails-pg"
に書き換えていたので今度はrails-pg
ディレクトリの中だけが次の様にファイルツリーに表示されます。
これで余計なファイルを見なくて済むしうっかり変更してしまうということもなくなるでしょう。
ターミナルがコンテナ内で開く
Dev Containerでプロジェクトを開いた状態で、VSCode内のターミナルを起動してみると、それもコンテナ内で動作しています。
Railsの開発は折りに触れ、bundle install
や、rails g …
コマンドを使うので、ターミナルを開いたらすでにコンテナの中というのは便利です。
この状態のVSCodeを使っっているならコンテナの外か内かを意識しないで済みそうです。
その他、気になったところ
コンテナ側に拡張を入れ直す必要がある
Dev Container環境で利用したい拡張はすでにインストールしていてもコンテナ側に再度インストールする必要があります。 そもそもEXTENTIONマネージャの表示からして、次の様にDEV CONTAINERとLOCALに分かれています。
私はEditorConfig for VS Codeは普段からインストールしています。Dev Container環境だと次の様にIntall in Dev Containerという表示がでてコンテナ側へのインストールを求められます。
おお、これは面倒だと思ったのですが、インストールの手間を軽減する方法はあります。
次の様に.devcontainer.jsonのextensions
に設定しておくと、Dev Container作成時にインストールしてくれます。
// See https://aka.ms/vscode-remote/devcontainer.json for format details. { "dockerComposeFile": "docker-compose.yml", "service": "rails", "workspaceFolder": "/", "extensions": [ "editorconfig.editorconfig", "rebornix.ruby" ] }
ただしコンテナを作る時だけにインストールされる様なので、既存コンテナがある場合には次のいずれかを実行する必要があります。
- 一旦コンテナを削除して、再度Dev Container環境を開く
- Remote-Containers: Rebuild Containerを実行する
.devcontainer.jsonをリポジトリに入れておけば、VSCodeを使うプロジェクトメンバーで同じ拡張をインストールした状態を共有できます。
プロジェクトで使うフレームワークや言語に特化していたり、コーディング規約やコードフォーマットを守らせる拡張は上記でいいでしょう。
でも、好みが分かれる汎用的な拡張はインストールを強要するような共有はしたくはありません。例えば、私はBracket Pair Colorizer 2をとても便利に使っていますが、この手の拡張を使いたいかどうかは人それぞれでしょう。
プロジェクト単位ではなくユーザ単位で必ずDev Container環境にインストールする拡張を設定するにはsetting.jsonに次の様に設定を追加します。
{ ・・・ "remote.containers.defaultExtensions": [ "coenraads.bracket-pair-colorizer-2" ] ・・・ }
するとDev Containerが作られるときにここで設定した拡張もインストールされるようになります。
これでチームの方針を共有しつつ、各メンバー独自の開発環境ができますね。
.gitディレクトリをコンテナに入れなきゃならない
Dev Container環境でファイルを編集していて、ファイルツリー状で変更が確認できないということに気づきました。
.gitをコンテナに入れる必要がないと思って、docker-compose.ymlの
volumes
の設定で/rails-pg/.git
を設定して空にしていたのですが、これが良くないようです6。
この設定を削除して、.gitディレクトリもDev Containerに含まれるようにして再度環境を開き直すとGitの履歴や変更状態を確認できるようになりました。
まとめ
この拡張自体、まだPreview版なので、今後改善されて使いやすくなっていくと思いますが、その際に仕様が変わったりするかもしれませんし、思わぬ不具合があるかもしれません。
その点には注意が必要ですが、コンテナの外か内かを意識せず開発でき、快適になると思います。
参考
最後に
アクトインディではエンジニアを募集しています。
-
コンテナ運用で使い捨てにするサーバが増えてSSHで中に入ってなにかするってことがあんまりないので。ゼロってわけでもないんですがね。↩
-
ローカルマシン上で動いているDockerコンテナがリモート? って思うかもしれませんが、ローカルマシン上でネイティブに動作するOS以外の仮想環境やコンテナで動作しているOSには何らかの通信で接続しておりそういう意味でリモートなんですね。↩
-
私は Remote - SSH拡張もインストールしているのでそのメニューも含まれています。↩
-
Remote-Containers: Create Container Configuration fileメニューを選択しても作成できます。
↩ -
なにが設定できるかはdevcontainer.json referenceに記載されています。↩
-
コンテナの高速化ためのTipsとして設定していました。↩