1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DockerでサーバーをPumaからNginx+unicornに切り替える

Last updated at Posted at 2021-03-02

はじめに

PumaでAWSにデプロイしていましたが、今回Nginx+Unicornに環境を切り替えましたので、その忘備録を作りました。dockerでPumaからサーバーを切り替えたい方の参考になればと思います。

ファイル構成

コンテナはrailsアプリ用、Mysql用、nginx用の3つを作成

.(railsプロジェクト)
├── Dockerfile
├── docker-compose.yml
├── Gemfile
├── Gemfile.lock
├── config
|   └──datebase.yml
|   └──unicorn.conf.rb
└── nginx
     ├──Dockerfile 
     └──nginx.conf

1. Dockerfile(rails)


# 19.01.20現在最新安定版のイメージを取得
FROM ruby:2.5.3

# dockerizeパッケージダウンロード用環境変数
ENV DOCKERIZE_VERSION v0.6.1

# 必要なパッケージのインストール
RUN apt-get update && \
    apt-get install -y --no-install-recommends\
    mariadb-client  \
    build-essential  \
    wget \
    vim \
    && wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
        && apt-get install -y nodejs

RUN mkdir /app_name
ENV APP_ROOT /app_name
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

# エラー回避の為、bundlerのバージョン下げる
RUN gem install bundler:1.17.3
RUN bundle install
ADD . $APP_ROOT

今回 bundlerがないよ!とのエラーが発生した為、RUN gem install bundler で取得しました。最初は最新版をダウンロードしてしまった為、もともとプロジェクトで使用していたbundlerと変わってしまい整合性が取れなくなってしまい、バージョンを指定することにしました。

2. Dockerfile(Nginx) 作成


FROM nginx:stable

COPY nginx.conf /etc/nginx/conf.d/myapp.conf

CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

3. nginx.conf 作成


upstream unicorn {
  server unix:/app_name/tmp/sockets/.unicorn.sock fail_timeout=0;
}

server {
  listen 80 default;
  server_name localhost;

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;
  root /app_name/public;

  client_max_body_size 100m;
  error_page 404             /404.html;
  error_page 505 502 503 504 /500.html;
  try_files  $uri/index.html $uri @unicorn;
  keepalive_timeout 5;

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

4. Gemfile追加

gem 'unicorn'

5. config/unicorn.conf.rb 作成

$worker  = 2
$timeout = 30
# 自分のアプリケーションまでのpath
$app_dir = "/app_name"
$listen  = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
$pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
$std_log = File.expand_path 'log/unicorn.log', $app_dir
# set config
worker_processes  $worker
working_directory $app_dir
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen  $listen
pid $pid
# loading booster
preload_app true
# before starting processes
before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      Process.kill "QUIT", File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end
# after finishing processes
after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

ここでは自分のアプリケーションまでのpathを間違えないこと。今回は $app_dir = "/app_name"で指定

6. 3.docker-compose.yml

version: '3'
services:
  # データベースのサービス定義
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - '3306:3306'

  # アプリケーションサーバーのサービス定義
  web:
    build: .
    # unicorn.pidを事前に削除
    command: /bin/sh -c "rm -f tmp/pids/unicorn.pid && dockerize -wait tcp://db:3306 -timeout 20s bundle exec unicorn -p 3000 -c /app_name/config/unicorn.conf.rb"
    volumes:
      - .:/app_name
      - bundle:/usr/local/bundle:delegated
      - tmp-data:/app_name/tmp/sockets
      - public-data:/app_name/public
      - /app/vendor
      - /app/tmp
      - /app/log
      - /app/.git
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
    links:
      - db
    environment:
    - "SELENIUM_DRIVER_URL=http://selenium_chrome:4444/wd/hub"

  # WEBサーバーのサービス定義
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    restart: always
    volumes:
      - tmp-data:/app_name/tmp/sockets
      - public-data:/app_name/public
    links:
      - web

  selenium_chrome:
    image: selenium/standalone-chrome-debug
    logging:
      driver: none

volumes:
  public-data:
  tmp-data:
  mysql-data:
  db-volume:
  bundle:

pidファイルが残ってしまいエラー発生していた為、事前に rm -f tmp/pids/unicorn.pid でpidファイル削除。Pumaだとserver.pidファイルだけど、今回はUnicornなのでunicorn.pidを削除します。

ここでコンテナはrailsアプリ用、Mysql用、nginx用の3つを作成します。自分はrailsアプリ用のコンテナが直ぐに落ちてしまい数日ハマりました。

さいごに

今回最も苦戦したことはrailsアプリ用のコンテナをどうしても立ち上げることができなかったことです。
またdockerの仕組みの理解がまだまだ曖昧なので、一つひとつ調べながら、それでも何度もdockerコンテナを削除しては作り直しました。その際余計なコンテナやイメージが残ってしまい時間を多く費やしてしまいました。その時にお世話になった記事も記載しておきます。ここまで読んで頂きありがとうございました。

今回主に参考にさせていただいた記事

docker-compose build/upがエラーで上手くいかなかった時に参考にした主な記事

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?