Rails on Docker on Vagrant環境構築

![](http://applech2.com/wp-content/uploads/2016/07/Docker-logo-icon.jpg)![](http://findicons.com/files/icons/1607/ruby_on_rails/128/ror_logo.png)![](http://www.kameneko.com/wp-content/uploads/2015/05/vagrantlogo.png)
## Environment
HostOS < Vagrnt < Ubuntu < Docker < Rails

## Vagrant

```bash
vagrant init bento/ubuntu-16.04
vagrant up --provider virtualbox
```

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

Vagrant.configure(2) do |config|
  config.vm.box = "bento/ubuntu-16.04"
  config.vm.provision "docker"
  config.vm.provision :docker_compose

  config.vm.network "forwarded_port", guest: 80, host: 9000
  config.vm.network "forwarded_port", guest: 443, host: 4000
  config.vm.network "forwarded_port", guest: 3000, host: 5000
  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.synced_folder "share/", "/vagrant/share", type: "rsync",
    rsync__args: %w(--verbose --archive --delete -z --copy-links --times),
    rsync__chown: false
  config.vm.provider "virtualbox" do |vb| 
    vb.memory = "4096"
  end
  config.vm.provision :shell, :path => "setup.sh", privileged: true
  config.vm.provision :shell, :path => "ruby.sh", privileged: false
  config.vm.provision :shell, :path => "rails_db_web_node.sh", privileged: true  
end
```

## General settings

```bash:setup.sh
home='/home/vagrant'
######################
# general
######################
apt-get -y update
# GCC4.9
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt-get -y update
# Kernel
apt-get -y install linux-image-extra-$(uname -r) linux-image-extra-virtual

######################
# rbenv
######################
# rbenv
git clone https://github.com/rbenv/rbenv.git ${home}/.rbenv
# .bashrcに追記
echo "export PATH=\"${home}/.rbenv/bin:$PATH\"" >> ${home}/.bash_profile
echo 'eval "$(rbenv init -)"' >> ${home}/.bash_profile
# ruby-build
git clone https://github.com/rbenv/ruby-build.git "${home}/.rbenv/plugins/ruby-build"
```

## Ruby Install
```bash:ruby.sh
home='/home/vagrant'
#######################
# ruby
#######################
sudo ~/.rbenv/bin/rbenv install 2.4.0
sudo ~/.rbenv/bin/rbenv global 2.4.0
sudo ~/.rbenv/bin/rbenv rehash
```

## Rails Install
```bash:rails_db_web_node.sh
home='/home/vagrant'
#######################
# rails
#######################
sudo apt-get -y install ruby-dev zlib1g-dev gcc make
gem install bundler
gem install pkg-config -v "~> 1.1.7"
sudo apt-get -y install libxml2-dev
sudo apt-get -y install libxslt-dev
gem install nokogiri -- --use-system-libraries
gem install rails --no-ri --no-rdoc 

# #######################
# # postgres
# #######################
# # postgres sqlite3 install
apt-get -y install libpq-dev libsqlite3-dev

# #######################
# # nginx
# #######################
# # nginx install
apt-get -y install nginx

# #######################
# # nodejs
# #######################
# # nodejs npm install
apt-get -y install nodejs npm
npm cache clean
npm install n -g
n stable
ln -sf /usr/local/bin/node /usr/bin/node
apt-get -y purge nodejs npm


#######################
# version
#######################
echo 'node -v' >> "${home}/.bash_profile"
echo 'ruby -v' >> "${home}/.bash_profile"
echo 'rails -v' >> "${home}/.bash_profile"
echo 'docker -v' >> "${home}/.bash_profile"
echo 'docker-compose -v' >> "${home}/.bash_profile"
```

## Docker Start

```bash
service nginx stop
service docker status
docker-compose run --rm app rails db:setup
docker-compose up -d
```

```:Dockerfile
FROM ruby:2.4

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    nodejs \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```

share drive使用しない場合

```:docker-compose.yml
version: '3'
services:
  db:
    image: postgres:9.6
    volumes:
      - pg:/var/lib/postgresql/data
      # - ./log:/var/log/postgresql
  app:
    build: .

    environment:
      - RAILS_ENV
      - SECRET_KEY_BASE
    depends_on:
      - db
  nginx:
    build:
      
    ports:
      - "80:80"
      - "443:443"
    command: ["nginx", "-g", "daemon off;", "-c", "/home/config/$RAILS_ENV.conf"]
    depends_on:
      - app
volumes:
  pg:
```

share drive使用する場合

```:docker-compose.yml
version: '3'
services:
  db:
    image: postgres:9.6
    healthcheck:
      test: "pg_isready -h localhost -p 5432 -q -U postgres"
      interval: 3s
      timeout: 5s
      retries: 5
    volumes:
      - pg:/var/lib/postgresql/data
      - ./log:/var/log/postgresql
  app:
    build: .
    volumes:
      - .:/usr/src/
    environment:
      - RAILS_ENV
      - SECRET_KEY_BASE
    depends_on:
      - db
  nginx:
    image: nginx:1.11
    volumes:
      - ./public:/home/public:ro
      - ./config/nginx:/home/config:ro
      - ./log:/var/log/nginx
    ports:
      - "80:80"
      - "443:443"
    command: ["nginx", "-g", "daemon off;", "-c", "/home/config/$RAILS_ENV.conf"]
    depends_on:
      - app
volumes:
  pg:
```

## ホストとVMでファイルシェアするのに必要
`vagrant plugin install vagrant-vbguest`

## ポートフォワード設定
Vagrant 1.9.3のバグでこれでは動かない

```
config.vm.network "forwarded_port", guest: 80, host: 4000
```

こうすると動く

```
config.vm.network "forwarded_port", guest: 80, host: 4000, host_ip: "127.0.0.1", id: 'http'
```

## VagrantのVM上でRailsを動かす
### IP指定してRailsを起動する`rails s -b 0.0.0.0`
0.0.0.0 (任意のIPアドレス)どこからでもアクセスできる状況だったが、現在は127.0.0.1(localhost, 仮想サーバ自身)からしか繋がらないため

## rsync設定
http://win.just4fun.biz/?%E9%96%8B%E7%99%BA%E3%83%84%E3%83%BC%E3%83%AB/Cygwin%E3%81%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E8%BF%BD%E5%8A%A0%E3%81%A8%E5%89%8A%E9%99%A4

# Vagrantネットワーク概要
![](http://www.kameneko.com/wp-content/uploads/2015/05/vagrantlogo.png)
## ブリッジアダプタ(パプリックネットワーク)
ホストOSと同じネットワークを使用
外部と直接通信できる

`config.vm.network :public_network, :bridge => "en0: Wi-Fi (AirPort)"`

## NAT
ホストOSを介して外部のネットワークに接続する
外部ネットワークからゲストOSへはアクセスできない
`config.vm.network "private_network", ip: "192.168.33.60"`

## ポートフォワーディング
ホストOSの特定のポートへのアクセスをゲストOSへ転送
http://ホストOSのIP:8080/で外部からアクセス可能
`config.vm.network "forwarded_port", guest: 80, host: 8080`