Where science and tech meet creativity.

Apologies for the lack of astronomy in this post. I just spent 6 hours trying to set up a server, and most of that time was spent fussing needlessly. No one should need to repeat my endeavors, so…. I’m taking what I learned and blogging it to save any poor souls who may be repeating what I do. These instructions should work for any OS X / linux system.

Goal: Setup on EC2 an Ubuntu server configured to run PHP software on an Apache Server connected to a MySQL database on an RDS (This is a LAMP server)

Uses: This type of configuration can be used for WordPress, phpBB, SMF, and any number of other php online toys

Notes: There are two ways to set this up servers. You can either go through the online GUI or use a commandline toolkit. For advanced features you have to use the command line, but… For basic setup you can just use the GUI. Also: Amazon does not allow capital letters and _ marks in all situations. It is easiest just to avoid uppercase and underscores at all times.

Step 0: Go sign up for AWS. Give them your credit cards, acknowledge this won’t be free. There is a good tutorial here, and it is worth going through, starting and terminating a server.

Step 1: Setup a Database. This step takes the longest for Amazon to process, so get it going first and it will be ready for you to configure things when you are done getting your EC2 server setup in the next step

  • Sign into your AWS console
  • On the RDS tab, set up a mysql db. Set up a 5GB instance and otherwise use all the defaults
  • Add a security group other than default (I called my web)
  • come back later and…. When the DB is finished setting up, modify it to add the new security group so it shows “default, web”

