Ubuntu LAMP 7.1

Last updated: September 9th 2022

The Perfect Server - Ubuntu LAMP 7.1

This document details how we've set up our Ubuntu LAMP (Linux Apache Mysql and PHP) 7.1 stack. By provisioning a base Ubuntu Xenial image, and following these steps exactly, you would be able to duplicate our server image.

This stack has been deprecated in favor of the Ubuntu LAMP 7.2 stack

Install fail2ban and enable firewall

apt-get update; apt-get upgrade -y; apt-get install -y fail2ban ufw;
ufw allow 21
ufw allow 50000:50099/tcp
ufw allow out 20/tcp
ufw allow 22
ufw allow 80
ufw allow 443
ufw --force enable

Add some PPAs to stay current

apt-get install -y software-properties-common
apt-add-repository ppa:nginx/development -y
apt-add-repository ppa:ondrej/apache2 -y
apt-add-repository ppa:ondrej/php -y

Set up MariaDB repositories

apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
add-apt-repository 'deb [arch=amd64,i386] http://mirrors.accretive-networks.net/mariadb/repo/10.1/ubuntu xenial main' -y

Install base packages

apt-get update; apt-get install -y build-essential curl nano wget lftp unzip zoo bzip2 arj nomarch lzop htop openssl gcc git binutils libmcrypt4 libpcre3-dev make python2.7 python-pip supervisor unattended-upgrades whois zsh imagemagick

Set the timezone to UTC

ln -sf /usr/share/zoneinfo/UTC /etc/localtime

Install PHP7.1 and common PHP packages

apt-get install -y php7.1-cli php7.1-dev php7.1-pgsql php7.1-sqlite3 php7.1-gd php7.1-curl php7.1-memcached php7.1-imap php7.1-mysql php7.1-mbstring php7.1-xml php7.1-imagick php7.1-zip php7.1-bcmath php7.1-soap php7.1-intl php7.1-readline php7.1-mcrypt php7.1-common php7.1-pspell php7.1-tidy php7.1-xmlrpc php7.1-xsl php7.1-opcache php-apcu

Install Composer

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Install and configure Memcached

apt-get install -y memcached
sed -i 's/-l 127.0.0.1/-l 0.0.0.0/' /etc/memcached.conf
service memcached restart

Update PHP CLI configuration

sed -i "s/error_reporting = .*/error_reporting = E_ALL/" /etc/php/7.1/cli/php.ini
sed -i "s/display_errors = .*/display_errors = On/" /etc/php/7.1/cli/php.ini
sed -i "s/memory_limit = .*/memory_limit = 512M/" /etc/php/7.1/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php/7.1/cli/php.ini

Configure sessions directory permissions

chmod 733 /var/lib/php/sessions
chmod +t /var/lib/php/sessions

Install Apache and PHP-FPM

apt-get install -y apache2 apache2-utils libapache2-mod-fastcgi php7.1-fpm

Tweak PHP-FPM settings

Please note: We are suppressing PHP error output here by setting these options to production values

  sed -i "s/error_reporting = .*/error_reporting = E_ALL \& ~E_NOTICE \& ~E_STRICT \& ~E_DEPRECATED/" /etc/php/7.1/fpm/php.ini
  sed -i "s/display_errors = .*/display_errors = Off/" /etc/php/7.1/fpm/php.ini
  sed -i "s/memory_limit = .*/memory_limit = 512M/" /etc/php/7.1/fpm/php.ini
  sed -i "s/upload_max_filesize = .*/upload_max_filesize = 256M/" /etc/php/7.1/fpm/php.ini
  sed -i "s/post_max_size = .*/post_max_size = 256M/" /etc/php/7.1/fpm/php.ini
  sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php/7.1/fpm/php.ini

Tune PHP-FPM pool settings

  sed -i "s/;listen\.mode.*/listen.mode = 0666/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/;request_terminate_timeout.*/request_terminate_timeout = 60/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/pm\.max_children.*/pm.max_children = 70/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/pm\.start_servers.*/pm.start_servers = 20/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/pm\.min_spare_servers.*/pm.min_spare_servers = 20/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/pm\.max_spare_servers.*/pm.max_spare_servers = 35/" /etc/php/7.1/fpm/pool.d/www.conf
  sed -i "s/;pm\.max_requests.*/pm.max_requests = 500/" /etc/php/7.1/fpm/pool.d/www.conf

If you want XDebug - install it and follow the on-screen instructions

This is not installed per default on Webdock stacks - included here for reference.

pecl install xdebug

