nginx from https://launchpad.net/~hda-me/+archive/ubuntu/nginx-stable and php7.1

March 26, 2017 1.8k views
Nginx Ubuntu 16.04

Hi,
I was testing nginx with dynamic modules from https://launchpad.net/~hda-me/+archive/ubuntu/nginx-stable but I could not get php7.1-fmp wordking. Nginx works, modules works but not php. I am not to knowledgeable is server management.
I followed this tutorial except for nginx that I installed from ppa and mariadb instead of mysql:
https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04
Something is missing but I don't know what?

Thank you

25 Answers
jtittle1 March 27, 2017
Accepted Answer

@stephgiguere

Generally this section:

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.1-fpm.sock;
    }

... would look something like:

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php7.1-fpm.sock;
    }

The difference being we're swapping snippets/fastcgi-php.conf with fastcgi_params.

Not all NGINX repositories have a snippets directory that contains blocks of code. Even if they do, not all of them contain everything that's needed (at least, that has been my experience).

...

If you don't mind trying something different, and you have a few extra minutes, I wrote and installer for NGINX that handles a source installation hands-free.

It includes HTTP2, Brotli, a few modules, and multiple example configurations with it.

If you run:

cd /opt

Then:

git clone https://github.com/serveradminsh/installers.git

Followed by:

cd installers/nginx
chmod +x installer.sh

And finally:

./installer.sh

You'll have a fully configured and optimized NGINX setup with a working PHP configuration that you can copy from the ./installers/nginx/examples directory.

Within this directory there's a php directory which contains a php.conf file. That's the one you need and to set it up, all you'd do is:

cp installers/nginx/examples/php/php.conf /etc/nginx/sites/yourdomain.conf

Then:

nano /etc/nginx/sites/yourdomain.conf

... and configure it to your liking. There's also examples on how to setup SSL, Load Balancing, Proxy, and others.

The installer will take about 20-30 minutes as this is a source compile, not a stock repo package. It's detailed and sets up everything you'd have to do a source compile to setup. A systemd service is also included, so NGINX is controlled using:

systemctl start nginx
systemctl restart nginx
systemctl stop nginx

The only thing I'd recommend doing is:

1). Run the installer on a fresh Ubuntu 16.04 droplet, or;
2). Run:

apt-get -y remove nginx
apt-get -y purge nginx
rm -rf /etc/nginx

This wipes your current NGINX installation, so if you need to backup anything, do it before the above commands. That said, the installer has all the examples you need to get things working and I will be more than happy to help should you have any questions.

As for the examples directory, most are setup so that you only need to change the server_name directive. The only other thing you may need to modify is the fastcgi_pass directive since you're using sockets instead of TCP, or you can modify:

/etc/php/7.1/fpm/pool.d/www.conf

and change listen to use 127.0.0.1:9000 and restart php-fpm and the example I provided will work without any changes other than those for your domain.

@stephgiguere

What doesn't seem to be working?

If you'll post your server block, I'd be more than happy to take a look at it for you :-).

@jtittle
I did a info.php file:
<?php
phpinfo();
Put it in my server directory and it won't load. I followed the DO tutorial mention before, it works when using ubuntu nginx but not the ppa nginx.

My nginx config looks like this:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name server_domain_or_IP;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.1-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Thank you

  • @stephgiguere
    This server_name server_domain_or_IP; should be your actual domain.
    If your domain is stephgiguere.tld then it should be
    server_name stephgiguere.tld;

@hansen Yes I had it in my test droplet, just didn't post it, thank you.
@jtittle Thank you will try.

  • @stephgiguere

    Awesome -- let me know how it goes. As noted above, it does take some time as the setup is definitely geared towards production, so it's a full source compile from scratch and it takes care of generating a dhparam.pem file, which is needed for SSL (which is one reason it takes so long to finish as that's a time-intensive process).

    I tested it on 2GB-64GB Droplets and they all seem to take around the same time to complete -- around 30-40 minutes.

@jtittle
Ok got it working with php and your script on a test droplet. I also installed php7.1 from your script. I had to change the pool.d www.conf. All of those details are so confusing when you don't know.
Does nginx have pagespeed compiled in it?
If so do I need to take extra step to use it?

@jtittle Also do you think it would be better to rebuild my live site droplet and install mariadb, nginx and php7.1 from your script or would just changing nginx to your compile be ok?

