前回は Docker の基本概念について学習した。
今回は実際に Docker Desktop をインストールし、Rails が動作するコンテナを作成してブラウザからアクセスするところまで試した。
なおこの記事はChatGPTとの会話をChatGPTにブログ形式で出力させたものとなっております。
Docker Desktopをインストールした
Windows環境へ Docker Desktop をインストールした。
インストール時には、
の選択肢が表示されたが、今回は WSL2 を利用する設定を選択した。
現在の Docker Desktop では WSL2 を利用する構成が一般的となっている。
また、Docker Desktop の動作には内部的に Linux 環境が利用されている。
Welcome to Docker コンテナとは何か
Docker Desktop を起動すると、
welcome-to-docker
というコンテナが表示されていた。
これは Docker Desktop の動作確認やチュートリアル用のサンプルコンテナであり、ユーザーが作成したコンテナではない。
Docker Desktop の導入が正常に完了していることを確認するためのものらしい。
RailsイメージではなくRubyイメージを利用する理由
Docker Hub を確認すると Ruby の公式イメージは存在するが、Rails の公式イメージは見当たらなかった。
当初は不思議に思ったが、Rails は独立したアプリケーションではなく Ruby のライブラリである。
そのため一般的には、
FROM ruby:3.3
RUN gem install rails
のように Ruby イメージをベースとして Rails を追加インストールする。
Dockerfileを作成した
学習用として次の Dockerfile を作成した。
FROM ruby:3.3
WORKDIR /app
RUN gem install rails
CMD ["bash"]
この Dockerfile を build すると、
がインストールされた独自イメージが作成される。
buildとrunの違いを体験した
Dockerを触り始めて最初に混乱したのが build と run の違いだった。
docker build -t my-rails .
を実行するとかなり時間がかかった。
これは Ruby イメージの取得や Rails のインストールが実行されているためである。
一方、
docker run
は作成済みのイメージからコンテナを生成するだけなので非常に高速だった。
実際に触ってみると、
- build = 環境を作る
- run = 環境を起動する
という違いが理解しやすかった。
CMD["bash"]の意味を理解した
Dockerfile の最後には
CMD ["bash"]
を記述した。
当初は Docker Desktop の Start ボタンを押せば bash が開くと思っていた。
しかし実際には何も表示されず、コンテナも停止してしまった。
調べてみると、
docker run -it my-rails
のように TTY を接続して起動しなければ、bash はすぐに終了してしまうことが分かった。
Docker Desktop の Start ボタンはコンテナを起動するだけであり、ターミナルへ接続する機能ではない。
コンテナが停止した理由
作成したコンテナの状態を確認すると、
Exited (0)
となっていた。
Dockerではメインプロセスが終了するとコンテナも終了する。
今回の場合、
bash
がメインプロセスだったため、
bash が終了するとコンテナも終了していた。
これは MySQL や nginx のような常駐プロセスとの大きな違いである。
Volumeを利用してローカルフォルダを共有した
Rails プロジェクトをコンテナ内だけに作成すると、コンテナを削除した際にソースコードも失われる。
そこで Volume を利用して、
Windowsフォルダ
⇔
コンテナの /app
を共有した。
これにより、コンテナ内で作成したファイルをホストOS側からも編集できるようになった。
rails newでプロジェクトを作成した
コンテナ内で
rails new .
を実行した。
すると Rails プロジェクト一式が生成された。
実行中には Dockerfile を上書きするか確認された。
これは Rails が独自の Dockerfile を生成しようとしたため。 Rails が生成する Dockerfile は「Railsアプリを配布・実行するための Dockerfile」 であり、今回は学習用に作成した Dockerfile を残すため上書きしなかった。
コンテナ削除後もファイルが残った理由
rails new 実行後にコンテナを削除した。
当初は Rails プロジェクトも消えたと思っていたが、実際にはファイルが残っていた。
理由は Volume を利用していたためである。
生成された Rails プロジェクトはホストOS側に保存されていた。
そのためコンテナを削除しても、
などはそのまま残っていた。
ポート公開とは何か
Rails サーバーへブラウザからアクセスするため、
-p 3000:3000
を指定してコンテナを作成した。
これは、
ホストOSの3000番
↓
コンテナの3000番
を接続する設定である。
この設定を追加したことでブラウザから Rails サーバーへ接続できるようになった。
0.0.0.0と127.0.0.1の違いを理解した
Rails を起動する際、
rails s -b 0.0.0.0
を使用した。
最初は、
3000番ポート
と
0.0.0.0
の違いが理解できなかった。
調べてみると、
IPアドレス
:
ポート番号
という構成になっていた。
例えば、
127.0.0.1:3000
は localhost の 3000 番ポートを意味する。
一方、
0.0.0.0
は特殊なアドレスであり、
すべてのネットワークインターフェースで待ち受ける
という意味になる。
Docker のポートフォワーディングを利用する場合は 0.0.0.0 で待ち受ける必要がある。
Railsのトップページへアクセスできた
最終的に、
rails s -b 0.0.0.0
を実行し、
http://localhost:3000
へアクセスした。
すると Rails のトップページが表示された。
Docker コンテナの中で動作しているアプリケーションへ、ホストOSのブラウザからアクセスできることを確認できた。
Dockerのデータはどこまで削除されるのか
学習中に、
の違いについても理解できた。
コンテナを削除しても、
は残る。
また Docker には、
docker system prune
という不要データを削除するためのコマンドも存在する。
Docker を使い続けると不要なイメージやビルドキャッシュが蓄積するため、定期的な整理が必要になる。
今回理解できたこと
今回の実践を通して次の点を理解できた。
- Docker Desktop は WSL2 上で Linux コンテナを動かしている
- Ruby イメージをベースに Rails 環境を作成できる
- build と run は役割が異なる
- bash は TTY がなければ終了する
- コンテナの終了はメインプロセスの終了を意味する
- Volume によってソースコードを永続化できる
- ポート公開によってブラウザからアクセスできる
- 0.0.0.0 は全インターフェースでの待ち受けを意味する
- コンテナを削除してもイメージやVolumeは残る
Docker の概念だけでなく、実際にコンテナを作成して Rails を動かしたことで理解が大きく進んだと感じた。