Postpostmodern » Apache http://postpostmodern.com Speaking of web development. Wed, 11 Jan 2012 00:21:50 +0000 http://wordpress.org/?v=2.9.1 en hourly 1 Slicehost (and Linode) LAMP Cheatsheet http://postpostmodern.com/2009/11/17/slicehost-and-linode-lamp-cheatsheet/ http://postpostmodern.com/2009/11/17/slicehost-and-linode-lamp-cheatsheet/#comments Tue, 17 Nov 2009 23:51:35 +0000 Jason Johnson http://postpostmodern.com/?p=120 I have set up several Slicehost slices as Ubuntu LAMP servers, but since I’m not a server admin, I always have to reference the tutorials to remember the steps. So, I’ve compiled the list of steps here, as concisely as possible. This process sets up everything you need for hosting multiple sites on a single server, and it works equally well for most servers running Ubuntu including Slices and Linodes.

Disclaimer
Please use these only if you already know the whys and wherefores. If you don’t generally understand one or more of these steps, consult the Slicehost Articles or the Linode Articles before asking questions here. Most of the information here comes from the Slicehost Articles for Ubuntu. I have also added a few extra steps from sources cited in the footnotes.
Helping Me Out
If you need to sign up for a Slicehost or Linode account, and you plan on using this article as a guide to configure your server, please use these referral links:
Corrections to this article are also appreciated. Please note, however, that corrections != personal preference. If you have a different way of doing something, you’ll need to present a convincing case as to why it is better.
Assumptions
This guide/cheatsheet assumes you have already created a virtual server with Ubuntu installed.
You should also set up your DNS. If you’re using Slicehost, my Slicehost DNS script will help.
Conventions
For this article, I’m using:
  • xxx.xxx.xxx.xxx to indicate the IP address of your server
  • bob as the server’s name (hostname)
  • example.com as the domain name
  • demo as the admin user
  • nano as my editor because I have no vi skills.

Configure Server for Terminal.app (Mac users only)

Terminal.app behaves as dtterm, but Ubuntu doesn’t have the dtterm entry in its terminfo database. This fixes that.1

Save Terminal Info to a File

On your Mac (local machine)…

  1. infocmp > /tmp/dtterm
  2. scp /tmp/dtterm root@xxx.xxx.xxx.xxx:/tmp

Import Terminal Info

  1. Log into your server as root
  2. tic /tmp/dtterm

Some Basic Package Setup

Aptitude Upgrade

Still logged in as root…

  1. Make sure you have access to the universe repositories nano /etc/apt/sources.list and uncomment the universe repositories
  2. Update
    aptitude update
  3. Upgrade
    aptitude safe-upgrade aptitude full-upgrade

Install Build Essentials

  1. Install
    aptitude install build-essential

Install CURL

  1. Install
    aptitude install curl
  2. Install ca-certificates for ssl connections aptitude install ca-certificates

SSH and Users

Create New User and Allow sudo

Still logged in as root…

  1. Change root password, if desired passwd
  2. Add user
    adduser demo
  3. Set up sudo config
    visudo and add demo ALL=(ALL) ALL to the end
  4. Log out or switch to your local machine

Set up SSH Keys

  1. On your local machine, copy local public ssh key to server (assuming you have already created your public key on your local machine) scp ~/.ssh/id_rsa.pub demo@xxx.xxx.xxx.xxx:/home/demo/
  2. Switch back to your server or log back in as root
  3. Create authorized_keys file
    cd /home/demo mkdir .ssh mv id_rsa.pub .ssh/authorized_keys
  4. Set permissions chown -R demo:demo .ssh chmod 700 .ssh chmod 600 .ssh/authorized_keys

Configure sshd

  1. Open sshd_config nano -w /etc/ssh/sshd_config
  2. Set these:
    Port 30000 (change to a port of your choosing)
    Protocol 2
    PermitRootLogin no
    PasswordAuthentication no
    X11Forwarding no
    UsePAM no
    UseDNS no
    AllowUsers demo

