What is the recommended way to deploy right now? And what is everyone’s thoughts about Docker?

phoenix
deployment
digitalocean

#1

I have been a long-time user of Gigalixir, but want to move to a DigitalOcean instance. I’ve always had my eye on running on a Ubuntu droplet and having more use of OTP having it run directly on the server.

I’ve always been slightly interested in Docker, but I heard that you lose the ability to run mix commands and a few other things. I just got back from EMPEX LA and someone was telling me how this isn’t true and that running within a Docker instance you have more efficient memory usage.

I also hear about eDeliver a lot less. Is mixing Distillery and eDeliver not a thing anymore? I’ve also heard of building the image with Docker and then running it on a DO instance.

Deployment has always been shaky for me and when I started using Gigalixir it was too easy to just stick with it, but I want to learn more about deploying without services like Heroku and Gigalixir.

What is the recommended way to deploy right now? And what is everyone’s thoughts about Docker?


#2

There is nothing inherit to running in a container that would prevent you from getting iex shells and the like, however, the networking environment becomes a bit more complex and working around those complexities can take some planning.

In my environment we use Kubernetes for “container orchestration”. In the testing clusters I can run arbitrary commands in containers and getting a shell (either unix or iex) is pretty straightforward. In the production clusters, I have much more restricted permissions - I can’t run arbitrary commands in the containers so my ability to run shells is much more restricted.

With planning, I could engineer (and secure) pathways in the production environment to let me get at those shells. It certainly would make debugging production issues much easier, but I haven’t done so. In other words, it would be possible, but would take dedicated effort.


#3

I don’t think there’s any recommended way, but I wish there was some plug n play solution for people who just starts out with elixir.

We’ve been using ansible to manage builds with distillery and a docker container. It has been a very solid solution so far.

Github: https://github.com/danschultzer/ansible-phoenix-build
Blog post: https://dreamconception.com/tech/phoenix-automated-build-and-deploy-made-simple/

The inspiration came from this blog post by Piotr Włodarek.

Edit: We’re using DigitalOcean, and don’t run the apps inside docker containers.


#4

I find that using Docker (for example on CoreOS) is extremely practical - also for small and medium sized projects. It requires very little setup and makes your deployment easily repeatable.
You do lose some of the features of OTP Releases, most notably hot upgrades. But I prefer the certainty of atomic and repeatable deployments over this convenience.

I have created a little guide for dockerizing Elixir Releases. Let me know what you think!


#5

This is how I planned on running my app. It wasn’t until the host of ElixirTalk was telling me about how Docker slows their app to perform more efficiently and it made me wonder what everyone else was doing. Before I was using Distillery with edeliver on a DO droplet.


#6

Did they explain how it performs more efficiently by slowing down their app? I’m curious to see some data on this.


#7

Deploying is always a complex subject that always fascinate me. Currently for my elixir projects I’m deploying directly on a VM with distillery.

