67795


**実現したいこと**  
docker-composeで立ち上げたRailsアプリに、ブラウザからアクセスする。

**解決したい事象**  
下記のコンテナ構成でdocker-compose upでコンテナを立ち上げました。

  * APサーバ：Rails
  * Webサーバ：Nginx
  * DBサーバ：MySQL

そして、docker-compose upではエラーが出なかったので、ブラウザでアプリへアクセスしたところ、  
下記エラー画面（500 Internal Server Error）が表示され、アプリの画面が正常に表示できません。  
何が原因として考えられるか、また解決方法についてお伺いしたい次第です。  
[![画像の説明をここに入力](https://i.stack.imgur.com/Hd9Tg.png)](https://i.stack.imgur.com/Hd9Tg.png)

なお、先日までは、「Rails」+「MySQL」という構成でDockerを使用しており（Nginxなし）、  
その際は問題なくアプリの画面が表示できていました。  
この度、Nginxを使用したいと思い、Nginxのコンテナも追加しました。

**試したこと**  
サーバ側のエラーメッセージに  
「worker_connections are not enough while connecting to upstream」  
とあったので、その内容を調査し、下記のQiita記事の内容から、  
worker_connectionsを増加させる記述をNginx設定ファイル（nginx.conf）へ行いました。  
しかし、事象・エラーメッセージ共に変化せずでした。  
[[Nginx]worker_connectionsとworker_rlimit_nofileの値は何がいいのか？](https://qiita.com/mikene_koko/items/85fbe6a342f89bf53e89)

現在、nginx.confの内容に原因があるのではと推測し、  
エラーメッセージで検索し、調査を続けているところですが、  
並行してご質問させていただきました。

**サーバ側エラーメッセージ**  
[![画像の説明をここに入力](https://i.stack.imgur.com/XO880.png)](https://i.stack.imgur.com/XO880.png)

**nginx.conf**

[code]

    # プロキシ先の指定
    # Nginxが受け取ったリクエストをバックエンドのpumaに送信
    upstream myapp {
      # ソケット通信したいのでpuma.sockを指定
      server unix:///myapp/tmp/sockets/puma.sock;
    }
    
    server {
      listen 80;
      # ドメインもしくはIPを指定
      server_name 192.168.99.100;
    
      access_log /var/log/nginx/access.log;
      error_log  /var/log/nginx/error.log;
    
      # ドキュメントルートの指定
      root /app/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 @myapp;
      keepalive_timeout 5;
    
      # リバースプロキシ関連の設定
      location @myapp {
        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://myapp;
      }
    }
    
    # エラーを受けて追加したが動作変わらず（2020/6/17）
    worker_rlimit_nofile 83000;
    
    events {
      worker_connections 4096; # 1つのworkerプロセスが開ける最大コネクション数
    }
    
[/code]

**docker-compose.yml**

[code]

    version: '3'
    services:
      db:
          （他情報は略）
        volumes:
          - db-volume:/var/lib/mysql
        ports:
          - "3306:3306"
      test-db:
          （他情報は略）
        ports:
          - '3307:3306' # ローカルPCから接続するために設定
      app:
        build:
          context: .
          dockerfile: ./docker/rails/Dockerfile
        command: bundle exec pumactl start
        tty: true
        stdin_open: true
        volumes:
          - .:/myapp
          - public-data:/myapp/public
          - tmp-data:/myapp/tmp
          - log-data:/myapp/log
          - sockets:/myapp/tmp/sockets
        privileged: true
        depends_on:
          - db
      web:
        build:
          context: .
          dockerfile: ./docker/nginx/Dockerfile
        ports:
          - '80:80'
        volumes:
          - public-data:/myapp/public
          - tmp-data:/myapp/tmp
          - sockets:/myapp/tmp/sockets
        depends_on: 
          - app
    volumes:
      db-volume:
      public-data:
      tmp-data:
      log-data:
      sockets:
    
[/code]

**Puma.rbの内容**

[code]

    threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
    threads threads_count, threads_count
    port        ENV.fetch("PORT") { 3000 }
    environment ENV.fetch("RAILS_ENV") { "development" }
    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
    
[/code]

**NginxのDockerfile**

[code]

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

### railsのDockerfile

[code]

    FROM ruby:2.6.5
    # apt-utils関連のエラーを表示させないようにする
    ENV DEBCONF_NOWARNINGS yes
    RUN apt-get update -qq && \
        apt-get install -y --no-install-recommends build-essential \ 
                           libpq-dev \      
                           nodejs \
                           && rm -rf /var/lib/apt/lists/*
    
    # 作業ディレクトリの作成、設定
    RUN mkdir /myapp
    WORKDIR /myapp
    
    # ホスト側（ローカル）のGemfileを追加する
    COPY Gemfile /myapp/Gemfile
    COPY Gemfile.lock /myapp/Gemfile.lock
    
    # Gemfileのbundle install
    RUN bundle install
    COPY . /myapp
    RUN mkdir -p tmp/sockets
    
    # Expose volumes to frontend
    VOLUME /app/public
    VOLUME /app/tmp
    
[/code]

**ディレクトリ構成**

[code]

    app/
    bin/
    config/
      -puma.rb
       （ほかは省略）
    core
    db/
    docker/
    　-nginx/
        -Dockerfile
        -nginx.conf
      -rails/
        -Dockerfile
    docker-compose.yml
    Gemfile
    Gemfile.lock
    lib/
    log/
    nginx/
    package.json
    public/
    Rakefile
    README.md
    spec/
    storage/
    tmp/
    　-sockets/
      -pids/
      （他は省略）
    vendor/
    
[/code]

なお、teratailでも同様の質問を行っておりますが、  
teratailで何か情報の更新がありましたら、すぐにこちらに情報反映させていただきます。  
何卒ご了承いただきますよう、お願い申し上げます。  
[teratailの質問リンク](https://teratail.com/questions/270839)

不足情報等ございましたら、お手数をお掛けし恐縮ではございますが、  
ご指摘いただけますと幸いです。

何卒宜しくお願い致します。


CC BY-SA 4.0
2020-06-18T00:06:56.110
67769
2020-06-18T23:48:33.240
2020-06-18T08:22:34.690
40311
40311
question
ruby-on-rails docker nginx docker-compose
Nginx+Railsコンテナでdocker-composeしてブラウザでアクセスすると500の内部サーバエラーが出る


解決しました。  
「①nginx.confのディレクティブを考慮できていないこと」と「②ビルドしたdockerイメージに設定が反映されていないこと」が原因でした。  
＜詳細＞  
①worker_rlimit_nofile は設定ファイルのトップレベルに記載すべき項目(参考→ context: main)ですが，私は
/etc/nginx/nginx.conf の httpディレクティブにincludeしてしまっていたため、  
worker_rlimit_nofileを削除しました。  
②nginx.confはビルドと関係なくdocker-compose
upの時のみ読み込まれると思っていましたが、ビルド時にも読み込まれるため、docker-compose
buildからやり直したところ、正常にブラウザでアクセスすることができました。


CC BY-SA 4.0
2020-06-18T23:48:33.240
67795
2020-06-18T23:48:33.240
40311
67769
answer