Hacker News new | past | comments | ask | show | jobs | submit login
Bakeware: Compile any Elixir application into a single binary (github.com/bake-bake-bake)
147 points by sergiomattei on June 8, 2021 | hide | past | favorite | 29 comments



I'm glad Bakeware is applying brainpower to the entry point problem for simple scripts.

I'm currently learning Elixir and the biggest initial hurdle was how to actually create an application. Most tutorials teach you through iex but rarely how to actually write a running program or library.

Things like "mix run" wouldn't work until I created an app with mix new, then I had to visit the rabbit hole of genservers and supervisors, etc...

It's a little complex for beginners and could use some polishing. I can't say that I truly understand it still.


I remember being a reviewer for an Elixir book where the first chapter was listing the pros and cons of Elixir, and one of the cons was: it's kind of hard to manage deployment of Elixir applications.

My feedback was "hum, that's kind of a turn off for someone trying to learn the language/tech no?"

I think the community has been looking for something for a while now and is iterating (too?) quickly. There was erlang releases, there was distillery, now it's elixir releases. There are different ways of configuring in production. It goes a little too fast to keep up with to be honest.


It took me 1 hour to convert a production app from Distillery to native releases when Elixir 1.9 released 2 years ago. And deployment in 2021, whatever the language, is best served with containers. Elixir is not harder to deploy than a Django or Node app.

In fact, releases and post-deploy ops are pretty well documented: https://hexdocs.pm/mix/Mix.Tasks.Release.html

Phoenix also has an example multi-stage Dockerfile which is fine for 99% use cases: https://hexdocs.pm/phoenix/releases.html


> And deployment in 2021, whatever the language, is best served with containers.

...in 2020 I deployed to bare metal servers. Mix released a gzip to S3 and pulled the artifact down, systemctl restart dnautics_service.

You're making me feel like some sort of dinosaur.


Bare Metal / Containers / VM It's all about managing your dependency chain, and how much variation of environment you're willing to accept. You don't need to feel like a dinosaur if what you're doing is principled and reasonable.

There's no one size fits all.


Haha we bought these servers for 5k, very op, but since we had a rack full of HW (that this one blade was managing) anyways, the server price/power consumption for a 1U was a drop in the bucket. Very strange world. I think the server was at 10% CPU consumption, and we didn't bother doing the erlang "turn off IO polling for modern cloud operating systems" option.


Don't let the kids get you down. My deployment scripts look something like this:

rsync --rsync-path=/usr/bin/openrsync -r --delete config lib mix.exs mix.lock priv server:my_project

ssh server "tmux respawn-window -t my_project:1 -k"

It's only weird if it doesn't work, right?


I also use tmux as part of my deploy process. ;)


If you're already using systemd, you can use systemd-nspawn to launch your service in a container and nothing would change in your workflow.


I agree! As a learning project, I wrote a small service[0] that reports data from our solar panels to InfluxDB every second.

I thought deploying would be a pain. It was really painless: a matter of cloning on the home server, running ‘mix release’ and pointing a systemd unit to the start script it generated.

It was a pleasant surprise, especially coming from the Django world where anything deployment related would be a day’s work.

[0] https://github.com/matteing/mate3s-influx-reporter


It's going fast because the original ways were (euphemism) sub optimal. Example: compiling configuration into a release was clearly wrong based on my experience with other languages. A small mistake and another run through CI/CD with production down vs edit a configuration file and restart? Ouch. Maybe inevitable with a lot of servers but very wrong for a single server application.


too fast? I was using Elixir releases two jobs ago.


My holy grail would be to (somehow) create a release on Windows (my dev system) and deploy on Linux (our prod servers). However, I have little hope because of the Erlang binaries requirement. Still, you can always hope :)


If all goes to plan, I am planning on sponsoring a bounty to get zig cc to cross-compile erlang this summer. In theory, that should enable what you're looking for.


That’s brilliant!


You can do this with WSL or Docker, can you not?


I not really sure I don't use WSL nor docker. Even if it was possible I'd really prefer a native solution...


WSL is not 'native' per se, but it's very well-integrated with Windows. I'd give it a look, even if it's just writing a script to run a build command in WSL from the same directory you're developing locally in.


CI/CD tools can do that for ya


Can the cpio command extract the Erlang VM from these binaries? If not, then it shouldn't be called cpio. Operating systems have been known to block binaries that have compressed binaries inside them using novel formats tools don't understand. The design here is very similar to ZIP, which would be a good thing to consider, since that would grant the end user the flexibility to copy the app out of the bakeware shell into their existing Erlang install without having another Erlang get installed.


This is pretty neat. One of the reasons why I started looking at golang and stopped writing erlang in 2016 was the single binary deployment. Time to look at elixir with this gem again!


I don't know much about elixir but I'm interested.

Are there disadvantages to this process?


Yes: dynamic linking allow receiving OS security updates for any library.

With static linking you become responsible for:

- tracking down the dependencies used during a build

- track where the binary is deployed

- follow publishing of vulnerabilities affecting the libraries you used

- either backport security fixes, rebuild and deploy the binary or deploy a newer version hoping it does not break anything


I'd assume it's incompatible with LGPL code/libraries (unless it's open source), then again I have no idea how widespread said license is in the Elixir world.


IIRC LGPL says you have to "convey" the code, not "you must bundle the code with your binary", it could be anything from "email this address to request the code" or "send a SASE to this address and I'll send you a CD-ROM". I believe GPL even lets you charge for the code, I could be wrong about that.


You can charge someone for gpl code but you can't expect to get paided if others give away that code.


Static linking with LGPL is OK as long as you allow users to relink to other libraries.

You can do that by shipping the object files with the binary, or on request, or providing the sources of your application under a closed license, or under any FOSS license.


Is this fundamentally different than how an escript works?


I think it embeds Erlang (erts), escripts require a working Erlang installation.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: