Windowsで Docker を用いて Rails 6.0 + MySQL の環境構築

【Rails】Rails 6.0 x Docker x MySQLで環境構築を参考にして、Docker上でRails環境を立ち上げようと思ってみたのですが、エラーに阻まれました。

Macで解説の通りにやるとうまくいくので、Windows固有の部分が問題だと推理。

手こずりつつも何とかRails環境を立ち上げることができたので、まとめました

(この一文を書いたときはまだできてませんでしたが)。

出ていたエラーメッセージ

Status: Downloaded newer image for ruby:2.6
 ---> 3b3333750de7
Step 2/12 : RUN 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 -qq     && apt-get install -y nodejs yarn     && mkdir /app  
Warning: apt-key output should not be parsed (stdout is not a terminal)
OK
deb https://dl.yarnpkg.com/debian/ stable main
E: Release file for http://security.debian.org/debian-security/dists/buster/updates/InRelease is not valid yet (invalid for another 3d 23h 37min 47s). Updates for this repository will not be applied.
E: Release file for http://deb.debian.org/debian/dists/buster-updates/InRelease is not valid yet (invalid for another 4d 8h 31min 12s). Updates for this repository will not be applied.
ERROR: Service 'web' failed to build : The command '/bin/sh -c 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 -qq     && apt-get install -y nodejs yarn     && mkdir /app' returned a non-zero code: 100

WSLでWindowsでもLinuxコマンドを使えるようにする

WSLはWindows Subsystem for Linux の略で、なんやかんやしてLinuxコマンドを使えるようにしてくれます。

僕はあまり興味がないので深堀しませんので、興味がある人は調べてください。

今回、Dockerを用いてRails環境を作るにあたって、何も考えずにコマンドプロンプトを使っていたのですが、それが問題のようなのでこちらを使います。

以下のリンクを参考にWSLを設定してください。

https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

Dockerの設定ファイルを作成

適当なフォルダを作って

$ mkdir rails-docker
$ cd rails-docker

その中にDockerfile、docker-compose.yml、Gemfile、Gemfile.lock、entrypoint.shの5つのファイルを作成します。

rubyのバージョンは2.7、MySQLのバージョンは8.0、Railsのバージョンは6にしています。

Dockerfile

FROM ruby:2.7.1
RUN 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 -qq \
    && apt-get install -y nodejs yarn \
    && mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

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"]

docker-compose.yml

version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  app:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local

Gemfile

source 'https://rubygems.org'
gem 'rails', '~>6'

Gemfile.lock

空のファイルを作成します。

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

rails new でアプリ作成+イメージをビルド

先ほど設定したwslのLinuxターミナルを開きます。

そして5つのファイルを置いたディレクトリに移動します。

私はC:\Users\user-name\git\rails-dockerというディレクトリにしたので、以下のコマンドの様に移動します。

$ cd /mnt/c/Users/user-name/git/rails-docker

WSLからWindowsのファイルシステムへアクセスするときは/mnt/の様にアクセスできます。

Cドライブにアクセスするなら/mnt/cのような感じです。

アプリ作成

rails new します。

$ docker-compose run app rails new . --force --no-deps --database=mysql --skip-test --webpacker

エラーがでました。

The command 'docker-compose' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

翻訳すると、 「‘docker-compose’コマンドはこのWSL2ディストリビューションで見つかりませんでした。 Dockerデスクトップ設定でWSL統合をアクティブ化することをお勧めします。」となります。

ふむふむ、Docker for Desktopの設定を見るとWSL2関連の設定にチェックはついてるように見えます。

      static media           2020 10 11 160844

Dockerのドキュメント(https://docs.docker.com/docker-for-windows/wsl/)を読むと、「必要に応じてWSL2を有効にする追加のディストリビューションを選択します。」とのこと。

SettingsのResources -> Ubuntu をONにします。

上のチェックボックスもチェックがついてなければつけた方がいいと思います。

変更したら「Apply&Restart」します。

      static media           2020 10 11 161307

WSLのターミナルを再起動して、もう一度 rails new します。

$ docker-compose run app rails new . --force --no-deps --database=mysql --skip-test --webpacker

今度は通りました。

      static media           2020 10 11 161556

イメージのビルド

$ docker-compose build

データベースの作成

config/database.yml を編集していきます。

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
  password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
  host: <%= ENV.fetch("MYSQL_HOST", "db") %>

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test

production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
  

データベースの作成。

$ docker-compose run app rake db:create

コンテナ起動してサイトを表示

コンテナを立ち上げます。

$ docker-compose up

立ち上げには少し時間がかかります。

以下のような表示がターミナルに出たら準備完了なので、

http://localhost:3000/

にアクセスしてみましょう。

...
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

するとRailsの初期画面を確認できます!

Railsの初期画面

まとめ

今回、初めはDockerコマンドをコマンドプロンプトに打っていて、少し苦戦しました。

(現実はだいぶ苦戦しました。)

ですが、Docker環境は一度作れば環境が変わった時に負担が少ないですし、Rubyやデータベースのバージョンを管理するのも楽だと思います。

この記事が僕の日曜日を消費した価値があると祈りつつ、買い物に出かけます。