Building A Lamp Stack On Ubuntu 12.04

Whenever I build or make changes to a server I always try to write down what I have done. This makes for some great references on future builds. In addition, their are a ton of guides and tutorials available for building a LAMP stack, you should read them all, or atleast as many as you can. I say this because there are no absolutes when it comes to building these stacks, only our experiences. Sharing our experiences and allowing open conversation is the best way to gain more knowledge and insight. In that vain I'm sharing my latest server build. This build is on a Rackspace instance using Ubuntu 12.04 (upgraded from 11.10). This should work on any clean instance of Ubuntu 11.x or greater for which you have root access; be it bare metal or a cloud solution. In following this you will walk away with a functional LAMP stack.


I'll start by going to Rackspace and logging into my cloud control panel. Then click on Hosting -> Cloud Servers -> Add Server and choose an operating system. We will choose Ubuntu 11.10. You will get a dialog with the admin password make a note of this and the IP address from the server's overview page.

To access the server and begin this build open a terminal window and use ssh to access your new server. Replace with your IP address.

ssh [email protected]

The first thing you'll want to do is change the password. Type the command


You'll be prompted to enter a new password and to confirm it. I recommend using a password generation tool such as the one provide in LastPass. You should set this to 20+ characters using alphanumeric mixed case and special characters (remember you shouldn't be logging in as root very often). Test your password after you have changed it. If you are familiar with Ubuntu you will probably notice I'm not using sudo. That is because the Rackspace images give you root. Just use the [su] command to toggle between root and a less privileged user.

ssh [email protected]


As I said, this tutorial is for Ubuntu 12.04 yet we grabbed an image for 11.10. That's because at the time of this writing Rackspace does not yet offer an Ubuntu 12.04 image, so we will just upgrade it from 11.10. We do this by making sure 11.10 has all of the latest updates, then we run a distribution upgrade. You will be prompted to make some choices throughout this process. I will accept say [Y], [y] or to all yes/no questions. I will accept the default for all other questions. If you have a reason for answering otherwise, do it. Every server is different, this should only be viewed as a guide.

apt-get update
apt-get upgrade
apt-get dist-upgrade

sudo apt-get update
sudo apt-get install update-manager-core
sudo do-release-upgrade

You know you've reached the end of the upgrade when you the message "The system is going down for reboot NOW!". At this point, log back in through ssh.

ssh [email protected]

If your greated with a the message "Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.0.0-12-virtual x86_64)"; the upgrade was successful.


I know this is a LAMP stack, but their are a couple of JAR files I Like; Google Closure and YUI Compressor. These are great for minifying and combining your CSS and JavaScript assets. If your not planing to use these you can probably get by without installing JAVA, in fact I wouldn't. Always remember; if you don't need it, don't install it. We will use OpenJDK.

apt-get install openjdk-7-jre-headless

LAMP Stack

One of my favorite things about Ubuntu is the ease at which you can install the LAMP Stack.

apt-get install lamp-server^

You will be prompted to enter the password for the MySQL root user. Again I recommend using a password generation tool such as the one provide in LastPass. You should set this to 20+ characters using alphanumeric mixed case and special characters.


We will want to add a new user. This is the user that will be responsible for keeping the web sites and directories up to date. I will call this user webmaster. We will start by creating the user webmaster and setting the password for the user webmaster. Again I recommend using a password generation tool such as the one provide in LastPass. You should set this to 20+ characters using alphanumeric mixed case and special characters.

adduser webmaster
passwd -l webmaster

Next we will apply the desired privileges to our web directory. I like to keep my web directories on the default Apache path /var/www, granting privledges on this directory will assure webmaster can always do his thing. We will change ownership to the www-data user and the webmaster group. The user www-data is the PID of the Apache Process. This will allow the server as needed. The group webmaster is the group of the webmaster user. This allows us to login as the webmaster user or any user we assign to the webmaster group and make changes to the web directory.