Setup iptables

  1. Dump existing rules cd /etc iptables-save > iptables.up.rules
  2. Copy rules file from Slicehost example curl -o iptables.test.rules http://articles.slicehost.com/assets/2007/9/4/iptables.txt
  3. Edit it and set port number for sshd nano -w iptables.test.rules
  4. Load it iptables-restore < iptables.test.rules
  5. Check the new rules iptables -L
  6. Save the new rules iptables-save > iptables.up.rules
  7. Make sure the new rules are read every time nano -w network/interfaces and make it look like this:
    ...
    auto lo
    iface lo inet loopback
    pre-up iptables-restore < /etc/iptables.up.rules
    
    # The primary network interface
    ...

Restart and Test sshd

  1. Reload sshd
    /etc/init.d/ssh reload
  2. Try to log in from another terminal
  3. If successful, logout

User Config

Logged in as demo...

Configure Nano

  1. Set some configuration cp /etc/nanorc ~/.nanorc nano -w ~/.nanorc
  2. Uncomment these lines:
    # set brackets ""')>]}"
    # set nowrap (should be set by default in recent versions) # set tabsize 8
  3. Change tabsize to 2 or 4 or something:
    set tabsize 4

Add Bash Aliases

  1. Create aliases file nano -w .bash_aliases and add:
    alias lo='logout'
    alias mksite='sudo /usr/local/a2mksite/a2mksite.sh'
    alias free='free -m'
    alias ag='sudo apache2ctl graceful'
    if [ "$TERM" != "dumb" ] && [ -x /usr/bin/dircolors ]; then
        eval "`dircolors -b`"
        alias ls='ls -la --color=auto'
    fi
    
    # Git
    alias gst='git status'
    # alias gl='git pull'
    alias ga='git add'
    alias gp='git push'
    alias gd='git diff | mate'
    alias gc='git commit -v'
    alias gca='git commit -v -a'
    alias gb='git branch'
    alias gba='git branch -a'
    alias gco='git checkout'
    alias glog='git log --pretty=format:"# %aD : %an%n%n* %s%n%n%b%n"'
    alias glt='glog --since=yesterday'
    alias gly='glog --since="2 days ago" --until="1 day ago"'
  2. If necessary, activate aliases in .bashrc nano -w .bashrc and uncomment the part that loads .bash_aliases
  3. Get the aliases working source ~/.bashrc

Basic Server Config

Set Hostname2

  1. Name your server by setting a short hostname in /etc/hostname sudo nano /etc/hostname and type bob.example.com
  2. Set the fully-qualified domain name in hosts
    sudo nano /etc/hosts and add xxx.xxx.xxx.xxx bob.example.com bob
    below the 127.0.0.1 localhost entry
  3. Reboot sudo reboot
  4. Check hostname
    hostname
  5. Check FQDN
    hostname -f

Set Locale

  1. Generate locale info
    sudo locale-gen en_US.UTF-8
  2. Update locale
    sudo /usr/sbin/update-locale LANG=en_US.UTF-8

Set Timezone

  1. Start up timezone configurator and follow instructions
    sudo dpkg-reconfigure tzdata

Git

Install Git

  1. Install
    sudo aptitude install git-core

Subversion

Install svn

  1. Install
    sudo aptitude install subversion

Web Server

Install a2mksite

a2mksite is a script that I wrote that allows you to create an Apache virtual host with one command (including the document root, config files, log rotation, etc). One thing you should know is that it creates a directory structure for multiple web sites (virtual hosts), placing each site's public and log directories in its own directory like so: /var/www/sites/example.com

Read the description here to learn more about what it does.

  1. Clone a2mksite from Github git clone git://github.com/postpostmodern/a2mksite.git
  2. Move it to /usr/local sudo mv a2mksite /usr/local
  3. CHOWN it to root sudo chown 0:0 /usr/local/a2mksite
  4. Make sure you have the script aliased as mksite in your .bash_aliases file (see Bash Aliases snippet earlier in this post).

Install Logrotate

  1. Install
    sudo aptitude install logrotate

Install Apache

  1. Install sudo aptitude install apache2 apache2.2-common apache2-mpm-prefork apache2-utils libexpat1 ssl-cert
  2. Set up basic config using my httpd.conf as an example wget https://raw.github.com/gist/236374/httpd.conf sudo mv httpd.conf /etc/apache2/httpd.conf sudo nano /etc/apache2/httpd.conf
  3. Enable Modules
    sudo a2enmod auth_digest dav dav_lock rewrite
  4. Create errors dir
    sudo mkdir /var/www/errors
  5. Create maintenance dir
    sudo mkdir /var/www/maintenance
  6. CHOWN them
    sudo chown -R demo:demo /var/www/errors /var/www/maintenance
  7. Create global 404
    nano -w /var/www/errors/404.html
  8. Create maintenance page
    nano -w /var/www/maintenance/index.html
  9. Make default site
    mksite default and overwrite the original default

