"Binary" distribution of Elixir/Erlang applications

I’m building an application that I would like to distribute as an installer so that people can set it up on their local machines. I’m planning to target Windows/Linux/MacOS.

I’ve done some looking around and I can’t seem to find if there is a strategy for bundling together the Erlang VM and and one’s code into a single executable.

Has anyone heard of such a thing?

1 Like

It’s called a release and done with distillery.

You can embed the runtime, then you do not even need to require Erlang as a dependency.

You need to build the release on the target system though. It has to meet the processor architecture, operating system, versions of required dynamically linked libraries, maybe other stuff.

Maintaining the build infrastructure to target more than just your own machine can get tedious, but is possible.

3 Likes

I have one build docker image per platform we support. It is pretty straight-forward to setup. I only have an erlang example but adding elixir to this should be easy.

FROM ubuntu:16.04

RUN apt-get update
RUN apt-get -y install curl build-essential git libssl-dev openssl libncurses5-dev

RUN mkdir /opt/erlang
RUN cd /opt/erlang && curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl
RUN chmod a+x /opt/erlang/kerl
RUN /opt/erlang/kerl update releases
RUN /opt/erlang/kerl build 20.3 20.3
RUN /opt/erlang/kerl install 20.3 /opt/erlang/20.3

CMD ["/bin/sh"]

Then I build a release like this:

docker run -it --rm -v $PWD/build:/build -w /build ${MACHINE} /bin/sh -c \
". /opt/erlang/20.3/activate &&\
cd /build && \
rm -rf _build && \
./rebar3 compile && \
./rebar3 as prod do clean, tar"

I guess you do something similar to mix.

Yeah, but I’m not aware of Mac or Windows containers, and I am not sure how current they are or how compatible to real hardware.

One can still use a virtual machine for Windows, but one needs probably to redist all the DLLs used and do that for each supported version (7, 8, 10, maybe 8.1 if it is different enough…)

Than we have Macintosh which you probably need in real hardware, and there I’m not sure about how installing software works there, I often read about brew. But to be honest I have no clue how to build packages for it.

Last but not least, even for Linux we have a plentora of package managers to deal with which all need a different setup or require different default locations for config files. The major ones that should be supported are Debian’s apt, redhats yum and maybe nix’ nix.

All of those needs to be learnt from scratch again.

To be honest, if it’s opensource I’d go with a source tarball and build instructions, the community will deal with the rest and then one can slowly take over maintenance of those packages or integrate their maintainers into the core team.

If it’s payware just ask your client for their spec and build for them. Or sell it as a service instead of software.

2 Likes

There was some discussion on the Erlang mailing list a while back about building executables which include application code. That sounds like what you need, though I am not sure what the current status is. It would be nice to have the “copy a single executable to the server” deployment model that Golang enjoys.

3 Likes

That’s definitely a point where Golang wins over Elixir/Erlang.

1 Like

Its a nightmare…

It requires me as a developer to hunt and chase bugs in libraries I use and recompile with newer libraries and to update my software.

Well, maybe sometimes we have a special team for such tasks, still it puts this burden of updating libraries to the application, instead of the system.

Don’t take me wrong, I do like the single-binary approach taken by go, when I write tools on my computer, that are meant to bootstrap a system from ground up. Things that I compile once, and will probably run only once (per system) in an environment about that I do know nothing but “it comes without anything pre-installed”.

1 Like

I think for server applications, if you are using releases, then it’s not that big of an improvement. https://www.cogini.com/blog/best-practices-for-deploying-elixir-apps/

With a binary, we would need to do most of this the same. Instead of/in addition to building the release, we would turn it into a binary. Then instead of supervising the release script, we would supervise the binary. And we lose the ability to do hot code updates.

The use case that’s most interesting is deploying Windows apps. There we avoid the question of running the release shell scripts on Windows. Perhaps moving more of that machinery into the VM would be a win.

Thanks for the info, I’ll give distillery a go and see if it meets my needs.

I just discovered that Elixir 1.9 supports releases natively. That seems to mean that distillery is no longer needed if you are running version 1.9.

1 Like