RailsアプリをNginxで動かすために、Nginxをサーバーに導入する方法と最低限これだけはしておきたいという設定をまとめます。
- ローカル環境:macOS Catalina
- サーバー環境:CentOS 7.7
Nginxインストール
ターミナルで以下のコマンドを実行し、サーバーにSSH接続します。
SSH接続の設定は事前に行っておいてください。
SSH接続の設定は事前に行っておいてください。
$ ssh server Enter passphrase for key '/Users/user/.ssh/server/id_rsa':
サーバーのユーザーディレクトリ直下にインストールします。
$ cd ~ $ sudo yum install nginx [sudo] user のパスワード: ...
バージョンが表示されればインストール完了です。
$ nginx -v nginx version: nginx/1.16.1
自動起動設定
サーバーの起動時にNginxを自動起動するように設定します。
$ chkconfig nginx on 情報:'systemctl enable nginx.service'へ転送しています。 ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-unit-files === Authentication is required to manage system service or unit files. Authenticating as: root Password: ==== AUTHENTICATION COMPLETE === ==== AUTHENTICATING FOR org.freedesktop.systemd1.reload-daemon === Authentication is required to reload the systemd state. Authenticating as: root Password: ==== AUTHENTICATION COMPLETE ===
OSの設定によっては一部の文章が赤文字でびっくりしますが、2回パスワードを入力して設定完了です。
SSL証明書作成
Let's Encryptを使って無料のSSL証明書を作成します。
まず、Let's Encryptのクライアントである「cerbot」をインストールします。
まず、Let's Encryptのクライアントである「cerbot」をインストールします。
$ cd ~ $ git clone https://github.com/certbot/certbot
ヘルプが表示されればインストール完了です。
$ cd certbot $ ./certbot-auto --help Usage: certbot-auto [OPTIONS] A self-updating wrapper script for the Certbot ACME client. When run, updates to both this script and certbot will be downloaded and installed. After ensuring you have the latest versions installed, certbot will be invoked with all arguments you have provided. Help for certbot itself cannot be provided until it is installed. --debug attempt experimental installation -h, --help print this help -n, --non-interactive, --noninteractive run without asking for user input --no-self-upgrade do not download updates --os-packages-only install OS dependencies and exit -v, --verbose provide more output
SSL証明書を作成する前に、Nginxを起動している場合は事前に停止させておきます。
スタンドアローンモードのLet's Encryptは自前のHTTPサーバーを起動して証明書の取得を行おうとするのですが、既にNginxを起動していてTCP/80が使用中だとLet's EncryptのHTTPサーバーが起動(TCP/80のバインド)ができないというエラーが出てしまいます。
Nginxを停止するには以下のコマンドを実行します。
スタンドアローンモードのLet's Encryptは自前のHTTPサーバーを起動して証明書の取得を行おうとするのですが、既にNginxを起動していてTCP/80が使用中だとLet's EncryptのHTTPサーバーが起動(TCP/80のバインド)ができないというエラーが出てしまいます。
Nginxを停止するには以下のコマンドを実行します。
# service nginx stop
ようやくSSL証明書を作成します。以下のコマンドを実行します。
$ ./certbot-auto certonly --standalone -t Requesting to rerun ./certbot-auto with root privileges... [sudo] user のパスワード:
certbot-autoコマンドの初回実行時は不足パッケージのインストールが始まります。
不足パッケージのインストールが完了したらメールアドレスを聞かれます。確認メールがくるわけではありませんが、すぐに確認できるメールアドレスを入力しましょう。
不足パッケージのインストールが完了したらメールアドレスを聞かれます。確認メールがくるわけではありませんが、すぐに確認できるメールアドレスを入力しましょう。
Creating virtual environment... Installing Python packages... Installation succeeded. Enter email address (used for urgent notices and lost key recovery) (Enter 'c' to cancel): user@example.com
次にライセンスに同意するか聞かれるので同意しましょう。
------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree in order to register with the ACME server at https://acme-v01.api.letsencrypt.org/directory ------------------------------------------------------------------------------- (A)gree/(C)ancel: A
次にSSL証明書を作成するドメイン名を聞かれます。
ドメイン名は名前解決できる必要があるので、DNSに登録していない場合は事前に登録しておきましょう。
また、ここで入力するドメイン名は「サブドメインあり/なし」が区別されます。例えば「www.example.com」で作成したSSL証明書は「example.com」では使えないので注意しましょう。
ドメイン名は名前解決できる必要があるので、DNSに登録していない場合は事前に登録しておきましょう。
また、ここで入力するドメイン名は「サブドメインあり/なし」が区別されます。例えば「www.example.com」で作成したSSL証明書は「example.com」では使えないので注意しましょう。
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel):www.example.com
以下のメッセージが表示されたら完了です。
登録したメールアドレスに完了メールが届いているかと思います。
登録したメールアドレスに完了メールが届いているかと思います。
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/www.hogehoge.com/fullchain.pem. Your cert will expire on 2016-11-11. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" - If you lose your account credentials, you can recover through e-mails sent to user@example.com. - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
最後に、SSL証明書を自動で更新する設定をしておきます。
管理者ユーザーのcronに設定します。
管理者ユーザーのcronに設定します。
$ su - パスワード: # crontab -e 0 0 1 * * /home/user/certbot/certbot-auto certonly --webroot -w /var/www/app -d www.example.com --agree-tos --force-renewal -n && nginx -s reload
設定ファイル
ここでいう設定ファイルとは、Railsアプリ固有の設定ファイルになります。
Nginx本体の設定ファイル(/etc/nginx/nginx.conf)から固有の設定ファイルが読み込まれるという仕組みになっています。
Nginx本体の設定ファイル(/etc/nginx/nginx.conf)から固有の設定ファイルが読み込まれるという仕組みになっています。
$ cat /etc/nginx/nginx.conf ... # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; ...
設定ファイルを作成する前に管理者ユーザーに変更しておきます。基本的にNginxに関する操作をするときは管理者ユーザーで行います。
$ su - パスワード:
以下のコマンドを実行して設定ファイルを作成します。
ファイル名は拡張子が「.conf」であれば何でもいいです。
ファイル名は拡張子が「.conf」であれば何でもいいです。
# cd /etc/nginx/conf.d # touch app.conf # ls -l total 4 -rw-r--r-- 1 root root 1391 Dec 4 17:00 app.conf
設定ファイルの全文は以下の通りです。
ディレクトリ名などを変更すればそのままコピペ可能です。
ディレクトリ名などを変更すればそのままコピペ可能です。
error_log /var/www/app/current/log/nginx.error.log; access_log /var/www/app/current/log/nginx.access.log; client_max_body_size 2G; upstream app_server { server unix:/var/www/app/current/tmp/sockets/.unicorn.sock fail_timeout=0; } server { listen 80; server_name www.example.com; return 301 https://$host$request_uri; } server { listen 80; listen 443; server_name example.com; return 301 https://www.$host$request_uri; } server { listen 443 ssl default_server; ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; server_name www.example.com; keepalive_timeout 5; root /var/www/app/current/public; try_files $uri/index.html $uri.html $uri @app; location @app { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; location = /500.html { root /var/www/app/current/public; } location = /robots.txt { alias /var/www/app/current/public/robots.txt; } }
「HTTP (TCP/80) かつ サブドメインあり」「HTTP (TCP/80) かつ サブドメインなし」「HTTPS (TCP/443) かつ サブドメインなし」でアクセスされた場合、「HTTPS (TCP/443) かつ サブドメインあり」にリダイレクトする設定をしています。
具体的には以下のとおりです。
具体的には以下のとおりです。
- http://example.com/
- http://www.example.com/
- https://example.com/
↓
- https://www.example.com/
また、Let's Encryptを使って作成したSSL証明書を指定しています。これを設定しないとアクセスした際に警告が表示されるようになってしまいます。
ポート確認
HTTP (TCP/80)とHTTPS (TCP/443)が開放されているか確認します。
確認にはnmapを使うのでインストールしましょう。
確認にはnmapを使うのでインストールしましょう。
$ sudo yum install nmap [sudo] user のパスワード: ... ================================================================================================================================================================================== Package アーキテクチャー バージョン リポジトリー 容量 ================================================================================================================================================================================== インストール中: nmap x86_64 2:6.40-19.el7 base 3.9 M 依存性関連でのインストールをします: nmap-ncat x86_64 2:6.40-19.el7 base 206 k トランザクションの要約 ================================================================================================================================================================================== インストール 1 パッケージ (+1 個の依存関係のパッケージ) 総ダウンロード容量: 4.2 M インストール容量: 17 M Is this ok [y/d/N]: y ... インストール: nmap.x86_64 2:6.40-19.el7 依存性関連をインストールしました: nmap-ncat.x86_64 2:6.40-19.el7 完了しました!
インストールが完了したら以下のコマンドを実行します。
$ nmap xxx.xxx.xxx.xxx Starting Nmap 6.40 ( http://nmap.org ) at 2019-12-05 09:57 JST Nmap scan report for vxxx-xxx-xxx-xxx.a091.g.tyo1.static.cnode.io (xxx.xxx.xxx.xxx) Host is up (0.00026s latency). Not shown: 996 closed ports PORT STATE SERVICE 80/tcp open http 111/tcp open rpcbind 443/tcp open https 3306/tcp open mysql Nmap done: 1 IP address (1 host up) scanned in 0.05 seconds
HTTP (TCP/80)とHTTPS (TCP/443)のポートが開放されていることが確認できました。
Nginx起動
さて、いよいよNginxを起動します。
しかしその前に、念のためNginxの設定ファイルが間違っていないかを確認しておきます。設定ファイルが間違っていなければ以下のように表示されます。
しかしその前に、念のためNginxの設定ファイルが間違っていないかを確認しておきます。設定ファイルが間違っていなければ以下のように表示されます。
# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
設定ファイルが間違っている場合、以下のように表示されます。
例は9行目の「server_name:」が間違っている場合です。正しくは「server_name」(コロンは不要)。
例は9行目の「server_name:」が間違っている場合です。正しくは「server_name」(コロンは不要)。
# nginx -t nginx: [emerg] unknown directive "server_name:" in /etc/nginx/conf.d/app.conf:9 nginx: configuration file /etc/nginx/nginx.conf test failed
Nginxを起動するには以下のコマンドを実行します。
# service nginx start
正常に起動できたか状態が確認したいときは以下のコマンドを実行します。
# service nginx status Redirecting to /bin/systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2019-12-02 22:54:13 JST; 37min ago Process: 12067 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS) Process: 12437 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 12434 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 12433 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 12439 (nginx) CGroup: /system.slice/nginx.service ├─12439 nginx: master process /usr/sbin/nginx └─12440 nginx: worker process Dec 02 22:54:13 150-95-152-189 systemd[1]: Starting The nginx HTTP and reverse proxy server... Dec 02 22:54:13 150-95-152-189 nginx[12434]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Dec 02 22:54:13 150-95-152-189 nginx[12434]: nginx: configuration file /etc/nginx/nginx.conf test is successful Dec 02 22:54:13 150-95-152-189 systemd[1]: Failed to parse PID from file /run/nginx.pid: Invalid argument Dec 02 22:54:13 150-95-152-189 systemd[1]: Started The nginx HTTP and reverse proxy server.
Railsアプリの設定
config/environments/production.rbの設定を以下の通り変更します。
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true
コメントアウトを外して強制SSL化設定を有効にします。なければ普通に追加すればいいと思います。
まとめ
いかがでしたでしょうか。
初めからすべてを設定しようとすると手順が多くなってしまって大変かと思います。SSL証明書の導入などは後回しにしてしまってもいいかもしれません。
間違いなどありましたらご指摘いただけると助かります。
初めからすべてを設定しようとすると手順が多くなってしまって大変かと思います。SSL証明書の導入などは後回しにしてしまってもいいかもしれません。
間違いなどありましたらご指摘いただけると助かります。
おまけ:よく使うNginxのコマンド
Nginxの停止・起動・再起動。
# service nginx stop # service nginx start # service nginx reload
Nginxの状態確認。
# service nginx status Redirecting to /bin/systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2019-12-02 22:54:13 JST; 37min ago Process: 12067 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS) Process: 12437 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 12434 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 12433 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 12439 (nginx) CGroup: /system.slice/nginx.service ├─12439 nginx: master process /usr/sbin/nginx └─12440 nginx: worker process Dec 02 22:54:13 150-95-152-189 systemd[1]: Starting The nginx HTTP and reverse proxy server... Dec 02 22:54:13 150-95-152-189 nginx[12434]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Dec 02 22:54:13 150-95-152-189 nginx[12434]: nginx: configuration file /etc/nginx/nginx.conf test is successful Dec 02 22:54:13 150-95-152-189 systemd[1]: Failed to parse PID from file /run/nginx.pid: Invalid argument Dec 02 22:54:13 150-95-152-189 systemd[1]: Started The nginx HTTP and reverse proxy server.
Nginxの設定ファイルがあっているか確認。
# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful