Windows10+WSL2+Ubuntu+Docker+Rails+Postgresqlの環境構築まとめ

最初,VirtualBox に Docker 入れてみたのですが,VS Code の Remote Development がイマイチうまく動かない。実はwindowsにはWSLなるものがあって,VirtualBox 使わないでも windows 上で Linux を実行できるようになっているのでそちらで環境構築してみました。WSL の方がシンプルで悩みが減ると思います。

ここでは備忘録として,rails を立ち上げてブラウザから localhost:3000 でアクセスできるところまでの手順を書き残しておきます。そこからさらにwebアプリを作る上で基本となる gem の導入についても紹介しています。

WSL の設定

  • [コントロールパネル] を開いて [プログラム] → [Windowsの機能の有効化または無効化] をクリック。
  • [Linux 用 Windows サブシステム] と [仮想マシン プラットフォーム] にチェックを入れる。

Ubuntu の立ち上げ

次に,Microsoft store から Ubuntu を検索。今回は Ubuntu 18.04 LTS を使う。検索で出てきたら,インストールをクリック。

WSL のバージョンを 2 にする。

wsl --set-default-version 2

[スタート] から Ubuntu 18.04 LTS を立ち上げる。

Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username:
  • ユーザー名を入力
  • パスワードを2回入力

これでユーザーの設定が終わったので,Ubuntu の画面を閉じる。

規定のサブシステムの設定

Powershell から wsl -l -v を入力すると,規定のサブシステムが確認できる。

  NAME            STATE           VERSION
* Ubuntu          Stopped         2      
  Ubuntu-18.04    Stopped         2      

さきほどインストールした Ubuntu-18.04 を使いたいので,wsl --set-default Ubuntu-18.04 と入力して,規定の OS を変更する。

wsl --list を入力すると

PS C:\Users\username> wsl --list
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-18.04 (既定)
Ubuntu

規定のサブシステムが変更されたことが確認できる。

VS Code から操作する

  • VS Code を起動し,[拡張機能] をクリック。
  • Remote Development」を検索して,インストール。
  • 画面左の [リモートエクスプローラ] をクリック。
  • Ubuntu-18.04 の上で右クリックして Connect to WSL をクリック。
  • 新しいウィンドウが開く。
  • ctrl+@ でターミナルを開くと,Ubuntu のコンソールである bash が表示される。

これで,WSL上にインストールされた Ubuntu を VS Code から操作できるようになる。

Dockerの導入

細かい説明は省いて,Docker を導入するためのコマンドを述べていく。以下のコマンドを順次入力する。

sudo は管理者権限でコマンドを実行するためのもの。sudo を最初に実行するときにパスワードの入力を求められるので,Ubuntu を立ち上げたときに設定したパスワードを入力する。

$ sudo apt update

$ sudo apt upgrade -y

$ sudo apt install curl -y

$ sudo apt install apt-transport-https -y

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ sudo apt update

$ sudo apt install docker-ce docker-ce-cli containerd.io -y

$ sudo apt install docker-compose -y

$ sudo service docker start

最後の sudo service docker start を実行して,Starting Docker: docker [ OK ] が表示されることを確認する。

次に,ユーザーを Docker グループに追加。

$ sudo gpasswd -a ユーザー名 docker

ここで,VS Code を再起動。再び WSL に接続する。

Docker を起動。

sudo service docker start

パスワードを求められるので入力。* Starting Docker: docker が表示されれば成功。

ここで,動作確認のために $ docker run hello-world を入力。

・・・・・・

Hello from Docker!
This message shows that your installation appears to 

・・・・・・

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

上の表示が出れば,docker のインストールがうまくいっている。

コンテナを動かす前処理

ここで,いったん VS Code を閉じて再起動。

再起動すると,上のような画面になる。ここにアプリを作成。

青枠で囲まれている部分を右クリックして,「新しいフォルダー」をクリック。ここでは,フォルダー名を「myapp」とする。cd myapp でフォルダーに移動。

この状態で myapp の中にファイルを作る。

右クリックして [新しいファイル] をクリック。

docker-compose.yml Dockerfile entrypont.sh Gemfile Gemfile.lock の 5 つのファイルを作成。それぞれのファイルを開いて以下の文を入力。

myapp は自分が作ったフォルダ名に合わせて変更。パスワードの admin も自分で決めて変更しておくと良い。

Dockerfile

FROM ruby:3.0.2

# setting yarn repository
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
# install packages
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client yarn
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

Gemfile

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

entrypoint.sh

#!/bin/bash
set -e

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

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

docker-compose.yml

version: "3"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: admin
  web:
    build: .
    command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

Gemfile.lock を作成し,中身は空のままにする。

 

Remote Containers でコンテナを構築

VS Code の拡張機能である Remote Containers でフォルダを開くとコンテナの中に入れる。このとき,.devcontainer というフォルダがあるとうまくいかないことがあるので,Remote Containers の起動に失敗するときはフォルダを削除する。

  • ターミナルで cd myapp を入力して移動。
  • 画面左下にある緑色の部分 [WSL: Ubuntu-18.04] をクリック。
  • Open folder in Container を選択。
  • myapp を選択して,[OK] をクリック。
  • From ‘docker-compose.yml’ を選択。
  • web を選択。

