Dockerはアプリケーションを軽量なコンテナとしてパッケージ化し、どこでも動作させることができる便利なツールです。
この記事では、まだまだ初学者ではある私ですが既存のwebアプリを任意のlocal環境で動作させる為のdocker化を覚えましたので、他者様が作った既に完成しているwebアプリをDockerとDocker Composeを使用してDocker化してlocalで起動する手順を解説したいと思います。
今回は railsアプリ、またdbはPostgreSQLを使用します。
追加で必要なファイルは2つ、修正するファイルは1つ
既存webアプリのdocker化の大まかな流れ
1. Dockerfileの作成
2. docker-compose.ymlの作成
3. database.ymlファイルの一部修正
4. Dockerイメージのビルド
5. データベースのセットアップ
6. アプリケーションの起動
7. localhost:3000にアクセス
まず手順だけ先に書き、その下に各解説を書いていきます。
1. Dockerfileの作成
まず、railsアプリのルートディレクトリ(README.mdやGemfileがあるディレクトリ)にDockerfile
を作成、中身は下記の通り。
# 以下、[app_name]はご自身で用意したアプリのルートディレクトリ名に変えて記入してください
# インデントが大事なので十分注意してください
FROM ruby:3.2.2 #任意のバージョンを指定してください
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
node.js
WORKDIR /app_name
COPY Gemfile Gemfile.lock /app_name/
RUN gem install bundler && bundle install
COPY . /rails-docker/
2. docker-compose.ymlの作成
docker-compose.yml
ファイルをアプリのルートディレクトリ(先程作ったDockerfileと同じディレクトリ)に作成し、中身は下記の通り。
# 以下、[app_name]はご自身で用意したアプリのルートディレクトリ名に変えて記入してください
# インデントが大事なので十分注意してください
version: "3"
volumes:
postgresql-data:
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
tty: true
stdin_open: true
volumes:
- .:/app_name
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:12
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
ports:
- "5432:5432"
volumes:
- postgresql-data:/var/lib/postgresql/data
3. database.ymlファイルの一部修正
/app_name(用意したアプリ)/config/databse.ymlの中の
一部記述(default: &defaultから下部の数行)を以下のように変更します。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: postgres
port: 5432
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
4. Dockerイメージのビルド
Dockerfileが正しく設定されたら、次のコマンドでDockerイメージをビルドします。
$ docker-compose build
※初回はビルドもするので処理が終わるまで数分かかります。
また、途中でダウンロードが失敗しエラーが出ることもあります(私も一度なりました)が、
再度$ docker-compose build
を行うことでダウンロード含め、処理は成功します。
5. データベースのセットアップ
$ docker-compose run --rm web rails db:create
6. アプリケーションの起動
$ docker-compose up
次回以降は5.のデータベースのセットアップは必要なくこの$ docker-compose up
1行を実行するだけでアプリケーションを起動できます。
$ docker-compose up
後、シェルはそのままの状態(アプリケーションが起動している状態)で、http://localhost:3000
にてアプリケーションが動作しているはずですので、
http://localhost:3000
にアクセスするとwebアプリケーションとして使用開始できます。
終了方法は$ docker-compose up
を行ったシェルに戻り、cmd + c (ctrl + c)を押すと終了します。
再度起動するときはシェルで$ docker-compose up
を実行するだけ。
以上が流れです。
解説はこちら↓
Dockerfile
FROM ruby:3.2.2 #任意のrubyバージョンを選択
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
node.js
# イメージのビルド時にOSのパッケージリストを更新と下記パッケージ郡をインストール
# build-essential: コンパイラやライブラリなどの開発に必要な基本的なパッケージ群
# libpq-dev: PostgreSQLデータベースを扱うためのライブラリ
# node.js: JavaScriptのランタイム環境であるNode.js
WORKDIR /app_name
#以降のコマンドは、/app_nameディレクトリ内(アプリのルートディレクトリ内)で実行
COPY Gemfile Gemfile.lock /app_name/
# ホストのGemfileとGemfile.lockをコンテナの/app_nameディレクトリにコピー
# 複数のファイルをコピーする際はapp_nameの後ろに`/`が必要
RUN gem install bundler && bundle install
# 最新のbundlerをインストールした後、コピーしたGemfileとGemfile.lockをもとに必要なRubyのライブラリをインストール
COPY . /rails-docker/
# ホストの現在のディレクトリ全内容をコンテナの/app_name/にコピー
docker-compose.yml
version: "3"
volumes:
postgresql-data:
services:
web:
webという名前のサービスを定義(アプリ側)
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
tty: true
stdin_open: true
volumes:
- .:/app_name
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:12
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
ports:
- "5432:5432"
volumes:
- postgresql-data:/var/lib/postgresql/data
docker-composeコマンド
$ docker-compose build
# Dockerfileを元にdocker imageをビルド
データベースの設定
docker-compose run --rm web rails db:create
# 初回アプリ起動前にデータベースの作成が必要(コマンド`$ rails db:create`)、このコマンドをwebコンテナのrailsに対して指示するコマンドの書き方が上記になる
また、--rmオプションをつけることで、コマンドが終わりコンテナからexitされたらこのコンテナが自動で削除されるように設定。
アプリケーションの起動
`docker-compose.yml`内のコマンド`bundle exec rails s -p 3000 -b '0.0.0.0'`でrails serverの起動も行っているため、
`$ docker-compose up`1行で完結するようになっている
まとめ
DockerとDocker Composeを使用してWebアプリをDocker化する方法を解説しました。この手順を参考にあなたもrailsアプリをDocker環境での動作確認をしてみてください。