カテゴリー
Linux

Visual Studio Code Remote Container を利用してもしなくても (Vim とかと docker-compose コマンド) 最強のローカル環境とデプロイ用のコンテナ化環境を作る方法、 Vue.js を例に添えて。

まとめ

作ったもの

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.ymlcommand: /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 ユーザでコンテナを起動することになる、といって良いと思います。 ちなみにこれは DockerfileUSER node と指定するのと等価です。

.devcontainer/docker-compose.ymluser についてのコメントには次のようにありました。

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.ymluser のみを指定した場合、 docker-compose exec コマンドを実行する時に、特に --user=node オプションを付けなくともログインユーザは node となります。 一方で .devcontainer/devcontainer.jsonremoteUser のみを指定した場合、 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.jsonremoteUser のみを指定する他ないと思います。 また、 .devcontainer/docker-compose.ymluser の指定を開発環境のみで行う場合、サーバ環境では root ユーザでコンテナを起動することになりますから、予期せぬ問題が発生する可能性もゼロではなさそうに思えます。 以上のことを考慮すると、 .devcontainer/devcontainer.jsonremoteUser のみの指定の方が、面倒ですが無難なように感じます。

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 でも、他のエディタとコマンドでも共存して開発環境もサーバ環境も用意できるようなやり方を模索し、ここに記しました。

以上です。

コメントを残す