Before that I was deploying with dockers in a kubernets cluster. The configuration that I had before allowed me to have shell to all my machines which was fine but it’s a little more complex to setup. I myself prefere to use dockers when I can, just because it’s easier to test and replicate some scenarios on different OS. But distillery is mature enought and there’s a number of guides to guide you through that (one example https://hackernoon.com/mastering-elixir-releases-with-distillery-a-pretty-complete-guide-497546f298bc)


#8

My company uses distillery and edeliver on AWS and hot deployments. Works fine.

I find Docker to bring philosophical friction to the BEAM culture. Docker comes from the culture of “servers as livestock, not pets” but BEAM comes from a culture of stateful long-running servers. I hear that people can have success treating BEAM like livestock in a container, but I don’t find that it solves any problems the BEAM faces. It’s a solution to different organizational-level concerns.


#9

My opinion is that unless you have a use-case that means you cannot afford to shut down nodes (say, if you’re working in some kind of embedded space) then hot code upgrades doesn’t offer anything worth the complexity. My approach is always to restart the entire VM when there is a new version to deploy, and manage traffic using a load balancer so that the user experience is not impacted by the nodes being swapped out.

This is largely down to my personal experiences and preferences, other opinions exist and are valid :slight_smile:

I like to use Docker as a deployment artefact- I enjoy how it bundles all OS dependencies inside and is much less susceptible to bit-rot compared to other formats such as (for example) apt packages. The fact there are now numerous platforms and services that work with docker images is a nice bonus.
I don’t use it in development in any fashion.

Inside the docker image my application is compiled into a release using distillery, which is working nicely.

Currently I’m deploying to Heroku, though previously I’ve deployed to Kubernetes, and to VPS’ that I’ve managed using Ansible.

At some point in future I may decide to move off of Heroku (possibly for cost and performance reasons), at which point I may also swap out docker for virtual machine images built with Packer, deployed to a cloud provider such as GCP using Terraform. I’m unlikely to use Kubernetes again, I personally found it too much work for a small team.


#10

There’s been quite a bit of interest for the guide and repo so I’ve updated them with Elixir 1.8, Phoenix 1.4, Ecto 3.0, ansible 2.6 and distillery 2.0.


#11

Docker is just slim down linux. You don’t lose anything you pick and choose want you need with the container.

From what Jose Valim stated their last thing they’re working on for current Elixir 1 version is release which will integrate distillery.

So I personally think distillery is safe.

Docker is pretty awesome it’s like VM but lighter. You can do kubernetes with docker (containers) which I did at an internship but I think kubernetes API changes too much and seems beta software. I’ll come back to it in 5 years.

Containerization is a solid technology. I wish the other team, coreos, is winning. Docker require a daemon to run and I think it’s meeeeh. It’s been a while but IIRC it’s a single point of failure.


#12

I host my phoenix application in a k8 cluster in Azure, and I use :peerage for resolving my erlang/elixir nodes that belong to this application’s cluster.

It works quite well.

The only issue/headache I sometimes get is how to manage the database in case I need to do something manual. Since my devops system automatically deploys and manages this by init-contaners or the like it is a little hard to do certain things. But I wouldn’t have it any other way as kubernetes is simplifying so many other aspects of hosting my application.


#13

Maye it should be added that if you want to use Docker, it’s still a good idea to use Distillery Releases.


#14

In general I find that using releases (Distillery) is the best bet (I have an email course on it here http://bit.ly/elixir-release-ecourse) Once you have the release you can just SCP the tar file up to the server, untar it and run. Docker works too if you want it but may be just an additional step for no good reason


#15

Any elixir folk has access to Github Action? We could share some common, basic infra configs, just configure credentials and go. It’s still old Docker and CI approach but I think it’s less involved


#16

The only thing that was said IIRC was that they can max out the CPU performance within a container compared to running it directly on something like a Ubuntu server on DO. I am also not that familiar with containers because I’ve for some reason steered away from them until now and this was also over a few beers so I could be hazy on the details. :rofl:


#17

At work I’ve used Edeliver and Distillery, but my coworkers and I are in the process of moving our fleet of Elixir apps over to Docker and Kubernetes. We’re roughly 1/2 done.


#18

It seems like people either love or hate Kubernetes. I had the exact opposite conversation with two different people at EMPEX this month. One was how they were migrating to Kubernetes and the other was migrating off. The more I went around and asked people what they thought there was no middle ground.


#19

If you’re deploying to a single Droplet, I’m fairly certain that adding Docker is going to be more pain than gain*. I do not recommend using Docker for that situation unless you want to do it just for the learning process. And even if the learning process is important, I would still recommend getting the OTP release (Distillery) process learned without Docker first. OTP releases are complex and error-prone enough as it is.

Some folks listed some benefits that Docker may provide you, but again I wouldn’t reach for Docker until it’s clear you need those benefits.

*One thing Docker might be overall beneficial for you is if you use it to build your OTP release locally. You have to build your OTP release on the same OS distribution and version (e.g. Ubuntu 16.04) that the production machine is running. Docker gives you the ability to build your release locally in that OS distribution environment without having to manage a virtual machine. You would use the Docker container to run mix release and write the files of the release to your local file system. Then those files can be tarred up, uploaded to your production Droplet, and deployed.

I suspect what someone said to you about not being able to run mix commands was actually about OTP releases, not Docker. One feature of OTP releases is that the production machine doesn’t need to have Elixir (or Erlang) installed on it. The Erlang runtime is included in the release. When you use mix on your development machine, it’s a system utility that is associated with your system Elixir. On your production machine running an OTP release, Elixir and mix aren’t there. But, just because you’re doing an OTP release doesn’t mean you can’t install Elixir and mix on the production machine yourself. You can do that. Just watch out for diverging Elixir versions.

It wasn’t until the host of ElixirTalk was telling me about how Docker slows their app to perform more efficiently and it made me wonder what everyone else was doing. Before I was using Distillery with edeliver on a DO droplet.

What they were probably talking about is the situation where you have multiple Docker containers running on a single machine. You can constrain the containers’ resources so that one container doesn’t use more than its fair share of resources.


#20

You always have the option of not including the ERTS with the release, by setting the set include_erts: false in the Distillery config.exs file and simply having Erlang installed on the machine.