chown www-data:webmaster /var/www
chown www-data:webmaster -R /var/www /var/www/*
chmod 775 -R /var/www
chmod 775 -R /var/www /var/www/*

Apache Modules

I have found the following mods to be useful. If you application does not require something listed here, do not install it.

a2enmod headers rewrite ssl env filter
service apache2 restart

Supporting Applications

Again only install what you need. My needs require the following.

apt-get install php5-gd zip mcrypt php5-mcrypt curl php5-curl
service apache2 restart


I like to use postfix to send email via PHP. You could use sendmail but in my experience postfix is a bit faster.

apt-get install postfix

You will get a dialog asking "General type of mail configuration:". Choose the "Internet Site" option.

You will then be asked "System mail name:" Enter the fully qualified domain name (FQDN).


While I mostly interact with my server over SSH, FTP can be very useful. I'll install ProFTP on my server and Filezilla on my client machine. At this point I can get the best of both worlds, a simple FTP client over an SSH connection. Answer [Y] to all of the questions and choose the standalone option.

apt-get install proftpd


Personally, I do not like to run non-ssl sites, unless they are completely static. I would never suggest using a self-signed certificate in a production environment. However, they are handy for development and local environments. For the sake of a complete tutorial I will walk you through installing self-signed certificate. For a production site, replace the self signing with the directions supplied to you by your SSL vendor. I like to start with an SSL directory under /etc/apache2. From here it's a matter of creating the certificate files and telling your site configuration where to find them.

mkdir /etc/apache2/ssl && cd /etc/apache2/ssl

Create the self-signed certificate.

sudo openssl req -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem

You will need to complete a certificate signing request (CSR). You will be asked several questions, since this is a self signed certificate, used in a non-production environment, you can just leave most of them blank or enter anything you want. I answered with the following

Country Name (2 letter code) [AU]: US
State or Province Name (full name) [Some-State]: IL
Locality Name (eg, city) []: Chicago
Organization Name (eg, company) [Internet Widgits Pty Ltd]: My Org
Organizational Unit Name (eg, section) []: My Unit
Common Name (eg, YOUR name) []:
Email Address []: [email protected]

You may be asked some challenge questions, leave these blank.

A challenge password []:
An optional company name []:

Now we need to tell the server that a specific site can use the certificate. For the sake of argument we will just configure the default-ssl setup.

vim /etc/apache2/sites-available/default-ssl

Find and comment out the following lines

SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

Find the following line

SSLEngine on

And add the following right below it

# Use our self-signed certificate by default
SSLCertificateFile /etc/apache2/ssl/apache.pem

You should now have the following

SSLEngine on

# Use our self-signed certificate by default
SSLCertificateFile /etc/apache2/ssl/apache.pem

Now (re)load the ssl site configuration and restart Apache

a2dissite default-ssl
service apache2 restart

a2ensite default-ssl
service apache2 restart


phpMyAdmin is a good, high level tool for managing a MySQL database.

apt-get install phpmyadmin

Choose apache2 Choose to db-common

You'll then be prompted for your MySQL root password, then you'll want to create a password for the phpMyAdmin application. The next step is telling apache how to access phpMyAdmin. You'll probably want to go to something like or Where is you domain name and is your sites IP. To do this, just tell Apache where to find phpMyAdmin.

vim /etc/apache2/apache2.conf

Add the following line

# Tell Apache how to find phpMyAdmin
Include /etc/phpmyadmin/apache.conf

service apache2 restart

Due to it's popularity phpMyAdmin is often the target of drive by attacks. You can add a little extra security by forcing SSL and putting phpMyAdmin behind an http password.

To force SSL and to create and force an http password create an .htaccess file in phpMyAdmins' web directory.

cd /usr/share/phpmyadmin
sudo vim .htaccess

Add the following lines replacing with your servers IP.

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} phpmyadmin
RewriteRule ^(.*)$ http://<Server IP>/phpmyadmin/$1 [R,L]

AuthUserFile /usr/share/phpmyadmin/.htpasswd
AuthName "Developer Web Tools"
AuthType Basic
<Limit GET POST>
require valid-user

Now create the credentials replacing valid user with the desired username.

htpasswd -c .htpasswd <validuser>

Enter the desired password for . At this point you should be able to use your servers IP address to get to phpMyAdmin. If you set up a self-signed certificate try http:///phpmyadmin otherwise http:///phpmyadmin (you really never want to access this over http use https). You get a dialog for entering your http password. After a successful authentication you'll be redirected to the phpMyAdmin login screen. If you make to this screen, your server is ready to go!