Flock: Automated Swift server deployment

Flock is a new tool for Swift server developers which automates project deployment and related tasks. A number of incredibly promising Swift server libraries have been created in recent months, but tools for Swift server developers have not seen the same rate of development. Flock aims to remove the pain of server deployment and automation for Swift developers as Capistrano has for Rails developers.

In this post, I’ll give you a quick example of how easy Flock is to set up and use to deploy your project. I’ll assume you have a server which you can connect to using an SSH key, but even if you don’t you can still follow along through most of the steps.

Installation

You can install Flock’s CLI with Homebrew or manually:

$ brew install jakeheis/repo/flock
# or
$ git clone https://github.com/jakeheis/FlockCLI
$ cd FlockCLI
$ swift build -c release
$ ln -s .build/release/FlockCLI /usr/bin/local/flock

To check that Flock was correctly installed, run flock --version and make sure the output is “Version: 0.0.1”

Initialization

Start by changing into your your project directory. Then just run flock --init. You should see output like this:

This command will create a number of new files/directories in your project:

  • Flockfile — This is Flock’s core file
  • config/deploy — This where all of Flock’s configuration files lives
  • .flock — This directory can be ignored

I’ll touch upon the most important files below, but for detailed information about all the files Flock creates, check out the documentation.

flock --init will also update your .gitignore file to ignore Flock’s internal build directories.

Configuring Flock

If we follow the instructions Flock outputs after initialization, we’ll see that the first file we need to alter is config/deploy/Always.swift, the configuration file which Swift will use regardless of environment.

import Flock
class Always: Configuration {
func configure() {
Config.projectName = "VaporExample"
Config.executableName = "App"
Config.repoURL = "https://github.com/jakeheis/VaporExample"

Config.swiftVersion = "https://swift.org/builds/swift-3.0-release/ubuntu1510/swift-3.0-RELEASE/swift-3.0-RELEASE-ubuntu15.10.tar.gz"

}
}
  • Config.projectName should be set the name of the project as a whole — in my case, “VaporExample”
  • Config.executableName should be set to whatever the name of the executable which swift build outputs is. In a Vapor project, the main file is located at Sources/App/main.swift, and so the executable’s name is “App”. In other projects which have a main file located at Sources/main.swift, the executable name will be the same as the project name
  • Config.repoURL is the url of this repository
  • Config.swiftVersion is optional — if you want Flock to install Swift onto your server for you when you call flock tools, set this property. If you don’t intend to ever call flock tools, leave this line out.

Before we deploy, we also have to let Flock know about how to reach our servers. For that, we’ll edit config/deploy/Production.swift, the configuration file which Swift will use only if invoked in the “production” environment.

import Flock
class Production: Configuration {
func configure() {
Config.SSHAuthMethod = .key("/path/to/.ssh/mykey")
Servers.add(ip: "9.9.9.9", user: "root", roles: [.app, .db, .web])
}
}
  • Config.SSHAuthMethod, for now, must be set to .key(“key/location). Plans to eventually support password authentication are in place, but for now you must authenticate using an SSH key.
  • Servers.add(ip: “9.9.9.9”, user: “root”, roles: [.app, .db, .web]) — in this call, you obviously pass the IP address of your server and the user to login as. I use root here, but that’s just for the purpose of demonstration. You should likely create a dedicated user just for deploying. You also pass an array of server roles. Certain tasks may specify that they only should be executed on servers in certain roles. In this case, since I’m working with only one server, my one server will play all three roles

If your server is not already set up to build Swift code, you should run flock tools to install everything necessary for Swift to work on your server.

That’s all it takes; you’re ready to deploy!

Deploying

Now that you’ve done all the set-up, deploying is a single call:
$ flock deploy

Flock will output all the commands which it is executing on your server. A deploy process goes generally like this:

  • Flock starts by cloning your project (using Config.repoURL) onto your servers into a timestamped directory, like /var/www/VaporExample/20161028211084
  • Flock then builds your newly cloned project
  • Flock links the new version of your project to /var/www/VaporExample/current

This is all Flock does by itself — if you want Flock to also restart your server using your new executable, check out then next section of this post. If you want Flock to do anything else during the deploy process, you should write your own tasks — Flock is designed to be completely extensible.

Server restart

If you want Flock to restart your application server after building the new version, check out the projects linked to from here. In this post, I’ll demonstrate how you might use VaporFlock, but they’re all used nearly identically.

Start by adding VaporFlock to your config/deploy/FlockDependencies.json file. It should look something like this:

{
"dependencies" : [
{
"url" : "https://github.com/jakeheis/Flock",
"version": "0.0.1"
},
{
"url" : "https://github.com/jakeheis/VaporFlock",
"version": "0.0.1"
}
]
}

Next, inform Flock about this new source of tasks by adding VaporFlock to your Flockfile, making it look something like:

import Flock
import VaporFlock
Flock.use(Flock.Tools)
Flock.use(Flock.Deploy)
Flock.use(Flock.Vapor)
...

That’s all it takes! Now, when you call flock deploy, Vapor will automatically restart with your new executable.

Further reading

If you want to read more about Flock, check out Flock’s README and Flock CLI’s README. You should also check out VaporExample which is essentially what we built in this post.

Additionally, it’s worth noting that Flock is currently in its very early stages. If Flock is missing something you want/need, create an issue (or even better a pull request) at https://github.com/jakeheis/Flock!

A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.