This guide is for Namecheap Domain, Vultr Hosting, Debian Linux OS, Apache and Nginx Servers, and PHP.

Use the following commands as a template for your site.

Namecheap Domain

DNS

Namecheap

Manage through Namecheap BasicDNS

In Advanced DNS, manage Host Records

Vultr

Manage Host Records through Vultr DNS.

In Advanced DNS, choose Custom DNS.

Add ns1.vultr.com and ns2.vultr.com

SSL

After setting up Server, use Linux to create SSL.

Create Directory you want to store certificate and key in.

sudo mkdir /etc/nginx/ssl
cd /etc/nginx/ssl

Genereate CSR and Key

sudo openssl req -new -newkey rsa:2048 -nodes -keyout example_com.key -out example_com.csr

Purchase your SSL Certificate from Namecheap. Submit your generated example_com.csr file by following their instructions. Do not lose or delete your example_com.key. Do not reveal your key to anyone or it will be compromised.

Namecheap will send back a crt and ca-bundle file to be used by your Server.

NGINX

You will need to combine both crt and ca-bundle files together and place in your created directory, such as /etc/nginx/ssl/.

sudo cat example_com.crt example_com.ca-bundle >> cert_chain.crt

Remove any extra linebreaks or whitespace in your cert_chain.crt file.

ssl_certificate /etc/nginx/ssl/cert_chain.crt;
ssl_certificate_key /etc/nginx/ssl/example_com.key;

server {
    # Redirect http www to https www
    listen 80 default_server;
    listen 443 ssl default_server;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl;
    ssl on;
    ssl_protocols TLSv1.1 TLSv1.2;
    ...
sudo service nginx restart

Set Permissions

sudo chown -R root:root /etc/nginx/ssl
sudo chmod -R 600 /etc/nginx/ssl

Vultr Hosting

Deploy New Server

After completion, you'll get an email with login credentials.
Login SSH as root. Use Putty if on Windows.
Change root password as required.

DNS

In Vultr DNS set your Records:

A Server IPv4 Address
A www Server IPv4 Address
AAAA Server IPv6 Address
NS ns1.vultr.com
NS ns2.vultr.com

Debian

Debian Linux
Debian Linux

It is recommended to create a new user and disable root SSH login.

Add a new user

adduser username

Enter new password.
Press enter to skip steps if needed.

Add user to sudoers

apt-get install sudo
adduser username sudo

Logout of root with exit.
Login with new username.

Disable Root SSH

sudo nano /etc/ssh/sshd_config

Change PermitRootLogin yes to no

sudo service sshd restart

Update Package List

sudo apt-get update && dist-upgrade

Directories

Make directories on your server:

/var/www/example.com
/var/www/example.com/public
/var/www/example.com/logs

NTP

Network Time Protocol daemon

sudo apt-get install ntp ntpdate

Apache

Apache HTTP Server
Apache HTTP Server
sudo apt-get install apache2 apache2-doc

Go to IP address to see site

Virtual Hosts

sudo nano /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
 ServerAdmin webmaster@example.com
 ServerName example.com
 ServerAlias www.example.com
 DocumentRoot /var/www/example.com/public/
 <Directory /var/www/example.com>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Order allow,deny
      allow from all
      </Directory>
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
</VirtualHost>

Disable Default Virtual Host

sudo a2dissite 000-default.conf

Enable new Virtual Host

sudo a2ensite example.com.conf

Enable mod_rewrite and mod_write

sudo a2enmod rewrite

In your website .htaccess, uncomment RewriteBase / if available.

Reload & Restart Apache

sudo service apache2 reload
sudo service apache2 restart

Nginx

Nginx HTTP Server
Nginx HTTP Server
sudo apt-get install nginx

If you already have Apache installed, you will need to remove, disable, or change to listen on port other than 80.

Uninstall Apache with:

sudo service apache2 stop
sudo apt-get remove apache2

Htaccess Rules can be converted to Nginx using http://www.anilcetin.com/convert-apache-htaccess-to-nginx/

Server Blocks

Create a new file in sites-available.

sudo nano /etc/nginx/sites-available/example.com
server {
    listen 80;
    server_name example.com www.example.com;
    server_name_in_redirect off;
    access_log /var/log/nginx/localhost.access_log;
    error_log /var/log/nginx/localhost.error_log info;
    root /var/www/example.com/public;
    if ($http_host != "www.example.com") {
        rewrite ^ http://www.example.com$request_uri permanent;
    }
    index index.php index.html index.htm default.html default.htm;
    # Support Clean (aka Search Engine Friendly) URLs
    location / {
        try_files $uri $uri/ /index.php?q=$request_uri;
        include  /etc/nginx/mime.types;
    }
    # deny running scripts inside writable directories
    location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
        return 403;
        error_page 403 /403_error.html;
    }
    location ~ \.php$ {
        # With php5-fpm:
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        # With php5-cgi alone:
        # fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /etc/nginx/fastcgi.conf;
    }
    # caching of files
    location ~* \.(ico|pdf|flv)$ {
        expires 1y;
    }
    location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
        expires 14d;
    }
}

Remove the default in sites-enabled.

sudo rm /etc/nginx/sites-enabled/default

Gzip

sudo nano /etc/nginx/nginx.conf
http {
[...]
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1100;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml$
[...]
}

Fast-CGI Buffers