画面左下の緑色の部分が [Dev Containers] に変われば成功。コンテナの中に入れるようになる。必要なファイルさえ用意しておけば,あとは Remote Containers がやってくれるので非常に便利。

次のコマンドを実行。

$ rails new . --webpack --force --database=postgresql

myapp の中に rails のファイルが作成される。

config/database.yml (赤文字部分を追加)

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

WSL の画面を開いて

$ sudo docker-compose build

$ docker-compose up -d

$ docker-compose exec web bash

# rails db:create

# exit

ブラウザで localhost:3000 を入力して以下の画面が出力されたら完了。

Dev Containers のままだと,localhost:3000 でアクセスできないので,WSL で接続し直しターミナルで docker-compose up -d を実行すると良い。

  • docker-compose build で permission denied が出たら,sudo docker-compose build で試してみる。

権限の変更

rails g model などで生成したファイルを WSL から書き換えようとするとパーミッションエラーが出る。ファイルの権限を変更すると問題が解決する。この操作は頻繁に行うことになる。

コンテナから出る
# exit
コンテナを止める
$ docker-compose stop
コンテナを再ビルド
$ sudo docker-compose build
権限の変更
$ sudo chown -R $USER:$USER .
コンテナをバックグラウンドで起動
$ docker-compose up -d
コンテナに入る
$ docker-compose exec web bash

このとき,localhost:3000 を実行しても画面が表示されないかもしれない。その場合は

$ docker-compose up

として,コンテナをバックグラウンドではなく通常で起動してみる。そして

・・・・・

web_1  | *          PID: 1
web_1  | * Listening on http://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

という出力が出るかどうかを確認する。問題があればエラーが出る。

これで基本的な環境構築は終了。

Rspec

ここから実際にアプリを構築していく上で導入した方が良いものについて導入手順を残しておく。ここからの作業は[Dev Containers]に移動して行うとよい。

Rspec はテストを行うためのもの。あとから入れると面倒なので最初に入れるべき。また,factory_bot はテーブルにダミーデータを入れるときに必要になる。サイトによっては database_cleaner も導入するように書かれているものがあるが,現在は不要。

テストに必要な gem にもう一つ capybara がある。これは統合テストを行うために必要だが,はじめから入っている。

Gemfile (赤文字部分を追加)

group :development, :test do
  gem 'rspec-rails', '~> 4.0.1'
  gem 'factory_bot_rails', '~> 6.1.0'
end

そしてコンソールから

# bundle install

# rails g rspec:install   #これを忘れると動かないので注意

これで導入完了。spec というフォルダが作成されているのを確認。また,フォルダ test は Rails に標準で入っているテスト機能である minitest 用のものなので削除して良い。

i18n

メッセージなどを日本語化するための i18n を導入する。ついでにタイムゾーンを日本時間に変更しておく。

config/application.rb (赤文字部分を追加)

module Workspace
  class Application < Rails::Application
    config.time_zone = 'Tokyo'
    config.active_record.default_timezone = :local
    config.i18n.default_locale = :ja
  end
end

Gemfile

gem 'rails-i18n', '~> 6.0'

config/localesja.yml を作成して。以下をコピペする。

