Breaking News

Default Placeholder Default Placeholder

はじめに

前回の投稿でdocker-compose + Ruby3 + Rails7 + MySQLの環境構築方法をまとめました。

今回の記事では↑で作成したプロジェクトをNginxを用いて起動できるように修正していきたいと思います。まずNginx抜きでやりたい、という方はぜひ↑の記事を参考に環境を作っていってください。

また、本記事の対応を行うと、今まで localhost:3000のようにポートを指定してブラウザアクセスしていたところが localhostのみでアクセスすることができるようになります。

筆者の環境

  • M1 Mac BigSur 11.4
  • docker-compose 1.29.2
  • Docker 20.10.7
  • 環境構築に使うもの

    • Rails7
    • Ruby3
    • Nginx 1.21-alpine
    • MySQL 8.0.25

    やること

    • RailsのDockerfile修正
    • NginxのDockerfile作成
    • Nginxのconfファイル作成
    • Puma.rb修正
    • docker-compose.yml修正
    • 起動スクリプト作成

    こうやって並べると盛り沢山ですが、大丈夫です。1つ1つやっていきましょう!

    各ファイルの冒頭にコメントでどこに作成するかを示しています。docker-composeでのファイル指定に関係するので、本記事を参考に環境構築する場合は全て示されている箇所に作成することをお勧めします。

    RailsのDockerfile修正

    Rails AppとNginxの連携をするためにこんな感じに修正します。

    # Dockerfile
    
    FROM ruby:3.0
    
    ENV APP /app
    RUN mkdir -p $APP
    COPY . $APP/
    
    WORKDIR $APP
    
    # ここのRUNを追加
    RUN mkdir -p tmp/sockets && \
        mkdir -p /tmp/public && \
        cp -rf $APP/public/* /tmp/public
    
    RUN bundle install

    NginxのDockerfile作成

    NginxのDockerfileを作成します。confファイルを指定する箇所がありますが、次の行程で作成しますので気にせず進めていきましょう。

    # nginx/Dockerfile
    
    FROM nginx:1.21-alpine
    
    # インクルード用のディレクトリ内を削除
    RUN rm -f /etc/nginx/conf.d/*
    
    # Nginxの設定ファイルをコンテナにコピー
    ADD nginx.conf /etc/nginx/conf.d/app.conf
    
    # ビルド完了後にNginxを起動
    CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

    ここでは1.21-alpineを使っています。新しいバージョンがあったらそちらを使ってほうがいいので適宜変更してください。

    nginxのdockerhubはこちら

    Nginxのconfファイル作成

    Nginxで受け取ったリクエストをRailsのpumaに渡す箇所を作成します。

    # nginx/nginx.conf
    
    # プロキシ先の指定
    # Nginxが受け取ったリクエストをバックエンドのpumaに送信
    upstream app {
      # ソケット通信したいのでpuma.sockを指定
      server unix:///app/tmp/sockets/puma.sock fail_timeout=30s;
    }
    server {
      listen 80;
      # ドメインもしくはIPを指定
      server_name localhost;
      # ドキュメントルートの指定
      root /app/public;
      large_client_header_buffers 4 32k;
      client_max_body_size 100m;
      error_page 404             /404.html;
      error_page 505 502 503 504 /500.html;
      try_files  $uri/index.html $uri @app;
      keepalive_timeout 120;
      # リバースプロキシ関連の設定
      location @app {
        proxy_ignore_client_abort on;
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        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://app;
      }
    }

    puma.rb修正

    Railsプロジェクト内に自動生成されている config/puma.rbを修正します。

    # config/puma.rb
    
    ...
    ...
    ...
    
    # Use the `preload_app!` method when specifying a `workers` number.
    # This directive tells Puma to first boot the application and load code
    # before forking the application. This takes advantage of Copy On Write
    # process behavior so workers use less memory.
    #
    # preload_app!
    
    # Allow puma to be restarted by `bin/rails restart` command.
    plugin :tmp_restart
    
    # ここを追加
    app_root = File.expand_path("../..", __FILE__)
    bind "unix://#{app_root}/tmp/sockets/puma.sock"
    stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

    docker-compose.yml修正

    docker-compose.ymlにnginxを追加し、また各種volumesを追加していきます。このままコピー&ペーストしてください。

    # docker-compose.yml
    
    version: '3'
    services:
      app:
        restart: always
        build:
          context: .
        volumes:
          - .:/app
          - /app/node_modules
          - public-data:/app/public
          - tmp-data:/app/tmp
          - log-data:/app/log
        command: sh launch.sh
        depends_on:
          - db
      db:
        restart: always
        image: mysql:8.0.25
        platform: linux/amd64
        environment:
          MYSQL_DATABASE: app_development
          MYSQL_USER: appuser
          MYSQL_ROOT_PASSWORD: asf#aks3AFja
          MYSQL_PASSWORD: asf#aks3AFja
          TZ: 'Asia/Tokyo'
          MYSQL_ROOT_HOST: "%"
        tty: true
        command: mysqld --character-set-server=utf8mb4 --explicit_defaults_for_timestamp=true --default-authentication-plugin=mysql_native_password    
        ports:
          - 3306:3306
      nginx:
        build:
          context: ./nginx
        ports:
          - 80:80
        depends_on:
          - app
        volumes:
          - public-data:/app/public
          - tmp-data:/app/tmp
    volumes:
      public-data:
      tmp-data:
      log-data:

    起動スクリプト作成

    railsサーバではなくpumaを起動するようにします。

    # launch.sh
    
    bundle exec rake db:migrate
    cp -rf /tmp/public/* /app/public/
    mkdir -p tmp/sockets
    bundle exec puma -C config/puma.rb

    お疲れ様でした。これで準備はOKです。あとはbuildしてupするだけです!

    Build

    以下のコマンドを実行し、コンテナをビルドします。

    $ docker-compose build --no-cache

    起動

    以下のコマンドを起動してコンテナ群を起動します。

    $ docker-compose up

    以下のような出力がされたらOKです。(環境によっては出力の結果が前後する場合があります)

    app_1    | * Listening on http://0.0.0.0:3000
    app_1    | * Listening on unix:///app/tmp/sockets/puma.sock
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: using the "epoll" event method
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: nginx/1.21.5
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027)
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: OS: Linux 5.10.25-linuxkit
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: start worker processes
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: start worker process 8
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: start worker process 9
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: start worker process 10
    nginx_1  | 2022/01/15 22:36:04 [notice] 1#1: start worker process 11
    app_1    | Use Ctrl-C to stop

    ではブラウザでアクセスしてみましょう!

    ブラウザアクセス

    ブラウザで`localhost`にアクセスしてみましょう。以下のようになったら成功です!

    Google ChromeのDeveloper ConsoleのNetworkでも、Nginxを通っていることが確認できますのでぜひ見てみください。ちなみにこんな感じになっているはずです。

    おわりに

    本番環境では結局Nginxを使うケースがあったりするので、ならローカルでの開発時からNginxを使っていた方が安心しますよね。こういうのを最初から取り入れておくと実際に本番でNginxを使いたい!となってもスムーズに進めることができると思います。

    簡単ではありますが、以上でdocker-composeでRuby3+Rails7+MySQL+Nginxの環境構築を行う方法まとめを終わります。

    最後までお読みいただきありがとうございました。