Ruby on Rails 4.2 with Docker & Devise: Case of the Disappearing Environment Variables

This is probably an extreme edge case that not many people run into. I run my Rails app in a Docker container, and inside the container, it runs with the privileges of a user account, instead of root. As such, in my entrypoint.sh script, I run a rake task via su — user_account rake...

That was working fine, until one day it wasn’t. Perhaps this change to Devise is what exposed the problem. The enivronment variables that I use in config/secrets.yml and config/initializers/devise.rb files just seemed to stop being recognized.

config/secrets.yml:
production
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
secret_token: <%= ENV["SECRET_TOKEN"] %>
config/initializers/devise.rb:
config.secret_key = ENV['DEVISE_SECRET_KEY']

After upgrading Devise, the error occurred when my app was starting up, when it got to this rake command in my entrypoint script:

su - app -c "cd /home/app/myapp; RAILS_ENV=production bundle exec rake assets:precompile --trace"

… it would crash with this message:

** Execute environment
myapp | rake aborted!
myapp | Devise.secret_key was not set. Please add the following to your Devise initializer:
myapp |
myapp |   config.secret_key = '95427860950704c84161efa35867cb00f5a113d30f44926db12b514ffb53fa19947f62893f72326336864bb12539728304bb0a0f716c2a4a9c6896cd9f45a389'
myapp |
myapp | Please ensure you restarted your application after installing Devise or setting the key.

As shown above, the Devise.secret_key was set, to ENV['DEVISE_SECRET_KEY'] , which previously worked fine and now suddenly it doesn’t exist.

The problem is that by using su, I’m effectively opening a new shell, with a new environment, that doesn’t include the environment variables available to the root user inside the Docker container. Running rake initializes the config/initializers scripts, including the one for Devise. The new version of Devise checks for the existence of the Devise.secret_key , and failing to find it, throws an error. An easy solution is to insert a SECRET_KEY_BASE token into the shell environment in which rake runs. It doesn’t need to be the real devise secret key, since the rake task (compiling assets) doesn’t need to decrypt passwords.

su - app -c "cd /home/app/workshops; RAILS_ENV=production SECRET_KEY_BASE=token bundle exec rake assets:precompile --trace"

Hopefully this post helps someone else who has become lost in the Rails/Docker weeds. 🤔

Show your support

Clapping shows how much you appreciated Brent Kearney’s story.