Friday, 26 June 2015

Getting PHP FastCgi Process Manager (FPM) and nginx working in cygwin

Despite the popularity of nginx and php, I was surprised that it wasn't easiy to find a working configuration for PHP-FPM (fast cgi) with a nginx server in front, running on cygwin.
Once I had the right fragments of settings, it was a case of systematically trying them all out.


pid = /var/run/

;note: i create a /var/log/php dir owned by the service user/group
;this allows the permissions to be inherited easily on the filesystem
error_log = /var/log/php/fpm-global.log

; cygwin user default is 256
rlimit_files = 1024

;pool configuration, having a pool config per site means you can easily have a separate log file
;they have to be set but the cygwin version ignores them

; The address on which to accept FastCGI requests.
listen =
; or
; listen = tmp/php-cgi.socket
; for socket unset these:

; this allows the process pool to be queried if it appears to be bogging down
pm.status_path = /status

php_admin_flag[log_errors] = on


The magic to get the pretty permalinks working is on the wordpress site.
error_reporting = -1
display_errors = On
display_startup_errors = On
log_errors = On
log_errors_max_len = 0


error_log  /var/log/nginx/error.log;
pid        /var/run/;

events {
    worker_connections  1024;

http {
    access_log off;
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # Upstream to abstract backend connection(s) for php
    upstream php {
      #server unix:/tmp/php-cgi.socket;

    include site1.conf;


server {
  listen       8000;
  server_name  localhost;
  ## This should be in your http block and if it is, it's not needed here.
  index index.php;
  root   /cygdrive/c/Projects/site1/wordpress/;
  location / {
      try_files $uri $uri/ /index.php?$args;
  rewrite /wp-admin$ $scheme://$host$uri/ permanent;
  # pass the PHP scripts to FastCGI server listening on
  location ~ [^/]\.php(/|$) {           
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
      return 404;
    # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)
    include fastcgi.conf;
    fastcgi_index index.php;
    fastcgi_pass php;
    # fastcgi_intercept_errors on;
    fastcgi_connect_timeout 40s;     

    # set the log file here so each site is different
    fastcgi_param PHP_VALUE "error_log = /var/log/php/php-site1.log";
  # pass status page request on
  location ~ ^/(status|ping)$ {
    access_log off;
    deny all;
    include fastcgi.conf;
    fastcgi_pass php;

Finally, I had some problems connecting from cygwin php to a windows native mysql. Discovered I just had to use the localhost IP to force it over TCP/IP (instead of trying to use unix sockets).


/** MySQL hostname */
define('DB_HOST', '');

Update 2015/07/02:

I've hit a few problems using cygwin and it's nearly wholly based around permissioning. I've written up a summary of my ad-hoc solution, mainly because I couldn't easily find sample setups and wasted a lot more time than one should on a popular platform.

The launch scripts themselves are a bit hacky but these are the best I've got so far. The cygrunsrv service launcher directly calls the service so you don't get a shell script (though this could easily be changed). I've found running as the "Local System" account causes too many problems relating to group access so setting up a dedicated user is the easiest.

Here are the 2 service install scripts:


No comments:

Post a Comment