LoginSignup
5
3

More than 5 years have passed since last update.

Windows + VirtualBox + vagrant + Ubuntu + Docker + Docker Compose で Ruby on Rails + PostgreSQL の開発環境を構築する手順

Last updated at Posted at 2019-05-27

タイトルにあるものを使って、Rails + PostgreSQL の環境を構築する手順を書きました。

Rails のソースコードは Windows のローカルにて管理する構成とします。
※Windowsのディレクトリを仮想環境へマウントし、Docker コンテナではそのマウント先を参照させる

「Docker Community Edition for Windows を入れる前に確認すること」
https://qiita.com/lmatsul/items/9f05e76e22d862eb8620)
で書きましたが、Windows 上での Docker 実行が出来なかったので、
仕方なく仮想環境上で Docker を試すことにしました。

Windows 10 の Windows Subsystem for Linux (WSL) 上でも試そうかと思いましたが、
以下の記事のように出来ないこともあるようなので、無駄足を踏まないように最初から仮想環境を選びました…。
https://qiita.com/guchio/items/3eb0818df44fdbab3d14

仮想環境の構築

VirtualBox をインストールする

https://www.virtualbox.org/wiki/Downloads
※今回試したのは バージョン 5.0.26 r108824

vagrant をインストールする

https://www.vagrantup.com/downloads.html
※今回試したのは バージョン 2.2.4

今回の環境用のディレクトリを作成

C:\Users\(ユーザー名)\dev_rails で作成したとします

最終的な構成は以下のようになります

構成
dev_rails
 ├ rails
 │  ├ src
 │  │  ├ Gemfile
 │  │  ├ Gemfile.lock
 │  │  └ (ここにRailsのソースコード一式が入る)
 │  ├ docker-compose.yml
 │  ├ Dockerfile
 │  └ entrypoint.sh
 └ vagrant
    └ Vagrantfile

Ruby on Rails 環境構築用のディレクトリを作成

dev_rails 配下へ Ruby on Rails 環境構築用のディレクトリを作成します
今回は dev_rails\rails とします

VagrantFile の作成

dev_rails 配下へ Vagrantfile を置くためのディレクトリを作成します
今回は dev_rails\vagrant とします

コマンドプロンプトを起動し、作成したディレクトリへ移動して vagrant init とコマンドを実行します

Vagrantfile が作成されるので、以下のように修正して保存します

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
-  config.vm.box = "base"
+  # Vagrant Box で 「ubuntu/bionic64(ubuntu-18.04)」を指定
+  config.vm.box = "ubuntu/bionic64"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port
-  # config.vm.network "forwarded_port", guest: 80, host: 8080
+  # Port転送(Ruby on Rails 用)
+  config.vm.network "forwarded_port", guest: 3000, host: 3000

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via 127.0.0.1 to disable public access
  # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
-  # config.vm.network "private_network", ip: "192.168.33.10"
+  # IPアドレスの固定
+  config.vm.network "private_network", ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
-  # config.vm.synced_folder "../data", "/vagrant_data"
+  # Windows上の rails ディレクトリを /vagrant_data としてマウント
+  config.vm.synced_folder "../rails", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
end

仮想環境の起動

コマンドプロンプトを起動し、Vagrantfile が置かれている場所で vagrant up コマンドを実行して仮想環境を起動します

$ cd dev_rails/vagrant
$ vagrant up

起動したらターミナルなどで 192.168.33.10 へ SSH 接続します
ログインID は vagrant
秘密鍵は vagrant up を実行した配下の .vagrant\machines\default\virtualbox にある private_key を使用してください

Docker CE のインストール

https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce
を参考にインストールしていきます

Docker には
CE(コミュニティエディション)[無償版]

EE(エンタープライズエディション)[有償版]
があり、Docker-CE は無償版となります。

Docker リポジトリの登録

apt-get で docker-ce をインストールできるようにするために、以下の手順でリポジトリの設定を追加します。

# パッケージの更新
$ sudo apt-get update
# HTTPS利用のためのパッケージをインストール
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# Docker公式の GPG を追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 追加されたことを確認
$ sudo apt-key fingerprint 0EBFCD88
# リポジトリの設定
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