MySQL

Install MySQL

  1. Install
    sudo aptitude install mysql-server mysql-client libmysqlclient15-dev
  2. Set root password (follow instructions during installation)

PHP

Install PHP

  1. Install PHP sudo aptitude install libapache2-mod-php5 php5 php5-common php5-curl php5-dev php5-gd php5-imagick php5-mcrypt php5-memcache php5-mhash php5-mysql php5-pspell php5-snmp php5-sqlite php5-xmlrpc php5-xsl php5-xcache
  2. Edit xcache.ini sudo nano /etc/php5/apache2/conf.d/xcache.ini and set xcache.var_size to something other than zero
  3. Edit php.ini sudo nano /etc/php5/apache2/php.ini and set error output, max upload size, etc.
  4. Restart Apache sudo /etc/init.d/apache2 restart

Mail (for sending via PHP)

Reverse DNS

  1. Set Reverse DNS in SliceManager or Linode Manager to your server's FQDN, i.e. what you see when you type hostname -f
  2. Check it
    sudo aptitude install dnsutils dig -x xxx.xxx.xxx.xxx

Postfix

  1. Install Postfix
    sudo aptitude install postfix mailx
  2. Test Postfix
    mail someone@somewhereelse.com and send a message. Don't forget: ctrl-d ends the message.
  3. Optionally continue configuration as described here

A Backup Solution

The following is my own backup solution for my web sites. It backs up the MySQL databases and web site files. Then, it sends a copy to Amazon S3.

Install Ruby for S3Sync

  1. Install Ruby sudo aptitude install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby sqlite3 libsqlite3-ruby1.8
  2. Symlink locations sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby sudo ln -s /usr/bin/ri1.8 /usr/bin/ri sudo ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc sudo ln -s /usr/bin/irb1.8 /usr/bin/irb
  3. Install Ruby Gems (optional) wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz tar xzvf rubygems-1.3.7.tgz cd rubygems-1.3.7 sudo ruby setup.rb cd .. rm -R rubygems-1.3.7* sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
  4. Update gems sudo gem update sudo gem update --system

Install S3Sync

  1. Download and move S3Sync wget http://s3.amazonaws.com/ServEdge_pub/s3sync/s3sync.tar.gz tar xvzf s3sync.tar.gz sudo mv s3sync /usr/local/ sudo chown 0:0 /usr/local/s3sync/ rm s3sync.tar.gz
  2. Make sure you installed the ca-certificates package earlier (see "Install CURL" above)

Install Web Server Backup Script

  1. Clone it from Github sudo git clone git://github.com/postpostmodern/web-server-backup.git /usr/local/web-server-backup
  2. Configure it according to the README sudo nano /usr/local/web-server-backup/backup.sh
  3. Test Run sudo /usr/local/web-server-backup/backup.sh

Schedule the Backup with Cron

  1. Create a cron job sudo nano /etc/cron.d/web_server_backup
  2. Make it look something like this:
    SHELL=/bin/bash
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
    MAILTO=demo@example.com
    HOME=/root
    
    30 4 * * * root /usr/local/web-server-backup/backup.sh > /dev/null

There is no step 54.

Okay. That was a lot of steps, but everything should be running properly now. Though this article is mostly for my own reference, your comments are welcome.

  1. OS X Terminal Emulation Woes ↑ back up there
  2. Linux Hostname Configuration ↑ back up there
]]>
http://postpostmodern.com/2009/11/17/slicehost-and-linode-lamp-cheatsheet/feed/ 16
A Smarter MAMP http://postpostmodern.com/2008/10/22/a-smarter-mamp/ http://postpostmodern.com/2008/10/22/a-smarter-mamp/#comments Wed, 22 Oct 2008 16:08:44 +0000 Jason Johnson http://postpostmodern.com/?p=170 This past weekend, I was cleaning up my ~/Sites folder, and I started thinking, “There’s got to be a better way!” And I wasn’t referring to baby hammock. I was talking about having to set up all those virtual hosts and whatnot. Well, a little research quickly brought me to the “how did I not know this before?!” point. And now, I will share it with you.

