0
0

More than 1 year has passed since last update.

RailsアプリにDockerを導入した①【webコンテナとdbコンテナ】

Last updated at Posted at 2022-12-08

やったこと

  1. Dockerfileで、rubyイメージをベースにwebコンテナ(railsサーバー)のイメージを作成し、コンテナを起動してみた。
  2. その後、docker-compose.ymlを作成し、webコンテナとdbコンテナの2つのコンテナをまとめて起動できるようにした。

用語について

  • Docker Engine: 各アプリケーションコンテナを載せている基盤部分のソフトウェア。Linuxカーネルを利用。Docker CLIを提供。

  • Docker CLI: docker container runなど、dockerで始まるコマンドを提供。

  • Docker Desktop: WindowsやMacでDockerを使うためのGUIアプリケーション。Docker EngineやLinuxカーネルが含まれているため(Docker Composeも)、Linux以外のOSでもDocker Engineを動かせる!

  • Docker Compose: Docker CLIのコマンドをまとめて実行してくれる便利ツール。docker composeで始まるコマンドを提供。ymlファイルに実行させたいコマンドの手順書を記述する。

  • Docker Hub: Dockerのイメージレジストリを提供するサービス。ここで公開されているイメージをpullしたり、構築したイメージをここにpushしたりできる。

  • コンテナ: ホストマシン上の隔離されたプロセス(LinuxのNamespaceという機能により他と分離されている)。イメージをもとに作られる。複数のコンテナは互いに独立し、影響を与えない。起動するたびに新しいコンテナが作られる。

  • イメージ: コンテナの実行に必要なパッケージ。ファイルやメタ情報を集めたもの。複数のレイヤーからなる。Docker Hubで公開されている。

  • レイヤー: ベース(例: Ubuntu), インストールされているもの(例: PHP), 環境変数, 設定ファイル, デフォルト命令などの情報。

    • デフォルト命令:コンテナ起動時に実行するコマンド。任意の命令を実行することも可能(コンテナ起動時に指定)。コンテナはメインプロセス(PID=1。デフォルト命令or起動時に指定された命令)が終了すると自動停止する。
  • Dockerfile: 既存のイメージにさらにレイヤーを積み重ねるためのテキストファイル。既存のイメージをもとに、自分のアプリに合ったイメージになるようカスタマイズする。

    • FROM: ベースイメージを指定
    • RUN: 任意のコマンドを実行
    • COPY: ホストマシンのファイルをイメージに追加
    • CMD: デフォルト命令を指定
    • ENV: コンテナにインストールされているソフトウェアの環境変数を設定(=コンテナ内に環境変数を埋め込む)
    • ARG: Dockerfile内で使える変数を設定
    • ENTRYPOINT: コンテナの実行時にデフォルトで実行するコマンドや引数を設定。CMDにデフォルトの引数や推奨のパラメータを設定し、コンテナ起動時にオプション付与で引数・パラメータを任意に変更できる。
    • EXPOSE: コンテナの実行時、指定した ネットワーク・ポートをコンテナがリッスンするように、Docker へ通知。docker run-pフラグを使い、ポートを指定することで実際にそのポートは公開される。
  • ボリュームのマウント: コンテナ内のファイルの変更を、ホストマシンに共有する。ボリュームマウントとバインドマウントの2つの方法がある。

    • ボリュームマウント: Docker Engine上に領域(=ボリューム)を確保し、コンテナ上にデータを保管する。データの保管場所は、コンテナごとに異なっている。Docker Hubの「Where to Store Data」の項目に記載がある。ホストマシンでの変更を反映させる必要がないものに向いている。(DBコンテナのデータなど)
    • バインドマウント: ホストマシンの任意のディレクトリをコンテナにマウントする。ソースコードの共有などに活用。ホストマシンでコード変更時に更新や同期の手間なく反映させることができる。絶対パスを指定することで、バインドマウントだと判断される。

コマンド

  • container run [option] <image> [command]: イメージからコンテナ起動 (image pull+container create+container start)
    • --rmオプション:コンテナ停止時に自動削除
    • --interactive --tty: コンテナを対話操作(コンテナの標準入力に接続&疑似ターミナルを割り当て)
  • image build [option] <path>: Dockerfileからイメージ作成
    • --tagオプション: イメージに名前をつけられる。イメージを参照・指定する際に便利。
    • <path>: COPYするファイルのパス
  • container exec [option] <container> command: 起動中のコンテナに接続し、linuxコマンドを実行
    • -itオプション: コンテナを対話操作

