Edited at

apacheからhttp2でsslなnginxにした話

More than 3 years have passed since last update.


経緯

大学に入って、奇跡的な出会いに恵まれてとても良いバイトに就けて、お金に余裕ができた

→VPSを一つ上のコースに変えよう

→なら、一緒にapacheから「ナウいヤングにバカ受けなnginx」というのに変えよう!

→労働って素晴らしい!


環境

CentOS7.2.1511

apache(バージョン不明) → nginx1.11.1

mod_php5.6x → php-fpm7.0.8

ruby/cgi → spawn-fcgi/fcgi-wrap/ruby2.0.0


まずはapacheからnginxへ

まず、nginx公式のリポジトリを入れる

viかnano等で/etc/yum.repos.d/nginx.repoというファイルを作ります


/etc/yum.repos.d/nginx.repo

[nginx]

name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

ここを見るとわかりやすいです

というか、丸パクリです

あとは、普通に

$ sudo yum install nginx

で大丈夫です


nginxの設定

設定ファイルはすべて/etc/nginx/下にあります

/etc/nginx/nginx.confの設定ですが、コメントアウトされている部分が多くて見にくいです...

自分は「関係なさそうだなぁ」と思うところ(プロキシ設定とか)は全部消しました

とりあえず、上の方の


/etc/nginx/nginx.conf

user  nginx nginx;       #default=nginx

worker_processes auto; #default=1

ってところをいじりました

worker_processesはCPUのコア数に合わせるのがいい(要出典)なので、適当に

自分はよくわからないので、とりあえずautoにしておきました


php-fpmをインストール

ここが参考になりました

$ sudo yum install epel-release

epelのリポジトリを入れて、

yum install --enablerepo=remi,remi-php70 php-fpm php php-devel php-mbstring php-pdo php-gd

これで必要なものはだいたい入ります

ですが、phpがphp70というコマンド名でインストールされてます

個人的に、PHPは一斉にファイルを操作したりするときに頻繁に使うので、不便

なので、

$ which php70

/usr/bin/php70 #←ここは環境によって変わる...?
$ sudo mv /usr/bin/php70 /usr/bin/php

こんな感じで名前を変えました

そして、php-fpmの設定

php-fpmは/etc/php-fpm.confがメインの設定ファイル

/etc/php-fpm.dにサブの設定ファイルがあります

(正確にはメインとサブではなく、php-fpm.confの中でphp-fpm.d以下のconfファイルをincludeしてます)

で、おそらく/etc/php-fpm.d/www.confというファイルがあると思います(環境によって変わる...?)

www.confで変更した点は、


/etc/php-fpm.d/www.conf(順不同/適宜文字列検索等で探してください)

user = nginx             # default = apache

group = nginx # default = apache(?:忘れた)
listen = 127.0.0.1:9000 # defaultから変更なし(任意で変更)
pm = static # dafault = dynamic(後述)
pm.max_children = 30 # default = 忘れた(後述)

とりあえずこのあたりです

userとgroupはドキュメントルートをどこに置くか等で変わってくるので、いい感じに

listenも他のfcgiと被らないようにいい感じに

pmはphp-fpmのプロセスをどうするかで、staticは一定、dynamicは変動します

個人的に、動的だと(ないと思いますが)一気にアクセスが来た時にプロセスのフォークでやや負荷がかかるので、最初から一定にしています

pm.max_childernは最大のプロセス数です

staticなら、ここを弄ればプロセス数が変わります

dynamicはよくわからないので調べてください

追記:php-fpmはTCPよりもUNIXドメインを使ったほうが早くなるそうです

inductorさんありがとうございます

次に、nginx側の設定で

