Summary of the steps to get a Ubuntu 16.04 production server running with LAMP, multiple virtual hosts and Let's Encrypt SSL.
-
Follow the Initial Server Setup with Ubuntu 16.04 tutorial from Digitalocean.
-
Change the time zone to match your location:
sudo dpkg-reconfigure tzdata
-
Update the machine:
apt-get update apt-get upgrade
-
Install LAMP:
apt-get install lamp-server^
-
Allow Apache through the firewall:
ufw allow http ufw allow https
You should now be able to reach your web server.
Multiple PHP versions on Ubuntu 16.04
After modifying a sites-available configuration file, a reload is sufficient:
service apache2 reload
To remove a host:
a2dissite example.local.conf
To add a module, for instance mod_rewrite
:
a2enmod rewrite
service apache2 restart
To easily distinguish development and production environments, we set a variable inside /etc/apache2/apache2.conf
:
# Environment
SetEnv APP_ENV "development"
MySQL 5.7 introduces some changes to the default configuration that can break some old script queries. For instance, the ONLY_FULL_GROUP_BY
. If you need to continue developing an old project containing such dependencies, here is how to adapt the MySQL configuration.
First, connect to mysql and run this query:
select @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
Copy the output string and remove ONLY_FULL_GROUP_BY
from it. We will then paste the result to a mysql configuration file.
But first, we must find out which configuration file our MySQL uses:
which mysqld
/usr/sbin/mysqld
Then, we use this path to execute the lookup:
/usr/sbin/mysqld --verbose --help | grep -A 1 "Default options"
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
We open the first existing file from this list, and add a [mysqld]
section with our customised string from the previous step:
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Restart MySQL:
sudo service mysql restart
How To Protect SSH with Fail2Ban on Ubuntu 14.04
To install Let's Encrypt certificate(s), each concerned domain (.conf ServerName
) must be defined in a separate configuration file.
Define all the domains/subdomains, and activate the default-ssl.conf
, use the eff.org certbot.
It will generate, install, register the SSL certificate(s) and edit your Apache virtual hosts accordingly. The bot also gives the option to redirect http
to https
.
When the certificates are installed and https
works, it is time to test the renewal:
letsencrypt renew --email [email protected] --agree-tos --dry-run
If it works, something like this can be added to your cronjobs crontab -e
:
36 4,16 * * * letsencrypt renew --email [email protected] --agree-tos --no-self-upgrade > /dev/null 2>&1
The cronjob should run twice a day at random minutes.
To get a log of what is happening:
36 4,16 * * * letsencrypt renew --email [email protected] --agree-tos --no-self-upgrade >> /var/log/letsencrypt/letsencrypt.renew.log 2>&1
On nearly all systems the above cron will fail because of a PATH issue: it seems that crontab uses a different PATH than a regular user, leading to execution failures.
To avoid that, get your PATH:
echo $PATH
Copy it, and paste at the beginning of your cron file:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin