Setting up Ubuntu with Teleport

A lightweight yet powerful way for preparing machines to deploy ruby apps

Some time ago I came across Teleport which pitches itself as a lightweight way to set up Ubuntu machines. Having failed at mastering the steep learning curve that full-blown tools like Chef or Puppet provide, I was willing to give Teleport a shot. Teleport stays simple by focusing on Ubuntu and providing just the right set of tools to set up the whole Ruby/Rails eco system. This makes it less powerful than the other aforemention tools, but in my case it’s just what I was looking for.

Some facts: Teleport …

  • consists of a configuration (Telfile) plus files you want to be present on the target
  • copies itself onto the target via ssh and then runs itself there (hence the name)
  • works idempotently - run it over and over again without breaking the target

My setup

For each project I store everything that belongs to Teleport in a specific deployment folder. This folder might look something like this:

| |____install_passenger_nginx.rb
| |____etc
| | |____gemrc
| | |____init.d
| | | |____nginx
| |____Gemfile
| |____Gemfile.lock
| |____opt
| | |____nginx
| | | |____conf
| | | | |____nginx.conf

The configuration is done inside the Telfile:

user "deploy"
ruby "1.9.3"
server "my-own-vps"

apt "deb lucid main", key: "C7917B12"

packages %w(openssl libreadline5 libreadline5-dev curl
  git-core libopenssl-ruby libcurl4-openssl-dev imagemagick
  libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev
  libmysqlclient-dev mysql-client mysql-server nodejs)

recipes %w(

user defines the name of the account you will later use to deploy your app. This user gets added to the sudoers and your ssh key is uploaded for password-less login. ruby tells Teleport which version to install and server is the name you gave to the machine in your ~/.ssh/config.

As you can see you can also define customs apts and packages that should get installed. For performing special setup routines or invoking more complex tasks you can utilize the recipes feature. Recipes are standalone files that can be written in Ruby and allow for sharing and reuse. Here’s an example of how to install nginx via the passenger gem:

version_gem = gem_version("passenger")
version_installed = `passenger-config --version`.strip

if !version_gem
  warn "Passenger is not installed. Please add it to your Gemfile."
elsif version_installed == version_gem.to_s
  banner "Passenger #{version_installed} is already installed"
  banner "Installing Nginx via Passenger (installed: #{version_installed}, gem version: #{version_gem})"
  run "passenger-install-nginx-module", %w(--auto --auto-download --prefix=/opt/nginx)  # install without prompting
  run "update-rc.d nginx defaults"                                                      # activate autostart
  run "service nginx restart"                                                           # restart nginx

The files directory contains files and directories that get copied over to the target machine - not much magic about that. To install system-wide gems you can place a Gemfile and Gemfile.lock inside the files directory.

Finally you can run the setup with

$ teleport my-own-vps

Keep in mind that you can re-run this every time you make a change to the Telfile or add new files. Teleport strives to be idempotent and can be run repeatedly without breaking the target machine(unless you explicitely messed up something ;)).

Let’s go…

There is much more to Teleport than what I could cover in this short post. For example you can define multiple servers with different roles or reverse engineering existing servers which makes it very easy to generate a Telfile from your current setup. In case you want to get started head over to the project wiki which contains a lot of information and examples.