Docker CE のインストール

以下のコマンドで Docker CE をインストールします

# パッケージの更新
$ sudo apt-get update
# Docker CE のインストール
$ sudo apt-get install docker-ce
# hello-world イメージを実行して動作確認
$ sudo docker container run hello-world

バージョンを指定してインストールしたい場合は、以下のようにバージョンを確認してから、バージョン指定してインストールする

# バージョン一覧を表示
$ apt-cache madison docker-ce
# バージョンを指定して Docker CE をインストール
$ sudo apt-get install docker-ce=<VERSION>

Docker Compose のインストール

https://docs.docker.com/compose/install/
を参考にインストールしていきます

Docker Compose とは、複数のコンテナを使う Docker アプリケーションを定義・実行するためのツールです。

# Docker compose のダウンロード
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 実行権限の付与
sudo chmod +x /usr/local/bin/docker-compose
# 動作確認(バージョン情報が表示されればOK)
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

Ruby on Rails 環境の構築

https://docs.docker.com/compose/rails/
を参考に進めます

Dockerfile の作成

以下の内容のファイルをWindows側で dev_rails\rails へ作成します
※文字コードは UTF-8、改行コードは LF で作成する

Dockerfile
# ベースイメージを Ruby 2.5 へ指定
# ベースイメージは https://github.com/docker-library/official-images/tree/master/library を参照
FROM ruby:2.5

# apt-get を更新し、Node.js、PostgreSQLクライアント、bundler をインストール
RUN apt-get update -qq && \
    apt-get install -y nodejs postgresql-client && \
    gem install bundler

# ./src をコンテナ内の /vagrant_data/src として追加し、作業ディレクトリを指定して bundle install する
ADD ./src /vagrant_data/src
WORKDIR /vagrant_data/src
RUN bundle install

# entrypoint.sh をコピーし、最初に実行されるものとして登録する
COPY entrypoint.sh /usr/bin/
ENTRYPOINT ["entrypoint.sh"]

# ポートの公開
EXPOSE 3000

# Rails コマンドでWebサーバを起動(ENTRYPOINTで指定された entrypoint.sh へ引き渡される)
CMD ["rails", "server", "-b", "0.0.0.0"]

Rails のソースコード用のディレクトリを作成

今回は dev_rails\rails\src とします

Gemfile の作成

上記で作成したディレクトリに以下の内容のファイルを Gemfile というファイル名で作成します
※文字コードは UTF-8、改行コードは LF で作成する

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

Gemfile.lock の作成

Gemfile と同じ階層に Gemfile.lock というファイル名で空のファイルを作成します
※文字コードは UTF-8、改行コードは LF で作成する

entrypoint.sh の作成

Rails固有の問題を修正するための entrypoint.sh を Dockerfile と同じ階層 へ作成します。
このスクリプトはコンテナが起動されるたびに実行されます。
※文字コードは UTF-8、改行コードは LF で作成する

entrypoint.sh
#!/bin/bash
set -e

# Rails 用の server.pid が存在する場合は削除する
# (server.pid が存在したままだと起動中と判断されてしまうため)
rm -f /vagrant_data/src/tmp/pids/server.pid

# CMDで渡されたコマンドを実行
exec $@

docker-compose.yml の作成

Docker Compose 用の設定ファイル(docker-compose.yml)を Dockerfile と同じ階層 へ作成します。
データベースとWebサーバの構成設定を記述しています。
※文字コードは UTF-8、改行コードは LF で作成する

docker-compose.yml
version: '3'
services:
  db:
    # 使用するイメージを postgres に指定
    image: postgres
    # データベースのデータディレクトリを別のVolumeへ逃して永続化
    volumes:
      - data:/var/lib/postgresql/data
  web:
    # ビルドパスの指定(Dockerfileのある位置を指定する)
    build: .
    # Railsのソースコードディレクトリをマウント
    volumes:
      - ./src:/vagrant_data/src
    # ポートの設定
    ports:
      - "3000:3000"
    # dbが起動後に起動するように依存関係を設定する
    depends_on:
      - db
