mattbrictson / tomo

A friendly CLI for deploying Rails apps ✨

Home Page:https://tomo.mattbrictson.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to isolate env variables for multiple Rails app on same server?

BilalBudhani opened this issue · comments

I have started moving all my Rails apps (side projects) on a single server to simplify my setup. I used tomo to move Project 1 and everything went well, then, I started moving Project 2 and it started throwing errors in the rails db:migration task. That's when I noticed that Project 2 is picking up Project 1's DATABASE_URL. However, when I run tomo run env:show I see proper variables.

I read the documentation & it seems project's envrc is loaded directly inside bashrc which I believe is causing this issue.

is there a better way to isolate project environment variables?

Hi, this has come up before so I added it in the FAQ:

https://github.com/mattbrictson/tomo#can-i-deploy-multiple-apps-to-a-single-host

Basically I suggest creating a separate deploy user per app. Would that work for you?

Hi Matt,

Yes, I believe that would be one of isolating multiple projects. However, I think rbenv will install ruby for each user in this approach. We could explore installing rbenv on system level. Is it possible to install rbenv on system level (for all users)?

Another approach I believe would also work is if we use rbenv-vars which is designed to handle exactly this situation.

What do you think?

Yes, rbenv would need to be installed for each user, but I think that is OK. I think the user-isolation is desirable, both for security reasons (2 different apps can't see/modify each other's files) and to allow configurability (2 apps might use 2 different versions of ruby, rubygems, bundler, node, etc.). To install rbenv shared across multiple users you would need root access. One of my design decisions with tomo is that setup/deploy should not require root.

I have tried many approaches over the years for setting env vars, including rbenv-vars and gems like dotenv. I ultimately landed on using .bashrc because:

  1. It is understandable and explainable by anyone with passing familiarity with Linux and shells.
  2. It doesn't lock you into a language or a runtime. Vars set via the shell work the same way whether you are running ruby, node, or whatever.
  3. It works with systemd processes, so you don't have to set vars in one way for your deployment and then a different way for systemd.
  4. It gives you consistent behavior whether you are running a command via tomo or via a shell directly on the host.
  5. It gives you portability: if you want to move your app off of a tomo-deployed VPS and onto a service like Heroku, you don't have to change your app since all platforms have a way to inject environment variables.

I will also admit that I have never found the need to deploy more than 1 app to the same host, which is why this is not really baked into tomo.

Perhaps what could help is if tomo shows an error if it detects you have multiple apps sharing the same envrc?

Thank you for sharing your in-depth views on this subject. I think the points you made makes complete sense. Rather than isolating just the environment variables, it would be more secure to have a completely isolated & independent set up to avoid potential issues in the future.

+1 on throwing a warning when tomo detects multiple apps sharing the same envrc.

+1 on throwing a warning when tomo detects multiple apps sharing the same envrc.

Hi @BilalBudhani I'm curious what you think of this PR: #155 . Does that look like a good improvement?

@mattbrictson left my thoughts on the #155 PR.