There is a new version of this tutorial available for Ubuntu 20.04 (Focal Fossa).

The Perfect Server - Ubuntu 18.04 (Bionic Beaver) with Apache, PHP, MySQL, PureFTPD, BIND, Postfix, Dovecot and ISPConfig 3.1 - Page 2

8. Install Apache, PHP, phpMyAdmin, FCGI, SuExec, Pear, and mcrypt

Apache 2.4, PHP 7.2, phpMyAdmin, FCGI, suExec, and Pear can be installed as follows:

apt-get -y install apache2 apache2-doc apache2-utils libapache2-mod-php php7.2 php7.2-common php7.2-gd php7.2-mysql php7.2-imap phpmyadmin php7.2-cli php7.2-cgi libapache2-mod-fcgid apache2-suexec-pristine php-pear mcrypt  imagemagick libruby libapache2-mod-python php7.2-curl php7.2-intl php7.2-pspell php7.2-recode php7.2-sqlite3 php7.2-tidy php7.2-xmlrpc php7.2-xsl memcached php-memcache php-imagick php-gettext php7.2-zip php7.2-mbstring php-soap php7.2-soap libapache2-reload-perl

You will see the following question:

Web server to reconfigure automatically: <-- apache2 
Configure database for phpmyadmin with dbconfig-common? <-- Yes
MySQL application password for phpmyadmin: <-- Press enter

Then run the following command to enable the Apache modules suexec, rewrite, ssl, actions, and include (plus dav, dav_fs, and auth_digest if you want to use WebDAV):

a2enmod suexec rewrite ssl actions include cgi
a2enmod dav_fs dav auth_digest headers

To ensure that the server cannot be attacked through the HTTPOXY vulnerability, I will disable the HTTP_PROXY header in apache globally. Create a new httpoxy.conf file with nano:

nano /etc/apache2/conf-available/httpoxy.conf

Paste this content into the file:

<IfModule mod_headers.c>
    RequestHeader unset Proxy early

Enable the config file by running:

a2enconf httpoxy

Restart Apache afterward:

service apache2 restart

If you want to host Ruby files with the extension .rb on your websites created through ISPConfig, you must comment out the line application/x-ruby rb in /etc/mime.types:

nano /etc/mime.types
#application/x-ruby                             rb

(This is needed only for .rb files; Ruby files with the extension .rbx work out of the box.)

Restart Apache afterwards:

service apache2 restart

8.1 PHP Opcode cache (optional)

Opcache is a free PHP opcode cacher for caching and optimizing PHP intermediate code. APCu is a compatibility module which provides APC compatible functions for Opcache which is used by many CMS caching systems.  It is recommended to have these PHP extensions installed to speed up your PHP page.

APCu can be installed as follows:

apt-get -y install php7.2-opcache php-apcu

Now restart Apache:

service apache2 restart


To use PHP-FPM with Apache, we need the mod_proxy_fcgi Apache module, which is installed by default and needs just be enabled. We can install PHP-FPM and as follows:

apt-get -y install php7.2-fpm

Make sure you enable the modules and restart Apache:

a2enmod actions proxy_fcgi alias 
service apache2 restart

10.1 Install HHVM (HipHop Virtual Machine), optional

In this step, we will install HHVM with apt. HHVM is a fast PHP engine developed by Facebook.

apt-get -y install hhvm

9. Install Let's Encrypt

ISPConfig 3.1 has built-in support for the free SSL Certificate Authority Let's encrypt. The Let's Encrypt function allows you to create free SSL Certificates for your website in ISPConfig.

Now we will add support for Let's encrypt.

apt-get -y install certbot

10. Install Mailman

ISPConfig allows you to manage (create/modify/delete) Mailman mailing lists. If you want to make use of this feature, install Mailman as follows:

apt-get -y install mailman

Select at least one language, e.g.:

Languages to support: <-- en (English)
Missing site list <-- Ok

The error 'Job for mailman.service failed because the control process exited with error code.' can be ignored for now.

Before we can start Mailman, a first mailing list called mailman must be created:

newlist mailman

[email protected]:~# newlist mailman
Enter the email of the person running the list:
 <-- admin email address, e.g. [email protected]
Initial mailman password: <-- admin password for the mailman list
To finish creating your mailing list, you must edit your /etc/aliases (or
equivalent) file by adding the following lines, and possibly running the
`newaliases' program:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"

Hit enter to notify mailman owner...
 <-- ENTER

[email protected]:~#

Open /etc/aliases afterwards...

nano /etc/aliases

... and add the following lines:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"



afterward and restart Postfix:

service postfix restart

Finally, we must enable the Mailman Apache configuration:

ln -s /etc/mailman/apache.conf /etc/apache2/conf-available/mailman.conf

This defines the alias /cgi-bin/mailman/ for all Apache vhosts, which means you can access the Mailman admin interface for a list at http://<vhost>/cgi-bin/mailman/admin/<listname>, and the web page for users of a mailing list can be found at http://<vhost>/cgi-bin/mailman/listinfo/<listname>.

Under http://<vhost>/pipermail you can find the mailing list archives.

Activate the configuration with:

a2enconf mailman

Restart Apache afterward:

service apache2 restart

Then start the Mailman daemon:

service mailman start

11. Install PureFTPd and Quota

PureFTPd and quota can be installed with the following command:

apt-get -y install pure-ftpd-common pure-ftpd-mysql quota quotatool

Edit the file /etc/default/pure-ftpd-common...

nano /etc/default/pure-ftpd-common

... and make sure that the start mode is set to standalone and set VIRTUALCHROOT=true:


Now we configure PureFTPd to allow FTP and TLS sessions. FTP is a very insecure protocol because all passwords and all data are transferred in clear text. By using TLS, the whole communication can be encrypted, thus making FTP much more secure.

If you want to allow FTP and TLS sessions, run

echo 1 > /etc/pure-ftpd/conf/TLS

In order to use TLS, we must create an SSL certificate. I create it in /etc/ssl/private/, therefore I create that directory first:

mkdir -p /etc/ssl/private/

Afterwards, we can generate the SSL certificate as follows:

openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem

Country Name (2 letter code) [AU]: <-- Enter your Country Name (e.g., "DE").
State or Province Name (full name) [Some-State]:
<-- Enter your State or Province Name.
Locality Name (eg, city) []:
<-- Enter your City.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
<-- Enter your Organization Name (e.g., the name of your company).
Organizational Unit Name (eg, section) []:
<-- Enter your Organizational Unit Name (e.g. "IT Department").
Common Name (eg, YOUR name) []:
<-- Enter the Fully Qualified Domain Name of the system (e.g. "").
Email Address []:
<-- Enter your Email Address.

Change the permissions of the SSL certificate:

chmod 600 /etc/ssl/private/pure-ftpd.pem

Then restart PureFTPd:

service pure-ftpd-mysql restart

Edit /etc/fstab. Mine looks like this (I added ,usrjquota=quota.user,,jqfmt=vfsv0 to the partition with the mount point /):

nano /etc/fstab
# /etc/fstab: static file system information.
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,,jqfmt=vfsv0 0 1
/dev/mapper/server1--vg-swap_1 none swap sw 0 0
/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0

To enable quota, run these commands:

mount -o remount /
quotacheck -avugm
quotaon -avug

 Which will show the following output:

[email protected]:/opt/metronome# quotacheck -avugm
quotacheck: Scanning /dev/mapper/server1--vg-root [/] done
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file // No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old user quota file //quota.user: No such file or directory. Usage will not be subtracted.
quotacheck: Cannot stat old group quota file // No such file or directory. Usage will not be subtracted.
quotacheck: Checked 13602 directories and 96597 files
quotacheck: Old file not found.
quotacheck: Old file not found.
[email protected]:/opt/metronome# quotaon -avug
/dev/mapper/server1--vg-root [/]: group quotas turned on
/dev/mapper/server1--vg-root [/]: user quotas turned on

12. Install BIND DNS Server

BIND can be installed as follows:

apt-get -y install bind9 dnsutils haveged

Enable and start the haveged Daemon:

systemctl enable haveged
systemctl start haveged

13. Install Vlogger, Webalizer, and AWStats

Vlogger, Webalizer, and AWStats can be installed as follows:

apt-get -y install vlogger webalizer awstats geoip-database libclass-dbi-mysql-perl

Open /etc/cron.d/awstats afterwards...

nano /etc/cron.d/awstats

... and comment out everything in that file:


#*/10 * * * * www-data [ -x /usr/share/awstats/tools/ ] && /usr/share/awstats/tools/

# Generate static reports:
#10 03 * * * www-data [ -x /usr/share/awstats/tools/ ] && /usr/share/awstats/tools/


14. Install Jailkit

Jailkit is needed only if you want to chroot SSH users. It can be installed as follows (important: Jailkit must be installed before ISPConfig - it cannot be installed afterwards!):

apt-get -y install build-essential autoconf automake1.11 libtool flex bison debhelper binutils
cd /tmp 
tar xvfz jailkit-2.19.tar.gz
cd jailkit-2.19
echo 5 > debian/compat

Then build the jailkit package by running this command:

./debian/rules binary

You can now install the Jailkit .deb package as follows:

cd ..
dpkg -i jailkit_2.19-1_*.deb
rm -rf jailkit-2.19*

15. Install fail2ban and UFW

This is optional but recommended, because the ISPConfig monitor tries to show the log:

apt-get -y install fail2ban

To make fail2ban monitor PureFTPd and Dovecot, create the file /etc/fail2ban/jail.local:

nano /etc/fail2ban/jail.local
enabled  = true
port     = ftp
filter   = pure-ftpd
logpath  = /var/log/syslog
maxretry = 3

enabled = true
filter = dovecot
action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 5

enabled  = true
port     = smtp
filter   = postfix
logpath  = /var/log/mail.log
maxretry = 3

Restart fail2ban afterwards:

service fail2ban restart

To install the UFW firewall, run this apt command:

apt-get install ufw
Share this page:

13 Comment(s)

Add comment

Please register in our forum first to comment.


By: ei8ht

It's either a bug or no longer needed, but php-auth does not exist in Bionic Beaver. Is php-auth-sasl (this one exists) a vlid replacement?

By: gLeW

Hi whe i try to make the quota installation i have this error


[email protected]:/usr/sbin# quotaon -avug

quotaon: using // on /dev/vda1 [/]: No such process

quotaon: Quota format not supported in kernel.

quotaon: using //quota.user on /dev/vda1 [/]: No such process

quotaon: Quota format not supported in kernel.


My fstab only have this 2 lines

LABEL=cloudimg-rootfs   /        ext4   defaults        0 0

LABEL=UEFI      /boot/efi       vfat    defaults        0 0

delete this 2 lines and copy this 


# /etc/fstab: static file system information.## Use 'blkid' to print the universally unique identifier for a# device; this may be used with UUID= as a more robust way to name devices# that works even if disks are added and removed. See fstab(5).## <file system> <mount point> <type> <options> <dump> <pass>/dev/mapper/server1--vg-root / ext4 errors=remount-ro,usrjquota=quota.user,,jqfmt=vfsv0 0 1/dev/mapper/server1--vg-swap_1 none swap sw 0 0/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0



By: till

The error message you posted explains your problem: "Quota format not supported in kernel.". You are installing on a server where the Kernel does not support quota. Most likely you are installing on some kind of virtual server were your server hoster does not allow quota inside the virtual machines.

By: willoriker

this a wonderful job. i have a doubdt, all the site createdin ispcpnfig with ssl let´s encrpt work perfect, but the wheni open sipconfu webpage o if i acces to the mail server , the certificate was refuse or not found, how can i refresh this certificate?

By: willoriker

good morning,

first , amazing job

second, i have a doubt

my server work perfect, all of components  fine, except

1 web ( only for 1 spcefic domain) cannot enable LE, i can enable ssl, but no LE

i have 10 sites w/o problemas, more i create  after this  situation an aditional site w/o problem

i suspect somebody ( an employe) delete key files ( i dont know where and what)

tha LE log  saids:"File "/usr/lib/python3/dist-packages/acme/", line 943, in _check_response    raise messages.Error.from_json(jobj)acme.messages.Error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type :: Error creating new order :: too many certificates already issued for exact set of domains:, see 11:31:03,549:ERROR:certbot.log:An unexpected error occurred:2019-03-11 11:31:03,549:ERROR:certbot.log:There were too many requests of a given type :: Error creating new order :: too many certificates already issued for exact set of domains:, see"

any idea?

are there any way to reinstall cert w/o to damage ispconfig instalation?

tx in advance

By: till

The error message explains exactly what the problem is, you requested too many ssl certs for the same domain set and therefore you reached your let's encrypt limit. See the link in the error message: So the problem is not ISPConfig here and the problem can not be solved by ISPConfig. As soon as LE allows you to create new certs again, you will be able to enable the let#s encrypt checkbox in the website in ISPConfig.

By: LGSmith

In regards to quota, I was using a vps and the kernal was different. Fortunately, this is a standard Ubuntu 18.04 install issue and addressed in user guides. The following article was helpful to me

though I never actually found the files the author was testing for. I did install the linux-image-extra-virtual package. The fstab modification was changed "defaults" to user, group quota ie:

LABEL=cloudimg-rootfs / ext4 usrquota,grpquota 0 0

No error on remount, group and user files were in root directory and the quotaon command responded affirmatively.

My key take-away for Till Breham, whose articles are always in depth, is to add note that quota is kernal dependent and the object is to add both user and group quotas.

By: pebkac

Is there a reason why PHP 7.3 is not installed?

By: till

The default PHP version of Ubuntu 18.04 is PHP 7.2 and not 7.3. ISPConfig requires it that you install the default PHP version of the operating system as the base PHP. You can install older and newer PHP versions as additional PHP versions and use them in the websites.

By: labsy

Till, at 11. just AFTER generating SSL certificate for pure-ftpd-mysql and BEFORE editing /etc/fstab, I found out you need to generate DH parameters hash, othervise quota might fail, system will mount read-only, and you will have problems. I did it with longer hash.

So, just after SSL generation, run this and then restart pure-ftpd-mysql service:

openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 3072

By: peterpetr

In this Ubuntu 18.04 install guide, you have instructions for Opcache. In the automated script, it prompts to install Xcache ('yes' or 'no').  But, when I Google this, I find that PHP 7.x already has such functionality built in:

PHP versions 5.5 and above include a built-in, high-performance, reliable opcode cache. The XCache extension was written before PHP had a built-in opcache. You should only use this extension if you have a specific need for it.

Q1: So, is HowToForge correct to advise such installation of Opcache or Xcache for PHP 7.x?

Q2: I've already used the automated script to install ISPConfig ( ). If it's advisable to install Xcache or Opcache, can it be easily installed after installing ISPConfig?



By: till

1) Yes, the commands above install the builtin opcache module, just follow the instructions. Xcache is not needed anymore and that's why this tutorial does not install it.

2) The script you used is not an official ISPConfig install script nor does it follow the perfect server guide instructions.

By: CaptainStarbuck

This article shows steps 8.1, 8.2, 10.1, then 9.