DEV Community

Valentine
Valentine

Posted on

How to setup Nginx and PHP7.1 with FPM on Mac OS X without crying

alt text

I had problems with my nginx for months. I read a ton of articles online but couldn't find a solution. Most of what I saw was for php7.0, and they used php-fpm-sock file which clearly does not exist in php7.1. Creating and configuring php7.1 to use the sock file was a different kettle of fish on it's own. I failed at it several times. When I upgraded to High Sierra (which basically wiped my system clean due to multiple failures), I had to start setup all over again. I decided to take my time and actually tackle this nginx setup issue. There was still no tutorial on it that worked for me. I made up my mind to figure it out on my own. Did I? This article will explain how I did it.

If you are new to http servers on your local machine, this article would make setting up nginx pretty easy for you even if you don't understand most of the stuff. If you use LAMP or WAMP or any of that, you might want to go read up on setting up nginx for your OS before coming right here. The nginx configurations would be the same. Just the folders to find the nginx.config file for nginx may change from OS to OS. Yes, this should work for non Mac users as well.

To make this article pretty useful to you, I'd skip a lot of stuff that are not the focus (stuff that there are probably like 1,000 articles on already). I'd speed through a lot of this. I use High Sierra on my Mac (I used Sierra before) so I cannot guarantee what would happen for other versions of macOS X. If you are following and anything is missing, do not fret. Just Google how to install it and then continue with this setup.

If you already have Nginx and PHP7.1 installed, you can skip to the installation section and head straight to configuration.

INSTALLATION

We are going to use Homebrew for all our installations. It makes life easy and it is pretty straightforward. Click here to read about it or just install right away.



/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


Enter fullscreen mode Exit fullscreen mode

When you are done, ensure homebrew's environment is setup correctly.



$ brew doctor


Enter fullscreen mode Exit fullscreen mode

Next we're going to install a launchctl wrapper that will stop, start, and restart any service we install with brew.



$ brew tap homebrew/services; brew tap homebrew/dupes


Enter fullscreen mode Exit fullscreen mode

Let's install php7.1 with fpm and display the version after installation.



$ brew install php71 --with-fpm --without-apache; php -v; php-fpm -v


Enter fullscreen mode Exit fullscreen mode

Start PHP right away.



$ brew services start php71 


Enter fullscreen mode Exit fullscreen mode

We would not have to setup much for PHP7.1 with FPM because it comes pretty configured right out of the box. Let's just get nginx and get the party going.



$ brew install nginx; brew services start nginx


Enter fullscreen mode Exit fullscreen mode

We are done with installations for now, time for configurations. Nginx should be running on port 8080 if you also have apache installed and running. Either way, you should see which port it is running on after installation, so you can quickly visit http://localhost:8080 to see the default nginx homepage (use the port displayed in your terminal after setup instead, if it is not 8080).

THE CONFIGURATION

When installed with homebrew, Nginxโ€™s configuration file would be found in /usr/local/etc/nginx. Open it with any editor you like (I use nano to save time).

We are going to leave everything the way it is and just edit only a few sections. The nginx.config file would be configured properly upon installation to serve static files. All your websites would be in /usr/local/var/www folder so that nginx can see them. Nginx mirrors all the files there to it's html folder that can be found in /usr/local/Cellar/nginx/[version_number]/html as of this writing. If you want to set a different part for your files, edit this block of the config file and set a different root.



location / {
            root   html;
            index  index.html index.htm index.php;
        }


Enter fullscreen mode Exit fullscreen mode

Don't forget to add index.php to the index list so that nginx can automatically load that file when it serves your site.

The next thing is to setup how our php files are proxied for execution. Edit your block to match the following.



  # 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$ {
            root           html;
            include        fastcgi.conf;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
        }


Enter fullscreen mode Exit fullscreen mode

I left the fastcgi_param line commented out just incase you need to set something there later. All params are already included below it and the fastcgi.conf file should have all the settings required to use php-fpm. Save your file and restart nginx.



$ brew services restart nginx


Enter fullscreen mode Exit fullscreen mode

If you are using multiple configuration files (all stored in /sites-available), you would have to adjust them one by one as well. You can store this setup block above in a separate file and include it in all of them if they all use the same root folder.

Time to test our beautiful setup. Create an info.php file in /usr/local/var/www folder and put any php code of your choice that should output stuff (I echoed phpinfo()). Go to http://localhost:8080/info.php and it should display just fine (use the port displayed in your terminal after setup if it is not 8080).

