Written by James McDonald

May 26, 2023

This is my setup to serve CakePHP from a virtual subdirectory on Windows 11

where http://localhost/subdir/ points to C:/dev/cake_test/webroot/

Run Terminal as Administrator then:

Install chocolatey https://chocolatey.org/install

Install MySQL, PHP and Nginx using choco

choco install mysql
choco install mysql.workbench # this one doesn't work at the moment so download and install separately
choco install php
choco install nginx

Make php-cgi a service

Download the latest stable version of WinSW https://github.com/winsw/winsw/tree/v3 (I downloaded the WinSW-x64.exe file)

Rename it and move it to the PHP dir. The name can be whatever you choose but just make the exe file and the xml file the same name e.g.

php-cgi-service.exe
php-cgi-service.xml

move WinSW-x64.exe C:\tools\php82\php-cgi-service.exe

Create a file named php-cgi-service.xml in C:\tools\php82\

<service>
  <id>php-cgi</id>
  <name>PHP Fast CGI</name>
  <description>Run PHP Fast CGI as a Service</description>
 <!-- <env name="JENKINS_HOME" value="%BASE%"/>  -->
  <executable>C:\tools\php82\php-cgi.exe</executable>
  <arguments>-b 127.0.0.1:9999</arguments>
  <log mode="roll"></log>
</service>

Install the PHP-CGI service

# php-cgi-service.exe is the renamed WinSW-x64.exe executeable
# you need a file named service.xml in the same directory 
# as above to be able to install the service
php-cgi-service.exe install

Edit the Nginx Configuration in C:\tools\nginx-1.25.0\conf\nginx.conf

Whenever you make a change restart Nginx with this powershell command: Restart-Service nginx

#user  nobody;
worker_processes 1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;

#pid        logs/nginx.pid;
events {
    worker_connections 1024;
}


http {
    include 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  logs/access.log  main;
    sendfile on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout 65;

    #gzip  on;

    server {
        listen 80;
        server_name localhost;

        error_log logs/error.log debug;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location / {
            root html;
            index index.html index.htm index.php;
        }

        location /subdir/ {
            index index.php;
            alias C:/dev/cake/webroot/;

            # this will serve the file or dir
            # then the frontend controller (index.php)
            try_files $uri $uri/ @subdir;

            location ~ \.php$ {
                try_files $uri =404;
                fastcgi_pass 127.0.0.1:9999;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include fastcgi_params;
                fastcgi_intercept_errors on;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param SCRIPT_FILENAME $request_filename;
            }
        }

        location @subdir {
            # thanks to https://www.paveltashev.com/blog/nginx-how-to-config-domain-subdirectory-to-point-to-a-subfolder/
            rewrite ^ /subdir/index.php last;
        }

        # this redirects /subdir to /subdir/
        location = /subdir {
            rewrite ^ /subdir/ permanent;
        }

        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9999;
            fastcgi_index index.php;
            fastcgi_intercept_errors on;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            try_files $uri =404;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       80;
    #    listen       80;
    #    server_name  somename  alias  another.alias;
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
    # HTTPS server
    #
    #server {
    #    listen       80 ssl;
    #    server_name  localhost;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;
    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
}

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…

Robocopy exclude Directories

Just trying to copy everything except a couple of directories from a drive to my NAS This is the secret incantation of...