location ~ \.php$ {

root /home/kiridaruma/html/top/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

こんな感じで設定しました

fastcgi_paramの設定がデフォルトのままだとうまく動作しないみたいです

nginxのconfファイルは変数が使えるみたいなので、それを使っていい感じに

あとはfastcgi_passをphp-fpmで設定したのに合わせて設定しました

最後に、php-fpmを実行します

$ sudo systemctl start php-fpm

$ sudo systemctl enable php-fpm #起動時に自動で実行されるように設定


spawn-fcgi/fcgiwrap/rubyの設定

これが一番面倒でした

ほとんど情報が落ちてなかったです

なぜruby/cgiが必要かというと、どどんとふというTRPGオンラインセッションツールを動かしているからです

どどんとふ

あと、Onset!という自作のTRPG向けチャットも動かしてまして、これは内部でどどんとふのダイスシステムを内蔵しているので、こっちもruby/cgiが必要でした

Onset!

はい、ステマですね

探してもあまり情報が出てこなかったので、fcgiをcgiのように呼び出せるfcgiwrapというのを使いました

インストール方法は覚えてないです、すいません

で、fcgiwrapをインストールしたら、spawn-fcgiのインストール/設定を行います

$ sudo yum install spawn-fcgi

さて、spawn-fcgiの設定ファイルですが、これも探すのに手間取りました

どうやら、/etc/sysconfig/spawn-fcgiが設定ファイル(?)みたいです

なぜ(?)がつくかというと、

OPTIONS="-u nginx -g nginx -a 127.0.0.1 -p 9001 -F 30  -P /var/run/spawn-fcgi.pid -- /usr/local/sbin/fcgiwrap"

これしか設定がないからです

とりあえず、

-uはプロセスのユーザー

-gはプロセスのグループ

-aはtcp接続のアドレス(UNIXドメインは-sで指定)

-pはポート

-Fは起動するプロセス数

-Pはよくわかりません、デフォルトで入ってた(と思う)ので、まぁ入れておいたほうがいいかな?という感じです

そして、最後に立ち上げるプログラムを指定

fcgiwrapを指定します

ここで重要なのが、フルパスで指定しないといけません

何故なのかは知りません、何故か動きません

また、php-fpmの時と同じようにnginx側の設定を合わせておきます

最後に、起動しておきましょう

$ sudo systemctl start spawn-fcgi

$ sudo systemctl enable spawn-fcgi #起動時に自動で実行されるように設定

ここまで来ると、とりあえず普通のhttpサーバとしての機能は一応十分です

$ sudo systemctl start nginx

をして、phpinfo()とかを使って動作確認


さらにsslでhttp2なイケてるサーバに

まず、sslの設定

ssl証明書はlet's encryptを使いました

Let's Encrypt

まず、gitでlet's encryptをクローン

そしてアップデートとヘルプの確認を行います

$ git clone https://github.com/letsencrypt/letsencrypt

$ cd letsencrypt
$ ./letsencrypt-auto --help

アップデートの際に管理者権限を求められることがあります

無事ヘルプが表示されたら、早速証明書を発行してもらいます

解説サイト等では./letsencrypt-autoによくわからない、長いオプションを付けて実行していますが、面倒なので

$ sudo ./letsencrypt-auto certonly

だけで実行します

しばらくするとTUIな画面が出てきます

1  Apache Web Server - Alpha (apache)

2 Place files in webroot directory (webroot)
3 Automatically use a temporary webserver (standalone)

というふうに表示されると思います

今回は2を選択しました

次に「ドメインを入力しろ(意訳)」と出るので、ssl証明書を発行したいドメインを入力

入力すると、次は「そのドメインのドキュメントルートを選択しろ(意訳)」と出るので、ドキュメントルートを選択

選択すると確認作業が始まって、無事にドメインの確認ができるとssl証明書を発行してもらえます

ssl証明書は/etc/letsencrypt/live/(ドメイン名)/以下に保存されています

ので、nginx側の設定をいじってssl証明書を指定してやります

server {

listen 443 ssl;
server_name kiridaruma.net;

ssl_certificate /etc/letsencrypt/live/kiridaruma.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kiridaruma.net/privkey.pem;
#以下省略...
}

ssl_certificateにfullchain.pemというファイルを指定

ssl_sertificate_keyにprivkey.pemというファイルを指定します

そして、listenを443にしてsslを追加

最後に、/etc/letsencrypt/live/(ドメイン名)/以下のファイルのパーミッションを600に、かつ、nginxがアクセスできるようにファイルの所有者を変更して、ssl化は完了です

これだけでも、このwebサイトでA-の評価をとれました

そして、http2化

実はこれはとても簡単で、

server {

listen 443 ssl http2
#以下省略...
}

とするだけで対応できます

nginxすごいめう!

あと、「httpsのみにして、httpは全部httpsにリダイレクトさせたい...」という方は

server {

listen 80;
return 301 https://$host$request_uri;
}

とするといい感じになります


まとめ

nginxはPHPやCGIの設定が少し面倒だけど、それさえできれば簡単にssl化できるし、ver1.9.5以降ならhttp2と一言入れるだけでhttp/2なhttpサーバが構築できる!

しかもapacheよりも性能良い場面が多いし、これからはnginx特に理由なければnginxで行こうと思いました。