gotoshin

主に学んだ事の自分メモ用です。記事に書くまでも無いような事はhttps://scrapbox.io/study-diary/に書いてます。

Railsアプリケーションをcapistrano × GCE(nginx × puma)× CloudSQL(MySQL)× でデプロイ【Nginx & SSL設定編】

この記事について

HTTPS通信が可能なwebサーバを、nginxと cerbotを使用して構築したので、自分用のメモも兼ねてまとめてみました。

アジェンダ

Nginxのインストール

以下の記事を参考に作成しました。

nginx の最新版を Ubuntu 18.04 に apt インストールする - サーバー構築と設定 ~初心者にも分かりやすく解説~

基本的にはこの記事の通りで問題ありませんが、インストールした時点で自動起動は有効になっており

sudo systemctl enable nginx

は必要ありませんでした。

SSL証明書を取得

cerbotを使用してSSL証明書を取得しました。以下の記事を参考に作成しました。

Certbot を使い3分で無料の SSL 証明書を取得する | Developers.IO

Certbot - Ubuntuxenial Nginx

  • cerbotのinstall
sudo apt-get install certbot python3-certbot-nginx
  • 証明書取得のコマンド実行
sudo certbot --nginx

メールアドレスやドメイン名を尋ねられる。 詳細は以下に詳しく書いてある。

Let's Encrypt で Nginx にSSLを設定する - Qiita

Nginxの設定ファイル編集

nginx.confを編集します。 以下の記事を参考に作成しました。

nginxについてまとめ(設定編) - Qiita

Nginx設定のまとめ - Qiita

user nginx;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 100;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

   ##
    # Server
    ##
        upstream book_memo_api {
            server unix:/var/www/book_memo_api/shared/tmp/sockets/puma.sock;
        }

        server {
            listen 443 ssl; # managed by Certbot
            ssl_certificate /etc/letsencrypt/live/api.book-memo.work/fullchain.pem; # managed by Certbot
            ssl_certificate_key /etc/letsencrypt/live/api.book-memo.work/privkey.pem; # managed by Certbot
            include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

            server_name api.book-memo.work;

            root /var/www/book_memo_api/current/public;

            try_files $uri/index.html $uri @book_memo_api;

            location @book_memo_api {
                proxy_pass http://book_memo_api;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
            }

            error_page 500 502 503 504 /500.html;
            client_max_body_size 4G;
            keepalive_timeout 30;

    }
}

注意点

先程certbotssl証明書を取得した際、以下の設定がnginx.confに記載される。

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.book-memo.work/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.book-memo.work/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

がしかし・・・なぜかserverモジュールの外側に記載され、そのままだと起動時にエラーになってしまう。 (listenはserverの内側に記載する必要があるため。) これでハマってしまったので要注意!自動で記載されたものだから間違い無いだろと信じたのに(泣)!

設定ファイル作成時に調べた事を自分メモ用に残しておく

ここからは自分のメモ程度に各項目についてまとめているので、↑の参考にしたリンクの方が詳しく書かれています。

user

  • nginxの実行ユーザ。デフォルトだとwww-dataとなっているが、参考にした記事に合わせてnginxに変更。(何となく・・・)

worker_processes

  • nginxがシングルスレッドで動作するため、コア数に合わせて記載。デフォルト設定でOK。

pid

  • pidが記載されているファイルの格納場所。デフォルト設定でOK。