手順

  1. railsコンテナのイメージを作成
  2. イメージのビルド docker image build --tag rails:server .
  3. イメージがビルドできているか確認 docker image ls
  4. railsコンテナとdbのコンテナを起動するようなdocker-compose.ymlの作成
  5. railsコンテナが正常に起動することを確認 docker compose up→ブラウザで開けるか確認

実際に作成したDockerの設定ファイル

Dockerfile

FROM ruby:3.1.2
ARG ROOT="/karoyaka"
ENV TZ=Asia/Tokyo

WORKDIR ${ROOT}

# 必須ではないパッケージも一緒にインストールされないようにオプション付与
# MariaDB: mysqlから派生。高性能。
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
                  mariadb-client tzdata libvips

COPY Gemfile ${ROOT}
COPY Gemfile.lock ${ROOT}
RUN gem install bundler
RUN bundle install --jobs 4

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

version: "3.9"
services:
  web:
    build: .
    command: bash -c "rm -f karoyaka/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/karoyaka:cached
      - bundle:/usr/local/bundle
    ports:
      - '3001:3000'
    depends_on:
      - db
    stdin_open: true
    tty: true
    environment:
      MYSQL_PASSWORD: password

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3307:3306'
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  bundle:
  mysql_data:

それぞれのファイルで何をしているか

Dockerfile

  1. ベースイメージにruby:3.1.2を指定
  2. タイムゾーンの設定
  3. 作業ディレクトリを命名して指定
  4. コンテナ内に必要なライブラリをインストール
    1. mariadb-client: MariaDBとは、MySQLから派生した高性能なRDBMS
    2. tzdata: タイムゾーンに関するデータ集
    3. libvips: 画像処理ソフトパッケージ(解析や変形)
  5. GemfileとGemfile.lockを作業ディレクトリ内にコピー
  6. bundlerをインストールし、gemたちもインストール(並列処理で高速化)
  7. コンテナの実行時、指定したポート(3000)をコンテナがリッスンするように、Dockerへ通知(ポートの解放)
  8. バインドするIPアドレスを指定してrailsサーバー起動
    • バインディングアドレス:外部からのリクエストを受け付けるために結び付けられているIPアドレス。
    • 0.0.0.0=ワイルドカード。
    • →全てのIPアドレスからのリクエストを受け付けられるようになり、ブラウザなどコンテナ外からもコンテナ内にアクセスが可能に。

docker-compose.yml

  1. webコンテナの定義
    1. ./Dockerfileに書かれたイメージからビルド
    2. pidファイルが存在していた場合、エラーになり新たにコンテナ起動ができないので削除する(bash -c: -cで渡される文字列をコマンドとして認識して実行する)。そして、すべてのIPアドレスをバインディングアドレスとして設定してrailsサーバー起動。(commandは、Dockerfileに書いたデフォルト命令CMDを上書きする)
    3. ホストマシンのカレントディレクトリのソースコードをバインドマウント(cached:ホスト→コンテナへの反映を効率的に行うモード) & bundleというボリュームに、インストールしたgemを保管。(rubyのコンテナでは、インストールされたgemはusr/local/bundleに入るように設定されている)
    4. ホストのポート番号は3001, コンテナのポート番号は3000に設定(ポートの定義によって、ホストマシンからコンテナへのアクセスが可能に)
    5. dbコンテナの起動後に起動するよう設定
    6. 標準入出力とエラー出力をコンテナに結びつけるよう設定。=docker container run -i
    7. 擬似端末(キーボードによる入力)をコンテナに結びつけるよう設定。=docker container run -t
  2. dbコンテナの定義
    1. イメージを指定
    2. mysqlにログインするルートユーザのパスワードを定義
    3. ホストマシンのポート番号は3007, コンテナのポート番号は3006に設定
    4. mysql_dataというボリュームに、DBのデータを保管(永続化)
  3. ボリュームの作成(bundleとmysql_data)

これから

Dockerで、webコンテナとdbコンテナを起動させることができるようになった :tada:
次はシステムテスト用のchromeコンテナ、そしてジョブ永続化のためにredisコンテナ、sidekiqコンテナも起動できるように設定していく!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0