DockerとRemote Containersでの開発環境が最高過ぎる

f:id:Keisuke69:20200604145924j:plain

はじめに

手元の開発環境を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です。このあたり気にする人はやめておいたほうがいいかも。僕は本番システムを動かす基盤でもないので全く気にしない。

marketplace.visualstudio.com

もともと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の左下の青いところをクリック f:id:Keisuke69:20200604134659p:plain
  • Reopen in Containerを選択
  • From Dockerfileを選択
  • (初回)イメージのビルドが実行される
  • プロジェクトフォルダに.devcontainerというフォルダが作成され、その下にdevcontainer.jsonというファイルが作成される
  • VS Codeの左下の青いところがDev Container: Existing DockerfileとかになってればひとまずOK

どんな感じで使ってるのか

基本の使い方は?

僕の場合は各言語、バージョンごとに雛形となるフォルダを用意しています。この環境に含まれるものは各言語ごとのDockerfiledevcontainer.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コンポーネントツールを試したときのもの。

実際に試したときのVSConsoleがこんな感じ f:id:Keisuke69:20200604145248p:plain

このときは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コマンドは$ 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'

 

 

 

 

©Keisuke Nishitani, 2020   プライバシーポリシー