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 httpsYou 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