@jtittle Answered my own question about pagespeed, just followed the end of this toturial:
https://www.digitalocean.com/community/tutorials/how-to-add-ngx_pagespeed-to-nginx-on-ubuntu-14-04

ngx_pagespeed, or just pagespeed, is an Nginx module designed to optimize your site automatically by reducing the size of its resources and hence the time the clients' browsers need to load it. This article will guide you through the installation and configuration of the pagespeed module for Nginx.

@stephgiguere

When it comes to PHP, that's one of the areas I'm working to simplify. Working with PHP-FPM is really easy, though it's not very obvious that you need to change or create multiple files in ./pool.d.

When it comes to secure deployments, each site you deploy should run as a different user and each user should have their own PHP-FPM configuration file in ./pool.d. Each configuration file should set it's own listen port as well.

The main lines you want to change in the original www.conf file for PHP-FPM are:

[www] => [yourusername]
user  = serveradmin => user  = yourusername
group = serveradmin => group = yourusername
listen = 127.0.0.1:9000 => listen = 127.0.0.1:9001 => listen = 127.0.0.1:9002

ect.

The rest of the configuration is something you'd want to take a look at should you need to tune for performance. The defaults work pretty well and in most cases, unless you're running a super-busy site, they'll work.

...

As for NGINX, currently the installer will install the latest Mainline version of NGINX as well as compile in the following:

-- NGINX Dev. Kit (Module)
-- NGINX Headers More (Module)
-- NGINX VTS (Module)
-- Brotli (for Brotli Compression)
-- LibBrotli
-- NGINX Brotli (Module -- Depends on Brotli & LibBrotli)
-- NAXSI (Module)
-- Google Pagespeed (Module)
-- NGINX Set Misc (Module)

All modules are statically compiled.

...

As for using my installers exclusively, you can for sure. Except for NGINX, the majority will use either official repositories, or repositories I've used for years without any issues (as is the case for PHP). If you plan to use mine though, I'd honestly recommend installing everything from scratch on a new Droplet that hasn't had anything else installed on it so there are no potential conflict scenarios.

The three installers will setup NGINX Mainline, PHP 5.6, 7.0, or 7.1 (your choice), and MariaDB 10.x. While they shouldn't cause issues on a system that has had them installed, I find it best to start with a blank canvas.

If you want to run them on your current, I would advise using both remove and purge. You would need to backup your MySQL databases first though as purge may destroy them.

