はじめに
Hello,Qiita!
今回は既存のRailsアプリをDockerに乗せてみようと思います!
コンテナの中に環境を移すというシンプルなものですが、
webpackやyarnのインストールで少し引っ掛かったので、記事にしてみました!
docker-composeでRailsとMySQLの2つのコンテナをオーケストレーションしてみましょう
それではいきましょう!!
前提条件
- OS: MacOS
- Ruby: 2.7.1
- Rails: 6.0.3
- データベース: MySQL
- Docker: 19.03.13
既存アプリの準備
既存アプリのあるディレクトリに移動します。
以下のような構造になっていると思います↓
.
├─ app
├─ bin
~
├─ README.md
└─ yarn.lock
このディレクトリ直下で作業をしていきます
Dockerfileの記述
以下のように記述します。
FROM ruby:2.7.1
ENV BUNDLER_VERSION="2.1.4" \
APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn \
TZ=Asia/Tokyo
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
mariadb-client \
sudo \
vim && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn
WORKDIR /app
COPY Gemfile Gemfile.lock /app/
COPY . /app
RUN bundle install -j4 && \
yarn upgrade && \
rails webpacker:install && \
yarn install --check-files
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
何をやっているのか
FROM
Docker Hub にある(今回はRubyのバージョン2.7.1の)公式イメージを取ってくる。
ENV
環境変数の定義をする。
APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
↑これを書くとWarningメッセージを非表示にできる
RUN
Dockerコンテナ上でコマンドを実行する。
apt-get
このコマンドは、Debian系ディストリビューション(DebianやUbuntu)のパッケージ管理システムであるAPT(Advanced Package Tool)ライブラリを利用してパッケージを操作・管理する、という意味。今回はRubyのイメージを取ってきたが、Debianイメージの上にrubyがインストールされてある。DebianはLinuxカーネルを利用しているためLinuxコマンドが使える。
WORKDIR
ワークディレクトリの設定をする。
同じDockerfile内に複数回指定可能で、ENVで登録したパスを利用してもよい。
COPY
新しいファイルをフォルダコピーする(圧縮されているファイルは展開されない)。
ENTRYPOINT
記述されたコマンドの実行をする。
EXPOSE
特定のポートを解放する。
CMD
実行するコンテナのデフォルト値を設定する。
同じDockerfile内で使用できるのは__一回のみ__で、ENTRYPOINTに対して引数を設定することも可能である。
Dockerfileには、少なくとも一回はENTRYPOINTかCMDを記載すべき。
docker-compose.ymlの記述
以下のように記述します。
version: '3'
services:
app:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
- ./vendor/bundle:/myapp/vendor/bundle:delegated
ports:
- "19802:3000" # "任意のポート:3000" とする
depends_on:
- db
tty: true
stdin_open: true
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "password"
ports:
- "19801:3306" # こちらも、"任意のポート:3306"とする
volumes:
- ./tmp/db:/var/lib/mysql
何をやっているのか
version
使用するdocker-composeのバージョンを定義する。
services
アプリケーションを動かすための各要素(service)を定義する。(今回はapp
とdb
)
build
composeファイルを実行し、ビルドされるときのパスを指定する。
command
デフォルトコマンドをオーバーライドする。
volumes
マウントする設定ファイルのパスを指定する。
ports
Dockerイメージを立ち上げる際のポート番号を指定する。
depends_on
service同士の依存関係を指定する。
environment
環境変数を指定する。
tty: true
コンテナが起動し続けるよう設定する。
stdin_open: true
コンテナ内の標準入出力の許可を設定する。
entrypoint.shの記述
以下のように記述します。
#!/bin/bash
set -e
# Railsのserver.pidファイルを取り除く
rm -f /app/tmp/pids/server.pid
# コンテナのメインプロセスを実行する (DockerfileでCMDと設定されているもの)。
exec "$@"
database.ymlの記述
以下のように記述します。
default: &default
adapter: mysql2
pool: 5
timeout: 5000 # 任意
development:
<<: *default
database: myapp_development
username: root
password: password
host: db
port: 3306
GemfileとGemfile.lockの確認
今回は既存アプリをDockerにのせるので、GemfileとGemfile.lockが存在していることを確認するだけで良いです。
docker-composeの起動
ターミナルで
docker-compose build
を実行します。
Successfully built ~
Successfully tagged ~
と出力されればビルド成功です。
次に、
docker-compose exec app bash
を実行し、appコンテナ内に入ります。その後、
bundle exec rails db:create
bundle exec rails db:migrate
bundle exec rails db:seed
を実行し、無事完了です!
終わりに
最後までご覧いただきありがとうございました。
個人的には、コンテナの中に入って作業をするのがめちゃ楽しいです。
なぜかはわかりません。(インセプション的な気持ちになる)
また、不適切な表現などありましたらお知らせいただけると幸いです。
それではまた!