This guide applies to Ubuntu 16.04, I’ll cover other versions later.

1. Installing Nginx
First, let’s update the repos:

sudo apt-get update

Then install nginx:

sudo apt-get install nginx

Then check the nginx version with the following command:

nginx -v

If we get at least version 1.10.0, everything is fine.

2. Installing MySQL
The first step is to install the MySQL server:

sudo apt-get install mysql-server

Naturally, you need to fill in the root user’s password, which you’ll use to access MySQL later.
For PHP pages to run, you need to install PHP version 5 and its associated MySQL instruction set:

sudo apt-get install php-fpm php-mysql

To increase security, it’s recommended to disable the feature where PHP, if it can’t find the referenced file, executes the most similar one instead:

sudo nano /etc/php/7.0/fpm/php.ini

Find the section where cgi.fix_pathinfo is, remove the semicolon (;) from in front of it, then set its value to 0 and save the whole thing.

cgi.fix_pathinfo=0

To set the upload limit, find the upload_max_filesize line, then change the value to whatever you want (megabyte=M, gigabyte:G)

upload_max_filesize = 1G

To set the download limit, find and modify the following line:

post_max_size = 1G

Once done, save the file and restart php-fpm:

sudo systemctl restart php7.0-fpm

3. Configuring Nginx
The basic config file can be edited like this:

sudo nano /etc/nginx/sites-available/default

The file should look something like this by default:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name localhost;

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

For plain HTTP, modify the file as follows:

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

 root /var/www/website;

 index index.php index.htm index.nginx-debian.html;

 server_name your_website_address;

 location ~ \.php$ {
 try_files $uri =404;
 fastcgi_pass unix:/run/php/php7.0-fpm.sock;
 include fastcgi_params;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 }

 location / {
 try_files $uri $uri/ /index.php?$args;
 }

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

For HTTPS (SSL) and HTTP2, modify the file as follows (if you don’t have an SSL certificate, you’ll find instructions below on how to get one for free for a year):

server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

root /var/www/website;

index index.php index.html index.htm;

server_name your_website_address;

location / {
try_files $uri $uri/ /index.php?$args;
}

# specifying the location of SSL files if you created them with letsencrypt
ssl on;
ssl_certificate /etc/letsencrypt/live/your_website_address/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_website_address/privkey.pem;

ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;

# specifying dh parameters as described later
ssl_dhparam {path to dhparams.pem file};

location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

server {
listen 80;
listen [::]:80;
server_name your_website_address;
return 301 https://$server_name$request_uri;
}

Save the file, then restart nginx:

sudo service nginx restart

4. Installing phpMyAdmin
You can install the package like this:

sudo apt-get install phpmyadmin

During installation, it will ask for the MySQL root user’s password, provide it. The next question is the phpMyAdmin root account password. Provide it, then confirm it when asked.
Then, to make phpMyAdmin accessible from your website, you need to create a symbolic link:

sudo ln -s /usr/share/phpmyadmin /var/www/website/phpmyadmin

Then you can access phpMyAdmin from your website:

http://mywebsite.hu/phpmyadmin

5. Requesting an SSL Certificate

If you don’t have an SSL certificate yet, a good solution for this is the StartSSL service, within which you can request one for 5 domains for 1 year. (after that you can order it again) – UPDATE: StartSSL stopped working in January 2018, I recommend Let’s Encrypt instead.

5.1 Requesting a Let’s Encrypt SSL Certificate

We can request a Let’s Encrypt SSL certificate using Certbot, which we can install and use as follows:

sudo apt-get update

sudo apt-get install software-properties-common

sudo add-apt-repository ppa:certbot/certbot

sudo apt-get update

sudo apt-get install python-certbot-nginx

Once that’s done, run Certbot in manual certificate creation mode (we don’t want it to mess with our nicely edited nginx config file)

sudo certbot --nginx certonly

The process is pretty straightforward, you need to provide your email address and the domain name for which you want to request the SSL certificate. Once done, it will show the expiration date and the location of the certificate files:

/etc/letsencrypt/live/your_website_address/

Edit the nginx configuration according to point 3 with the existing filenames inserted.

5.2 Verifying the SSL Connection

It’s worth checking that we’ve properly set up SSL on the web server, which we can do at https://www.ssllabs.com/ssltest/analyze.html.

Once you’re done with that, everything should be working great 🙂