Now buddy, go enjoy your nginx and cry no more.


NGINX is a free, open-source, high-performance HTTP server known for its high performance, stability, rich feature set, simple configuration, and low resource consumption. If you want to see how nginx performs in handling requests and heavy usage when compared to apache, read Web server performance comparison. If you would like to understand better about the individual strengths of nginx and apache, checkout this article on Digital Ocean.

Top comments (11)

Collapse
 
thanhoangxuannghiep profile image
thanhoangxuannghiep

Hi, I am following this article. But when I run "brew tap homebrew/dupes". I got this error: "Error: homebrew/dupes was deprecated. This tap is now empty as all its formulae were migrated". How can I fix this? I tried to search but I do not found any solution. I am using Homebrew 1.6.4. MacOS high sierra version 10.13.4 (17E202). Thanks.

Collapse
 
chiefoleka profile image
Valentine

Did you find a solution? You only needed to find the replacement for homebrew/dupes

Collapse
 
enggsher profile image
Sher Bahadur

When, I have created info.php file as you suggested and when I am hitting the URL (localhost:8080/info.php) the file is getting downloaded instead of displaying details.

Can you please help me out.
I want to setup a Laravel project and run through Nginx.

Thanks in advance.

Collapse
 
chiefoleka profile image
Valentine

Hi Sher,

I apologise for getting to this late. This usually happens when PHP is not properly configured. Nginx isn't passing the PHP script to FPM or FPM is not processing it at all (probably not set up properly), so it is sending the file because it does not know what to do.

Also, be sure your PHP installation is not using the .sock file but is processing via port 9000. Look at /etc/php/{PHP_VERSION}/fpm/pool.d/www.conf and be sure what it is listening to sock file: prnt.sc/s2dr4p or port 9000: prnt.sc/s2dvdv. It may also be in /etc/php/{PHP_VERSION}/php-fpm.d/www.conf depending on your installation. Just find it.

Let me know if you have found a solution for it.

Collapse
 
madaarya profile image
Mada Aryakusumah • Edited

about fastcgi_param , not sure about the default is not work. But this config will work

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
Enter fullscreen mode Exit fullscreen mode
Collapse
 
e4neilook profile image
e4ne

This was pretty much useless, it still didn't work for many reasons.
Thanks for trying

Now I have to cry

Collapse
 
chiefoleka profile image
Valentine

What result did you get at the end of the day?

I mean, I wrote this about 1 year ago, so a lot might have changed since then.

Nonetheless, share what didn't work let me see if I can help.

Collapse
 
e4neilook profile image
e4ne

Hi Valentine!

Thanks for replying.

I might found a solutions that now works. It took me three days to reach there. Now the only thing I have left is to make a websocket proxy works properly with SSL.

You're right things seems to happens very rapidly. There are many non up to date articles out there that sometimes confusing a bit.

Your solution might work indeed if I had the pleasure to be use a new fresh sierra. But that was unfortunate not the case. I have been sort of messing up a few configurations, packages, not update, miss to set permissions, right user etc.

But now that is in right place/order.

The only thing I have left is to setup a properly websocket proxy to sort of prevent expose ports for the end-user. Here is what it looks like:

Thanks for helping , very kind of you!

....

http {

   ....

    server {
        listen          443 ssl;
        server_name     mydomain.com;
        client_max_body_size 20M;

        root            /Users/myusers/Documents/www/;

        access_log      /Users/myusers/Documents/logfiles/default-ssl.access.log  main;

        ssl_certificate      /Users/myusers/Documents/cert/mydomain.com/public_cert.crt;
        ssl_certificate_key  /Users/myusers/Documents/cert/mydomain.com/private_cert.key;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;


        location / {
            index  index.php index.html index.htm;
        }

        ....

        # For the websocket
        location /websocket/ {
            proxy_pass https://mydomain.com:8443;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        }
    }

}

(note: everything working and SSL cert and php, permissions, etc.
But now I also have a node-js-server that is up and running correctly. the DNS mydomain.com is a changed host DNS, so its not live or real!
It points to localhost/127.0.0.1 in the hostfile on my machine, but that should work too).

Collapse
 
milosb793 profile image
milosb793

I'm crying nevertheless :'(

Collapse
 
http91 profile image
T

Dude...

Thanks.

Collapse
 
rango3526 profile image
Ranger

This was a huge help even in 2023, thank you!!