Ruby on Rails, on Dokku!
29 Apr 2015 · CommentsIn my last post I showed how to setup Dokku and deploy a simple “Hello World” web application. Now let’s turn it up to 11 and build a fully-blown Ruby on Rails application with its own database, taking a look at some of Dokku’s management features along the way.
The app will be flicklog - a journal of movies that you’ve seen recently at the cinema with a short synopsis and a star rating.
Ready? Adequately caffeinated? Let’s go.
Create a Rails Application
To get started you’ll need a development environment with Ruby, Rails 4 and PostgreSQL. Setting this up can be a little tricky, I would recommend that you install Vagrant and use my lovingly crafted Vagrantfile to provision a development VM. That way we’ll all be on the same page.
On your development VM, run the following commands to create a database and a new Rails application, specifying that it should use PostgreSQL as the database:
createdb flicklog_development
rails new flicklog --database=postgresql
cd flicklog
Next, we have to add a couple of gems to the Gemfile:
# Gemfile
gem 'therubyracer', platforms: :ruby
gem 'rails_12factor', group: :production
therubyracer
provides Rails with a JavaScript runtime and the rails_12factor
gem is needed for the logging to work with Dokku.
We can now install the gems and run the web application:
bundle install
rails s -b 0.0.0.0
This starts up the web application on port 3000, you can visit the site on http://localhost:3000. It will show the default “Welcome aboard” page with getting started instructions.
Next, we want to create a movie entity that has a title, synopsis, release date
and star rating. Rails provides a scaffold
command that generates the code
for this automatically:
rails generate scaffold movie title synopsis:text released:date rating:integer
rake db:migrate
The scaffold command creates a model, view, controller and database migration for our movie entity. The migrate command applies the database migration to our database, creating a new table to store our movies.
Finally, edit the default route to make the home page our list of movies:
# config/routes.rb
root 'movies#index'
If you visit your local site now, you will see an empty table of movies and you can start adding movies to your log.
Deploy to Dokku
Now that we’ve got our simple app working, it’s time to deploy it to Dokku. My previous post explains how to setup a Dokku server, I’m going to push my app to flicklog.colinthegeek.com.
Dokku uses Git to deploy your application, so your code has to be checked into a Git repository before it can be deployed. You may already use an online service like GitHub or BitBucket to store your code, but for the purposes of this article I’m going to add the code to a local repository on my development VM:
git init
git add .
git commit -m 'Initial Commit'
Now the code is in a repository, we add a remote that points to our Dokku server, don’t forget to substitute colinthegeek.com with your own server address:
git remote add geek dokku@colinthegeek.com:flicklog
…where “geek” is the name of the remote, “dokku” is the Git user name, “colinthegeek.com” is the server, and “flicklog” is the name of the app.
That’s the configuration complete, lets push the code to Dokku and see what happens:
git push geek master
The code should deploy successfully and return the URL at the bottom of the deployment log:
=====> Application deployed:
http://flicklog.colinthegeek.com
Viewing the Logs
If you visit the site now, you’ll be disappointed to see the following error message:
Something has gone wrong, and Rails won’t tell us what because it’s running in
production mode. It does suggest that we check the logs, so lets try that. SSH
onto your server and execute dokku
to see the commands that are available:
> ssh root@colinthegeek.com
> dokku
Usage: dokku COMMAND <app> [command-specific-options]
apps:create <app> Create a new app
apps:destroy <app> Permanently destroy an app
apps List your apps
backup:export [file] Export dokku configuration files
backup:import [file] Import dokku configuration files
config <app> Display the config vars for an app
config:get <app> KEY Display a config value for an app
config:set <app> KEY1=VALUE1 [KEY2=VALUE2 ...] Set one or more config vars
config:unset <app> KEY1 [KEY2 ...] Unset one or more config vars
domains:add <app> DOMAIN Add a custom domain to app
domains <app> List custom domains for app
domains:clear <app> Clear all custom domains for app
domains:remove <app> DOMAIN Remove a custom domain from app
help Print the list of commands
logs <app> [-t] Show the last logs for an application (-t follows)
nginx:build-config <app> (Re)builds nginx config for given app
nginx:import-ssl <app> Imports a tarball from stdin; should contain server.crt and server.key
plugins-install Install active plugins
plugins Print active plugins
plugins-update Update active plugins
run <app> <cmd> Run a command in the environment of an application
url <app> Show the first URL for an application (compatibility)
urls <app> Show all URLs for an application
version Print dokku's version
The command that we are looking for is dokku logs
:
> dokku logs flicklog
Started GET "/" for 82.132.212.222 at 2015-04-27 18:15:15 +0000
PG::ConnectionBad (could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
):
The logs tell us that our application cannot find the PostgreSQL server, that’s OK, we haven’t created one yet. We’ll do that in the next section.
PostgreSQL Plugin
Dokku doesn’t have any support for databases, but it does have rich support for plugins. There are a number of community plugins for PostgreSQL, my favourite one is by kloadut.
Install the plugin by executing the following commands on your Dokku server:
cd /var/lib/dokku/plugins
git clone https://github.com/Kloadut/dokku-pg-plugin postgresql
dokku plugins-install
The plugin extends the available Dokku commands:
> dokku
...
postgresql:console <db> Open a PostgreSQL console
postgresql:create <db> Create a PostgreSQL container
postgresql:delete <db> Delete specified PostgreSQL container
postgresql:dump <db> > dump_file.sql Dump database data
postgresql:info <db> Display database informations
postgresql:link <app> <db> Link an app to a PostgreSQL database
postgresql:list Display list of PostgreSQL containers
postgresql:logs <db> Display last logs from PostgreSQL container
postgresql:restore <db> < dump_file.sql Restore database data from a previous dump
All we have to do is create a database and link it to our application:
dokku postgresql:create flicklog-db
dokku postgresql:link flicklog flicklog-db
Finally, lets run the migration to create our movies table:
dokku run flicklog rake db:migrate
Now you can visit the site and start logging flicks!
Managing Data
The PostgreSQL plugin includes some handy commands for exporting and importing
data. These commands use the postgresql-client
behind the scenes, so you must
install it on your Dokku server before you use them:
sudo apt-get install postgresql-client
You can export the database with the dump
command:
dokku postgresql:dump flicklog-db > ~/flicklog-db.sql
This creates a full backup of your database schema and data. You can restore a
backup with the restore
command:
dokku postgresql:restore flicklog-db < ~/flicklog-db.sql
Finally, the console
command is useful if you want to run SQL queries against
your database. The following commands open a console, selects all of the movies
and quits:
dokku postgresql:console flicklog-db
select * from movies;
\q
Hopefully this was guide was helpful, I’ve been using Dokku to host side projects for a while and I find it very useful. You can find the source code from in this article on my GitHub: https://github.com/ColinOrr/dokku-rails