Paint the Web - a micro-Blog in .md about Dev, Web and more

Local Web Server on Ubuntu 16.04 with a Server Control Panel

Fast Walkthrough of getting a LAMP or LEMP stack running on Ubuntu, meant not for a production server.


  • Ubuntu 16.04 Server
  • Apache or nginx runtime
  • MySQL and PostgreSQL support
  • PHP 7+ with suggested extensions
  • no Mailserver
  • simple server control panel - no virtual host control panel

Prepare System

Go to Ubuntu and download 16.04 LTS.

Make a boot medium and install on your desired system. During the setup you will be asked what you want to install. Select PostgreSQL database, standard system utilities, OpenSSH server. I suggest DNS Server, Samba file server and Virtual Machine Host for other tasks.

Continue and set the rest like you need.

After the reboot you could now login to the server from your workstation through SSH with the IP of the server.

Now fetch updates and upgrade your fresh linux.

apt update && apt upgrade -y

I prefer to do a reboot after the first upgrade after installation.

PHP and dev tools

apt install -y python-software-properties &&
apt-add-repository -y ppa:ondrej/php &&
apt update && apt upgrade -y

Install these PHP packages:

apt install -y php7.1 php7.1-bcmath php7.1-bz2 php7.1-cgi php7.1-cli php7.1-common php7.1-curl php-date php7.1-dev php7.1-enchant php7.1-fpm php7.1-gd php-gettext php7.1-gmp php7.1-imap php7.1-interbase php7.1-intl php7.1-json php7.1-ldap php7.1-mbstring php7.1-mcrypt php7.1-mysql php7.1-odbc php7.1-opcache php7.1-pgsql php7.1-phpdbg php7.1-pspell php7.1-readline php7.1-recode php-redis php7.1-snmp php7.1-soap php7.1-sqlite3 php7.1-sybase php7.1-tidy php7.1-tokenizer php7.1-xmlrpc php7.1-xsl php7.1-zip php-imagick openssl

or for PHP 7.2:

apt install -y php7.2 php7.2-bcmath php7.2-bz2 php7.2-cgi php7.2-cli php7.2-common php7.2-curl php-date php7.2-dev php7.2-enchant php7.2-fpm php7.2-gd php-gettext php7.2-gmp php7.2-imap php7.2-interbase php7.2-intl php7.2-json php7.2-ldap php7.2-mbstring php7.2-mysql php7.2-odbc php7.2-opcache php7.2-pgsql php7.2-phpdbg php7.2-pspell php7.2-readline php7.2-recode php-redis php7.2-snmp php7.2-soap php7.2-sqlite3 php7.2-sybase php7.2-tidy php7.2-tokenizer php7.2-xmlrpc php7.2-xsl php7.2-zip php-imagick openssl

Notice: mcrypt was removed

Recommended dev tools

apt install -y git nodejs npm composer tree curl ftp
npm install -g node-sass sassdoc grunt-cli bower

For LAMP / Apache Stack

apt install -y apache2 libapache2-mod-php7.1
a2enmod proxy_fcgi setenvif
a2enconf php7.1-fpm

or for PHP 7.2:

apt install -y apache2 libapache2-mod-php7.2
a2enmod proxy_fcgi setenvif
a2enconf php7.2-fpm
vi /etc/php/7.1/apache2/php.ini
systemctl restart apache2.service

First create folder for public files:

mkdir -p /var/www/vhosts/

and a test file, add any content:

vi /var/www/vhosts/

Copy default config file and edit:

cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/

vi /etc/apache2/sites-available/

Change those:

DocumentRoot /var/www/vhosts/
ErrorLog /var/www/vhosts/
CustomLog /var/www/vhosts/ combined

AllowOverride None # or all when .htaccess should be allowed

Enable new vhost and disable default:

a2dissite 000-default.conf

service apache2 reload

The domain must route to the server (e.g. Windows\System32\drivers\etc\hosts or /etc/hosts) or a DNS server.

Test with simply:


If it return the content of your previously created index.html, you just created your first virtual server!

SSL Support

