jeremyjh

jeremyjh

Releases of course are not a new thing at all, but I’ve only used them in one prior project that used distillery and edeliver for deployment to a VPS. At work we use Heroku and the buildpack and guides for that have always focused on mix deployment. Actually I’m contemplating writing a new buildpack that would use releases, and migrating to that. The other strategy available on Heroku is using Docker images, which would have the advantage of being more portable but still does not support features we really like such as PR apps.

Still, I do not think this should be done “just because”, and frankly, the benefits promoted in the releases documentation do not seem very compelling in a containerized world but I wanted to discuss further in the context of a containerized Phoenix app.

Let’s break them down.

You can do this in a mix project too:

MIX_ENV=prod ERL_FLAGS="-mode embedded" mix phx.server

As far as I know you can pass all VM options either via ERL_ZFLAGS or ERL_FLAGS.

I see the benefit in traditional server deployments but in the context of a dockerized application we achieve the same thing (as do traditional Heroku buildpack slugs) - at the end of the build you have a single artifact to deploy and manage. Yes your source code is included and that may be a factor for ISV doing on-premise deployment but this is not relevant to me or my projects. In any case the BEAM code is not obfuscated and can be decompiled to Erlang quite easily.

I may be missing something of significance here because I do not use umbrella projects but I think I can supply different configuration to each application in an Umbrella project. Maybe someone can provide an example that sheds some light on this?

Again this is very relevant in traditional server deployments, but in containers it works fine to just use mix commands (and they are the same commands you use in dev!); the container itself is the entry point that will be started/stopped/restarted.

Showing Posts 1 to 10

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Does this actually work? This just crashes for me. It was my understanding that embedded mode requires that there be a list of the beam files the application actually needs so that it can eager load them. Part of what a release does is compile this list.

Sort of. We build and run in containers. The build container is enormous since it requires that we have a working Erlang / Elixir, plus all the dependencies you need to build those. The run container is an incredibly minimal Linux image with just the release on it. This difference is even more stark for applications that contain various NIFs and need build tools for that (Rust).

If you use releases, you have a much smaller image overall, and you’re basically guaranteed that the only layer to change per version is just the release itself.

Really though it’s a cost benefit analysis question. If you don’t use releases you still need to manually re-implement (without mistakes!) embedded mode, setting up a remsh, and optimize your docker images for building as well as execution, etc. You can get rid of all that headache by just calling mix release.

jeremyjh

jeremyjh OP

Yes it seems to work fine locally for me in MIX_ENV=prod mode, but I admit I don’t use it in production. It does indeed crash in MIX_ENV=dev. Perhaps its not actually working in embedded mode when there is no manifest? If that’s the case its definitely an advantage to using releases, though I’ve never observed latency issues on restarts I haven’t tried to measure them either.

This is a really good point and is very compelling.

sasajuric

sasajuric

Author of Elixir In Action

At Aircloak, we have containerized deployments, and we still use OTP releases. Besides what @benwilson512 said, there are some other benefits, such as getting a remote iex shell, or the ability to execute custom commands inside the running system. Polite system termination is also supported out of the box.

cnck1387

cnck1387

That’s what I planned to do when I deploy my first Phoenix app but how do you deal with testing that released image? If it’s a super minimal image with nothing but the release, that means you can’t run any test suites against it right?

In other words, if you build that release image on a CI server (based off the bulky dev image having its tests pass), aren’t you effectively shipping an untested release to production?

LostKobrakai

LostKobrakai

Tests are run in MIX_ENV=test, while releases build/mix runs in MIX_ENV=prod so you’re essentially never testing the production build to begin with. There will always be some differences between what you ship to production vs what you run tests against (besides maybe for external integration tests).

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

As @LostKobrakai notes, your Elixir test suite is already a different compilation artifact from the production beam files.

This isn’t actually a huge concern though either for MIX_ENV=prod mix phx.server or releases. The only thing the test suite can validate is your application logic. It can’t validate that your production config is setup such that your container can actually start. This is what liveliness and readiness checks are for. Your deployment process should be such that no traffic is routed to the new container until it passes both liveliness (your application is running) as well as readiness checks (it has finished the boot process and can handle load) anyway. This is the final kind of validation, and it works perfectly well regardless of how you start your app.

cnck1387

cnck1387

Yeah that makes sense. Fire off a health check to a route to ensure it reports a 200 (the app booted and is ready). That’s something I do already in other tech stacks, but Elixir is slightly different in the sense that with a Flask or Rails app, the exact image I built and pushed to Docker Hub in CI is what ends up running in production which in turn is also the exact image I was running locally too.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

ehhhh not as much as you might thing. Rails, for example, metaprograms so much based on configuration that you aren’t really running the same thing. A classic example would be Active Record, where whole methods are metaprogrammed in by reflecting on the database tables. You’re running the same code sure, but when it comes to the actual byte code being run it’s all over the map.

If the “use the same image” is a hard requirement by the way, there’s nothing stopping you from doing mix release in the same image you do mix test in. All this really gives you though in all of these languages is the guarantee that you’re using the same code, but this is something git gives you, you don’t need docker to give it to you.

The release-with-two-images approach has the same code oriented guarantees. You use git to make sure you’re running the same code, but that code, just like flask / rails, is parameterized. You insert one set of parameters and do tests, you insert another set of parameters, get a new artifact, and run it in production. It just so happens that in the case of Rails there’s a different ratio of how much parameterization happens at runtime vs compile time.

I think the main point I’m trying to make is that mix test and rspec are not tools for testing production artifacts, and just that your production artifact is on the same docker image as where you ran mix test doesn’t change that. Validation in production looks more like staging environments, monitoring, and status checks. For example we do run identical images in both staging and production for that purpose precisely.

keathley

keathley

I worked on a Java system where the readiness checks were the integration test suite. Once integration tests had passed it was safe to add to the load balancer. This strategy also had the benefit of warming up the JVMs. That might be overkill for a lot of people but these ideas don’t need to be mutually exclusive.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Fair enough, and I think that’s a great idea. Those kinds of tests though are not the same kind of test you have with mix test.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New
marciol
It would be helpful to have a list of companies worldwide that hire engineers without prior experience in Elixir. Often, it can be quite ...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews