Server-side use of ASDF and similar tools (split thread)

I would strongly discourage server-side use of asdf and similar tools, especially in a production environment. They’re best viewed as developer tooling only.


curious for what reasons? I would strongly encourage using asdf in prod - for dev/staging/prod parity - and not being at the mercy of any of the built-in package manager that may be slow to get important updates - may not compile elixir against latest(used) OTP etc etc

1 Like

I agree with this so also want to know @shanesveller reasons not to use asdf in production. Using it has allowed me automate release builds of multiple elixir projects (with different erlang/elixir versions) on my build server which emits releases. If my .tool-versions file references an erlang/elixir version that does not yet exist on the build server then it automatically downloads and builds the proper versions from source achieving dev/prod parity.

I agree it’s not necessary to install asdf on the actual production servers running the built releases as they are fully self-contained… hoping that is what he meant.


This is non-exhaustive, and some of my concerns are more subjective than others due to my surrounding technology preferences, like my affinity for Docker/Kubernetes. Anyway, here goes:

  • To my knowledge, ASDF and its plugins have never gone through any kind of security audit. If you don’t also own the infrastructure implementation, good luck convincing a disciplined infra/ops team that this is the way to go.
  • While not nearly as insidious as similar tools like rvm, which makes extensive alterations to the shell’s core behavior, ASDF still entails prepending to your PATH and transparently overriding any conflicting binaries that might exist in the system-level PATH. In a server context, that’s a bug, not a feature.
  • Simply activating ASDF’s core behavior requires sourcing shell scripts that you must implicitly trust to not introduce security flaws or behavioral problems. Right now all they do is set PATH and shell completions.
  • With ASDF comes a reduction or absence of ownership of your foundational supply chain - you are (perhaps blindly, unless you go RTFS) trusting that ASDF is installing a secure, accurate, and unmodified instance of the language runtime, and that it will always continue to do so. Review of the installation methods is a community effort with no official involvement or oversight by OS/distribution maintainers or language authors.
  • ASDF makes no assertions about the reproducibility of the language installs it provides, and asdf-erlang by way of kerl defaults to building OTP from source while linking system-level libraries. Different hosts will produce subtly different versions of Erlang over time, albeit in ways that rarely bite us in practice. This can be mitigated by:
    • Preferring pre-built OS packages (even if you start to maintain your own with something like fpm)
    • Adopting something like Nix/Guix that has stricter guarantees about provenance, checksums, etc.
    • Replacing shared-host-level runtime environments with immutable/reproducible artifacts, such as Docker containers
  • If the use of ASDF on the servers extends to a fleet of actual application servers, you’re repeating all of that build-OTP-from-source work for each host, when a build-once approach is preferable. (Folks who come from a Ruby background remember the pain of Nokogiri compilation needing to happen on each runtime host.)
  • The desire for server-side ASDF implies a couple possible practices are in place within your organization, one of which I find especially troubling. I strongly disagree with multi-tenancy of applications using disparate versions of the BEAM runtime on the same host, without using ERTS-included releases, and/or without applying an isolation technique like LXC/Docker/BSD jails/Solaris zones.

The tiny pragmatist inside me will acknowledge that most of these aren’t really pertinent if you’re only installing ASDF in a CI environment or a build host in an edeliver-ish stack. Since those aren’t using ASDF on a production server, I still don’t recommend it but I have far fewer objective qualms with it.

I would maintain that there are significantly better approaches to achieve the same goals, once people are able to separate the specific goal from the existing, known, sub-optimal tools to get there. I’ve mentioned a couple throughout the post.


Not all version management tools should be treated the same. There is Nix which can be used in both environments (with slightly different configuration). It can even describe building process for your whole project, so if you have multirepo micro services then you can add your project as a development dependency to another service and the second developer will need no knowledge about Erlang to use it.

1 Like

I think we can all agree that modern Linux package tooling is showing cracks, especially in this era of rampant containerization and ephemeral pods where Docker, K8s and co. are the mostly preferred deployment method.

While tools like fpm definitely do help we are in a dire need of a more universal and modern deployment friendly format.

I am 50/50 on asdf on prod servers. I agree it hasn’t been seriously audited but then again relying on sh / bash for more than 50-100 lines of scripts is just asking for trouble anyway. So whatever tool you end up using is not much better than any sh wrappers (exceptions probably include Go- or Rust-written tools instead of shell scripts).

I can go back to dreaming about single self-contained binaries for Erlang releases a la Golang style. :icon_rolleyes:

I definitely agree. You should use releases to deploy your app, packaging the Erlang VM inside your release. That way you don’t install Erlang on your prod machine globally at all.


ASDF should be viewed as a development tool, not a service dependency IMO. Our approach is to have ASDF installed on development and build hosts and using that to build a deployable artifact (RPM, tar, container, etc) which includes the Erlang runtime. The artifact is then installed on the target host and configured appropriately based on the deployment environment.

Edit: Another advantage is that the deployable services are now language agnostic - a big plus if you work in a polyglot environment.