volumes:
  # データベースのデータ保存用Volume
  data:
    external: true
  • ハマった点 (T_T)

最初、以下のようにWindows上のディレクトリへPostgreSQLのデータディレクトリをマウントしようとしたが、

services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data

とすると、以下のようなエラーにハマった。

FATAL:  data directory "/var/lib/postgresql/data" has wrong ownership
HINT:  The server must be started by the user that owns the data directory.

データの永続化のためには、今回のように Volume を作成してそこで保持するようにすることで対処可能でした。

Rails プロジェクトの作成(まだRailsのソースコードを作成していない場合)

sudo docker-compose run web rails new . --force --no-deps --database=postgresql

Rails の設定ファイルを編集

dev_rails\rails\src\config\database.yml にある Rails のデータベース設定ファイルを以下のように編集します。

database.yml
# PostgreSQL. Versions 9.1 and up are supported.
#
# Install the pg driver:
#   gem install pg
# On OS X with Homebrew:
#   gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On OS X with MacPorts:
#   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
# On Windows:
#   gem install pg
#       Choose the win32 build.
#       Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem 'pg'
#
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+  host: db
+  username: postgres
+  password:

development:
  <<: *default
  database: src_development

  # The specified database role being used to connect to postgres.
  # To create additional roles in postgres see `$ createuser --help`.
  # When left blank, postgres will use the default role. This is
  # the same name as the operating system user that initialized the database.
  #username: src

  # The password associated with the postgres role (username).
  #password:

  # Connect on a TCP socket. Omitted by default since the client uses a
  # domain socket that doesn't need configuration. Windows does not have
  # domain sockets, so uncomment these lines.
  #host: localhost

  # The TCP port the server listens on. Defaults to 5432.
  # If your server runs on a different port number, change accordingly.
  #port: 5432

  # Schema search path. The server defaults to $user,public
  #schema_search_path: myapp,sharedapp,public

  # Minimum log levels, in increasing order:
  #   debug5, debug4, debug3, debug2, debug1,
  #   log, notice, warning, error, fatal, and panic
  # Defaults to warning.
  #min_messages: notice

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: src_test

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
production:
  <<: *default
  database: src_production
  username: src
  password: <%= ENV['SRC_DATABASE_PASSWORD'] %>

Docker Compose

ビルド

192.168.33.10 へ SSH 接続しているターミナルで docker-compose.yml があるディレクトリへ移動し、以下のコマンドでビルドします。

$ cd /vagrant_data
$ sudo docker-compose build

データベースのデータ保存用Volumeの作成

ビルドが完了したら以下のコマンドでデータベースのデータ保存用の Volume を作成をします

$ sudo docker volume create --name=data

データベースとWebサーバを起動

Volume の作成が完了したら以下のコマンドで各サービスを起動します

# -d を付けることでバックグラウンドで実行されます
$ sudo docker-compose up -d

データベースとWebサーバの起動確認

$ sudo docker-compose ps
# 以下のような表示で State が Up となっていたら起動成功
       Name                     Command               State           Ports
------------------------------------------------------------------------------------
vagrant_data_db_1    docker-entrypoint.sh postgres    Up      5432/tcp
vagrant_data_web_1   entrypoint.sh rails server ...   Up      0.0.0.0:3000->3000/tcp

データベースの作成

sudo docker-compose run web rake db:create

Rails の起動確認

ブラウザで http://192.168.33.10:3000 へアクセスして Rails の画面が表示されれば、環境構築完了です。

その他

  • コンテナがうまく起動しない場合、sudo docker-compose logs でログを確認する
  • コンテナを終了させたい場合、sudo docker-compose down で終了させる
  • コンテナの中に入りたい場合、sudo docker-compose exec web bash で入ることができる
    web のところは、docker-compose.yml で記述したサービス名)
  • Volume の一覧を確認したい場合、sudo docker volume ls で確認ができる
  • 特定の Volume を削除したい場合、sudo docker volume rm [volume name] で削除ができる
5
3
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
5
3