Install latest NodeJS

curl --silent --location https://deb.nodesource.com/setup_8.x | bash -; apt-get update; apt-get install -y nodejs;

Install MariaDB (MySQL) and set a strong root password

Remember to make a note of your password, you are going to need it in a minute

apt-get install -y mariadb-server;

Secure your MariaDB installation

mysql_secure_installation

Install PHPMyAdmin

At first the installation will ask you which web server we are using. Select Apache.

The following prompt will ask you if you would like dbconfig-common to configure a database for phpmyadmin to use. Select "Yes" to continue.

apt-get install -y phpmyadmin;

Symlink PHPMyAdmin, create logs dir and set permissions and ownership on /var/www

ln -s /usr/share/phpmyadmin/ /var/www/html/phpmyadmin;  mkdir /var/www/logs;  chown www-data:www-data /var/www/html; chown www-data:www-data /var/www/logs; chown www-data:www-data /var/www; chmod -R g+rw /var/www;

Install Mongodb

apt-get install -y libcurl4-openssl-dev pkg-config libssl-dev libsslcommon2-dev mongodb
pecl install mongodb

add extension=mongodb.so to PHP-fpm and PHP-cli configuration:

echo "extension=mongodb.so" > /etc/php/7.1/fpm/conf.d/30-mongodb.ini
echo "extension=mongodb.so" > /etc/php/7.1/cli/conf.d/30-mongodb.ini

Create Apache virtual host config

Edit the file /etc/apache2/sites-available/webdock.conf and set the following

Now disable the default and symlink in your config

rm /etc/apache2/sites-enabled/000-default.conf
ln -s /etc/apache2/sites-available/webdock.conf /etc/apache2/sites-enabled/webdock.conf

Make sure Apache modules are enabled

a2enmod suexec rewrite ssl actions include cgi actions fastcgi proxy_fcgi alias;

Install Letsencrypt Certbot

add-apt-repository ppa:certbot/certbot -y; apt-get update; apt-get install -y python-certbot-apache;

Restart PHP-FPM and Apache

service php7.1-fpm restart; service apache2 restart;

Setup and configure FTP

apt-get install -y pure-ftpd-common

Set some configuration

echo "no" > /etc/pure-ftpd/conf/PAMAuthentication
echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone
echo "1" > /etc/pure-ftpd/conf/TLS

Set MinUID to 33 (to allow www-data as user)

echo "33" > /etc/pure-ftpd/conf/MinUID

Add our chosen passive portrange to config

echo "50000 50099" > /etc/pure-ftpd/conf/PassivePortRange

Setup SSL Certificate for FTP 

openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 2048
openssl req -x509 -days 36500 -nodes -newkey rsa:2048 -sha256 -keyout \
  /etc/ssl/private/pure-ftpd.pem \
  -out /etc/ssl/private/pure-ftpd.pem
chmod 600 /etc/ssl/private/*.pem

Complete the configuration

touch /etc/pure-ftpd/pureftpd.passwd; /usr/bin/pure-pw mkdb;
ln -s /etc/pure-ftpd/pureftpd.passwd /etc/pureftpd.passwd
ln -s /etc/pure-ftpd/pureftpd.pdb /etc/pureftpd.pdb
ln -s /etc/pure-ftpd/conf/PureDB /etc/pure-ftpd/auth/PureDB
service pure-ftpd restart

Set up logrotate for Apache logs

Edit /etc/logrotate.d/vhost and add the following

/var/www/logs/*.log {
 rotate 8
 weekly
 compress
 delaycompress
 sharedscripts
 
 postrotate
 /usr/sbin/apache2ctl graceful > /dev/null
 endscript
}

Setup unattended security upgrades

cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF
Unattended-Upgrade::Allowed-Origins {
"Ubuntu xenial-security";
};
Unattended-Upgrade::Package-Blacklist {
//
};
EOF
cat > /etc/apt/apt.conf.d/10periodic << EOF
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
EOF

Restart your server

Make sure all services come up properly. You can see what services are listening on which ports on your server by running

netstat -tap

Congratulations. All services should now come up and you have a production-ready webserver stack running. You can further tune your webserver and PHP-FPM settings based on your use-case (e.g. whether you have a high or low traffic site, mostly serve static or dynamic content etc.). Try Googling "optimize php-fpm" or "optimize apache" for example and pick settings that fit your requirements and chosen Webdock profile. If you find some optimized defaults you would like us to include in our stacks, please let us know and we will take a look.

Related articles

We use cookies. Please see our Privacy Policy.