Ubuntu 18.04 に nginx + fcgiwrap + php-fpm で CGI 環境を構築する
以前、CentOS 系の Linux で CGI on nginx をやったが、今回はそれの Ubuntu 版。
前提条件
- Ubuntu 18.04
- nginx はインストール済 (
apt install -y nginx
程度) - root ユーザで作業
$ nginx -v
nginx version: nginx/1.14.0 (Ubuntu)
CGI として動かす言語をインストールする
まずは CGI として動かしたい言語をインストールしていく。今回はバージョン管理など省略して、さっさと入れていく。
# Perl : 最初から入っていたので無視
$ perl -v
This is perl 5, version 32, subversion 0 (v5.32.0) built for x86_64-linux-thread-multi
# Ruby
$ apt install -y ruby
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
# Python
$ apt install -y python3.7 python3.7-dev python3-pip
$ python -V
Python 3.7.5
# Node.js
$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
$ apt install -y nodejs
$ node -v
v14.8.0
$ npm -v
6.14.7
# PHP
$ apt install -y php
$ php -v
PHP 7.2.24-0ubuntu0.18.04.6 (cli) (built: May 26 2020 13:09:11) ( NTS )
fcgiwrap を入れていく
$ apt install -y fcgiwrap spawn-fcgi libfcgi-dev php-fpm
- 参考 : ruby - Rails error while installing fcgi: Failed to build gem native extension - Stack Overflow
- CentOS (Yum) では fcgi-devel だったが、Ubuntu (apt) では代わりに libfcgi-dev を入れる
ところで nginx の実行ユーザは…
CentOS 系だと nginx
というユーザで nginx が動いていたが、Ubuntu だと www-data
というユーザおよびグループで動いていた。
$ ps aux | grep nginx
root 852 0.0 0.0 33184 884 ? Ss Aug22 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 856 0.0 0.3 38208 3400 ? S Aug22 0:00 nginx: worker process
/etc/nginx/nginx.conf
などにも user www-data;
と書かれているので、ココだけ留意。
fcgiwrap を設定する
fcgiwrap の設定を行う。
$ vi /etc/init.d/fcgiwrap
次のように修正する。
# デフォルトでは "1" なので増やす (プロセス数)
FCGI_CHILDREN="6"
そしたら fcgiwrap を再起動する。
# 以下のような行をコメントアウトする?
FCGI_SOCKET="/var/run/$NAME.socket"
# 以下の2行を付け足す?
FCGI_PORT="8999"
FCGI_ADDR="127.0.0.1"
↑ こんなことが書いてある文献もあったのだが、自分は上手くいかなかった。9000番あたりのポートでリスンして処理するやり方は上手く動かなくて、Socket を使うやり方なら上手く行った。
# 多分以下のどちらでも動く
$ /etc/init.d/fcgiwrap restart
$ systemctl restart fcgiwrap
$ systemctl status fcgiwrap
Socket を確認する
この後の nginx 設定で使用するので、fcgiwrap.socket
と php-fpm.socket
の存在を確認する。
$ ls -l /var/run/*.socket
srw-rw-rw- 1 root root 0 2020-08-19 10:18 /var/run/acpid.socket=
srw-rw-rw- 1 root root 0 2020-08-25 10:57 /var/run/fcgiwrap.socket=
srw-rw-rw- 1 root root 0 2020-08-20 06:09 /var/run/snapd-snap.socket=
srw-rw-rw- 1 root root 0 2020-08-20 06:09 /var/run/snapd.socket=
$ ls -l /var/run/php/php7.2-fpm.sock
srw-rw---- 1 www-data www-data 0 2020-08-25 14:40 /var/run/php/php7.2-fpm.sock=
コレを把握しておく。
nginx 設定を変更する
nginx.conf
と conf.d/default.conf
を作って修正していく。全量貼り付けておく。
/etc/nginx/nginx.conf
# user が CentOS 系の nginx ではないことに留意
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
# HTTPS 対応している場合は以下のように書く
#listen 443 ssl;
#ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
root /var/www/html;
index index.html index.cgi index.pl index.rb index.php;
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}
# Enable 'Index Of'
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# For CGI : Perl Ruby
location ~ \.(pl|rb|cgi)$ {
try_files $uri /404.html;
root /var/www/html;
# 以下が CentOS 系では 127.0.0.1:9001 などと設定したが、Socket を使う
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
# For PHP
location ~ \.php$ {
try_files $uri /404.html;
root /var/www/html;
# 以下が CentOS 系では 127.0.0.1:9000 などと設定したが、Socket を使う
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
CentOS 版と違うのは fastcgi_pass
部分。ホスト名とポート番号を指定していたのと比べて、今回は Socket 指定で行っている。
設定できたら構文チェックをして、nginx を再起動する。
$ nginx -t
$ systemctl restart nginx
テストファイルを作成する
それぞれの言語でちゃんと CGI が動作するか、確認用のファイルを作る。
$ cat << EOL > /var/www/html/example.pl
#!/usr/bin/perl
print "Content-Type: text/plain\n\n";
$my_var = 'Perl';
print "Hello World from $my_var .";
EOL
$ cat << EOL > /var/www/html/example.py
#!/usr/bin/python3
print('Content-Type: text/plain\n\n')
my_var = 'Python'
print('Hello World from ' + my_var)
EOL
$ cat << EOL > /var/www/html/example.rb
#!/usr/bin/ruby
print("Content-Type: text/plain\n\n")
my_var = 'Ruby'
print("Hello World from #{my_var} .")
EOL
# 拡張子 .cgi は Node.js を動かすことにする
$ cat << EOL > /var/www/html/example.cgi
#!/usr/bin/node
console.log('Content-Type: text/plain\n\n');
const myVar = 'Node.js';
print(`Hello World from ${myVar}`);
EOL
$ cat << EOL > /var/www/html/example.php
<?php phpinfo(); ?>
EOL
$ chmod 755 /var/www/html/example.pl
$ chmod 755 /var/www/html/example.py
$ chmod 755 /var/www/html/example.rb
$ chmod 755 /var/www/html/example.cgi
# PHP は実行権限不要
コレで
http://【サーバ URL】/example.pl
などにアクセスできれば nginx で CGI や PHP が動かせている。