First, make sure the lamp-server package is installed.
root@jiffybox # apt-get install tasksel
root@jiffybox # tasksel install lamp-server

Step 1 - Install the Apache2 webserver

Important config files:
  • /etc/apache2/sites-available/default
Install webserver package:
root@jiffybox # apt-get install apache2
Start the service and check if it works properly:
root@jiffybox # service apache2 restart # (or '/etc/init.d/apache2 restart')
root@jiffybox # wget http://localhost -O - 2>/dev/null

Configure a subdomain

We want to bind a subdomain to a file system directory.
In this setup, the html documents stored in
/data/www-data/toplevel/ are accessible from the URL http://mydomain.ws , while the htdocs located in
/data/www-data/subdomain-test/ are accessed through http://test.mydomain.ws .

The relevant (DNS) name server settings are:

Hostname Type Priority Target
mydomain.ws A - 141.0.20.92
test.mydomain.ws A - 141.0.20.92

The binding is defined in /etc/apache2/sites-available/default :
<VirtualHost *:80>
        ServerName mydomain.ws
        ServerAlias www.mydomain.ws
        ServerAdmin webmaster@localhost
        DocumentRoot /data/www-data/toplevel
        
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /data/www-data/toplevel>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        
</VirtualHost>
<VirtualHost *:80>
  ServerName test.mydomain.ws
  DocumentRoot /data/www-data/subdomain-test
</VirtualHost>

Step 2 - PHP installation

Important config files:
  • /etc/php5/apache2/php.ini
Install Apache PHP module:
root@jiffybox # apt-get install libapache2-mod-php5
You should disable the deprecated '<? ' PHP start tags (If you do not use legacy code using them).
This will ensure that files that start with '<?xml' can never be executed as code by the PHP interpreter. (security issue)
Uncomment/add the following statement in /etc/php5/apache2/php.ini :
set 'short_open_tag = Off'
Start the webserver and test if the module works properly:
root@jiffybox # echo '<?php phpinfo(); ?>' > /var/www/test.php
root@jiffybox # service apache2 restart
root@jiffybox # wget http://localhost/test.php -O - 2>/dev/null | grep -iEo 'php version 5[^<>]*'
root@jiffybox # rm /var/www/test.php

Step 3 - MySQL installation

Important config files:
  • /etc/mysql/my.cnf
Install the server software, and modules for apache and php:
root@jiffybox # apt-get install mysql-server libapache2-mod-auth-mysql php5-mysql
Test your installation using the password you defined during installation: (exit prompt with '\q' )
mysql@jiffybox $ mysql -u root -p
First you should change your mysql root password:
mysql@jiffybox $ mysqladmin -u root -p

Enable remote access

If you need access to your databases from outside this host, you can comment out the following statement in /etc/mysql/my.cnf. If the database should be accessible only by a single host, you can replace 'localhost' with its IP address (or hostname).
bind-address = localhost
Set firewall exception rule for the mysql port (3306 by default)
root@jiffybox # /sbin/iptables -A INPUT -i eth0 -p tcp --destination-port 3306 -j ACCEPT

Create a database and a mysql user:

Enter the mysql prompt and setup a db and a user:
mysql@jiffybox $ mysql -u root -p

mysql> CREATE USER 'user1'@'%';
mysql> UPDATE mysql.user SET Password = PASSWORD('foo') WHERE User = 'user1';

mysql> CREATE DATABASE database1;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON database1.* TO 'user1'@'%';

mysql> FLUSH PRIVILEGES;
To grant remote access to user1, browse to phpmyadmin as root user, go to Privileges and change the host of user1 to "any host",
or enter:
mysql@jiffybox $ mysql -u root -p
mysql> UPDATE mysql.user SET Host = '%' WHERE User = 'user1';
mysql> FLUSH PRIVILEGES;

Step 4 - Install phpmyadmin

Important config files:
  • /etc/phpmyadmin/*
Simply install the phpmyadmin package:
root@jiffybox # apt-get install phpmyadmin

To enable the phpmyadmin webconsole, add this line to
apache's configuration file /etc/apache2/apache2.conf :

Include /etc/phpmyadmin/apache.conf
Test the console by restarting your webserver with
root@jiffybox # service apache2 restart
and browse to phpmyadmin and try to login with your mysql user account(s).

Step 5 - Finish the installation

Restart the server and perform a config check:
root@jiffybox # /usr/sbin/apache2ctl stop
root@jiffybox # /usr/sbin/apache2ctl configtest
root@jiffybox # /usr/sbin/apache2ctl start
If you want to use your apache installation only locally (e.g. for development), you can bind it by adding/editing the following line in your /etc/apache2/ports.conf file to prevent the webserver from handling incoming connection attempts.
Listen 127.0.0.1:80
On public accessible hosts, you should harden your system. This can be done easily by installing and running bastille:
root@jiffybox # apt-get install perl-tk bastille
root@jiffybox # bastille # and follow the wizard
There are also good guides for hardening ubuntu systems in this and this article.