Michael Rose

Software generalist, backend engineer, bit-herder, building distributed systems on the JVM for FullContact.

Dropwizard Deployment for the Lazy Using Rake and Net::SSH

| Comments

Today I embarked on automated deployment of one of my basic Dropwizard/Angular.JS projects. This project’s purpose is to extract unstructured data from forum posts and turn them into data directly consumable by an API. It’s split into a four major pieces:

  • Core — reusable representation objects to keep things tidy between phases
  • Extraction — Extracts data from forum posts by executing a large unwieldy JDBC query and iterating over the results, then pushing each into MongoDB
  • Query — Dropwizard/JAX-RS REST API for exposing the data found by the extraction phase
  • Frontend — Angular.JS frontend app that consumes the REST API

As with many projects, they all begin somewhat manually, but today I wanted to automate the deployment of my project. Jenkins is a little heavy weight for a personal project, and I don’t really need a full-blown continuous integration framework. Capistrano is more along the lines I wanted, but is too Rails-flavored to be immediately useful for my needs.

Rake

Rake is simple. Stupid simple. It’s a Ruby DSL for running commands, a step up from a hand-rolled bash script.

I had three goals: build the project, deploy the frontend, deploy the API. All three turned out to be simple. Deploying the API builds the project, runs tests, and deploys the uberjar via rsync.

Deploying the frontend simply rsyncs the site remotely. Eventually, it’ll compile assets and version them, but that’s another project. :)

rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require 'net/ssh'

desc "Create a distribution package"
task :package do
    sh "mvn package"
end

namespace "deploy" do
    host        = 'my.ssh.host'
    user        = 'myuser'
    options     = {:keys => '~/.ssh/id_dsa'}

    desc "Deploy the frontend webapp"
    task :frontend do
        remote_dir = "/home/mysite/www/library"
        sh "rsync -avz library-frontend #{host}:#{remote_dir}"
    end

    desc "Deploy the Library REST API (non-rolling)"
    task :api => [:package] do
        remote_dir = "/home/mysite/api"

        sh "rsync library-api/target/library-api-1.0-SNAPSHOT.jar #{host}:#{remote_dir}/library-api.jar"

        Net::SSH.start(host, user, options) do |ssh|
            puts ssh.exec! 'supervisorctl restart library-api'
        end
    end
end

The only aspect of this deployment not managed by rake is process management which Supervisord controls easily and efficiently.

It’s not a rolling deploy, but Dropwizard boots so quickly I have no need for a complicated deployment, especially on a personal project.

Comments