nginx & fcgiwrap
雖然很久以前就想換到 nginx 試試看,不過直到最近這次更新才換成功,最早單純只是想要輕量一點的 HTTP server,後來則是因為和 Apache 相比,nginx 明顯開發更新比較快,最近有很多想要嘗試各種新功能都是 nginx 先做,像是 HTTP/2,還有最近這次的 brotli 支援,而以前沒辦法換過去的最主要原因,其實是 nginx 沒有 CGI 的支援,跑 MovableType 會有困難,雖然 MovableType 可以用 FastCGI,不過很難設定,我安裝過 n 次大概也只有成功過一兩次,所以其實一直都不太考慮這個選項。
不過認真研究了一下,終於發現其實可以透過 FCGI Wrap 這個工具來達成 nginx 對 CGI script 的支援,它的作法其實就是一個中間人,把 FCGI 介面轉到 CGI 介面過去,我大概設定了一下跑 MovableType 的 nginx conf 如下:
location ~ ^/path/to/mt/mt.*\.cgi {
gzip off;
fastcgi_index index.cgi;
fastcgi_split_path_info ^(.+?\.cgi)(/.*)$;
if (!-e $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi.conf;
## MT-related
fastcgi_param PERL5LIB $document_root/mt/lib;
fastcgi_param MT_HOME $document_root/mt/;
fastcgi_param MT_CONFIG $document_root/mt/mt-config.cgi;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $fastcgi_path_info;
fastcgi_pass unix:/var/run/fcgiwrap.sock;
}
然後主機上要開好 FCGI Wrap 的服務,我是用 ArchLinux 的 pacman 直接裝套件,然後參考官方文件,有寫說設定檔位置/usr/lib/systemd/system/fcgiwrap.socket
,cat 出來就可以看到 UNIX Socket 檔案位置ListenStream=/run/fcgiwrap.sock
,這個路徑的位置其實就指到上面設定最後一行的/var/run/fcgiwrap.sock
,/run
和/var/run
兩邊其實有 Symbolic Link 起來,所以兩個 sock 檔案其實是同一個。
最後要說一下 conf 裡的這行:
include fastcgi.conf;
這個fastcgi.conf
檔案其實是 nginx 內建好方便大家使用的,內容如下:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
可以看到其實這個檔案就是把直接走 FCGI 時會遺失的環境變數補回去用的,nginx 還提供很多這類檔案,以前都不太清楚怎麼剛裝好的 nginx 會附上一堆沒有用到的 conf 檔,直到這次才瞭解它們其實都很有用啊。