まとめ
作ったもの
docker-compose
コマンドだけで環境をうまく切り替える方法
docker-compose -f
オプションを使うことで、使用する YAML ファイルを取捨選択できるようになった。これを利用して、開発環境用ではボリューム共有を使い、サーバ環境用では別のサービスを追加する、といったことが可能になる。docker-compose -f
オプションで毎回 YAML ファイルを指定するのはとても手間がかかるが、解決することができる。Compose の設定に用いられる環境変数のデフォルト値を.env
という 環境ファイル で行うことができる。このファイルにCOMPOSE_FILE
という CLI 変数 を定義し、その値に使用する YAML ファイルを指定することで-f
オプションを省略することができる。- Dockerfile のマルチステージビルド を使うことによって、複数の環境を一つの Dockerfile で表現することができる。
Visual Studio Code で開発環境コンテナも使う方法
- Visual Studio Code の Remote – Containers – Visual Studio Marketplace 拡張機能で実現する。
- コマンドパレットから "Remote-Containers: Add Development Container Configuration File…" を選んで設定ファイルを自動生成するのが楽。
.devcontainer/devcontainer.json
が独自の設定ファイル。.devcontainer/docker-compose.yml
はただの Docker Compose ファイル。.devcontainer/devcontainer.json
と.devcontainer/docker-compose.yml
の難しい箇所は本投稿の続きに記載した。
構築にあたって勉強になった点
node – Docker Hub を使って開発環境を構築していきました。そのため以下の文章で node といった単語が登場します。
コンテナを起動させ続ける方法について
.devcontainer/docker-compose.yml
の command: /bin/sh -c "while sleep 1000; do :; done"
によって、コンテナが終了してしまうのを強制的に防いでいます。
ちなみに、この行に対するコメントは次でした。
Overrides default command so things don’t shut down after the process ends.
tty: ture
でも実現できるのにもかかわらずこれではないのは、おそらくこちらの方が、広いバージョンの Docker に対応できるからだと予想しています。
ですので、最新の Docker を使っているのならば積極的に tty: ture
に置き換えて良いのではないかと思います。
ボリューム共有時のディレクトリとファイルの所有者を揃えたい、パーミッションのエラーとしないようにしたい、について
WSL2 など Linux で開発するときは、 Docker Desktop for Mac と異なりコンテナ内の UID 及び GID をホストに合わせる必要があります。そうしないボリューム共有したディレクトリでコンテナ内で作成したファイルの所有者が root となり、パーミッションのエラーでいろいろ面倒となることが多いです。
これを解決するのに 2 通りの方法を思いつきました。
一つ目は、 .devcontainer/docker-compose.yml
では service 下で例えば user: node
と指定することです。
これによりコンテナの 1 つめのプロセスを実行する時のユーザを node とすることができるとのこと。つまり、 node ユーザでコンテナを起動することになる、といって良いと思います。
ちなみにこれは Dockerfile
に USER node
と指定するのと等価です。
.devcontainer/docker-compose.yml
の user
についてのコメントには次のようにありました。
If you want add a non-root user to your Dockerfile, you can use the "remoteUser" property in devcontainer.json to cause VS Code its sub-processes (terminals, tasks, debugging) to execute as the user. Uncomment the next line if you want the entire container to run as this user instead. Note that, on Linux, you may need to ensure the UID and GID of the container user you create matches your local user. See https://aka.ms/vscode-remote/containers/non-root for details.
2 つ目の方法は、 .devcontainer/devcontainer.json
で "remoteUser": "node"
とすることです。
これにより node ユーザでコンテナに接続することができるとのこと。 docker-compose exec --user=node ...
と等価となるはずです。
.devcontainer/docker-compose.yml
と異なるのは、コンテナ起動ユーザは root などだが、接続、ログイン、するときのユーザは node となる、という点だと思います。
.devcontainer/devcontainer.json
の "remoteUser":
のところのコメントにはこうありました。
// Uncomment to connect as a non-root user if you’ve added one. See https://aka.ms/vscode-remote/containers/non-root.
さて、以上を踏まえて、 VS Code を使う場合も、使わないで例えば Vim と docker-compose
コマンドを使って開発する場合も、ほとんど同じ状態のコンテナに揃え、かつできるだけ操作の楽な開発環境とするにはどうしたら良いでしょうか?
.devcontainer/docker-compose.yml
の user
のみを指定した場合、 docker-compose exec
コマンドを実行する時に、特に --user=node
オプションを付けなくともログインユーザは node となります。
一方で .devcontainer/devcontainer.json
の remoteUser
のみを指定した場合、 docker-compose exec
コマンドを実行する時に、 --user=node
オプションを付なければログインユーザは root となり、 VS Code でコンテナにアクセスした時と結果が異なってきます。
人間は忘れっぽい生物であることを考えると、 .devcontainer/docker-compose.yml
の service 下で user: node
を指定して docker-compose exec
時に --user
オプションを不要とした方が良いように思えます。
そして、 .devcontainer/devcontainer.json
の "remoteUser": "node"
は VS Code とそれ以外のどちらも開発の環境を揃えるためには指定しないようにするのが良いと思います。
ただし、このやり方が通用しない場合もあります。コンテナを root で起動したい場合です。例えば Supervisor を root で起動するコンテナなどです。
この場合は、 .devcontainer/devcontainer.json
の remoteUser
のみを指定する他ないと思います。
また、 .devcontainer/docker-compose.yml
の user
の指定を開発環境のみで行う場合、サーバ環境では root ユーザでコンテナを起動することになりますから、予期せぬ問題が発生する可能性もゼロではなさそうに思えます。
以上のことを考慮すると、 .devcontainer/devcontainer.json
の remoteUser
のみの指定の方が、面倒ですが無難なように感じます。
Visual Studio Code Remote – Container のイカしたところ
ホストの ~/.gitconfig
を、コンテナの例えば /home/node/.gitconfig
にコピーしてくれました。これによって、コンテナ内で編集した内容をコンテナ内で Git コミットすることが簡単になっています♪
今後の Docker ライフのために覚えておきたいこと
コンテナでのユーザを node とするために https://aka.ms/vscode-remote/containers/non-root を読みました。この中の次の箇所は、今回は関係ありませんでしたが、今後別の機会に Dockerfile で root ユーザ以外の一般ユーザを作成する時のテンプレートとして使えそうですのでメモします。
おわりに
Visual Studio Code Remote – Container はまだプレビュー段階ですが、近い未来に正式にリリースされることと思います。
私はずっと Vim と docker-compose
コマンドのみで開発をしてきました。ですけれども VS Code でも楽に開発できるのなら、喜ぶ方もきっといるはずです!
そんなわけで、 VS Code でも、他のエディタとコマンドでも共存して開発環境もサーバ環境も用意できるようなやり方を模索し、ここに記しました。
以上です。