# Nginx (日本語)

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

## インストール

オフィシャルレポジトリから 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 が組み込まれており多くの外部ツールが動きます、例えば Perl、PHP、Python など。これらを使うためにはまず 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

- http://php-fpm.org

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.conf` か `fastcgi_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.

## 参照

- Init script for Nginx
- Nginx Official Site
- Nginx HowTo
- Easy Config Files

Category:

- Web Server (日本語)