Nginx (日本語)

From ArchWiki
Jump to: navigation, search

Nginx ("エンジンエックス"と発音します)は2005年から Igor Sysoev(ロシア)によって開発されている、フリーでオープンソースかつハイパフォーマンスな HTTP サーバーかつリバースプロクシで、IMAP/POP3 プロクシサーバーとしても機能します。Netcraft の March 2013 Web Server Survey によると、世界中の全てのドメインのうち 13.53% は Nginx によってホストされています。一方、Apache は54.68%をホストしています。Nginx は主に、その安定性・多機能・単純な設定・低リソース消費によって知られています。

Contents

インストール

オフィシャルレポジトリから nginx パッケージをインストールできます。

Ruby on Rails のためにインストールするには、The Perfect Rails Setup を参照してください。

サービスの開始

Nginx サービスを走らせるには:

# systemctl start nginx

スタートアップ時に Nginx サービスを起動するには:

# systemctl enable nginx

http://127.0.0.1 にデフォルトで表示されるページは:

/usr/share/nginx/html/index.html

設定

/etc/nginx/ にあるファイルを編集することで Nginx の設定ができます。メインの設定ファイルは /etc/nginx/nginx.conf です。

より詳しい解説はこちら: Nginx Configuration Examples.

FastCGI

FastCGI、または FCGI はウェブサーバーでインタラクティブなプログラムを動作させるためのプロトコルです。FastCGI は Common Gateway Interface(CGI) の変種で、ウェブサーバーと CGI プログラムのオーバーヘッドを減らすよう設計されていて、サーバーはより多くのウェブページのリクエストを一度に捌くことができます。

Nginx には FastCGI が組み込まれており多くの外部ツールが動きます、例えば PerlPHPPython など。これらを使うためにはまず FastCGI サーバーを動かす必要があります。

PHP を動かす

PHP のために FastCGI サーバーを動かす方法は複数あります。ここでは推奨方法として php-fpm を使う方法を記載しています。

Step 1: PHP の設定

