Software development and beyond

Deployment with Fabric

Deployment with Fabric

Fabric is an awesome tool written in Python that we can utilize to execute shell commands on a remote computer via SSH, so any commands we would run locally on our computer we can run on remote servers without much effort. The way this works is that we will create a local utility program where we define local commands that will execute the remote ones.

We can execute anything with Fabric, so everything from deployment to complex server management is a fair game. In this blog I want to focus on deployment and how we can create a simple and automated deployment process with Fabric.

Let’s first think of how the deployment of our example application can work:

The best way would be to create a project with its own Python virtual environment using Pipenv or Poetry, but we can also use our system Python for simplicity. Let’s start by installing Fabric:

pip install fabric

Now we need to prepare our Fabric file, where we will define our deploy command. Let’s save it in fabfile.py:

from fabric import Connection
from invoke import task


HOST = 'user@IPADDRESS'
GIT_DIR = '/home/git/.'
APP_DIR = '/home/serverapp'


@task
def deploy(ctx, version):
"""Deploy specific version of serverapp"""
connection = Connection(HOST)
branch = f'releases/v{version}'

# Checkout and pull changes from releases/<version> branch
connection.run(f'git -C {GIT_DIR} fetch origin {branch}')
connection.run(f'git -C {GIT_DIR} checkout {branch}')
connection.run(f'git -C {GIT_DIR} pull origin {branch}')

# Copy all files from GIT_DIR to APP_DIR
connection.run(f'rsync -av --progress {GIT_DIR} {APP_DIR} --exclude .git')

# Run any deployment scripts we need, e.g. update dependencies using Pipenv
connection.run(f'cd {APP_DIR} && pipenv sync')

# Restart application, assuming we have 'serverapp' systemd service defined
connection.run(f'sudo systemctl restart serverapp')

# Check the status of the service if deployment worked well
connection.run(f'sudo systemctl status serverapp --no-page')

This Fabric script defines one command called deploy, taking one argument called version. It will:

All there is left to do is to start our deployment! Run:

fab deploy -v 0.1.18

This will call our deploy command with 0.1.18 as our version argument. We can define any number of commands we want and run them individually like this. There is also a way to show all commands we have defined via Fabric:

fab --list

Another thing we will get for free with Fabric is that it will show us output of the commands automatically, so when we run our deploy, we will see the output of git, rsync and systemd status commands on our own command line, which is really neat.

I really like Fabric and I think it is a great tool for many situations. Check out the documentation and make great stuff. I hope it will work well for you as well! Let me know at @stribny.

Last updated on 16.1.2020.

development-tools devops python