Webアプリをdocker化する方法とは?

はじめに

開発したwebアプリをdocker化することで他者と手軽に実行環境を共有できます。
今回はその方法を解説していきます。

使用技術

手順

  1. Dockerfile / docker-compose.ymlを作成
  2. config/database.ymlを編集
  3. コンテナを作成、起動
  4. データベースを作成、型を作成
  5. 動作確認

1. Dockerfile / docker-compose.ymlを作成

Railsアプリ直下にDockerfile、docker-compose.ymlを作成します。
DockerfileはDocker imageの設計図であり、拡張子がないテキストファイルです。
以下の様に記載します。

FROM ruby:3.2.2
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs && mkdir /myapp
WORKDIR /myapp
COPY Gemfile Gemfile.lock /myapp/
RUN bundle install
COPY . /myapp

上から順に説明します。
1. DockerfileはFROMから始めます。 そして元となるimage名を記載します。
今回はruby:3.2.2を指定しています。

2. RUNコマンドでコンテナを作成し、起動します。
そしてapt-get update -qqコマンドで最新のパッケージリストを取得します。
-qqとすることでログを表示させないようにしています。

&& apt-get install -y build-essential libpq-dev nodejs
先ほど取得したリストからbuild-essentiallibpq-devnodejsをインストールします。ダウンロード中のyes/noの回答として-yを指定してyesとします。

&& mkdir /myappにてmyappディレクトリを作成します。

3. WORKDIR /myappLinuxコマンドで表すとcd /myappであり、コンテナ内で行われます。

4. COPY Gemfile Gemfile.lock /myapp/ではGemfileとGemfile.lockをmyappディレクトリ直下にコピーします。

5. bundle installではGemfileを元にgemをインストールします。

6. 最後にCOPY . /myappにてRailsアプリのディレクトリを/myappにコピーします。

続いてdocker-compose.ymlを編集します。

version: '3'
services:
  db:
    image: postgres:12
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
    volumes:
     - db-data:/var/lib/postgresql/data
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/rails-docker
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  db-data:

こちらも上から順に解説していきます。

services

コンテナを定義します。
今回はdbwebの2つのコンテナを作成します。

image

docker imageを指定しています。
今回はpostgres:12を使用します。

environment

環境変数を設定します。
今回はPOSTGRES_USER,POSTGRES_PASSWORD共にpostgresを指定しています。後ほど環境変数を読み込む箇所を説明します。

volumes

コンテナ外にデータを保存する方法を指定します。
dbは名前付きボリュームを作成して保存する方法で行います。
はじめに最終行で名前付きボリュームを作成します。

volumes:
  db-data:

そしてボリューム名:保存したいデータの場所を指定します。
今回は使用しているpostgresの保存先を指定しています。

db-data:/var/lib/postgresql/data


webではローカルのディレクトリにマウントさせる方法で行います。
今回はカレントディレクトリをコンテナ内のrails-dockerにマウントします。

volumes:
      - .:/rails-docker

build

作成したDockerfileを元にimageを作成します。

build: .

command

デフォルトで実行されるコマンドを指定します。 bundle exec rails sにてコンテナ内でrails serverを起動します。
-p 3000 -b '0.0.0.0'にてポート番号3000を指定し、バインドオプションを指定し0.0.0.0とします。
こうすることでIPアドレスを問わずにアクセス可能になります。

depends on

コンテナの起動順を指定します。
今回はdbwebの順に起動するようにします。

depends_on:
      - db

2. config/database.ymlを編集

デフォルトのものに追記していきます。

  default: &default
    adapter: postgresql
    encoding: unicode
+  host: db
+  username: <%= ENV.fetch("POSTGRES_USER") %>
+  password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
    # For details on connection pooling, see Rails configuration guide
    # https://guides.rubyonrails.org/configuring.html#database-pooling
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

host:[サービス名]と入力します。
今回はdbですね。
そしてusernamepasswordにはdocker-composeの環境変数として設定した値を使用しています。

3. コンテナを作成、起動

docker-compose up -dにてdocker-compose.ymlに記載したものを作成、起動します。

4. データベースを作成、設定

  • データベースを作成します。
docker-compose exec run web rails db:create
  • database.ymlに基づいてデータベースを設定します。
docker-compose exec run web rails db:migrate

5. 動作確認

http://localhost:3000/にアクセスできるか確認します。

最後に

今回はwebアプリをdocker化する方法についてまとめてみました。
少し設定が大変でしたが今後はコンテナを起動してすぐに環境構築できます。
皆さんも試してみてください。

参考URL