/etc/php/php.ini の中にある open_basedir に PHP ファイルが含まれているベースディレクトリを (/srv/http//usr/share/webapps/ のような感じで)指定しなくてはなりません:

open_basedir = /usr/share/webapps/:/srv/http/:/home/:/tmp/:/usr/share/pear/
Step 2: php-fpm

php-fpm をインストールします:

# pacman -S php-fpm

設定ファイルは /etc/php/php-fpm.conf です。

サービスを動かします:

# systemctl start php-fpm

php-fpm をスタートアップ時に有効にします:

# systemctl enable php-fpm.service
Step 3: Nginx の設定

それぞれの server ブロックの中の location ブロックに PHP アプリケーションを次のように記述します:

 location ~ \.php$ {
      fastcgi_pass   unix:/run/php-fpm/php-fpm.sock;
      fastcgi_index  index.php;
      include        fastcgi.conf;
 }

/etc/nginx/php.conf を作って設定をそこに書く場合、このファイルを server ブロックに入れて下さい。

 server = {
     ...
     include  php.conf;
     ...
 }

.html や .htm ファイルを PHP として処理したい場合は、以下のようにしてください:

 location ~ \.(php|html|htm)$ {
      fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_index  index.php;
      include        fastcgi.conf;
 }

拡張子が .php でないファイルを php-fpm で動かすことを /etc/php/php-fpm.conf で有効にする必要があります:

 security.limit_extensions = .php .html .htm

設定を変えた後は php-fpm デーモンを再起動してください。

# systemctl restart php-fpm

fastcgi_pass 引数に注意を払って下さい、FastCGI サーバーの設定ファイルで定義された TCP や Unix ソケットでなくてはなりません。デフォルトの php-fpm (Unix) ソケットは

fastcgi_pass unix:/run/php-fpm/php-fpm.sock;

デフォルトの代わりに、通常の TCP ソケットを使うこともできます

fastcgi_pass 127.0.0.1:9000;

ただし Unix ドメインソケットの方が高速です。

Nginx のための FastCGI 設定がある fastcgi.conffastcgi_params が含まれていますが、後者は使われなくなりました。これらのファイルは Nginx をインストールしたときに作られます。

最後に、Nginx が動作している場合は再起動してください:

# systemctl restart nginx

FastCGI をテストしたい場合は、/usr/share/nginx/html/index.php を次の内容で作成して

<?php
  phpinfo();
?> 

ブラウザで http://127.0.0.1/index.php を開いて下さい。

CGI を動かす

This implementation is needed for CGI applications.

Step 1: fcgiwrap

Install fcgiwrap. The configuration file is /usr/lib/systemd/system/fcgiwrap.socket. Enable and start the systemd fcgiwrap.socket.

The systemd unit file is currently being discussed on this ArchLinux task page. You may want to examine the unit file yourself to ensure it will work the way you want.

Multiple worker threads

If you want to spawn multiple worker threads, it's recommended that you use multiwatch, which will take care of restarting crashed children. You will need to use spawn-fcgi to create the unix socket, as multiwatch seems unable to handle the systemd-created socket, even though fcgiwrap itself does not have any trouble if invoked directly in the unit file.

Copy the unit file from /usr/lib/systemd/system/fcgiwrap.service to /etc/systemd/system/fcgiwrap.service (and the fcgiwrap.socket unit, if present), and modify the ExecStart line to suit your needs. Here is a unit file that uses multiwatch. Make sure fcgiwrap.socket is not started or enabled, because it will conflict with this unit:

/etc/systemd/system/fcgiwrap.service
[Unit]
Description=Simple CGI Server
After=nss-user-lookup.target

[Service]
ExecStart=/usr/bin/spawn-fcgi -u http -g http -s /run/fcgiwrap.sock -n -- /usr/bin/multiwatch -f 10 -- /usr/sbin/fcgiwrap
ExecStartPost=/usr/bin/chmod 660 /run/fcgiwrap.sock
PrivateTmp=true
Restart=on-failure

[Install]
WantedBy=multi-user.target

Tweak -f 10 to change the number of children that are spawned.

Warning: The ExecStartPost line is required because of strange behaviour I'm seeing when I use the -M 660 option for spawn-fcgi. The wrong mode is set. This may be a bug?
Step 2: Nginx configuration

Inside each server block serving a CGI web application should appear a location block similar to:

 location ~ \.cgi$ {
      fastcgi_pass   unix:/run/fcgiwrap.sock;
      include        fastcgi.conf;
 }

The default (Unix) socket for fcgiwrap is /run/fcgiwrap.sock.

トラブルシューティング

ローカル IP へのアクセスが localhost にリダイレクトされます

Arch Linux フォーラムからの解決法があります。

/etc/nginx/nginx.conf を開き、"server_name localhost" の前の # を取り除き、以下を付け加えます:

server_name_in_redirect off;

デフォルトでは、nginx は設定にある server_name へのリクエストをすべてリダイレクトします。

Error: 403 (Permission error)

This is most likely a permission error. Are you sure whatever user configured in the Nginx configuration is able to read the correct files?

If the files are located within a home directory, (e.g. /home/arch/public/webapp) and you are sure the user running Nginx has the right permissions (you can temporarily chmod all the files to 777 in order to determine this), /home/arch might be chmod 750, simply chmod it to 751, and it should work.

If you have changed your document root

If you are sure that permissions are as they should be, make sure that your document root directory is not empty. Try creating index.html in there.

Error: 404 (Pathinfo error)

いくつかのフレームワーク (thinkphp、cakephp など)や CMS では pathinfo が必要です。

1. /etc/php/php.ini ファイルを開き、次のように付け加えます

cgi.fix_pathinfo=1

2. /etc/nginx/conf/nginx.conf を開き、次の部分をコメントアウトします

location ~ \.php$ {
...
}

#location ~ \.php$ {
#...
#}

そして以下を加えます

location ~ ^(.+\.php)(.*)$ {
  root   /srv/http/nginx;
  fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock; 	
  #fastcgi_pass   127.0.0.1:9000; #Un-comment this and comment "fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;" if you are not using php-fpm.
  fastcgi_index  index.php;
  set $document_root2 $document_root;
  if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") { set $document_root2 $1$2; }
  if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") {	set $document_root2 $1$2; }
  if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") {	set $document_root2 $1$2; }
  if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") {	set $document_root2 $1$2; }
  if ($document_root2 ~ "^(.*\\\\).*?[\\\\|\/]\.\.\/(.*)$") {	set $document_root2 $1$2; }
  fastcgi_split_path_info ^(.+\.php)(.*)$;
  fastcgi_param	SCRIPT_FILENAME	$document_root2$fastcgi_script_name;
  fastcgi_param	PATH_INFO	$fastcgi_path_info;
  fastcgi_param	PATH_TRANSLATED	$document_root2$fastcgi_path_info;
  include	fastcgi_params;
  fastcgi_param  DOCUMENT_ROOT      $document_root2;
}

Error: The page you are looking for is temporarily unavailable. Please try again later.

FastCGI サーバーが動作していないか、ソケットが間違ったパーミッションに設定されています。

Error: No input file specified

おそらくスクリプトのフルパスを含んだ SCRIPT_FILENAME がありません。 nginx の設定 (fastcgi_param SCRIPT_FILENAME) が完全でも、このエラーは php が requestd スクリプトをロードできないことを意味しています。これは単純にパーミッションの問題であることが普通で、root で php-cgi を実行するか

# spawn-fcgi -a 127.0.0.1 -p 9000 -f /usr/bin/php-cgi

php-cgi を起動するグループとユーザーを作成する必要があります。例えば:

# groupadd www
# useradd -g www www
# chmod +w /srv/www/nginx/html
# chown -R www:www /srv/www/nginx/html
# spawn-fcgi -a 127.0.0.1 -p 9000 -u www -g www -f /usr/bin/php-cgi

他の可能性としては、nginx.conf 内の "location ~ \.php$" セクションの "root" 引数が間違っていることがありえます。"root" が同じサーバーの "location /" と同じディレクトリを示しているか確認してください。もしくは root をグローバルに設定するには、location セクションで定義しないでください。

Also keep in mind that your php script path was defined as /srv/http by default using the variable "open_basedir" in /etc/php/php.ini; you can change them if you need.

Also notice that not only php script should have read permission, but also the entire directory structure should have execute permission so that PHP user can traverse the path.

参照