(Editor’s Note: This article turned out to be a little longer than I expected. The whole process is really quite simple. It should only take about 10 minutes, at the most.)

The first thing I didn’t realize is that Apache supports something called dynamic virtual hosts. That means you don’t have to create a virtual host in your conf files and restart Apache every time you want to create a new site. This is incredibly handy for development. Combine that with a real DNS server (BIND), and you have a much smarter system. I can now create a whole new site on my MacBook just by creating a new folder! Much simpler than the old way.

The Old Way?

To put this in context, let’s quickly review the old way. For years, I’ve developed websites on Mac OS X using the standard ‘MAMP’ setup: Mac/Apache/MySQL/PHP. When starting a new site, the first thing I do is set up a virtual host for Apache. If you’re like me, you know this as a 4-step process:

  1. Create a directory for the site’s files. Something like:

    mkdir -p ~/Sites/domain.com/public

  2. Create a line in /etc/hosts for the domain:

    127.0.0.1 domain.dev

  3. Add a few lines to my Apache conf file to configure the virtual host:

    <VirtualHost *>
      ServerName domain.dev
      DocumentRoot /Users/jason/Sites/domain.com/public
    </VirtualHost>
    
  4. Restart Apache:

    sudo apachectl graceful

The New Way!

  1. Create a directory for the site’s files. Something like:

    mkdir -p ~/Sites/domain.com/public

Done.

Not only that, but I also decided to set up a few TLDs to separate my sites. I use .ppm for my personal and freelance sites, .dev for my experimental stuff, and .bsi for my company work. This allows me to separate sites like so:

Sites
|-- bsi
|   |-- this
|   |-- that
|   `-- theother
|-- dev
|   |-- experiment1
|   |-- experiment2
|   |-- youget
|   `-- thepoint
`-- ppm
    |-- postpostmodern
    `-- littlebeestudio

These would be:

  • this.bsi
  • that.bsi
  • theother.bsi
  • postpostmodern.ppm
  • littlebeestudio.ppm
  • experiment1.dev
  • experiment2.dev
  • youget.dev
  • thepoint.dev

First, let’s talk about the hosts file.

The first thing you need for an Apache virtual host is a unique hostname. As can be seen in step 2, above, this is usually accomplished via the /etc/hosts file. The only problem is the hosts file doesn’t support any wildcards. So, you can’t say:

127.0.0.1    *.dev

Instead, you have to have this:

127.0.0.1    postpostmodern.dev
127.0.0.1    littlebeestudio.dev
...
...

…and eventually, you end up with a hosts file a mile long.

Enter BIND — the built-in, but inactive DNS server

BIND (named) comes with Mac OS X. We just need to configure it and turn it on.

I should mention here that DNS server stuff falls outside of my comfort zone. I just followed a few articles (on macosxhints and Ubuntu Forums) to get this working. I’m not sure how it impacts the vulnerability of your Mac from a security standpoint. All I know is that it works and provides a few advantages over the hosts file:

  • You can set up TLDs to resolve to your local IP address. So, anything.dev and anything.test will automatically stay local.
  • Apparently, since BIND will be caching DNS info, it will make web browsing faster. I haven’t formally tested this, but if it’s true, it’s a nice bonus. It does seem a little quicker.

Setting up rndc

This creates a configuration file and key for rndc, which controls named.

Get into sudo, and make it stick.

sudo -s

Generate the conf file.

rndc-confgen > /etc/rndc.conf

Copy the key to the key file.

head -n 6 /etc/rndc.conf > /etc/rndc.key

Exit sudo.

exit

Creating your DNS zone files

DNS zones are created via files in /var/named. Create a new file in there called dev.zone and fill it with this:

