Help us understand the problem. What is going on with this article?

Docker で Rails(Nginx + Unicorn + MySQL) を動かす。

More than 1 year has passed since last update.

DockerHub にて、公式で各種プログラミング言語のベースイメージも公開された(Rails もある)ので使ってみようと思う。

Docker Adds 11 Top Language Stacks to Docker Hub Registry | Business Wire : http://www.businesswire.com/news/home/20140924005223/en/Docker-Adds-11-Top-Language-Stacks-Docker#.VCVCRSt_tGR

OSX 環境なので、boot2docker使う。

$ boot2docker init
$ boot2docker start
# 追記しておくと良い。
+ export DOCKER_HOST=tcp://192.168.59.103:2375

Raisアプリつくる

$ rails new sample-app -d mysql
$ cd sample-app
$ rails g scaffold article title:string content:string
$ bundle exec rake db:migrate
config/route.rb
+ root "articles#index"
Gemfile
+ gem 'unicorn'
+ gem 'foreman'
$ bundle
confg/unicorn.rb
# config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end 

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end
Procfile.dev
web: bundle exec unicorn -p 8080 -E production -c config/unicorn.rb
$ bundle exec rake db:create && bundle exec rake db:migrate
$ foreman start -f Procfile.dev

ここまでで、ローカルで動くことを確認。(Unicorn + MySQL)
http://localhost:8080/

Docker Hub から各イメージをとってきて動かす(pull + run)

https://hub.docker.com/ でたくさんイメージが公開されている。
今回は公式っぽいのを使う。
docker runコマンド時に指定して自動的に pull + run してくれる。

MySQL

mysql Repository | Docker Hub Registry - Repositories of Docker Images : https://registry.hub.docker.com/_/mysql/

$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql

Rails

Production用の設定を反映させる。
--link オプションで コンテナ間の環境変数にアクセスできる。

config/database.yml
production:
  <<: *default
  database: sample-app_production
  username: root
  password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
  host: <%= ENV['DB_PORT_3306_TCP_ADDR'] %>
  port: <%= ENV['DB_PORT_3306_TCP_PORT'] %>

Dockerfile(rails) は onbuild のものを参考にする。
https://github.com/docker-library/rails/blob/master/onbuild/Dockerfile

Dockerfile
FROM ruby:2.1.3

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD Gemfile /usr/src/app/
ADD Gemfile.lock /usr/src/app/
RUN bundle install --system

ADD Procfile /usr/src/app/

ADD . /usr/src/app

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

# ENV SECRET_KEY_BASE RUN ["bundle", "exec", "rake", "secret"]

# ONBUILD RUN bundle exec rake db:create RAILS_ENV=production
# ONBUILD RUN bundle exec rake db:migrate RAILS_ENV=production

EXPOSE 8080

# CMD ["bundle", "exec", "foreman", "start" ]
ENTRYPOINT bin/start_server.sh

start_server.sh 使わないで Dockerfile だけでやりたい(コメントアウトしたとこ)
けど、うまくできてない。。

bin/start_sever.sh
#!/bin/bash -x
export SECRET_KEY_BASE=`bundle exec rake secret`
bundle exec rake db:create RAILS_ENV=production
bundle exec rake db:migrate RAILS_ENV=production
bundle exec foreman start
$ sudo chmod 755 bin/start_server.sh
Procfile
web: bundle exec unicorn -E production -c config/unicorn.rb

build。

$ docker build -t 7kaji/sample-app .

Railsコンテナ起動。

$ docker run -d --name unicorn --link mysql:db 7kaji/sample-app

-p 8080:8080 オプションをつけると、ホストサーバへフォワードされるので、
http://192.168.59.103:8080 で確認できるはず。

Nginx

nginx Repository | Docker Hub Registry - Repositories of Docker Images : https://registry.hub.docker.com/_/nginx/

リバースプロキシを導入する。
Nginx用の Dockerfileを作る。

config/nginx/Dockerfile
FROM nginx:1.7.5

COPY nginx.conf /etc/nginx/nginx.conf
config/nginx/nginx.conf
http {
    upstream unicorn{
      server app:8080;  # appは--linkで名前解決できる
      # server <% ENV['APP_PORT'] %>;  # ruby入れて、.erbで参照してもいいかも
    }

    server {
        listen       80;
        #server_name  localhost.com;

        location / {
            proxy_pass http://unicorn;
        }
    }
}

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

Nginx用のDockerfile のとこでbuild。

$ docker build -t 7kaji/sample-nginx .

Nginxコンテナ起動。

$ docker run -d --name nginx --link unicorn:app -p 80:80 7kaji/sample-nginx

確認

$ docker ps
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                         NAMES
dbb77e3d9835        7kaji/sample-nginx:latest   "nginx -g 'daemon of   21 seconds ago      Up 21 seconds       443/tcp, 0.0.0.0:80->80/tcp   nginx
a9c41d021def        7kaji/sample-app:latest     "/bin/sh -c bin/star   11 minutes ago      Up 11 minutes       8080/tcp                      nginx/app,unicorn
104c5f356384        mysql:latest                "/entrypoint.sh mysq   23 minutes ago      Up 23 minutes       0.0.0.0:3306->3306/tcp        mysql,nginx/app/db,unicorn/db

ブラウザで確認

http://192.168.59.103/

スクリーンショット 2014-10-02 0.26.38.png

Dockerイメージ

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
7kaji/sample-nginx   latest              ffa7aa42869b        6 minutes ago       100.2 MB
7kaji/sample-app     latest              b376d11c5669        18 minutes ago      853.8 MB
mysql                latest              e65bb8be14c0        3 days ago          235.6 MB
ruby                 2.1.3               5cd733bb7b03        3 days ago          801.5 MB
nginx                1.7.5               d2d79aebd368        4 days ago          100.2 MB

参考・引用

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした