This log covers Ruby environment (runtime environment and environment variables). Heroku introduced developers to The 12-factor App Approach. It lay out the best practices for creating apps that are easy to deploy (environment variables is the section most influential).

Shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script.1 Under Unix-like operating systems, when a script with a shebang is run as a program, the program loader parses the rest of the script’s initial line as an interpreter directive;

Environment

Runtime Environment

RUBY_PLATFORM contains the name of the current environment (operating system).

Environment Variables

Environment variables are a set of dynamic named values that can affect the way running processes will behave on a computer.2

Environment variables are passed “by value” not “by reference”.

The operating system sets special variables called environment variables. In all Unix and Unix-list systems, each process has its set of environment variables at the moment you launch it. When a process is created, it inherits a duplicate environment of its parent process.

Environment variables die with their process, which means you lose environment variables when the server reboots or exit your shell. To make environment variables persist across sessions, it has to be stored inside a config file like .bashrc (insecure approach)3

Example of UNIX environment variables includes,

  • PATH, a list of directory path
  • HOME, indicates user’s home directory
  • TEMP, location where processes can store temporary files

Inspect the environment variables on the machine using Ruby4,

puts ENV['variable_name']

ENV.each { |e| puts e.join(': ') }

To set environment variable,

ENV['variable_name'] = value

Environment variables are easy to change between deploys without changing any code.

Setting environment variables from within a program only apply to the local process and any child processes. However, children cannot set their parents’ environment variables.

Environment Variables in Practice

The different running app needs different environment variables possibly with the same name since environment variables are per-process which makes it possible to achieve the goal. Two Ruby gems are helpful to manage the environment variables for you.

Figaro

Any values that you enter into config/application.yml will be loaded into Ruby ENV hash on startup. It is very important to add this file to .gitignore.

Dotenv

Dotenv similar to Figaro, except it loads environment variable from .env at project root. Add .env file to .gitignore.

Securing Environment Variables

Environment variables will be compromised when a hacker has gained access to the server as root.

  1. Always add sensitive files to .gitignore
  2. Avoid using .bashrc/.bash-profile for secrets (environment variables in these files are sent to every program)
  3. Only reveal secrets to processes that need them
  1. https://en.wikipedia.org/wiki/Shebang_(Unix)

  2. https://en.wikipedia.org/wiki/Environment_variable

  3. http://blog.honeybadger.io/ruby-guide-environment-variables/

  4. https://ruby-doc.org/core-2.1.4/ENV.html