Deploying the Winds API to Digital Ocean with Fabric

6 min read
Nick P.
Nick P.
Published September 25, 2018 Updated March 4, 2020

Winds is a popular RSS and Podcast application provided by Stream – a service that allows you to build news and activity feeds in hours instead of months. Because Stream values collaboration and the opinions of our users, Winds is 100% open-source and the backend is easy to install in a local environment or in the cloud. Fabric, a tool that we’ll be using in this tutorial, is a Python library and command-line tool for streamlining the use of SSH for application deployment and administration tasks. It’s an extremely powerful tool, however, for sake of time, we’ll only be touching the very basics of what is possible with Fabric. To ensure that you make it through the tutorial, please make sure to complete all of the prerequisites.

Prerequisites 📚

As with any tutorial, there are some requirements that come with it. For this post, you’ll need to ensure that you have the following up and running, and ready to go prior to continuing on. If you decide to skip the requirements, you’ll likely get hung up at some point along the way – and we don’t want you throwing your computer against the wall when you get frustrated. 😉 Please make sure you’ve got:

  1. An account on DigitalOcean with billing enabled and your SSH key set
  2. A fresh clone of Winds from
  3. An account with MongoDB Atlas or another MongoDB provider (we recommend MongoDB Atlas)
  4. A free account with Stream
  5. An instance of Redis – we recommend AWS ElastiCache (copy the URI as you’ll need it shortly)
  6. A free API key from Mercury (this handles RSS article parsing, so it’s very important)
  7. A free set of credentials from Algolia
  8. A domain name configured for use on DigitalOcean

Creating and Configuring Your Droplet 💧

Under the “Manage” section of your DigitalOcean dashboard, there will be an option for “Droplets”. Click “Droplets” and then click “Get Started with a Droplet”. Follow the instructions below:

  1. Choose your image (Ubuntu 18.0.4 x64)
  2. Choose a size (1GB @ $5/mo.)
  3. Choose data center region (New York - 1)
  4. Add your SSH key (for me, it’s Nick)
  5. Choose a hostname (winds-api)

Let your Droplet build – this can take up to 2 minutes. Once complete, copy the IP address and SSH into the Droplet using your terminal and the username root.

Update & Upgrade

For good measure, update and upgrade your packages (and be sure to follow any prompts that show up in the terminal): And, don’t forget to install the essentials:

NVM (Node.js)

Now, let’s install NVM (Node Version Manager): Run command -v nvm to source NVM and then run the following command: As you probably noticed, NVM listed out all of the available versions of Node.js. Go ahead and select the latest (v10.10.0 at the time of this post): Now if you type node --version, the output should say “Now using node v10.10.0 (npm v6.4.1)”.


Next, let’s go ahead and install Yarn, the package manager that we’ll be using for Node. On Ubuntu, you can install Yarn via the Debian package repository. You will first need to configure the repository: Then, you can simply “run” to finalize the Yarn installation:


PM2 is a great package that will handle the clustering of our Node.js processes and ensure that they stay alive. It’ll even keep an eye on scripts and restart them after an update. Install is simple since we have Yarn installed:


Now that most of our dependencies are installed, let’s go ahead and get Nginx installed as well. This will serve as an important aspect of our installation – as our Node.js API runs off of port 8080 and not 80 or 443.

Let’s Encrypt

Now that Nginx is setup and port 80 is open, let’s go ahead and set up SSL for our future API. This will ensure that all traffic going to and from the server passes in a safe manner. Let’s Encrypt is freely available to the public and allows us to generate a certificate in no time with Certbot. Note: Be sure to answer yes (Y) to all of the questions. Note: I chose the option to redirect all traffic to HTTPS from HTTP. This is the safest option available.

Setting up GitHub 💻

Once the API is built, go ahead and push the code to a repository on GitHub. I’m going to use the repo name @nparsons08/Winds. I’m also going to make this private as it contains sensitive keys. Once you add the origin with git remote add github <YOUR_SSH_URL>, you can go ahead and push to GitHub. Next, let’s create a Deploy Key so that the server has access to the private repository. To do so, click Settings > Deploy Keys > Add Deploy Key. Specify the “Title” as “Digital Ocean” and we’ll generate a key on the server using the ssh-keygen command. On the server, type ssh-keygen and follow the prompts (the default values are fine). Once complete, type cat /root/.ssh/ and paste the results of the output to the “Key” section of the Deploy Key page. Then click “Add Key”. Now, the server will have access to pull the latest code from GitHub!

Clone the Repo 📀

Move into the /var/www directory and clone your repo. Be sure to use the SSH version of the URL or your Fabfile won’t be able to pull the code later on. Let’s go ahead and compile the app. Head over to the root Winds directory and enter ./api/ to kick off the build script (you must first install dependencies in the /Winds and /api directories with the yarn install command). Before you continue on, you’ll want to create a .env file inside of /app where your environment variables will be stored. To make things easy, I’ve provided a template below: Now, move into the Winds directory and type the following command to kick things off:

Modify the Nginx Configuration 👩‍💻

In order for Nginx to pick up on what app we’re running, we need to specify the correct path. Let’s go ahead and do that now. Open default with vim, nano, or your favorite editor and change your configuration to resemble the following: Note: Line numbers 15-19 are the most important. Once you’re done, you can run sudo service nginx restart to restart the Nginx process.

Validate That the API is Working ✔

Drop your URL into your browser of choice and voila! If you see “pong”, the API is up and running! If you need to debug anything on the server side, some useful PM2 commands are:

  1. pm2 list (lists the current processes running)
  2. pm2 kill (kills all process running)
  3. pm2 restart all --update-env (restarts all process while also reloading your .env file)

Next, we’ll dive into Fabric and show you how to create a Fabfile for deploying automatically.

Creating a Fabfile 📝

In order to run a Fabfile, you must first install Fabric, which can be done with pip. You can use the following script to install from your terminal: To speed things up, I’ve created a Fabfile for you. Copy the contents of the file below and save them as in the root of your project. Be sure to swap out the IP address, and the path to your SSH key (if it differs from mine). Once saved, you can run fab deploy and the script will SSH into your Droplet, install dependencies if new, and reload the environment file.

That’s It! 🎉

If you have any questions or comments on this tutorial, please leave them in the comments below. Your feedback is greatly appreciated. I hope you enjoyed this tutorial! Happy coding! 👏