As mentioned in my previous post "Logging into my first AWS micro instance", I've setup my first micro instance for my own personal sites. And having done so, here is the setup I'm following for this instance. While it's not the most secure, it'll do for my small testing and play-sites.
Also, this setup obviously doesn't limit itself to a micro instance. I'm installing this on an Ubuntu 11.04 Natty Narwhal box, but I'm sure most of it translates to modern linux-distros.
This will be a command-heavy post, but I'll detail the reasoning behind each code segment.
Being logged in, let's start:
Packages and Timezone
sudo apt-get update
sudo apt-get -y upgrade
sudo dpkg-reconfigure tzdata
This updates your system's listing of the packages available to be installed/upgraded, upgrades the packages that are already installed, and prompts you to choose the timezone for your linux-box.
Shell Customizations
sudo vi ~/.bashrc
This file contains code that is executed/compiled each time you connect to your system via SSH. I enter the following commands, aliases and functions at the end of the file:
# pimping
export PS1="e[35;40mu@He[0m [w] e[33;1m: e[0m"
export LS_COLORS="di=36:fi=0:ln=31:pi=5:so=5:bd=5:cd=5:or=31:mi=0:ex=35"
# custom aliases
alias ls='ls -la --color=auto --time-style=long-iso'
alias c='clear'
alias cls='clear && ls'
alias php.ini-edit='sudo vi /etc/php5/apache2/php.ini'
alias apache-restart='sudo /etc/init.d/apache2 restart'
alias apache.conf-edit='sudo vi /etc/apache2/apache2.conf'
alias ftp-restart='sudo service vsftpd restart'
alias mysql-connect='mysql --user=root --password=PASSWORD[MYSQL::ROOT]'
alias mysql-restart='sudo service mysql restart'
# functions
ff () { sudo find / -name "*$@*" ; }
ft () { sudo grep -r "$@" /var/www/ --color ; }
The above commands do a few things.
The first set (commented as "# pimping"
) colour the terminal and ls program.
While you may think it's a design/asthetic preference, it's actually pretty
useful. My OSX box's terminal is coloured green. My VM's is purple, and my live,
production-available boxes (whether AWS or Slicehost) are coloured red. This
allows me to know exactly where I am whenever I'm in front of the terminal. This
can help prevent potentially dangerous commands being run on the wrong box.
The section "# custom aliases"
lists a set of alias that make using the
terminal easier (eg. basically, shortcuts). They all me to manage my PHP, Apache
and MySQL installs quickly.
Finally, the "# functions"
block lists two functions that make it quick and
easy to search through file names and file contents in the /var/www
directory:
source ~./.bashrc
This reboots your .bashrc file and makes the changes made immediately available.
SSH Configuration
sudo vi /etc/ssh/sshd_config
This prompts you to edit your SSH config file. I generally change my port from the default 22. When doing this, however, you will have to make changes to your AWS Security Group to allow that port to be accessed.
sudo reload ssh
This simply reloads the ssh application, with the new configuration details applied (you may get disconnected at this time).
Application Server Setup
sudo apt-get -y install memcached unzip vsftpd apache2 libapache2-mod-php5 php-pear php5-dev make apache2-prefork-dev php5-imagick php5-gd php5-geoip php5-curl
This is a biggie, and takes a while. It installs a group of packages, including memcached, Apache, VSFTP (ftp-server), PHP5, along with some PHP extensions.
Memcached Setup
In the previous application server setup step, we installed the memcached package. But now we need to configure it.
sudo vi /etc/rc.local
While I honestly don't know the purpose of this file, I do know that the following needs to be put before the exit 0 statement to ensure memcached get booted after each system restart:
/usr/bin/memcached -u www-data -d -m 64 -p 11211
sudo reboot
This reboots your system.
sudo netstat -tap
This will print out information on your network connections; search for one that looks like "localhost:11211". This is the memcached daemon, and ensure that it's running properly after the reboot you just did.
sudo updatedb
cd
sudo apt-get -y install g++
wget http://launchpad.net/libmemcached/1.0/0.39/+download/libmemcached-0.39.tar.gz
tar zxvf libmemcached-0.39.tar.gz
cd libmemcached-0.39/
./configure
make
sudo make install
cd /usr/lib
sudo ln -s /usr/local/lib/libmemcached.so
sudo pecl install memcached
sudo rm -r ~/libmemcached-0.39
sudo rm ~/libmemcached-0.39.tar.gz
This is a fairly significant code chunk. It does quite a few things which I'll outline here in order:
- Update your system's file name database, to make searching relevant with all the new files that have recently been installed
- Move to your home directory
- Install the g++ compiler
- Download the libmemcached binary library
- Move into it, configure it, make it and install it
- Make a symbolic link to the generated libmemcached.so file
- Install the PECL extension (which allows PHP to talk to the libmemcached library; which talks to the Memcached application)
Remove the garbage
php.ini-edit
Add in the following command to have PHP boot the memcached extension in:
extension="memcached.so"
APC Setup
cd /usr/local/src
sudo wget http://pecl.php.net/get/APC-3.1.9.tgz
sudo tar xzvf APC-3.1.9.tgz
cd APC-3.1.9
sudo phpize
sudo ./configure --enable-apc --enable-mmap
sudo make
sudo make install
cd ..
sudo cp APC-3.1.9/apc.php /var/www/apc.php
sudo rm -rf APC-3.1.9
sudo rm APC-3.1.9.tgz
sudo rm package.xml
The above code follows a very similar process as the memcached setup listed above. In short, it downloads the APC PECL extension, configures it, installs it, copies over a status PHP file to the Apache webroot, and removes the garbage generated by the installation/setup.
php.ini-edit
Add in the following command to have PHP boot the APC extension in:
extension="apc.so"
Apache Configuration
sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
sudo ln -s /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled/auth_digest.load
sudo ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load
sudo a2enmod headers
apache-restart
This will make symbolic links between the modules available and modules enabled
for Apache. These modules allow mod_rewriting
, auth_digest
(security) and
ssl to be usable via Apache. We then restart the server.
sudo vi /etc/apache2/sites-available/default
This default apache configuration file gets served when no specific virtual host
can be found (eg. if you try connecting to your box's IP directly). To prevent
directory listing and viewing the root /var/www directory, add in the following
two rules at the top of the /var/www
directory funnel:
RewriteEngine On
RewriteRule ^(.*) http://www.domain.com/ [R=301,L]
This will redirect all traffic to your Apache that isn't explicitly allowed via a VirtualHost to your domain. And finally, after those two rules, change the Options rule to the following:
Options -Indexes FollowSymLinks MultiViews
This prevents the directories from being indexable, Apache-wide (eg. should take effect in each VirtualHost).
PHP Configuration
php.ini-edit
There are some small modifications that need to be set to ensure clean running of PHP. Ensure the following is set:
expose_php = Off
apc.slam_defense = Off
default_charset = "UTF-8"
Those removes the PHP signature from header responses, prevents a cache-lookup collision/race-condition within APC, and sets the default encoding for PHP responses unless otherwise specified.
MySQL Setup
Before I started this installation, I'd assumed I would transition over to RDS. That was until I checked the price (about $80/month). Simply not worth it. Therefore this MySQL Setup process is near the end since I've got to circle back.
sudo apt-get -y install mysql-server php5-mysql
This installs the mysql-server itself, along with the PHP extension for it. You'll be prompted for a root password for the server.
apache-restart
You need to now change the alias you created earlier that points to the mysql server to have your newly changed passowrd.
sudo vi ~/.bashrc
source ~/.bashrc
Now, we need to create two new users. One for administration by third-party apps (Sequel Pro), and one for the applications themselves.
mysql-connect
CREATE USER 'admin'@'%' IDENTIFIED BY '13wQ991nsQm';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
CREATE USER 'app'@'localhost' IDENTIFIED BY '13wQ981bDm';
GRANT ALL PRIVILEGES ON *.* TO 'app'@'localhost' WITH GRANT OPTION;
exit
The above code created the new users and granted permissions for the from specific hosts (eg. wildcard % and localhost)
Now let's make some changes to how MySQL runs.
sudo vi /etc/mysql/my.cnf
We want to comment out the configuration line bind-address to allow for remote connections (eg. Sequel Pro). Next, I change the port to a non-default one for the mysql-server (not client). This port also needs to be opened in the AWS console Security Group/firewall. And finally, we want to ensure the following settings are set:
init_connect='SET collation_connection = utf8_unicode_ci; SET NAMES utf8;';
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_unicode_ci
mysql-restart
apache-restart
And boom. Both servers have been restarted, and should/are ready for use.
Language Installation
While I recently wrote a post "Adding a language package (french) to Ubuntu Linux (10.10)", in this step I'm only going to ensure the english language packages are installed properly:
sudo apt-get -y install language-pack-en
sudo locale-gen en_US.UTF-8
sudo dpkg-reconfigure locales
sudo vi /etc/default/locale
The above code installs the english language pack, generates the en_US.UTF-8 locale, reconfigures all available locales in the OS, and prompts you to choose which of those locales is actually usable (so many moving parts..).
As you're now prompted with an editor, your job is to simple ensure the following is present:
LANG="en_US.UTF-8"
sudo reboot
Now let's reboot :)