sudo nano /etc/nginx/nginx.conf
http {
[...]
    fastcgi_buffers 8 16k;
    fastcgi_buffer_size 32k;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
[...]

Restart Nginx to load changes

sudo service nginx restart

PHP

PHP
PHP

PHP 5

sudo apt-get install php5-common php5-dev make php-pear libpcre3-dev libapache2-mod-php5 php5-cli

PHP 7

sudo nano /etc/apt/sources.list
deb http://packages.dotdeb.org jessie all
wget https://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg
sudo apt-get update
sudo apt-get -y install php7.0-fpm php7.0-mysql php7.0-simplexml php7.0-curl php7.0-gd php7.0-intl php7.0-mcrypt php7.0-pspell php7.0-recode php7.0-tidy php7.0-xmlrpc php7.0-xsl php7.0-mbstring php7.0-zip php-gettext php-pear

php.ini Locations

Apache

/etc/php5/apache2/php.ini
/etc/php/7.0/apache2/php.ini

Nginx

/etc/php5/fpm/php.ini
/etc/php/7.0/fpm/php.ini

Upload Temp Directory

Uncomment and set your path:
upload_tmp_dir = /var/www/example.com/public/tmp

Change Upload Limits

Default upload size is 2MB

Edit php.ini

max_execution_time
max_input_time
default_socket_timeout
memory_limit
post_max_size
upload_max_filesize
max_file_uploads

Edit /etc/nginx/nginx.conf

client_max_body_size 20M;

Restart php5-fpm (Nginx)

sudo service php5-fpm reload
sudo service php5-fpm restart 

Restart Apache / Nginx

sudo service apache2 restart
sudo service nginx restart

Zend OPcache

PHP7

Add to end of php.ini:

zend_extension=opcache.so

APC

PHP5

Alternative PHP Cache

sudo apt-get install php-apc

create /etc/php5/conf.d/apc.ini

extension=apc.so
; enable APC
apc.enabled=1
; The number of shared memory segments
apc.shm_segments=1
; The size of each shared memory segment
apc.shm_size=64
; The number of seconds a cache entry is allowed to idle in a slot in case this
; cache entry slot is needed by another entry.
apc.ttl=7200

APCu

PHP7

Alternative PHP Cache

https://wiki.archlinux.org/index.php/PHP#APCu

Install

apt-get install php7.0-apcu

or

sudo apt-get install php7.0-dev
sudo pecl channel-update pecl.php.net
sudo pecl install -Z apcu
echo "extension=apcu.so" | sudo tee -a /etc/php/7.0/mods-available/apcu.ini
sudo ln -s /etc/php/7.0/mods-available/apcu.ini /etc/php/7.0/fpm/conf.d/30-apcu.ini
sudo ln -s /etc/php/7.0/mods-available/apcu.ini /etc/php/7.0/cli/conf.d/30-apcu.ini

/etc/php/7.0/mods-available/apcu.ini

extension=apcu.so
apc.ttl=7200
apc.enable_cli=1

PHP-FPM

FastCGI Process Manager

Use with Nginx

You will need to install from non-free repositories.

sudo nano /etc/apt/sources.list

Add to Sources:

deb http://httpredir.debian.org/debian jessie main contrib non-free
deb-src http://httpredir.debian.org/debian jessie main contrib non-free

deb http://httpredir.debian.org/debian jessie-updates main contrib non-free
deb-src http://httpredir.debian.org/debian jessie-updates main contrib non-free

deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free
sudo apt-get update
sudo apt-get install php5-fpm
sudo apt-get install php7.0-fpm

Restart

sudo service php5-fpm restart
sudo service php7.0-fpm restart

MySQL

MySQL Database Management
MySQL Database Management
sudo apt-get install mysql-server php5-mysql
sudo mysql_secure_installation
Change the root password? [Y/n] n
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Enter mysql root password

phpMyAdmin

phpMyAdmin
phpMyAdmin
sudo apt-get install phpmyadmin

Apache

sudo nano /etc/apache2/apache2.conf

Add to bottom of file:

Include /etc/phpmyadmin/apache.conf

Change KeepAlive On to Off

NGINX

Enable access to phpMyAdmin

server {
[...]
location /phpmyadmin {
        root /usr/share/;
        index index.php index.html index.htm;
        location ~ ^/phpmyadmin/(.+\.php)$ {
            try_files $uri =404;
            root /usr/share/;
            # With php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            # With php5-cgi alone:
            # fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include /etc/nginx/fastcgi_params;
    }
    location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
        root /usr/share/;
    }
}
location /phpMyAdmin {
        rewrite ^/* /phpmyadmin last;
}
[...]
}

Create a symlink in sites-enabled.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Fail2ban

Fail2ban
Fail2ban
sudo apt-get install fail2ban
cd /etc/fail2ban
sudo cp jail.conf jail.local
sudo nano jail.local

Permissions

sudo chown -R www-data:www-data /var/www
sudo chmod -R g+w /var/www
sudo usermod -a -G www-data username
id username
groups username
sudo nano /etc/apache2/envvars

Add to bottom of the file:

umask 007

Restart

sudo service apache2 restart
sudo service nginx restart

FTP

Host: Server IP Address
Protocol: SFTP
Logon Type: Normal
Default remote directory: /var/www/example.com/public

www-data

Enable SFTP upload writing to files owned by www-data.

Create Group and add User

sudo adduser --group www-pub
sudo usermod -a -G www-pub www-data
sudo usermod -a -G www-pub username

Change directories and files owner

sudo chown -R www-data:www-pub /var/www

Change directories and files permissions

sudo chmod 2775 /var/www

sudo find /var/www -type d -exec chmod 2775 {} +
sudo find /var/www -type f -exec chmod 0664 {} +