I wanted to setup ufw but when I run ufw status I only see OpenSSL and not nginx https. How to add it

  • @stephgiguere

    ufw is already setup on 16.04/16.10, so we'd just need to configure it.

    I normally don't use service names as I prefer to be a little more precise, so I'll be using ports in place of ssh, nginx, https, etc.

    First thing, disable ufw.

    ufw disable
    

    Now to ensure we're working from a clean slate, we'll reset ufw.

    ufw reset
    

    With a clean slate, we want to configure our default policies. We're going to deny all incoming and allow all outgoing. These settings won't lock you out since ufw should be disabled before running these commands (double check, because running these will lock you out if it's not).

    ufw default deny incoming
    
    ufw default allow outgoing
    

    We're setting up a deny all on incoming as we want to deny access on all ports except those we specify. It's far easier to whitelist than it is to blacklist.

    Now we'll allow SSH (22), HTTP (80), and HTTPS (443)

    ufw allow 22/tcp
    
    ufw allow 80/tcp
    
    ufw allow 443/tcp
    

    At this point, connections will be allowed on ports 22 (SSH), 80 (HTTP), and 443 (HTTPS), but all other connection attempts on other ports inbound will be denied (i.e. someone trying to connect on port 3434 won't be permitted).

    Unless you're running a a database server (external -- on another droplet), or have a need to open up another port, that's it. We just need to enable ufw again now.

    ufw enable
    

    It'll ask you to confirm that you want to enable it and warn that you may get disconnected, and that's fine. You won't be disconnected as you've added port 22, which, unless you've changed the SSH port, should be the port you're connected on when running these commands.

Thank you
Does your compile include naxsi?

@jtittle Never mind just saw naxsi, on to learning to use it now :)
Thank you for your work

@jtittle
Having issues upgrading my existing droplet. I know it works in a new droplet.

If I build a new droplet can I just transfer my dns record to that new droplet in the dashboard?
I am using invision power suite 4 and can not have 2 license running at the same time.

  • @stephgiguere

    Absolutely, just change the DNS entries that point to the current Droplet IP to the new and that will allow the DNS to swap over. It may take a minute or two, but generally DigitalOcean is quick to update.

    What issues are you having on the previous droplet if you don't mind me asking?

@jtittle
Excellent. I also have google mail setup, I guess no need to change that.

What issues are you having on the previous droplet if you don't mind me asking?
I do not mind, the website did not load, I changed the nginx config, defut config an www.conf but nothing loaded. got nothing.

  • @stephgiguere

    No need to change Google Mail / G Suite / Google Apps -- only the A entry(ies) with IP's.

    As for NGINX, that may have been due to an existing /etc/nginx directory and the configuration files within it. To install NGINX via the installer, you'd need to wipe that directory clean (after backing it up, if you need the configuration files for your server blocks).

    rm -rf /etc/nginx/*
    

    Since we'd still be using /etc/nginx, there's no reason to delete the entire directory, but all files in it.

    Sometimes things can conflict there, though that's all I can think of off the top of my head that would cause an issue.

I will try again tomorrow after work, I had a few to many beer to try tonight.

@jtittle
About to setup ssl, I used to just insert certificate in default.conf, is it better to use a seperate file like in your setup?
Do I need to include path in nginx setup?

  • @stephgiguere

    If using ./examples/ssl/ssl.conf as your template, you should change:

    server_name _;
    

    ... in both server blocks (so they match);

        ssl_certificate /etc/letsencrypt/live/_/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/_/privkey.pem;
    

    ... if you're using LetsEncrypt, then you'd replace _ with your domain name, otherwise, you'd need to modify the paths to define the locations where you've stored your certificates;

    root /home/nginx/htdocs/public;
    

    ... so that it matches the path where you'll be storing your files;

        location /
        {
            try_files $uri $uri/ =404;
        }
    

    ... to match you're specific needs. If this is a WordPress site, for example, you'd replace =404 with /index.php?$args.

    ...

    For LetsEncrypt, if using the standard LetsEncrypt command that's available as:

    letsencrypt
    

    ... from the CLI, then you want to use certonly to generate the certificate. For example:

    letsencrypt certonly -d domain.com -d www.domain.com
    

    That prevents any specific configuration by the plugins included with LE. Since my NGINX configuration uses non-standard directories, chances are that the LE NGINX plugin won't work as intended, though it doesn't need to. Passing certonly prevents any server-specific plugin from running and stores the certs in:

    /etc/letsencrypt/live/domain.com
    

@jtittle
Two more questions:
1) I can not import my database into the new droplet, it give me an connection error, I use adminer. I changed these setting in php.ini

upload_max_filesize 120M
post_max_size 120M
max_execution_time 200
max_input_time 200

Still does not work. Any workaround this? Database in 54mg

2) I just realize my previous issue was this line in php.ini

cgi.fix_pathinfo=0

This toturial claims it is safer but it seems to conflict with your install, is it safe to just comment it?

https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04

The LEMP software stack is a group of software that can be used to serve dynamic web pages and web applications. This is an acronym that describes a Linux operating system, with an Nginx web server. The backend data is stored in the MySQL database and the dynamic processing...

@stephgiguere

Ideally, if your database is more than a few MB's in size, you want to use MySQL's CLI interface to do a restore. A web-based interface, such as phpMyAdmin or Adminer should be able to handle it, though it's not the best tool for the job.

That being said, if you want to use a web-based interface to do the restore, you'll need to modify one more variable, and that'd be client_max_body_size 50m;, which can be found in:

/etc/nginx/config/nginx.conf

You'll need to change the current 50m to match that of your php.ini, or change them all to a value a little over, such as 64m. You'd then want to reload NGINX using:

systemctl reload nginx

If you want to do this using MySQL's CLI, you'd use:

mysql -u dbuser -p dbname < db.sql

Where dbuser is the database username, -p will prompt you for the password, dbname is the name of the database, and db.sql is the SQL dump file that you created.

To run that command, you'd login as root using SSH, or your sudo user. You don't need to actually enter the MySQL CLI, just change the placeholders and run the command as-is.

@jtittle
Thank you!!
So many little settings.

  • @stephgiguere

    That there are :-).

    I'm working on a full LEMP Stack auto-installer that installs NGINX, PHP 7.1.x + PHP-FPM and MariaDB together as one. I just need to finish up the utilities to simplify creating new user accounts (which will create SFTP, User Directories, PHP Pool Files, etc all at once).

    They're almost done as-is, but there's a few more I want to add as well as a few general utilities.

@stephgiguere

As a general note, I would recommend commenting out max_input_time. It's default setting is -1, which means PHP will use max_execution_time instead.

I would then set max_execution_time to something like 60 as setting it to 200 means that a script can run for a little over 3 minutes before it's killed off. Setting it to 120 is about the max I would recommend unless you're going to be uploading large files that you know will require more time to complete.

As for cgi.fix_pathinfo=0, the latest versions of PHP should be able to correctly handle what was once an issue, whether you have this set to 1 or 0.

The better option would be to make sure that you have set:

security.limit_extensions = .php

In your PHP-FPM pool file. The default is:

/etc/php/[vers]/fpm/pool.d/www.conf

Where [vers] is the PHP version you're running.

The reason for this setting was to prevent requests, such as:

http://domain.com/image.jpg/file.php

... from executing image.jpg as a PHP file when file.php isn't found. What the above setting does is tells PHP-FPM that unless it has a .php extension, it shouldn't be executed as a PHP file.

Now, that doesn't stop someone from uploading a PHP file using your uploader and then executing it -- keep that in mind. That falls on the application (i.e. such as WordPress) to limit what extensions can be uploaded by an admin/user/etc by configuration options, built-in core options, or a plugin.

@jtittle
Thank you
I have pagespeed and naxsi running.
When I run nginx -t I get these:

nginx: [alert] could not open error log file: open() "/etc/nginx/logs/error.log" failed (13: Permission denied)
2017/04/02 19:09:53 [warn] 8021#8021: the "user" directive makes sense only if t he master process runs with super-user privileges, ignored in /etc/nginx/config/ nginx.conf:7
2017/04/02 19:09:53 [info] 8021#8021: [ngx_pagespeed 1.12.34.2-0] No threading d etected. Own threads: 1 Rewrite, 1 Expensive Rewrite.
2017/04/02 19:09:53 [info] 8021#8021: pagespeed: rollback gzip, explicit configu ration in /etc/nginx/config/nginx.conf:51
nginx: the configuration file /etc/nginx/config/nginx.conf syntax is ok
2017/04/02 19:09:53 [emerg] 8021#8021: open() "/etc/nginx/pid/nginx.pid" failed (13: Permission denied)
nginx: configuration file /etc/nginx/config/nginx.conf test failed

Not sure how to fix.

@jtittle
Well I feel stupid, I just forgot to run it with sudo. All good.

@jtittle
Just updated my ubuntu 16.04 droplet and now nginx won't load. In troubleshooting mode now, if you have any steps that would save me time please tell me.

Thank you

  • @stephgiguere

    The first step would be to tail the error log and see what it's showing:

    tail -20 /etc/nginx/logs/server/error.log
    

    or

    tail -20 /etc/nginx/logs/error.log
    

    I'm going to be updating the installer soon enough to further organize things a bit more. There was an issue with one of the releases sticking the initial server logs in ./logs, which is why I've provided both above.

@jtittle
The error log shows:
2017/05/19 16:46:57 [emerg] 1297#1297: open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)

My nginx conf is in /etc/nginx/config/nginx.conf

Why does it think it is in /etc/nginx/nginx.conf and how do I tell it to go in /etc/nginx/config/nginx.conf

@jtittle
From my google search I need to purge and reinstall nginx. Do you see any other options?

@stephgiguere

If you installed NGINX and then used the auto-installer that I posted without removing the previous install, it's most likely attempting to use the version that you installed from the OS repositories.

You should be able to run apt-get remove nginx to remove the repository version that was installed. That shouldn't remove anything that the auto-installer created, though I'd still recommend backing up the /etc/nginx directory.

Something such as:

mkdir -p /usr/local/src/nginx

...and then:

cp -R /etc/nginx/* /usr/local/src/nginx

That way if something doesn't work, you can copy the files back in to place from the backup directory.

Have another answer? Share your knowledge.