Step 2: Get security keys. You will need a whole variety of security keys. Might as well set them all up now. These can be found under AWS Account > Security Credentials

  • X.509 certificate and private key file (rename these to something useful. I use X509cert_instancename.pem and X509priv_instancename.pem
  • AWS account id
  • Keypair (I use the naming convention key_pk_instancename.pem // key_rsa_instancename.pem)

When you have all the Keypairs, put them somewhere you won’t lose them (I use ~/.ssh on my local machine)

Step 3: Create an EC2 server. The set of default Amazon Machine Images (AMIs) may not include what you want. These change regularly, and when I setup my server they were useless. A complete list of AMIs can be found on the Cloud Market. Official Ubuntu installs are posted by the user “Canonical.” I found the most recent for the current stable version of Ubuntu. On 1/22/2011 this was Maverik Merrkat and ami-c0a959a9.

  • Go to the Cloud Market to find the AMI you want and note the code number
  • Sign into your AWS console
  • On the EC2 tab, launch a new instance. To use the AMI you selected, click on the “Community AMIs” tab and type in the code number you noted above. I just used default values for everything
  • For you sanity, give the instance a name. You may find your self growing servers like mushrooms
  • You will be prompted to create a new keypair – this is required for you to login. Save it to ~/.ssh (naming convention instancename.pem)
  • Create a security group with the same name you used for the DB (you’ll still need to link them).
  • Add default ports for HTTP, HTTPS, MySQL, SSH for the whole internet
  • While it is launching, go to the RDS tab > DB Security Groups, and edit the security group you created in step 1 to include the EC2 security group you just created (you’ll also need the account ID, which can be found under account > security credentials)
  • NOTE: If the Public DNS is ec2-123-456-78-90.compute-1.amazonaws.com the IP is 123.456.78.90

Step 4: Login to your server and set up user. Initially your server will only require the keypair in order for you to login. This is mostly safe, but you likely want to force a password as well. It is also good to not do all your work as root.

  • Note: The username varies with type of instance. For ubuntu it’s ubuntu
    localhost:.ec2 $ ssh -i instancename.pem username@ecX-XX-XXX-XXX-XX.compute-X.amazonaws.com
    This will provide you a regular command line login
  • Setup the new user :~$ sudo useradd -d /home/username -m -s /bin/bash username
    :~$ sudo passwd username
    Enter new UNIX password: NEWPASSWORD
    Retype new UNIX password: NEWPASSWORD
    passwd: password updated successfully
  • You also need to add to the sudo file
    :~$ sudo visudo
    Go to the line ALL = (ALL) ALL and add the new user following example of admin (the leading % not needed)
  • Give the user ssh access
    :~$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original
    :~$ sudo chmod a-w /etc/ssh/sshd_config.original Change PasswordAuthentication to yes
    :~$ sudo /etc/init.d/ssh restart

Step 5: Update your distribution and install LAMP and EC2 Tools. The Ubuntu AMI you started is a plain install of Ubuntu and doesn’t have all the libraries you need. That’s ok. These are easy to get via apt.

  • Log back into your instance as the user you just created.
  • Install updates
    :~$ sudo aptitude update && sudo aptitude dist-upgrade
  • Reboot
    :~$ sudo reboot
  • Log back in and use apt to get needed software
    :~$ sudo apt-get install apache2 libapache2-mod-php5 php5-mysql postfix mysql-client unzip php5-memcache php5-curl memcached php5-gd
    :~$ sudo a2enmod rewrite headers expires

    Say yes to all options, including the mysterious postfix options
  • Check if it works by going to your public IP or public DNS. You should see a basic apache test page
  • Install the EC2 Tools after enabling multiverse
    :~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
  • And edit the sources.list file so that all the multiverse lines are uncommented.
  • Update the list of apt files and then install the commandline ec2 tools. You’ll need these if you ever need to configure dynamic servers.
    :~$ sudo apt-get update; sudo apt-get install ec2-api-tools
  • Copy your certificates to your .ssh directory. From your local machine
    localmachine: $ scp -i ~/.ssh/instancename.pem X509priv_instancename.pem X509cert_instancename.pem ubuntu@ec2-67-202-7-11.compute-1.amazonaws.com:~/.
  • Configure on the EC2 instance your Bash profile (and the user you created’s profile) to include the following lines
    export EC2_PRIVATE_KEY=$HOME/.ssh/X509priv_instancename.pem
    export EC2_CERT=$HOME/.ssh/X509cert_instancename.pem
    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/

    And then enable these features using :~$ source .bashrc

Step 6: Test MySQL. Call me paranoid, but this is a whole lot of work to have something not work.

  • Test ability to connect to db from command line
    mysql -u [Master User name] --password=[Master Password] -h [Endpoint hostname]
  • That should work! If it doesn’t, um… Google.

Step 7: Setup Virtual Host. By default, your server wants all its web files in /var/www. This is fine, but requires a whole lot of sudo (or permissions changing), and limits your ability to have a bunch of applications (potentially with different domain names) all on the one server. This is a rather boring virtual host that simply sets up a project folder. I assume you are working as ‘username’ and the code is in ~username/public_html/Project and if you are allowing uploads, they are in ~username/public_html/Project/uploads.

  • Backup the apache default config incase you step on something, then create copy to change and change it
    :~/ sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/default.original
    :~/ sudo cp /etc/apache2/sites-available/default.original /etc/apache2/sites-available/ProjectName
    :~/ sudo vi /etc/apache2/sites-available/ProjectName

    Edit the file to look like
    <VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /home/username/public_html/Project
    <Directory /home/username/public_html/Project>
    Options FollowSymLinks
    AllowOverride None
    </Directory>

    # Don't let anything in wp-content/uploads be executed as php
    <Directory /home/username/public_html/Project/uploads>
    Order allow,deny
    Allow from all
    <IfModule mod_php5.c>
    php_admin_flag engine off
    </IfModule>
    AddType text/plain .html .htm .shtml .php .php3 .phtml .phtm .pl
    </Directory>

    ErrorLog /home/username/public_html/Project/logs/error.log
    LogLevel warn
    CustomLog /home/username/public_html/Project/logs/access.log combined
    </VirtualHost>

  • disable the default site: :~/$ sudo a2dissite default
  • enable the new configuration :~/$ sudo a2ensite ProjectName
  • restart apache :~/$ sudo /etc/init.d/apache2 restart
  • Create a test file in your new directory: vi /home/username/public_html/Project/test.php
    Include in the file the code
  • Copy the test.php file to the uploads directory
  • Test both files. The first should show a php config file, the second should show the file contents

Step 8: Connect to MySQL via php. This should be the hint you need to do everything else.

  • Create a mysql test file :~/public_html/Project$ vi mysqltest.php
  • make the file contents
    <?php
    //connection to the database
    $con = mysql_connect("name.abc123def456.us-east-1.rds.amazonaws.com",root,"PASSWORD") or die(mysql_error());
    echo "Database connected.";
    ?>
  • Go to the webpage for mysqltest.php (http://SERVERNAME/mysqltest.php). This should give you a “Database connected” message

Optional: SAVE your AMI in case you need it later

  • Upload your private key and x509 certificate if you haven’t yet (and you should have, but…).
    localhost: $ scp -i ~/.ssh/instancename.pem X509priv_instancename.pem X509cert_instancename.pem ubuntu@ec2-67-202-7-11.compute-1.amazonaws.com:~
  • And then on the Amazon image, move them to /mnt
    :~$ sudo mv ~/*_instancename.pem /mnt
  • Next export everything
    :~$ sudo ec2-bundle-vol -d /mnt -k /mnt/X509priv_instancename.pem -c /mnt/X509cert_instancename.pem -u -r x86_64 -p sampleimage
    (Use apt-get as needed and indicated by error messages)
  • check that it is there with
    :~$ ls -l /mnt/sampleimage.*
  • upload it with
    :~$ ec2-upload-bundle -b [name of s3 bucket that will be created] -m /mnt/sampleimage.manifest.xml -a AWS-ACCESS-KEY-ID -s AWS-SECRET-KEY --location US

Optional: Download and install the Amazon API Tools locally

  • Create ~/.ec2
  • cp your 4 .pem files to ~/.ec2
  • Download and unzip the Amazon API Command Line Tools and move the bin and lib to ~/.ec2.
  • Your directory should now look like this
    styx:.ec2 $ ls
    UserID_PK.pem
    UserID_PUB.pem
    X509cert_instancename.pem
    X509priv_instancename.pem
    bin
    lib
  • You also need to configure some environmental variables. Edit you ~/.bash_profile to include the text below at the end.
    # Setup Amazon EC2 Command-Line Tools
    export EC2_HOME=~/.ec2
    export PATH=$PATH:$EC2_HOME/bin
    export EC2_PRIVATE_KEY=`ls $EC2_HOME/X509priv_instancename.pem`
    export EC2_CERT=`ls $EC2_HOME/X509cert_instancename.pem`
    export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home/
  • When you are done editing your bash_profile, you will need to use restart your shell
    styx:.ec2 $ source ~/.bash_profile
  • Check if it works
    styx:.ec2 $ cd ~/.ec2
    styx:.ec2 $ ec2-describe-images -o amazon
  • This will produce a list of available EC2 Images. Grep can be used to find specific features.