---
ja:
  activerecord:
    errors:
      messages:
        record_invalid: 'バリデーションに失敗しました: %{errors}'
        restrict_dependent_destroy:
          has_one: "%{record}が存在しているので削除できません"
          has_many: "%{record}が存在しているので削除できません"
  date:
    abbr_day_names:
    - 日
    - 月
    - 火
    - 水
    - 木
    - 金
    - 土
    abbr_month_names:
    - 
    - 1月
    - 2月
    - 3月
    - 4月
    - 5月
    - 6月
    - 7月
    - 8月
    - 9月
    - 10月
    - 11月
    - 12月
    day_names:
    - 日曜日
    - 月曜日
    - 火曜日
    - 水曜日
    - 木曜日
    - 金曜日
    - 土曜日
    formats:
      default: "%Y/%m/%d"
      long: "%Y年%m月%d日(%a)"
      short: "%m/%d"
    month_names:
    - 
    - 1月
    - 2月
    - 3月
    - 4月
    - 5月
    - 6月
    - 7月
    - 8月
    - 9月
    - 10月
    - 11月
    - 12月
    order:
    - :year
    - :month
    - :day
  datetime:
    distance_in_words:
      about_x_hours:
        one: 約1時間
        other: 約%{count}時間
      about_x_months:
        one: 約1ヶ月
        other: 約%{count}ヶ月
      about_x_years:
        one: 約1年
        other: 約%{count}年
      almost_x_years:
        one: 1年弱
        other: "%{count}年弱"
      half_a_minute: 30秒前後
      less_than_x_seconds:
        one: 1秒以内
        other: "%{count}秒未満"
      less_than_x_minutes:
        one: 1分以内
        other: "%{count}分未満"
      over_x_years:
        one: 1年以上
        other: "%{count}年以上"
      x_seconds:
        one: 1秒
        other: "%{count}秒"
      x_minutes:
        one: 1分
        other: "%{count}分"
      x_days:
        one: 1日
        other: "%{count}日"
      x_months:
        one: 1ヶ月
        other: "%{count}ヶ月"
      x_years:
        one: 1年
        other: "%{count}年"
    prompts:
      second: 秒
      minute: 分
      hour: 時
      day: 日
      month: 月
      year: 年
  errors:
    format: "%{attribute}%{message}"
    messages:
      accepted: を受諾してください
      blank: を入力してください
      confirmation: と%{attribute}の入力が一致しません
      empty: を入力してください
      equal_to: は%{count}にしてください
      even: は偶数にしてください
      exclusion: は予約されています
      greater_than: は%{count}より大きい値にしてください
      greater_than_or_equal_to: は%{count}以上の値にしてください
      inclusion: は一覧にありません
      invalid: は不正な値です
      less_than: は%{count}より小さい値にしてください
      less_than_or_equal_to: は%{count}以下の値にしてください
      model_invalid: 'バリデーションに失敗しました: %{errors}'
      not_a_number: は数値で入力してください
      not_an_integer: は整数で入力してください
      odd: は奇数にしてください
      other_than: は%{count}以外の値にしてください
      present: は入力しないでください
      required: を入力してください
      taken: はすでに存在します
      too_long: は%{count}文字以内で入力してください
      too_short: は%{count}文字以上で入力してください
      wrong_length: は%{count}文字で入力してください
    template:
      body: 次の項目を確認してください
      header:
        one: "%{model}にエラーが発生しました"
        other: "%{model}に%{count}個のエラーが発生しました"
  helpers:
    select:
      prompt: 選択してください
    submit:
      create: 登録する
      submit: 保存する
      update: 更新する
  number:
    currency:
      format:
        delimiter: ","
        format: "%n%u"
        precision: 0
        separator: "."
        significant: false
        strip_insignificant_zeros: false
        unit: 円
    format:
      delimiter: ","
      precision: 3
      separator: "."
      significant: false
      strip_insignificant_zeros: false
    human:
      decimal_units:
        format: "%n %u"
        units:
          billion: 十億
          million: 百万
          quadrillion: 千兆
          thousand: 千
          trillion: 兆
          unit: ''
      format:
        delimiter: ''
        precision: 3
        significant: true
        strip_insignificant_zeros: true
      storage_units:
        format: "%n%u"
        units:
          byte: バイト
          eb: EB
          gb: GB
          kb: KB
          mb: MB
          pb: PB
          tb: TB
    percentage:
      format:
        delimiter: ''
        format: "%n%"
    precision:
      format:
        delimiter: ''
  support:
    array:
      last_word_connector: "、"
      two_words_connector: "、"
      words_connector: "、"
  time:
    am: 午前
    formats:
      default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      long: "%Y/%m/%d %H:%M"
      short: "%m/%d %H:%M"
    pm: 午後

bcrypt

bcrypt はパスワードを暗号化してテーブルに保存するためのもの。初期ではコメントアウトされている。

# gem 'bcrypt', '~> 3.1.7'

# を外して,bundle install を実行。

better errors

better errors はエラー表示をより詳しく表示させるためのもの。エラーの原因を解明するのに役立つ情報を出力してくれる。

Gemfile (赤文字部分を追加)

group :development do
  gem 'better_errors'
end

bundle install を実行。

devise の導入

devise はユーザー認証機能を導入するためのもの。最初の段階で入れておいて開発を進めた方がよい。ついでに devise の画面を日本語化する devise-i18n も入れておく。

Gemfile (赤文字部分を追加)

gem "devise"
gem 'devise-i18n'
> bundle install
> rails g devise:install
> rails db:migrate
> rails g controller home index 

config/routes.rb

root to: "home#index"

config/environments/development.rb

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

config/environments/production.rb

config.action_mailer.default_url_options = { host: 'xxxx.com' }

さらに以下を実行してモデルとビューファイルを作成する。

> rails g devise:i18n:views
> rails g devise:i18n:locale ja
> rails g devise User
> rails db:migrate

config/localesdevise.views.ja.yml が生成される。

ここでコンテナを再ビルドしておかないと設定が反映されないので注意。

git の導入

開発を進める上で git も入れておいたほうが良い。VS Code はGUIでgitを操作できるようになっているので便利が良い。

使い方は以下が詳しい。

VSCodeでのGitの基本操作まとめ
https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be

参考

WSL2 のインストール,Ubuntu のインストールと利用(Windows 11 対応の記事)(Windows 上)
https://www.kkaneko.jp/tools/wsl/wsl2.html

WSL2のUbuntuでDockerを使う
https://zenn.dev/sprout2000/articles/95b125e3359694

Windows10のWSL2(Ubuntu)でDockerを使ったRails環境構築
https://qiita.com/na-777/items/fcccb48b4f3b549abe61