Correctly setting environment variables for Rails

Cover

What are environment variables?

Intuitively, environment variables are made up of name/value pairs. They can be set inside your operation system but outside your rails applications. One of them you probably have seen around is PATH variable which defines a set of paths that your terminal looks at for executables in your operating system. If you echo it out in your terminal like the following:

~ echo $PATH
# /Users/martin/.rvm/rubies/ruby-2.6.3/bin:/Users/martin/.rvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

You can see the value that’s saved in there and the first one is my user account .rvm folder and then user bin and so on. Each of these folders is separated by a colon. When you type a command like ruby into your terminal, it will go through the first folder and check to see if there's a ruby command available in there and then if there's not it'll go to the next one and look to see if there's ruby in there and the next one and so on. If it gets through all of them and it doesn't find any ruby command and it'll just give you an error and say command not found: ruby

Image

If you want to see what’s going on, you can list out the first folder and you’ll see that there’s a whole bunch of executables and one of those is ruby


Why

Normally, in your rails application, you have a database password which you don’t necessarily want to store in your code or git repository and you definitely don’t want to do that if your rails application is public. So here is the problem: Where should you store the database password for your rails application? The answer is to set it into environment variables.

In most cases the password is set like this:

password: ENV['DATABASE_PASSWORD']

How

So how do you go about setting the variable that you sort of want to have just on your computer but not inside your application or your code? There’re a coupe of ways you can do, but for different situation.

1) setting it before irb

~ DATABASE_PASSWORD=[email protected] irb

then you can here if you type ENV["DATABASE_PASSWORD"] and you'll get [email protected]

irb(main):001:0> ENV["DATABASE_PASSWORD"]
=> "[email protected]"

And you can take a look at all of ENV, just type ENV in irb.

But what if you set DATABASE_PASSWORD before irb with separate lines like this:

~ DATABASE_PASSWORD=[email protected]
~ irb

again you type ENV["DATABASE_PASSWORD"], you will get nil.

irb(main):001:0> ENV["DATABASE_PASSWORD"]
=> nil

Because it set the variable once for the line, but then it’s cleared out. So it’s only a temporary assignment.

2) use export

If you want it to be permanent for this session so that you can see at every single time you’ve run it. You can use export in order to make it permanent. The export command is going to basically put the password into the environment permanently at least for this session, so you can do it like this:

~ export DATABASE_PASSWORD=[email protected]
~ irb

then you can in here if you type ENV["DATABASE_PASSWORD"] and you'll get [email protected] again.

3) Store it in terminal’s config file

If you want it to be permanent between sessions like you open a new window or tab in terminal. You can put export command inside of your terminal’s config file, by default you’re probably using bash, if you’re on Linux you can edit .bashrc file, if you're on a Mac you can edit .bash_profile and if you're using zsh, you want to do your .zshrc file.

For me, I’m using zsh, so I edit .zshrc file like this:

# .zshrc
...
export DATABASE_PASSWORD=[email protected]

Put export [email protected] at the end of the file.

After that, when you check ENV["DATABASE_PASSWORD"] in irb, you'll permanently get the value. So this is how we can configure our operating system to load that variable every time that we start a terminal session and then we can access that every single time with no problems.