Continuous deployment for your Node.js projects in 10 minutes with Exoframe

Tim Ermilov
Aug 23, 2017 · 5 min read

Setting up continuous deployment for your project can be quite tricky. Puppet, Ansible, Chef — all those tools are great, but sometimes you just want something small and simple to use to deploy your pet projects to your virtual or dedicated server.
I want to show you how to setup continuous deployment for your Node.js project with rolling updates, HTTPS and all that fancy stuff in ~10 minutes using Exoframe.

For demo purposes we’re going to be deploying simple Node.js project based on Express.js, you can find the source code (along with all the other mentioned bits) in this GitHub repo:

If you prefer video format to reading, you can watch me doing the whole walkthrough here:

Preparing the server

Before you get started, you obviously need a server. If you already have one — awesome. If not, grab one at Hetzner / DO / Vultr or whatever hoster you prefer.

Once you’d setup the server with your favorite OS, you will need to configure public key SSH authentication.
This is required because Exoframe uses private-public key pairs for authentication process.
If you are using login-password pairs for SSH authentication, I strongly recommend switching to public-private key method.
Also note the part in the linked article about disabling password authentication after you are done with public key authentication part— that is also a must-have, in my opinion.

Once you are done with that — you’ll need to install Docker since Exoframe relies on it for service execution and management.
After you’ve finished with docker, all you need to start Exoframe server is to execute the following command:

docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /path/to/exoframe-folder:/root/.exoframe \
-v /home/user/.ssh/authorized_keys:/root/.ssh/authorized_keys:ro \
-e EXO_PRIVATE_KEY=your_private_key \
--label traefik.backend=exoframe-server \
--label \
--name exoframe-server \

Be sure to change the parameters to fit your server — you want to at least:

  1. Set EXO_PRIVATE_KEY to something unique. It’s used during generation of authentication tokens.
  2. Set --label to point to your host. It’s used to expose Exoframe server API endpoint.

Important note: This will also start an instance of Traefik that will occupy ports 80 and 443. It is used to route requests to your deployed services, setup HTTPS, etc.

For more detailed explanation of those parameters and startup procedure, see docs in Exoframe server GitHub repository.

Testing deployment from CLI

Before configuring continuous deployment, we need to make sure that Exoframe server works fine.
To do that, we’re going to install Exoframe CLI locally and deploy our project manually to see if that works.
Currently, Exoframe CLI only works on Node 8+ because it relies on async/await, so make sure you have the latest Node installed.
To install Exoframe CLI locally simply execute:

npm install exoframe -g

Now that we have it installed, we need to point it to our new server. You can do that by executing the following command:

exoframe endpoint http://you.server.url

Once finished, you will need to login into your server by running the following command and selecting the private key that is used for authentication with your server (and possibly entering passphrase for your private key):

exoframe login

After you have successfully logged in, you can deploy your project. But before deployment, we’ll do one last thing — generate a new project configuration file. This can be done by executing the following command inside of the project folder:

exoframe config

The command will guide you through the config creation in interactive manner. For this demo, the only important field there would be “domain”.

Important note: since Exoframe doesn’t know what is entry point of your Node.js project, it’ll simply execute npm start on deployment and expect service to listen on port 80. So, make sure that you have start script in your package.json and use port 80!

Once desired domain for your new deployment has been set, you can deploy the project by simply running this command inside of the project folder:


After Exoframe CLI reports that project has been deployed, you should test its availability on the domain you have entered during config step.
If everything works as expected — we’re green to setup continuous delivery!

Configuring continuous delivery with Travis-CI

We’re going to use Travis-CI for testing and deploying our project.
Here’s a simple .travis.yml config for Node.js project:

Travis does most of the work on testing Node.js projects for us, so all we need to care about here is specifying language and Node.js version. You can read more about that in official Travis-CI docs.

Now that we have Travis config file and we’ve made sure it works, we need to add Exoframe deployment to it.
Exoframe has a special feature called “deployment tokens” that allows you to deploy projects to your server without the need to login using your private key. So, to setup the deployment, we first need to generate such token. This can be easily done by executing the following command:

exoframe token

Upon execution you should get a freshly generated token that can be used to deploy projects to current Exoframe server.

Important note: Make sure to save the token as there’s no way to read it again, only to generate a new one.

Once you have the token, you want to use Travis-CI encryption system to store encrypted token in your Travis config, like so:

travis encrypt EXO_TOKEN="your-token-here"

After that, you’ll need to tweak the config itself to install Exoframe CLI before running tests and to trigger deployment after tests has been successful.
Config file should look something like this:

After you’ve push it to GitHub, you should be able to open Travis logs and watch your project being deploy to your server.

Bonus: Rolling updates

Note the tiny -u flag in the config above. That tells Exoframe server to execute a rolling update for the current deployment.
The way it works is pretty simple — it’ll deploy new version, wait for it to start and then tear down the old one, which will result in zero downtime deployments.

Bonus: Other project types

Exoframe also supports other project types!
Currently, along with Node.js project, you can also deploy static HTML projects, Docker project and Docker-Compose projects.

Give it a try!

If you found Exoframe interesting — give it a shot!
It is available right now on GitHub.
As usual — any feedback as well as contributions are appreciated.


 by the author.

Sign up for Get Better Tech Emails via


how hackers start their afternoons. the real shit is on Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Tim Ermilov

Written by

Hi, I’m Tim! I talk about webdev, javascript and big data.

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store