May 6, 2021

nginx howto

Nginx is a small web server that can also be used as a proxy/load-balancer to optimize a system for speed. Here we’ll install nginx from Debian repositories and then get it to interface with php5 and mysql, which you have to do (for now) with a cgi handler. This will hopefully be fixed in future packages, but this will get you up and running for now.

Install/configure nginx

su (or sudo, your choice)
apt-get install nginx php5-fpm php5-mysql php5-curl mysql-server
or
apt install nginx php-fpm php-mysql php-curl
cd /etc/nginx
vi /var/www/html/index.nginx-debian.html (change it to whatever you want)

Now visit http://your.servername.com and you should see the default page. Now let’s make it serve php. To do this you uncomment some stuff in the default config to make fpm handle php for you, and change your index.whatever to index.php too like:

vi /etc/php/7.3/fpm/pool.d/www.conf
  ;listen = /run/php/php7.3-fpm.sock <-- comment out and add next line
  listen = '127.0.0.1:9000'
/etc/init.d/php7.3-fpm restart
netstat -plunt | grep 9000
  tcp   0   0 127.0.0.1:9000   0.0.0.0:*   LISTEN  61995/php-fpm: mast
vi /etc/nginx/sites-available/default
  index index.php index.htm; <-- add index.php
  location ~ \.php$ {  <-- uncomment
  include snippets/fastcgi-php.conf;  <-- uncomment
  # With php5-fpm:
  fastcgi_pass unix:/var/run/php5-fpm.sock;  <-- uncomment
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_buffers 16 16k;
  fastcgi_buffer_size 32k;
  }  <-- uncomment

You can test your config by doing:

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Now let’s add a virtual host of whatever.com (obviously change it to your real server name, not whatever.com). You just copy the last few lines of /etc/nginx/sites-available/default, or just copy what’s below (this will emulate mod_rewrite/php5, like if you have a wordpress site):

cp /etc/nginx/sites-available/default /etc/nginx/sites-available/whatever
vi /etc/nginx/sites-available/whatever
  server {
    listen 80;
    server_name whatever.com *.whatever.com;
    error_log /var/www/whatever.com/logs/whatever.com.error.log;
    access_log /var/www/whatever.com/logs/whatever.com.access.log;
    root /var/www/whatever.com/www;
    index index.php;
    location / {
	try_files $uri $uri/ /index.php?$args;
    }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }
  }
ln -s /etc/nginx/sites-available/whatever /etc/nginx/sites-enabled/whatever
mkdir /var/www/whatever.com
cd /var/www/whatever.com
mkdir logs www
touch logs/whatever.com.error.log
touch logs/whatever.com.access.log
chown -R www-data.www-data /var/www/whatever.com/
vi /var/www/whatever.com/index.php
  test page
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
/etc/init.d/nginx/restart

Now go visit your new virtual host at http://whatever.servername.com, you should see just the text “test page” in your browser

site alias

This is if you want a site like http://your.serv.er/tacos that points to someplace else than http://you.ser.ver/

vi /etc/nginx/sites-available/default
  location /tacos {
 
      alias /var/www/html/tacos;
      #try_files $uri $uri/;
      location ~ \.php$ {
          fastcgi_pass unix:/var/run/php5-fpm.sock;
          include fastcgi_params;                       
          fastcgi_param SCRIPT_FILENAME $request_filename;
          #fastcgi_intercept_errors on;
      }
}

phpmyadmin

apt-get install phpmyadmin &lt;-- ignore prompts to set up apache/lighttp, but set up db
ln -s /usr/share/phpmyadmin/ /var/www/html/phpmyadmin
/etc/init.d/nginx reload

Now visit phpmyadmin in a browser like:

http://what.ever.ip/phpmyadmin

Nginx SSL

First, you have to buy an SSL from some company like GoDaddy, Network Solutions or whoever. Then you have to tie that cert to a domain you have with them. In order to do that, they want you to login to your server where the site is hosted and create a CSR (Certificate Signing Request) to start the process, so login to your server and do:

apt install openssl
cd /etc/nginx
mkdir ssl
cd ssl
openssl req -new -newkey rsa:4096 -nodes -keyout yourdomainname.key -out yourdomainname.csr
  Generating a RSA private key
  ..............................++++
  .....................................................................................................
  ................................++++
  writing new private key to 'yourdomainname.key'
  -----
  You are about to be asked to enter information that will be incorporated
  into your certificate request.
  What you are about to enter is what is called a Distinguished Name or a DN.
  There are quite a few fields but you can leave some blank
  For some fields there will be a default value,
  If you enter '.', the field will be left blank.
  -----
  Country Name (2 letter code) [AU]:US
  State or Province Name (full name) [Some-State]:Vermont
  Locality Name (eg, city) []:YourTown
  Organization Name (eg, company) [Internet Widgits Pty Ltd]: Whatever  
  Organizational Unit Name (eg, section) []:
  Common Name (e.g. server FQDN or YOUR name) []:www.yourromainname.com
  Email Address []: whatever@wherever.com
  Please enter the following 'extra' attributes
  to be sent with your certificate request
  A challenge password []:
  An optional company name []:
ls 
yourromainname.csr  yourdomainname.key

Now you have to open the .csr file and copy the contents, it should look something like this:

cat yourdomainname.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIEqDCCApACAQAwYzELMAkGA1UEBhMCVVMxDzANBgNVBAgMBk9yZWdvbjEhMB8G
A1UECgwYSW50ZXJuZDDQgV2lkZ2l0cyBQdHkgTHRkMSAwHgYDVQQDDBd3d3cucmFu
ZG9tY29kZW5vdGVzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AMvQici0Fi+F3458TN6pLffl2gw50Um0JcoAlskaCs9/8vziFJ2PYNoy6SOO8Skt
nJMZHZjpheNbUeJipSS+OToq054dGGV/IHgwv8M3CQk5RQt0aPke7YfYXQWo8POg
BkEo1iIBbsOVOAfAaqNnYxMa3BrZ6inzojy/+LhwuN1VtHM4mW2ANCZwYs/gQu4F
ih1BSP7heDWTqRWeOKFeUkCxjT/6zlQsO0Ypyc59OvHnpH1HaSjMsmLA2OuIS6mQ
e8lDXybpolyKHizYgbyVbbB6YO5GC03HD8cCF4hC7QatxOmGk8uXL2RI1r56d3lK
6wCcEpnhdCljPWX0nDFDFLtQ5qpspmbo7blm+DbnUYBadk2MA9hbVlQNG1hUhBYS
2zSsJ6dBn6xZcLC2dnGHCUIj/H8LaFt27l1TqUF3K5zUKfbjLvpn2e2Na7nswcxF
9xsp/A/bfmFCRAkXFsU5b15t0XF97RsjZW+SqkSOBZeKjVmhoWFbI+Z77n4JeGV8
8jn/cG68d/d5iKduNQl5ro7BD2AEjeTQLdFxBs/jH5+dJ+gPREf6vAybJwrIv6fV
O05clDnbvBlRR3VwgDCUHEHMXzkHsVo4+EXitbcJ0gEySI6XGXAFk4yD6I1X/iV9
XOumttS525XTvdlfPXYI888r4PaanmfkTHXKubtafMnxAgMBAAGgADANBgkqhkiG
9w0BAQsFAAOCAgEAwz1Ho11Bv+UX3DIPhTDEVSyVxRJY7wxq0bPEQa0RSnNNXQ2k
TjrCFekltEOZaMdLorvF+7VCuYlso2fAUgj/bYgow/MbtJOaHUAYw6v/fZE6EY4D
IznTL5rSBeN/PbnGG34oG0MyxNqJO2tfAtRvo+A3wAdkbuvSsIT2K2sxspU3SELT
GfGfUDmQ8D4MTeP3ntigM33wf+eSHE2fgTDNJePfgKl5YWT43S54rZx+2rl5/yQT
Bd4LKBc8oyPwFt7VJpIGd7a9ULqQZOkAsnXSlJoQkR025Ud7uddFY2l4gmkUmec2
JtS80TASjjm9vHhFqLzxT((3fJWuGUPQNnyVfTPY+/a3iLO25ZJdhf50Zld07TZY
Mmj1HyQ0aHw4LbhuaR+wp0iHjYt08C87sg86IEPInPofeq5/syMkgvAiw+DY1k/z
EOQYRzbE6O39MAl0+oW6Zbh2Y1bDLJh0xlsyruzKYlRNbaImjS83xkpbDJJt7H6b
C5PQQeVQrffQe6q1eos9NJHHzqFBpqlwRwYHsJupwVf/5fBMQPQux0PS2i5krJh9
donoygVjK3ac065BLYh6ArIu/1ugb2MnlhRktjjI9zU/Kdgk8Rfxl9nFfuOTvMll
CvxOL9yAJ3hZYrays4PMBhjGsV8C2/vO23GaMVsI0ZDaR4YIFM+zHevjHmE=
-----END CERTIFICATE REQUEST-----

So just copy that to your clipboard, then go back to the site you bought the SSL from and paste it in their window they give you to paste it in.

Once you paste it in there, the site should auto-detect what domain it is based on the CSR info.

Then you have to validate your email through steps the SSL site will give you, then it will send you an email with a zip file with two files in it, just upload the .zip file to your server with FTP or whatever and install it like:

unzip www_yourdomain.zip
ls
www_yourdomain.crt
www_yourdomain.ca-bundle
cp www_yourdomain* /etc/nginx/ssl
cd /etc/nginx/ssl
cat www_yourdomain.crt www_yourdomain.ca-bundle >> cert_chain.crt

Now you have to tell Nginx to listen on the SSL port (443) for your domain. This means you have to create a new config file for your site just for SSL’s. The one below is just an example, yours has 100% chance of being different, so modify this one to suit your situation.

cd /etc/nginx/sites-available
vi yourdomain.ssl.conf
  server {
    listen 443;
    ssl on;
    ssl_certificate /etc/nginx/ssl/cert_chain.crt;
    ssl_certificate_key /etc/nginx/ssl/yourdomainnamekey.key;
    server_name  yourdomainname_com;
    access_log /var/log/nginx/nginx.vhost.access.log;
    error_log /var/log/nginx/nginx.vhost.error.log;
    location / {
    root /var/www/;
      index index.html;
    }
  }
ln -s /etc/nginx/sites-available/yoursitename.ssl.conf /etc/nginx/sites-enabled/yoursitename.ssl.conf

Now test your nginx config to see if it has errors like:

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If it’s okay, reload nginx like:

service nginx reload

Now visit https://yourdomain.com and see if your site appears with a lock symbol in the address bar 🙂

Nginx errors

Here’s how to fix some common errors:

Nginx Error – 413 Request Entity Too Large

Edit your nginx.conf or individual host in /etc/nginx/sites-available/whatever.conf:

 http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
 
    server {
        client_max_body_size 20M; &lt;-- add this line there somewhere
        listen       80;
        server_name  localhost;
 
        # Main location
        location / {
            proxy_pass         http://127.0.0.1:8000/;
        }
    }
}

phpmyadmin

when you install phpmyadmin, ignore the pre-configuration for apache/lighttpd, you will set up that part later:

apt-get install phpmyadmin
php5enmod mcrypt

Now set up the default url by adding this near the end of the /etc/nginx/sites-available/default:

vi /etc/nginx/sites-available/default
  location /pmadmin/ {
                alias /usr/share/phpmyadmin/;
 
                index  index.html index.htm index.php;
 
                location ~ ^/pmadmin(.+\.php)$ {
                        alias /usr/share/phpmyadmin$1;
                        fastcgi_pass unix:/var/run/php5-fpm.sock; #OR fastcgi_pass 127.0.0.1:9000;
                        fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin$1;
                        include fastcgi_params;
                        fastcgi_intercept_errors        on;
        }

Or in Stretch like:

vi /etc/nginx/sites-available/default
  location /pmadmin/ {
                alias /usr/share/phpmyadmin/;
 
                index  index.html index.htm index.php;
 
                location ~ ^/pmadmin(.+\.php)$ {
                        alias /usr/share/phpmyadmin$1;
                        fastcgi_pass unix:/var/run/php/php7-fpm.sock; #OR fastcgi_pass 127.0.0.1:9000;
                        fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin$1;
                        include fastcgi_params;
                        fastcgi_intercept_errors        on;
        }

Now test your nginx config for errors and reload it like:

nginx -t
  nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
  nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx reload

now test it by visiting http:server.name.or.ip/pmadmin

redirect all http to https SSL

This is for a virtual host, you just need this stuff at the top of your config file:

cd /etc/nginx/sites-available/
vi yoursite.com.conf
server {
        listen 80;
        server_name www.yoursite.com;
        return 301 https://www.yoursite.com$request_uri;
/etc/init.d/nginx reload

Now, when you try to visit http://www.yoursite.com it should automatically redirect you to https://www.yoursite.com with an SSL connection.