;
; BIND data file for dev sites
;
$TTL    604800
@       IN      SOA     dev. root.dev. (
                     2008101920         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      dev.
@       IN      A       127.0.0.1
*.dev.  14400   IN      A       127.0.0.1

Repeat the above for each TLD you want to set up, replacing ‘dev’ of course.

Configuring named.conf

Now, open /etc/named.conf. The first thing you want to do here is to show named where to get its DNS info (for the rest of the internet), i.e. forwarding servers. Let’s use OpenDNS. Add these lines in the options section of named.conf (after ‘directory “/var/named”;’):

forwarders {
    208.67.222.222;
    208.67.220.220;
};

Now, we just need to let named know about those zone files we created a minute ago. For each of the zone files, create a section like this:

zone "dev" IN {
  type master;
  file "dev.zone";
};

You’ll see where to put it. There’s a ‘localhost’ section already there. Just put yours below that.

Configuring and loading the LaunchDaemon

Okay. One last thing. Tell Mac OS X to activate named. Open the LaunchDaemon plist file for named (I had to use Textmate because Property List Editor didn’t let me save a file belonging to root.):

/System/Library/LaunchDaemons/org.isc.named.plist

Change ‘disabled’ from true to false, and save the file.

Now, load it:

sudo launchctl load /System/Library/LaunchDaemons/org.isc.named.plist

If everything went well, your DNS server should be up and running, and your personalized TLDs should resolve to your local machine. Try visiting something.dev and see if it resolves correctly. You might want to comment out all those custom lines from your /etc/hosts file too.

Now for the Apache Magic!

Now that the DNS stuff is out of the way, it’s just a matter of setting that magic directive in your Apache conf file. The directive is called VirtualDocumentRoot.

I don’t know how you have your Apache configured, but personally, I like to keep all of my custom configuration in my own file (the one in /etc/apache2/users). Here is what my /etc/apache2/users/jason.conf file looks like:

DocumentRoot "/Users/jason/Sites/default/public/"

NameVirtualHost 127.0.0.1

<VirtualHost 127.0.0.1>
    VirtualDocumentRoot /Users/jason/Sites/%-1/%-2+/public
</VirtualHost>

The DocumentRoot directive is for the default site — the site that comes up when you visit http://localhost. The NameVirtualHost should be the reverse IP for your local machine. Finally, the VirtualDocumentRoot is an interpolated path for finding your sites. ‘%-1’ means the last part of the domain name (the TLD). ‘%-2+’ means everything before that. So, http://example.dev/ would load files from /Users/jason/Sites/dev/example/public. If you want a different scheme, read more about directory name interpolation on Apache’s web site.

Now, restart Apache!

sudo apachectl graceful

You should be good to go!

Please let me know your thoughts and corrections in the comments.

Update – 28 Oct, 2008

As Brian Toth mentioned in the comments, it’s probably also necessary to add 127.0.0.1 in your DNS settings in the Network System Pref pane.

]]>
http://postpostmodern.com/2008/10/22/a-smarter-mamp/feed/ 57
Dog Days of an Indian Summer http://postpostmodern.com/2006/08/07/dog-days-of-an-indian-summer/ http://postpostmodern.com/2006/08/07/dog-days-of-an-indian-summer/#comments Tue, 08 Aug 2006 02:18:44 +0000 Jason Johnson http://blog.postpostmodern.com/2006/08/07/dog-days-of-an-indian-summer/ “The future of Rails deployment belongs to Mongrel,” they said.

So, about a month ago, not long after Lighty had settled into its little corner of the new server and was happily churning out web sites, I decided to shut it down. Lightttpd is a great web server, but my new CRAM setup feels so much better.

I’m talking about Capistrano, Rails, Apache, Mongrel. Coda Hale wrote a great article on setting it up. I used his basic procedure, tailored it to my specific needs/personality, and voila! CRAM!

See, Apache + FastCGI was sketchy at best, but Apache + Mongrel seems to be delightful. Now that Apache’s back in the mix, it’s a lot easier to run my PHP-based sites (and sites that rely on .htaccess files) alongside my Rails apps. And, even though Apache 2.2 wasn’t my favorite thing to install (nor was it my least favorite), I’m feeling darn good about my decision. Not only have I had much success with CRAM so far, there’s plenty of evidence that the Mongrel will be around for a bit. Edge Rails now uses Mongrel by default, and it’ll even be a part of Leopard’s Rails setup.

Speaking of Rails in Leopard. Nothing surprised me more that that news. I’m still a bit dumbfounded.

So, if you are developing in Rails and are trying to decide what sort of server stack/deployment you want to use, try CRAM.

]]>
http://postpostmodern.com/2006/08/07/dog-days-of-an-indian-summer/feed/ 0