I did a multistage Docker image today in which you compile a release first, and then copy the binaries into the final image. In development, this application only needs build-essential, ssh, and git, there are no other system dependencies, and production does not need any as far as the application is concerned.
The final image is based on the same official Ubuntu image as the one used in the build Hex image for Elixir.
I believed releases were self-contained, but looks like it is missing something:
/app/erts-10.7.2/bin/beam.smp: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
I could try to install a package and repeat until the application starts, but would like to know what I am doing and looks to me like an ERTS system dependency is missing (perhaps for the console?).
Are those runtime dependencies documented somewhere?
You need to look at your erlang used to compile the release and make sure that its runtime dependencies are available on the target container.
And releases are not self contained, they just contain the runtime, though not the libraries used by the runtime, those still need to be provided by the host system.
This is why we always say, CPU and OS have to match between host and build system.
Then, you copy the release files into an image based on
ubuntu:focal-20200703
However, ERTS seems to have runtime dependencies?
This page documents what’s needed to build Erlang, I am looking for a page that says: “In order to run a release, you need ncurses installed, as well as A, B, and C”.
Again, the runtime dependencies depend on the erlang you used to compile.
Sure, but where do I find them documented?
If you used a package from your systems pacakge manager, you need to install its dependencies manually, but can drop the actual package.
Disagree here, Erlang should document its runtime dependencies for releases, the same way it documents its build dependencies.
Again, the point of a release is to not have Erlang installed. Users should not be inspecting package dependencies or peeking at binaries to guess (not know) what is dynamically linked or needed to start a release. You need documentation that says: you need ncurses unless you compiled Erlang with such flag. Something like that.
Feature X requires libraries and headers available for the build, you require the same libraries (though usually not the headers) available at runtime. There is your list.
The current crypto implementation uses nifs to interface OpenSSLs crypto library and may work with limited functionality with as old versions as OpenSSL 0.9.8c. FIPS mode support requires at least version 1.0.1 and a FIPS capable OpenSSL installation. We recommend using a version that is officially supported by the OpenSSL project. API compatible backends like LibreSSL should also work.
I’m not sure exactly by what libtinfo is used. Sometimes I have the feeling docker images in a quest to reduce image size tend to remove more and more stuff, which previously where just baseline.
I’m not sure exactly by what libtinfo is used. Sometimes I have the feeling docker images in a quest to reduce image size tend to remove more and more stuff, which previously where just baseline.
I believe it is related to the console, but I had to figure out with a release that did not start. I could install and try until it boots, but that is not a robust procedure.
By now, to play safe I am using the same image I am using to assemble the build, which kind of misses the point.
The runtime dependencies are unclear. By unclear I mean not clearly documented. Anyone can try to find their way around and figure out what is needed in practice, but I do not like that approach.
only as a new image with the release copied, the natural option is to opt-out from including ERTS. You have full consistency guaranteed using Docker images, so this approach should work just fine.
As you want to know the runtime dependencies of your Ubuntus erlang, you will need to look at the dependencies of your Ubuntus erlang DEB.
Even if the erlang team would have documented the runtime dependencies of their build properly, that would not hold for a Ubuntu build, as that is customized compared to the canonical build.
Also, in theory, by hitting the right knobs and buttons, you could compile erlang statically linked, basically reducing its actual runtime dependencies to zero…
Erlang has to document what it needs to be built, and what it needs to run. The latter may have conditionals, but it has to be there.
Then, you may need to check the conditionals with your package, but the basic information has to be in Erlang docs (like build dependencies are in the Erlang docs, and they have also conditionals).
You could also take a look at the Dockerfiles of hex. They already separate building of erlang from the runtime image. So you could use an image, which installs exactly the same as in those highlighted lines, skipping the copy from build.
As you can see there are some dependencies to be installed at runtime as well on top of the base image.
Oh sure, but that is the kind of guess work I do not like my production setups to be based on. By using the same base image and not including ERTS I treat this as a black box, whatever runtime dependencies are needed, they figured it out, and when I upgrade, it’s all consistent again even if they changed.