Back in September 2016 I’ve presented the first public version of Exoframe. At a time I’ve positioned it as a tool to simplify management of Docker. The idea was pretty simple — take away the pain of writing, maintaining and deploying docker images to your server.

That was done through templates and project detection — Exoframe alpha would read your project directory, try to figure out which template to use, add Dockerfile from that template and then deploy it to your server while asking you a bunch of questions.

In a long run — it didn’t quite work out for me (or anyone else according to download statistics). It was annoying to answer so many questions on each deploy, there was no way to easily assign domains to demos and most of the Docker features that I’d coded into deploy step were not used as frequently as I thought they would. So, at some point I just stopped using it altogether.

Then I discovered Now.sh from ZEIT. It’s an amazingly simple tool that allows you to deploy Node, HTML and Docker projects in one command. No questions asked.

Even though Now is great and gets even better with every update (e.g. latest update allows you to work with GCP, AWS and Azure), it still has it’s limitations. Biggest one for me is the fact that I cannot use it with my own servers. I’m sure some of you also have a few demo servers at work, one or two VPSes you already own and maybe even some dedicated servers just for fun. Sadly, currently there’s no way to run self-hosted Now.

Another issue is complex docker projects — while Now allows you to deploy project from simple Dockerfile, there’s now way to deploy one using docker-compose that describes multiple services (e.g. database with backend and front-end).

That’s why I decided to re-think and re-build Exoframe to address all those issues. Think of it as a self-hosted alternative to Now that allows you to easily deploy your projects to your server, while getting automated domain configuration, load balancing, HTTPS (thanks to letsencrypt) and all that good stuff.

If you prefer video format, you can watch the demo and explanation of how it works in the video below. If you prefer text — scroll on :)

Exoframe server and how it works

The way Exoframe works is pretty straightforward — the only thing you will need to install it is a server with Docker daemon. Some server providers even have pre-configured servers (e.g. one-click Docker server from DigitalOcean).

Exoframe server itself works in a pretty simple way — upon execution, it’ll spawn an instance of Traefik that’ll handle domain management, HTTPS, load balancing and all that stuff.

Then it simply gets packaged projects from Exoframe CLI and deploys it to your Docker daemon while configuring Traefik and Docker for you.

Authentication is done using private-public RSA keys, so normally you wouldn’t need any additional setup if you already can SSH into your server using your private key. If you are still using login and password for SSH, see this guide that’ll help you to switch to more secure key authentication.

All you need to do to set the whole thing up is to execute Exoframe server within your Docker daemon, like so:

This command will start Exoframe server, allow it to access your docker via docker.sock, link config folder to your local folder to persist configuration upon restarts/updates/etc, link your authorized_keys files for authentication and finally — setup rules for Traefik. You can find more detailed explanation of each line in the server repository.

Exoframe client and commands

Once Exoframe server is up, you’ll want to install Exoframe CLI. Currently, this can only be done using npm, so you’ll need latest Node.js and npm installed on your system.

Once you have them, you can install exoframe using the following command:

npm install exoframe -g

After that you will need to point Exoframe CLI to your newly set up server using the following command:

exoframe endpoint http://exoframe.server.url

And finally login into it by using exoframe login and selecting the private key that has been authorized to access your server.

Once logged in, you’ll get access to main commands:

exoframe [deploy] — deploys current project to your server

— deploys current project to your server exoframe config — generate new config file for current project

— generate new config file for current project exoframe list | ls — lists active deployments

— lists active deployments exoframe remove | rm <id> — removes active deployment

— removes active deployment exoframe logs | log <id> — displays logs for active deployment

The deploy command currently understands and is able to handle the following project types:

Static HTML based projects — will be deployed using nginx image Node.js based projects — will be deployed using node:alpine image Docker based projects— will be deployed using your Dockerfile Docker-compose based projects— will be deployed using your docker-compose file

Configuration for deploy command is done using config file that contains the name of your project, domain you want to assign to it, environment you want to set, restart policy and internal container hostname. Structure of config file is covered in Exoframe readme.

HTTPS with letsencrypt

Since Exoframe uses Traefik to manage domains, you get out-of-the-box support for HTTPS with letsencrypt certificates!

To enable it, you’ll need to edit your server config file and set the following fields:

letsencrypt: true # whether to enable letsencrypt, default "false"

letsencryptEmail: your@email.com # email used for letsencrypt

Once this has been set, just start your Exoframe server.

Warning: If you already had Exoframe server and Traefik running, you’ll also need to remove old Traefik instance from Docker daemon and restart Exoframe server. This is required since Traefik needs to be re-created with additional letsencrypt parameters.

Once this is done — all your projects will be automatically deployed to HTTPS with letsencrypt certificates!

Automatic subdomain generation

Exoframe server also allows you to enable automatic subdomain names generation (similar to how Now.sh does it, but with your domain). This can be done by setting baseDomain field in server to config to the top domain you want to use. E.g. setting it to .codezen.net will result in deployed services without explicitly specified domain names getting domains like exo-user-demo-d234ah3.codezen.net

This is useful when you want to quickly deploy and test your projects without using the real domain name for them.

Current limitations

Exoframe obviously has its own limitations:

Largest one being limited support for docker-compose projects configuration. While Exoframe can easily manipulate containers it deploys directly, changing configuration of docker-compose services is quite limited. Because of that, you’ll have to set e.g. Traefik labels for domains manually. Unfortunately, there’s no real way to “fix” this issue but to provide better docs.

Another limitation is the fact that currently you can only login using private-public key pairs. While this works pretty well for people, using it from CI/CD daemon is not exactly nice. I am planning to address that in future by adding deploy tokens that’d allow re-deploying one specific project without need to authenticate using private key.

One more obvious limitation is support for only 4 project types. While Dockerfile and Docker-compose projects do allow users to deploy pretty much anything, it could be nice to have more autoconfigured projects. I am planning to address this in future by introducing plugin system to project deployments if there’s enough interest in it.

Conclusions

If you found Exoframe interesting — give it a shot!

The beta is available now on GitHub.

As usual — any feedback as well as contributions are appreciated.