0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DockerでRailsの開発環境を構築

Last updated at Posted at 2023-06-25

はじめに

Dockerに関する学習のアウトプットとして、RailsプロジェクトをDocker化しましたため、その方法を記事として残しておきます。また、詳細は後述しますが、初めてマルチステージビルドでインストールにも挑戦してみましたため、今後マルチステージビルドで環境構築される方の参考になればと思います。

前提条件

開発環境は以下の通りです。

  • Mac(Intel)
  • Ruby 3.0.2
  • postgres 12.0
  • node 14.8.0
  • yarn 1.22.4

作成したファイル

Dockerで開発環境を構築するために作成したDockerfiledocker-compose.ymlについて説明していきます。ちなみにローカル環境のディレクトリ構成は以下の通りとなっております。

/rails-docker
    ├── Dockerfile
    ├── Gemfile
    ├── Gemfile.lock
    ├── README.md
    ├── Rakefile
    ├── app
    ├── babel.config.js
    ├── bin
    ├── config
    |     └- database.yml
    ├── config.ru
    ├── db
    ├── docker-compose.yml
    ├── lib
    ├── log
    ├── node_modules
    ├── package.json
    ├── postcss.config.js
    ├── public
    ├── storage
    ├── test
    ├── tmp
    ├── vendor
    └── yarn.lock

まずはDockerfileについてです。

Dockerfile
FROM node:14.8.0-stretch as node

FROM ruby:3.0.2

ENV YARN_VERSION 1.22.4
COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn/bin/yarn /usr/local/bin/yarnpkg \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    postgresql-client

WORKDIR /rails-docker
COPY Gemfile Gemfile.lock /rails-docker/
RUN bundle install

マルチステージビルドについて

最初に説明しましたが、nodejs、yarnはapt-getを使用せずにマルチステージビルドでインストールしております。DockerファイルにFROMを2つ書くことによって実現しております。

そもそもマルチステージビルドとは??という方のために、まずそのことについて記載します。

マルチステージビルドでインストールすることの最大のメリットは イメージが軽量になることです。

イメージが軽量になることによって、ビルド時間の短縮やホストへのディスク容量の逼迫を防ぐことなど にも繋がります。

なぜイメージの軽量化が実現しているのかと言いますと、nodejsやyarnをapt-getでインストールする方法ですと、Railsプロジェクトを実行するのに不要なファイルも含まれてしまいます。そのため、FROMを2つ書くことで、nodejsのイメージ(node:14.8.0-stretch)の中からRailsプログラムを実行するのに必要なプログラムだけを抽出して、rubyのイメージ(ruby:3.0.2)にコピーすることによって、イメージの軽量化を実現しております。

例えば、Go言語のようにビルドした結果のバイナリファイルだけあればプログラムとして、実行できます。コンパイル前のファイルはプログラムを実行するのには不要なため、コンパイル前のプログラムはイメージに含めずに作成することによって、イメージの軽量化を実現しています。

以下の記事を参考にしました。

Dockerfileのコード説明

以下コードはマルチステージビルドの説明で概要はお伝えしておりますので、細かいコードについて説明を記載します。

Dockerfile
FROM node:14.8.0-stretch as node

FROM ruby:3.0.2

ENV YARN_VERSION 1.22.4
COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn/bin/yarn /usr/local/bin/yarnpkg \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx

  • FROM node:14.8.0-stretch as nodeas 〜nodeというエイリアス(別名)を定義しております。

  • ENV YARN_VERSION 1.22.4YARN_VERSIONという環境変数にyarnのバージョン1.22.4を設定しております。

  • COPY --from=nodeFROM node:14.8.0-stretch as nodeで指定したエイリアスnodeのイメージからFROM ruby:3.0.2で指定したRubyのイメージにnodeとyarnをコピーしております。

  • ln -s リンク元 リンク先はLinuxコマンドでシンボリックリンクを作成しております。これによって、Rubyイメージでyarnやnodeなどを使用できるようになります。

Dockerfile
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    postgresql-client
  • apt-get updateでパッケージリストを最新の状態に更新します。

  • apt-get install -yで指定したパッケージをインストールします。-yオプションでパッケージのインストール中にYes、Noが聞かれた際にYesで回答するように指定しております。

  • build-essentialは開発に必須のビルドツールを提供しているパッケージ。gcc(GNU C Compiler)、g++(GNU C++ Compiler)、 makeなどが入っております。(RubyはC言語で作られた言語のため、インストールが必要と思われます。)

  • libpq-devはRuby(C言語で作られたプログラム)からPostgreSQLに通信するために必要なライブラリ

  • postgresql-clientはpsqlを使用して、PostgreSQLデータベースに接続して対話的にクエリを実行できます。SQLのコマンドを直接入力できます。

  • &&はLinuxコマンドを続けて実行することができます。

  • \は改行で、見た目を整えることができます。

以下の記事を参考にしました。

docker-compose.ymlのコード説明

docker-composeを使用することで、長くなってしまうDockerコマンドを短いコマンドで実行できるようにしております。こちらもコードの細かい説明を記載しております。

docker-compose.yml
version: '3'

volumes:
  db-data:

services:
  web:
    build: .
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails-docker
    environment:
      - 'DATABAS_PASSWORD=postgres'
    ports:
      - "3000:3000"
    depends_on:
      - db
    links:
      - db
    tty: true
    stdin_open: true

  db:
    image: postgres:12.0
    volumes:
      - 'db-data:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'

Dockerfileをビルドします。.と指定しているため、ビルドするためにはdocker-compose.ymlDockerfileが同じ階層にある必要があります。

build: .

bundle exec rails s -p 3000 -b '0.0.0.0'でrailsサーバを起動しております。また、/bin/sh -c "rm -f tmp/pids/server.pid"と記載しているのはrailsサーバを立ち上げる際に前回立ち上げた際に作成されたtmp/pids/server.pidが残っていることによって、railsサーバがうまく立ち上がらない事象が発生しましたため、毎回削除するようにしております。

command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

ホストのdocker-composeコマンドを実行するディレクトリとコンテナのディレクトリ/rails-dockerをマウントしております。マウントすることによって、コンテナからホストのRailsプログラムを参照できるため、コンテナ上にRailsプログラムを持たなくてよくなり、コンテナの軽量化にも繋がります。Dockerコマンドの-v ホスト:コンテナと同一です。

volumes:
  - .:/rails-docker

以下はconfig/database.ymlで定義しているpassword: <%= ENV.fetch("DATABAS_PASSWORD") %>で使用するために記述しております。Railsからposgresに接続するためのパスワードを設定するために記述しております。

environment:
  - 'DATABAS_PASSWORD=postgres'

以下でポートの開放を行います。
左にホストのポートを、右にコンテナのポートを指定します。
Dockerコマンドの場合、 -p 3000:3000 オプションと同一です。

ports:
  - "3000:3000"

サービス間の依存関係を示します。webの前にdbを開始して、その後にwebが開始するようにしております。

depends_on:
  - db

コンテナを他のサービスとリンクlinkします。サービスwebからdbを参照できるようになります。
以下は記述しなくてもwebからdbを参照できます。networkで名前解決してくれるためです。

links:
  - db

コンテナに接続(実行中のコンテナにdocker-compose exec web bashコマンドを叩いて接続)した際にstdin_open: trueで標準入力を可能にしております。また、tty: trueで出力結果をきれいに表示できるようにしております。Dockerコマンドの-itと同一です。

tty: true
stdin_open: true

以下はDBデータをコンテナ上に保存するのではなく、ホスト側に保存するようにマウントしております。コンテナ上に保存してしまうとコンテナが消えてしまうと、DBデータが消えてしまうためです。コンテナを止めてもデータが残るようにホスト側に保存するようにしております。

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

上記で指定したdb-dataは以下でDocker volumeを作成しております。

volumes:
  db-data:

以下の記事を参考にしました。

webアプリケーションの起動・停止方法

Dockerとdocker-composeで作成したアプリケーションを起動・停止するためのコマンドを記載します。

  1. アプリケーションを起動
docker-compose up

2. データベースを作成。docker-compose upを実行したターミナルとは別のターミナルを新たに開き、以下コマンドを実行
docker-compose run web rake db:create

3. データベースにテーブルを作成
docker-compose run web rake db:migrate

4. ブラウザを開き、以下URLを入力
http://localhost:3000/

以下画面が表示される。

image
5. アプリケーションを停止。`docker-compose up`を実行したターミナルで以下を実行
Ctrl-C

6. アプリケーションを再起動
docker-compose up
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?