“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey (contact@robl.me)
Senior Software Engineer, Brighton, UK

Internal Server Error on new Rails 4 deploy

First deploy of a new app shows an Apache Internal Server Error and the following errors appear in the VirtualHost’s log. Not particularly helpful.

/var/log/apache/app-error.log

[Wed Oct 29 07:02:17 2014] [error] [client 81.111.42.20] Premature end of script headers: 
[Wed Oct 29 07:36:06 2014] [error] [client 81.111.42.20] Premature end of script headers: 
[Wed Oct 29 07:37:56 2014] [error] [client 81.111.42.20] Premature end of script headers:

The default Apache error log shows more information. Seems I haven’t set up the Production secret key.

/var/log/apache/error.log

App 12630 stdout: 
App 12424 stderr: [ 2014-10-29 07:37:56.3925 12630/0x0000000157c988(Worker 1) utils.rb:68 ]: *** Exception RuntimeError in Rack application object (Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`) (process 12630, thread 0x0000000157c988(Worker 1)):
App 12424 stderr: 	from /var/www/app/shared/bundle/ruby/2.1.0/gems/railties-4.2.0.beta1/lib/rails/application.rb:510:in `validate_secret_key_config!'
App 12424 stderr: 	from /var/www/app/shared/bundle/ruby/2.1.0/gems/railties-4.2.0.beta1/lib/rails/application.rb:243:in `env_config'
App 12424 stderr: 	from /var/www/app/shared/bundle/ruby/2.1.0/gems/railties-4.2.0.beta1/lib/rails/engine.rb:510:in `call'
App 12424 stderr: 	from /var/www/app/shared/bundle/ruby/2.1.0/gems/railties-4.2.0.beta1/lib/rails/application.rb:161:in `call'
App 12424 stderr: 	from /home/deployer/.rvm/gems/ruby-1.9.3-p448/gems/passenger-4.0.41/lib/phusion_passenger/rack/thread_handler_extension.rb:74:in `process_request'
App 12424 stderr: 	from /home/deployer/.rvm/gems/ruby-1.9.3-p448/gems/passenger-4.0.41/lib/phusion_passenger/request_handler/thread_handler.rb:141:in `accept_and_process_next_request'
App 12424 stderr: 	from /home/deployer/.rvm/gems/ruby-1.9.3-p448/gems/passenger-4.0.41/lib/phusion_passenger/request_handler/thread_handler.rb:109:in `main_loop'
App 12424 stderr: 	from /home/deployer/.rvm/gems/ruby-1.9.3-p448/gems/passenger-4.0.41/lib/phusion_passenger/request_handler.rb:448:in `block (3 levels) in start_threads'

Which is true.

Robs-iMac:matotu rl$ cat config/secrets.yml 
# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.

# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.

development:
  secret_key_base: somekey
test:
  secret_key_base: somekey

# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

I need to generate a new key, not the one I just posted though because that would be silly. I could place this in the repo replacing the ERB segment above but that’s not very secure.

Robs-iMac:app rl$ bundle exec rake secret
daf28cd197710437091a7bb8fef64b8fe0ccafc164f1c1a74f7b237e6a4b35cb9f6929259b41527035100c7a7a020b7bb1c2d6f6e4ce07df8a14a176ef50e40b
</pre></code>

Instead I shall place it in */etc/apache/envvars*

<pre><code>
bash-4.3# cat /etc/apache2/envvars 
# envvars - default environment variables for apache2ctl

# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
export APACHE_PID_FILE=/var/run/apache2.pid

## The locale used by some modules like mod_dav
export LANG=C
## Uncomment the following line to use the system default locale instead:
#. /etc/default/locale

export LANG

## The command to get the status for 'apache2ctl status'.
## Some packages providing 'www-browser' need '--dump' instead of '-dump'.
#export APACHE_LYNX='www-browser -dump'
export SECRET_KEY_BASE=somesecretkey

You’ll need to restart Apache, rather than just reload to get this to work. Obviously this is a environment variable for the entire Apache process, so if you wanted to host multiple applications on one server you could have to make the names of each secret unique.

And working…