include /etc/nginx/modules-enabled/*.conf;

  • /etc/nginx/modules-enabled/配下の設定ファイルを読み込んでいるよう。意味は分からなかった。。。 f:id:hatehate-nazenaze:20200708085443p:plain

events

  • eventモジュールの定義。主にパフォーマンス・チューニングらしい。

worker_connections

  • 1つのワーカーが同時に処理出来る接続数。以下の記事に色々と書いてあったが、今回はデフォルトで設定する。

[Nginx]worker_connectionsとworker_rlimit_nofileの値は何がいいのか? - Qiita

http

  • webサーバとして使用するメインとなる処理を記載するモジュール

sendfile、tcp_nopush、tcp_nodelay

  • デフォルトonのままでOK。

keepalive_timeouty

types_hash_max_size

  • 調べたところハッシュテーブルの最大サイズと記載があった。詳しくは不明。デフォルト設定のまま。

include /etc/nginx/mime.types;

  • MINEタイプと拡張子の関連付けが記載されているファイルを読み込んでいる。デフォルト設定のまま。

default_type application/octet-stream;

  • 上述のmime.typesで拡張子からMIMEタイプを決定できなかったときに、ここで指定したMIMEタイプが適応されます。   

  • 調べてみたところapplication/octet-streamとは、要はファイル形式を気にしない設定。

https://wa3.i-3-i.info/word15821.html

access_log /var/log/nginx/access.log;

error_log /var/log/nginx/error.log

  • エラーログの保管場所

upstream

  • サーバーを定義する事が可能。今回はpumaが1つだけなので、puma.sockを定義する。

listen

  • listenするポート番号を記載する。今回はhttps通信を行うので443に設定(cerbotでコマンドを実行した際に自動で記載された設定を使用)

ssl関連の設定

ssl_certificate /etc/letsencrypt/live/api.book-memo.work/fullchain.pem; # managed by Certbot
            ssl_certificate_key /etc/letsencrypt/live/api.book-memo.work/privkey.pem; # managed by Certbot
            include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  • cerbotでコマンドを実行した際に書かれた設定をそのまま使用

server_name

  • 今回ドメイン名はbook-memo.workのため、そのままそれを設定。しかし、別の名前でも通信は上手くいったため、あくまで識別用の名前という認識。

root

nginxがアクセスするルートディレクト

try_files

$uri/index.html $uri @book_memo_api;

左から順に

  1. urlのhtmlファイルがあるか
  2. urlのファイルがあるか
  3. それらが無かった場合、指定したロケーションに移動する

Nginxのtry_filesディレクティブ設定例 - Qiita

location ここに個別のアクセス先を定義する事が出来る。 今回socketで接続しているpumaサーバを定義。

error_page

エラーステータスに応じたページを表示します。

今回そんなhtmlファイルは用意してないが一応記載。

client_max_body_size

クライアントから送られてくるボディのマックス値です。これ以上のサイズが送られてくると413(Request Entity Too Large)エラーが発生します。

その他今回調べたけど記載はしなかった設定。一応残しておく

log_format main

  • ログのフォーマットを指定出来る。ログのフォーマットとかあるの?って感じだったけど、以下の様に便利なフォーマットが存在するらしい。

LTSV FAQ - LTSV って何? どういうところが良いの? - naoyaのはてなダイアリー

keepalive_requests

  • keepalive_timeoutが有効な時に、1つのクライアントから受け付ける最大のリクエスト数。デフォルト2048。

multi_accept

  • 複数の接続を全て1度に受け入れる。

Nginxの再起動

設定が完了したので、Nginxを再起動します。 再起動してみたところ

nginx: [emerg] getpwnam("nginx") failed in /etc/nginx/nginx.conf:

というエラーが発生。。。

CentOS7.1でnginxを用いたウェブサーバの構築 - Qiita

↑の記事を参考にnginxというユーザ・グループを作成してみることに。

$ sudo groupadd hoge
$ sudo useradd -g hoge hoge
  • そもそもユーザ・グループとは

全体像がすぐにわかる!Linuxグループの設定方法まとめ

  • 主に権限をまとめて管理するために使われる仕組み
  • ユーザ一人一人は必ずどこかのグループに所属しなければならない
  • メイングループ:一人のユーザがメインで所属しているグループ
  • サブグループ:メイン以外で登録しているグループ。複数登録可能。
  • Linuxに登録されているグループの一覧は/etc/groupに記録されている。

結論、ユーザrootで良かったのでは・・・

Nginx自動起動の設定

systemctl status nginx.service
  • まず現在のステータスを確認。Activeの箇所がdisabledだった場合以下のコマンドでactiveに。
sudo systemctl enable nginx.service
  • 再度確認コマンドで以下の様になっていればOK。
Active: active (running) since Wed 2020-07-08 11:04:53 JST; 14min ago

ていうかNginxって何のためにあるの?

ふと思った。 巷にある記事には、静的ファイルはwebサーバで処理して、それ以外をアプリケーションサーバに投げる役割とあるが、今回デプロイするアプリケーションはRailsでしかもAPIモードで動作している。。。 だったらほとんどのリクエストはpumaで処理されるじゃん!!せっかく立てたんだから、Webサーバ立てた感を味わいたいッッッ! という事で今回のWebサーバで静的ファイルを表示させて、Webサーバ立てた感を味わおうと思います。手順は以下の2ステップです。

  1. nginxのrootで指定したパスに適当なpdfファイルを配置
  2. そこに直接アクセスした際にpumaが動いてない事を確認

nginxのroot配下に適当なファイルを配置

  1. 今回nginxで指定したパスは/var/www/book_memo_api/current/public
  2. ここにネットで拾ってきた表示用のsample.pdfを置く
  3. デプロイする

そこに直接アクセスした際にpumaが動いてない事を確認

  1. 今回のWebサーバのURLは https://api.book-memo.work
  2. そこに今回のhttps://api.book-memo.work/sample.pdfをURLに加える
  3. 表示される!! f:id:hatehate-nazenaze:20200708104021p:plain
  4. アクセスした時のログを確認する

以下のコマンドを打っておいて、再度pdfにアクセス。

pumaのログ

tail -f /var/www/book_memo_api/current/log/production.log

nginxのログ

tail -f /var/log/nginx/access.log

・・・

見事puma側のログは表示されず、nginx側のログのみ表示!! つまりこのpdfファイルはnginxから返されたファイルということになる。

120.51.45.0 - - [08/Jul/2020:10:46:31 +0900] "GET /sample.pdf HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"

Webサーバ立てた感!!!!