Set up a web stack

This article wasn't updated in the last 4 years. Please double check if the content is still up-to-date.

If you find any error, please send me a quick heads-up.

This is a continuation of the install a new server guide, and explains – after the set up of the OS and the actual server – what to do to install a web stack.

This guide uses explicit version numbers in some commands. You need to regularly go through the tools and update these numbers to always stay up-to-date.

Be sure that you are root

All of the following commands only work as root, so be sure that you are root

sudo su

Upgrade System

Whatever you do: always start with bringing everything to the newest versions.

apt update && apt -y upgrade

Configure Bash

Add the following lines to your ~/.bashrc:

alias ll='\''ls -alh --color=always'\''

Add the following lines to your ~/.bash_profile:

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

Install default environment

These are tools you need for basic server maintenance and some build systems.

apt -y install curl nano software-properties-common build-essential g++ zip htop iotop ntp bash-completion autoconf

Install fail2ban

You only need to do that if you are not already behind a cloud firewall.

apt -y install fail2ban

Now add the following to /etc/fail2ban/jail.local:

[DEFAULT]
bantime = 604800 # ban for 1 week
maxretry = 3

[sshd]
enabled = true

You now need to restart fail2ban:

service fail2ban restart

Install MySQL

apt -y install mysql-server mysql-client

Finish up the MySQL configuration:

mysql_secure_installation

Also you might need to update the auth mechanism to use passwords instead of local users, use one of:

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '<password>';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '<password>';

Install Certbot + nginx

You don’t need to do that if you are using Caddy.

For certbot, you should look up on what’s the current way to install it is, on certbot’s website.

Installing nginx:

apt update && apt -y install nginx

Install node.js

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - && \
apt -y install nodejs && \
npm -g install npm

Install PHP

LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \
apt update && \
apt -y install php7.4-cli php7.4-common php7.4-curl php7.4-fpm php7.4-gd php7.4-intl php7.4-json php7.4-mbstring php7.4-mysql php7.4-xml php7.4-zip php-imagick

Install Composer

Install composer according to the documentation.

Install Cachetool

curl -sLO https://github.com/gordalina/cachetool/releases/latest/download/cachetool.phar && \
chmod +x cachetool.phar && \
mv cachetool.phar /usr/local/bin/cachetool

Install Git

apt -y install git

Disable TCPv4 timestamps

echo 0 > /proc/sys/net/ipv4/tcp_timestamps && \
echo 'net.ipv4.tcp_timestamps = 0' >> /etc/sysctl.conf

Install mail delivery

If you are not using an API for mail delivery, you need to install postfix for sending mails (which then can use a smart relay for actual delivery).

apt -y install postfix libsasl2-modules

Cleaning apt

apt -y autoclean && \
apt -y autoremove

Check installed versions

echo '' && \
echo '> PHP' && \
php -v && \
echo '' && \
echo '> composer' && \
composer -V
echo '' && \
echo '> Git' && \
git --version && \
echo '' && \
echo '> Certbot' && \
certbot --version && \
echo '' && \
echo '> mysql' && \
mysql -V && \
echo '' && \
echo '> nginx' && \
nginx -V && \
echo '' && \
echo '> node' && \
node -v && \
echo '' && \
echo '> npm' && \
npm -v && \
echo '' && \
echo '> Postfix' && \
postconf -d | grep mail_version && \
echo '' && \
echo '> fail2ban' && \
fail2ban-client -V

Finishing up

You still need to do some things

  • Add further config for fail2ban
  • Update postfix config (inet_interfaces = loopback-only)

Troubleshooting

MySQL

No password set during installation

In case you weren’t offered setting a MySQL password during installation, this can be done by executing mysql_secure_installation.

Can’t connect to MySQL database with newly set password

This happened a couple of times already and resulted in a completely purge of MySQL and a clean new install.

Purging MySQL:

apt remove --purge mysql*
apt purge mysql*
apt autoremove
apt autoclean
apt remove dbconfig-mysql

After that, install MySQL again:

apt install mysql-server mysql-client