Check if something listens to port 443 in /etc/apache2/ports.conf.

Then activate

a2enmod ssl

Generate a self signed cert

openssl genrsa -out /etc/ssl/private/apache.key 2048 &&
openssl req -new -x509 -key /etc/ssl/private/apache.key -days 365 -sha256 -out /etc/ssl/certs/apache.crt  

Create SSL vhost File

vi /etc/apache2/sites-available/
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/apache.crt
    SSLCertificateKeyFile /etc/ssl/private/apache.key

    DocumentRoot /var/www/vhosts/
    ErrorLog /var/www/vhosts/
    CustomLog /var/www/vhosts/ combined

    AllowOverride None # or All when .htaccess should be allowed

and activate

service apache2 force-reload

Now skip the next step and go to installing the control panel.

For LEMP / nginx Stack

apt install -y nginx
vi /etc/php/7.1/fpm/php.ini

vi /etc/php/7.1/cli/php.ini
# chnage inside to:

systemctl restart nginx.service php7.1-fpm.service

Create virtual server file:

vi /etc/nginx/sites-available/
server {
    listen 80;
    root /var/www/;
    index index.php;

    location / {
        try_files $uri $uri/ =404;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.1-fpm.sock;
        include snippets/fastcgi-php.conf;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    location ~ /\.ht {
        deny all;

Activate through setting a symlink in enabled:

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Restart nginx:

systemctl restart nginx.service

Auto run nginx with FPM:

systemctl enable nginx.service
systemctl enable php7.1-fpm.service

Install the Control Panel

How to install Ajenti:

Ajenti 2.*

An easy and light UI for seeing server stats, a web notepad for system files, networking tools and much more. This is not a virtual server control panel.

curl | sudo bash -s -

Ajenti needs root rights, change root pw, root ssh doesn't need to be allowed. Or add another account to sudoer.

passwd root

Now reboot or service ajenti restart.

You could now login to https://domain-or-host-or-ip:8000 with any linux user, but should login with root to configure and setup Ajenti.

Access Webspace

SFTP / SSH File Transfer Protocol:

If you want to use root and have activated root ssh login, you are ready to go.

Using Apache?

But preferred is to let Apache run different vhosts with different users, giving each of them FTP access,

apt install -y libapache2-mpm-itk
a2enmod mpm_itk

Adding user example_usr to user group web_usr and change owner of vhost folder

adduser example_usr
addgroup web_usr
adduser example_usr web_usr

chown -cR example_usr:web_usr /var/www/vhosts/ 

Then add to the needed vhosts files

<Virtualhost *:80>

    <ifmodule mpm_itk_module>
        AssignUserID example_usr web_usr


And reload and start:

service apache2 reload &&
service apache2 restart

Now you could login to your server with SFTP and the user example_usr.

Using nginx?

Got something to add? Just add a PR.


Install the MySQL server:

apt install -y mysql-server

Thanks to Ubuntu updating iptables is easy:

ufw allow 3306

But MySQL listens only to as default, with * it is bound to all interfaces.

vi /etc/mysql/mysql.conf.d/mysqld.cnf

# then change:
bind-address = *

service mysql restart

Check the bound iface:

netstat -tupan | grep mysql

# example:
Proto Recv-Q Send-Q Local Address Foreign Address State  PID/Program name
tcp6  0      0      :::3306       :::*            LISTEN 3614/mysqld

In MySQL the user need also be able to connect from other hosts, this allows root access from anywhere.

Login to MySQL on server:

mysql -u root -p

Where password must be the password of root, it seems not to be a selector.

  IDENTIFIED BY 'password'


Can't connect?

  • Check is a mysqld process runs ps xa | grep mysqld.
  • Are the IP bound correct?
  • Is the port correct?
  • Does the user have remote access right from the host you are on?
  • Is your host firewall blocking?
  • Are you on the same network?
  • Or anything else?


So, now you are able to connect, transfer, modify your code and files. In a basic environment needed for most web development done with PHP/HTML.

Some PHP modules need to be activated, e.g. mod_rewrite

a2enmod rewrite
service apache2 restart