この投稿がきっかけでソフトウェアデザインに寄稿しています。この投稿の加筆修正ですが、自分のパート以外にもVS Code全般の特集となってますので興味あるかたはぜひそちらも!
はじめに
手元の開発環境をDockerとVS CodeのRemote Containersを使う方式にしたらあまりに最高なので書いておきます。
皆さんは普段手元の開発環境ってどんな感じで用意してますかね? これまで僕は普通に手元のMacに各言語のランタイムやらパッケージ管理ツールやらを普通にインストールしてました。でもこれだとちょっと試しに何か入れてみてってのを繰り返していくうちに段々と環境が汚れて来るんですね。
以前は汚れてきた結果なんらかの問題(パッケージの衝突とか)が起きたりしてくるとOSをクリーンインストールをし直しとかしていたわけです。フルタイムのソフトウェアエンジニアであればともかく、今はそういうわけではないのでこれがとても嫌になってました。
というわけで昨年、今のMacbook Proに買替えてから頑なに各言語のランタイムとかAWS CLIもローカルにはインストールせず、代わりにAWS Cloud9を使ってた。でも、Cloud9だと時間あけてアクセスするときのEC2の起動時間とかAWSの認証が必要とかで、さくっとコード書きたい、とかちょっと何か試したいってときにはだるくてやっぱりVS Code使いたいってなってたわけですよ。
そんなときにRemote Containersというものを遅ればせながら知りまして、試してみたら最高の体験でした。
あ、ちなみに前提として僕が試してるのはNode.jsとPythonの場合です。 でもVS Codeでコード書くなら何でもあてはまるんじゃないかと思います。
Remote Containers
Remote ContainersってのはVS Codeの拡張です。ちなみにまだPreviewです。このあたり気にする人はやめておいたほうがいいかも。僕は本番システムを動かす基盤でもないので全く気にしない。
もともとVS CodeにはRemote Developmentという拡張機能があってこれを使うとリモートサーバ上のコードを手元のVS Codeから透過的に編集できたりします。SSHで接続できるのでEC2インスタンス上に環境作って開発するってことも可能ではあります。が、僕のやりたいことは作って捨ててをお手軽にってのがあります。あとは仕事柄、飛行機に乗ることとかも多いのでインターネット接続を必須としないほうが嬉しいってのがありました。というわけでEC2でSSHは選択肢としてはナシです。Cloud9使ってるやんけってのは言わないで。
さて、このRemote Developmentってのは接続先としてコンテナを使うことも可能なんですね(知りませんでした)。
Docker
言わずとしれたDockerです。コンテナです。僕の場合はMacにDocker Desktopを入れて使ってます。Dockerでローカルの開発環境を分離するってのは選択肢としてありなんですが、これまではそうはいっても面倒くさいしなーというのがありました。個人的には。ここで言ってる開発環境ってのは利用するプログラミング言語のランタイムとかを導入したイメージを使って開発するってことです。
何が面倒くさいかってVS Codeでコード書いてそのまま実行みたいなのがDockerコンテナだけだと手間に感じるんですよね。例えばPythonだとMicrosoft謹製のPython拡張を入れるとVS Code上でRun出来たりするわけですがそれができない。少し頑張ればできるのかもしれないが頑張らずに済ませたい、ここ重要。
Pros / Cons
Docker + Remote Containersでやる場合のProsとCons。あくまでも僕の視点。
Pros
- コンテナなので環境移行するのが楽。Dockerfileさえあればいい
- インターネット接続不要なので飛行機の中でもできる(やるとは言ってない)
- よくあるxx env系のツールが不要(もちろんasdfとかも)。バージョン切り替えたい場合はバージョンごとのコンテナを作ってしまえばいい
- 手元の環境汚さずにガンガン試せるのがとてもストレスフリー
- 実行環境がコンテナだけどVS Codeの利便性が享受できる
Cons
- 一部の拡張機能がRemote Developmentに対応していない
- ImageのBuildが入ると時間がかかる
- プロジェクトフォルダ開いてコード書けるようになるまで少し時間がかかる(コンテナ起動するから。でもCloud9よりは全然いい)
導入方法
- Docker Desktop入れる
- VS Codeの拡張機能としてRemote Containersをインストール
- プロジェクトフォルダに
Dockerfile
もしくはdocker-compose.yaml
用意する - そのプロジェクトフォルダをVS Codeから開く
- VS Codeの左下の青いところをクリック
Reopen in Container
を選択From Dockerfile
を選択- (初回)イメージのビルドが実行される
- プロジェクトフォルダに
.devcontainer
というフォルダが作成され、その下にdevcontainer.json
というファイルが作成される - VS Codeの左下の青いところが
Dev Container: Existing Dockerfile
とかになってればひとまずOK
どんな感じで使ってるのか
基本の使い方は?
僕の場合は各言語、バージョンごとに雛形となるフォルダを用意しています。この環境に含まれるものは各言語ごとのDockerfile
とdevcontainer.json
だけ。あとはいくつかのHello World
するだけのコードが書かれたサンプルファイル。
新しく何かを始めるときはこのフォルダをまるごとコピーして、そっちで始める感じでとりあえず運用してる。
VS Codeの拡張機能は?
Remote Developmentに対応しているものであれば使えます。Dev Containerに接続している状態で拡張機能を開くと、VS Codeにインストールされている拡張機能であればDev ContainerにインストールできるようになってますのでそれをクリックしてReloadするだけです。
でも、実はdevcontainer.jsonに定義しておくと最初から拡張機能を使えます。僕のPython用のdevcontainer.jsonはこんな感じ。extensionsの中に使いたい拡張をIDで入れておくだけです。
{ "name": "cooool", "context": "..", "dockerFile": "./Dockerfile", "settings": { "terminal.integrated.shell.linux": null }, "extensions": [ "ms-python.python", "hookyqr.beautify", "alefragnani.bookmarks", "lacroixdavid1.vscode-format-context-menu", "eamodio.gitlens", "oderwat.indent-rainbow", "ionutvmi.path-autocomplete", "chrmarti.regex", "humao.rest-client", "wayou.vscode-icons-mac" ] }
拡張機能のIDは拡張の画面で右クリックしてコピーするかCLI入れているなら code --list-extensions
で一覧表示できるのでそこからどうぞ。
Dockerfileは?
これは普通に作ればいいだけ。Dockerhubに各言語の公式イメージもあるのでそれを利用するのが楽かもしれない。僕のPython用のDockerfileも晒しておく。これは公式イメージに依存関係管理ツールとしてPoetryを入れてる。
FROM python:3.8.3 RUN set -x && \ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python ENV PATH /root/.poetry/bin:$PATH RUN poetry config virtualenvs.create false
ちなみにPoetryを使う場合はPoetryがデフォルトで作成するvirtualenvの環境とVS Codeが相性悪いので、virtualenv使わないようにするのがいい。それが上記のDockerfileの最後の1行。
ローカルでサーバー起動したりできる?
フロントエンドの開発なんかではこのあたり必須になってくるわけだけどもちろんできる。以下はNode.jsの環境で先日経産省が公開したIMIコンポーネントツールを試したときのもの。
住所変換は手元で簡単に試せるので試してみた。住所が解釈されて番地とかが簡単に取り出せるように。あとその住所の緯度経度も返ってくる。
— Keisuke Nishitani (@Keisuke69) 2020年5月29日
その他👇
* 法人種別名の抽出
* 全角-半角統一
* データバリデーション
* 電話番号正規化
* 日付型正規化
* 産業分類候補生成https://t.co/xHIEfgkLhv https://t.co/NWdTTwXYA3 pic.twitter.com/4raC55vSyy
実際に試したときのVSConsoleがこんな感じ
このときはREST Clientという拡張機能を使ってnpm start
で起動したローカルサーバにリクエストしている。このときのDockerfileはFROM node:lts
とだけ書いたシンプルにイメージだけ指定して追加で何もやってないというもの。
そして.devcontainer.jsonでフォワードするポートを指定してあげるだけでいい。
{ "name": "Existing Dockerfile", "context": "..", "dockerFile": "./Dockerfile", "settings": { "terminal.integrated.shell.linux": null }, "extensions": [ ], "forwardPorts": [8080], }
最後の1行がそれ。もちろん普通のブラウザからもリクエストできる。
まとめ
そんなわけでDocker + Remote Containers最高なのでぜひ試してみて欲しい。とはいえまだガッツリ使ってないので今後不満も出てくるだろうけど。
余談
同様の理由でAWS CLIもローカルの環境に入れずにいたんだけど、これもDockerで用意することにした。ただ、AWS CLIに関しては自分でコンテナイメージ作るのもいいけどv2であれば公式イメージがあるのでそれを使うのがいい。
AWS CLI v2をコンテナで動かすには、
— Keisuke Nishitani (@Keisuke69) 2020年5月21日
1⃣Ubuntuなどに自分でinstall
2⃣Alpineで足りないglibc入れて自分でinstall
3⃣AWSの公式Image使う
のどれか。やりたいことは手元のMacを汚さずにCLI使いたいだけなので3にした。毎回docker run叩くのは手間だがまるごと"aws"にailias張ることで使い勝手も解決。
この方式だとawsコマンドは$ docker run --rm -it amazon/aws-cli command
みたいな感じで実行する必要があるけどこれを丸々aws
に以下のような感じでエイリアスはってあげると使い勝手がだいぶよくなる。
$ alias aws='docker run --rm -it -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli'