アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

DockerでRails newしてみました

こんにちは。Webエンジニアのnakamuraです。

Dockerには日々お世話になっているのですが、そもそもDockerについても何もわかっていなかったので、自分でDockerfileを書いてみました。 また、弊社では、現在、育成枠でのエンジニア採用も検討中ということもあり、Dockerに関する入門編、投稿します。

Dockerインストール

公式サイトからダウンロードしてインストールしてください。 (開発環境はOSXを想定しています。)

https://docs.docker.com/docker-for-mac/install/

新規アプリ用のディレクトリを作成

まず、ローカル環境に作業用のディレクトリを用意します。

$ mkdir src
$ cd src

新規Railsアプリの作成(DockerでRails new)

次に、rubyのimageを使ってコンテナを起動します。

$ docker run -it --rm -v ${PWD}:/usr/src/app ruby:2.5 bash

-itはインタラクティブモードで起動してね。という意味で、コンソールからの入力が可能になります。このオプションを指定しないとコンテナはすぐに終了してしまいます。

-v ${PWD}:/usr/src/appでローカルの今いるディレクトリにコンテナ上の/usr/src/appをマウントしてという意味です。

成功すると↓のような感じでコンソールが表示されるので、/usr/src/appに移動してください。

$ root@f332b4bd3dbf:/# cd /usr/src/app

次に、Rails gemをインストールします。

$ root@f332b4bd3dbf:/usr/src/app# gem install rails

次に、Rails newコマンドでアプリを作成します。

$ root@f332b4bd3dbf:/usr/src/app# rails new myapp --skip-test --skip-bundle --database=mysql

exitでコンソールからぬけます。

$ root@f332b4bd3dbf:/usr/src/app# exit

すると、ローカル環境に戻るので、lsコマンドでmyappが作成されているか確認してください。

$ ls
myapp
$ cd myapp
aipc-157:myapp nakamura.masayuki$ ls
Gemfile     Rakefile    bin     config.ru   lib     package.json    storage     vendor
README.md   app     config      db      log     public      tmp
$

これで、ローカル環境にはRailsをインストールすることなく、Rails新規アプリを作成することができました。Docker便利。

Dockerfile作成

ローカル環境に、空のDockerfileを準備します。

$ touch Dockerfile

次に、お使いのエディターで、以下のように追記します。

FROM ruby:2.5.3

RUN apt-get update -qq && apt-get install -y build-essential mysql-client nodejs

RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY Gemfile* /usr/src/app/
RUN bundle install
COPY . /usr/src/app/

DB周辺設定

ここでデータベースの作成に必要なファイルを準備します。

$ mkdir -p .env/development
$ touch .env/development/database

databaseを以下のように編集し、Gitを使用している場合は、.gitignoreファイルに.envを追記してください。

MYSQL_ROOT_PASSWORD=適当に長いパスワード

myapp/config/database.ymlを開いて、以下のように編集します。 ポイントはhostの箇所で、このあとdocker-compose.ymlのservicesで使用します。

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
  host: db

Docker composeファイル作成

docker-compose.ymlを作成し、以下のように編集します。

versionなどは適宜、修正してください。

version: '3'
services:
  db:
    image: mysql:5.7.17
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
    env_file:
      - .env/development/database

  web:
    build: .
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    environment:
      RAILS_ENV: development
    env_file:
      - .env/development/database
    depends_on:
      - db

volumes:
  db-data:

volumesにある- db-data:/var/lib/mysqlはデータ永続化のための設定です。

-b '0.0.0.0'は、rails serverがローカルマシーン上の全てのIPv4に接続するための設定です。

ローカルからのhttp://localhost:3000リクエストは、Docker Engineに転送され、コンテナ上のrails serverにリクエストします。しかし、コンテナ上のrails serverはlocalhostのリクエストしかlisteningしていないので、異なるIPアドレスのリクエストに応答できません。よって、-b '0.0.0.0'でコンテナ上のrails serverを全てのIPアドレスにバインドします。

コンテナ起動

以下のコマンドでコンテナを起動します。

$ docker-compose up

DB作成

docker-compose up後は、別のコンソールを開いて、以下のコマンドでデータベースを新規作成します。

$ docker-compose exec web bin/rails db:create

もし、コンテナが起動してない状態で、データベースの新規作成を行う場合は、以下のコマンドを実行してください。

$ docker-compose run --rm web bin/rails db:create

ブラウザで確認

ブラウザでhttp://localhost:3000にアクセスし、Railsの起動画面が表示されていればOKです。

開発スタート

あとは、コンテナが起動している時は、以下のようにexec webに続いてrailsのコマンドを実行していけば、scaffoldやmigrationの実行が可能です。

$ docker-compose exec web bin/rails g scaffold User first_name:string last_name:string

マイグレーションの場合は、以下のような感じです。

$ docker-compose exec web bin/rails db:migrate

コンテナを終了させたい場合は、以下のコマンドになります。

$ docker-compose down

Gemを追加したときは、イメージを再構築する必要があるので、以下のコマンドを実行してください。

$ docker-compose build web

最後に

アクトインディでは、エンジニアを募集しています!

サッカー好きの方、お待ちしております!!