Hi!
I would love to learn more about Elixir by moving over my website backend from Node.js, however, there is one obstacle that is providing some friction.
I’ve heard that Elixir is not great for raw computation (neither is JavaScript, to be fair), and doesn’t seem to have any solid image manipulation libraries/wrappers such as sharp. I made my own little library for Node.js called IPP that provides wrappers around pre-compiled binaries (Go) that are distributed via npm. It works for 99% of cases. The advantage is that you don’t need a Go toolchain, just pull in the package and run!
This is something I would really miss when moving to Elixir, an easy way to run something like Primitive. Ports seem like a good way to spawn a foreign process, but they expect the executable to be available/pre-installed. IPP tries to make this as easy as just installing a package, as the pre-compiled assets are stored in node_modules
in the respective @ipp/...
package.
Is there an elegant solution for this in Elixir with Mix? I’m very new to Elixir/Erlang concepts. Phoenix can deploy static assets (HTML, CSS, …), is there any parallel with other foreign code? The ideal solution would be to have a small Go module in the Phoenix project that can be compiled as a wrapper around the library I want to use, which I could deploy along with the built Elixir application and run on the server.
I was thinking about using Docker, it would allow for bundled dependencies (executables), without requiring the server to already have the library installed globally, such as with Mogrify. Although from my understanding, Elixir/Erlang wasn’t meant for Docker, and runs well on a VM on the host machine (for hot code swapping, for example). Are there any other downsides?
Or perhaps a several-step deployment process, where the executable is compiled to /usr/bin
and then Elixir is deployed? I am kind of opposed to the idea of polluting the host system path with application-specific executables. WebAssembly looks promising, but the actual interface (transfer of settings and binary data) would be complex (and it would be easier from Rust than from Go, I’ve actually been considering re-writing IPP in Rust so it can be potentially used from any language ecosystem, as it has fantastic WebAssembly support, but that needs time!).
The intended purpose is to process uploaded thumbnails, another solution I had in mind is to have a small Node.js serverless function in the cloud that handles image processing that Elixir could call over the network, but it of course has a dependence on the cloud (and increased cost).
Thanks for your help!