Best practice for running your Elixir App where root permissions are needed

I’m trying to figure out what the best practice is for running my elixir / phoenix app where my app needs access to lets encrypt certs that are apart of the root group.

Currently I’ve just been starting my app via sudo which has been working ('though not ideal"). I’m trying to debug a different issue where I believe I’m running to a path issue in something else not directly related to this question.

Sidenote: I’m use to using nginx for my https but I wanted to try http2 and found that I could not upstream my requests to cowboy so I had to switch to using cowboy as my primary http server. Typically nginx is ran via sudo so thus it has the right permissions, it just feels odd running my elixir app via sudo and also makes it a little more complicated when deploying via edeliver.

I wanted to rule out that running my app via sudo is not corrupting / losing my env paths as I know it can do that.

So that leads me to my actual question:

  • What group do you have your user in that starts your elixir app?
  • Do you start your elixir app via sudo.
  • What do you do for granting your app permissions to read secure files?

So I’ve tried to set my app, certs and user all to being in the same www-data group and yet I still get a permission error when trying to start cowboy related to loading the certs :frowning:

I know this is not a elixir specific question so sorry for that.

  • Josh

At first blush, what I would probably do is create a setuid application that does little more than retrieve the data I’m interested in. I would be inclined to call out to that application from the Erlang VM using a Port. The application could be small, focused, and expose just the functionality I need to access the data I want to make available to Elixir.

I’m sorry I’m having a real hard time understanding your concept. Could you re explain that to a non dev ops person?

Create a small application, probably in another programming language, whose job is to get at the data you want to access. (in your example the certs).

In UNIX you can set up an application like that so that it runs as a “setuid” application. In short, whenever you run that application, it runs with root privileges (regardless of who starts it). That way it has access to information that’s only available to root, but it also only does one thing.

Then you can call that application from your Elixir application to get the data you want. That little application will run (as root) retrieve the data, and pass it back to Elixir. Your use of root privileges is scoped to a small set of functionality, for a short time, rather than having to run the entire Erlang VM as root just to access a tiny bit of functionality.


Ok that makes sense. Though it also sounds complex to set up for a noob like my self.

Do you have any good links that support how to learn this idea?

I’m afraid I do not. :frowning:

Hey no worries, thanks for the good idea its still better than what I’ve managed to look up for myself.

We as a community really should do more to talk about dev ops as its really an important yet often over looked aspect to development.

You shouldn’t load as root just to get port access <2000, instead you should set your network mappings to map the right port to something your program uses.

I’ve tried to do that on a hobby project recently and it’s certainly easier said than done. Had to fight quite a bit with ufw and iptables and I’m still not sure it’s setup in a way it’s supposed to be done.

Well for anything ‘nowdays’ I’d probably just recommend docker. ^.^

Generally speaking, you should not run as root. You should make the files you want to be readable have group read permissions, then add the user account that the Elixir app runs under to that group. For example, make a “certs” group. The root user will still be able to read them, as it can read anything.

As for adding special permissions to your app, you can add capabilities to the systemd unit which runs your app.

This blog post has information on setting things up:


Just a warning for devs using Macs, setuid will be ignored on text scripts–it’s a security feature and I know of no way around it. So that makes it hard to test this kind of thing without running it in a VM or container.