preloader
軟體工程

Problems of deploying rails 5.2.0 to production

When I deploying a new rails 5.2.0 app to production machine, which has been the other rails 5.2.0 app there, I encounter a serious problem:

ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage

ArgumentError: invalid base64

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/core_ext/module/delegation.rb:271:in `method_missing'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:433:in `secret_key_base'

 

Below are a part of debug info when I use capistrano to deploying a rails 5.2.0 app:


DEBUG [b79779f0] Command: cd /var/www/blogApp/releases/20180802145508 && ( export RAILS_ENV="production" RAILS_GROUPS="" ; /usr/local/rvm/bin/rvm [email protected] do bundle exec rake assets:precompile )

DEBUG [b79779f0]   rake aborted!

DEBUG [b79779f0]   ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage

DEBUG [b79779f0]   /var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:206:in `rescue in _decrypt'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:184:in `_decrypt'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:157:in `decrypt_and_verify'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/messages/rotator.rb:21:in `decrypt_and_verify'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:79:in `decrypt'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:42:in `read'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:21:in `read'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:33:in `config'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:38:in `options'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/core_ext/module/delegation.rb:271:in `method_missing'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:433:in `secret_key_base'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:176:in `key_generator'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/globalid-0.4.1/lib/global_id/railtie.rb:26:in `block (2 levels) in <class:Railtie>'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:69:in `block in execute_hook'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:51:in `each'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application/finisher.rb:75:in `block in <module:Finisher>'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:32:in `instance_exec'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:32:in `run'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:61:in `block in run_initializers'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:60:in `run_initializers'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:361:in `initialize!'

/var/www/blogApp/releases/20180802145508/config/environment.rb:5:in `<main>'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `block in require_with_bootsnap_lfi'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:65:in `register'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:20:in `require_with_bootsnap_lfi'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:29:in `require'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `block in require'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `require'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:337:in `require_environment!'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:520:in `block in run_tasks_blocks'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb:62:in `block (2 levels) in define'

/var/www/blogApp/shared/bundle/ruby/2.4.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli/exec.rb:74:in `load'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli/exec.rb:74:in `kernel_load'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli/exec.rb:28:in `run'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli.rb:424:in `exec'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli.rb:27:in `dispatch'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/cli.rb:18:in `start'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/exe/bundle:30:in `block in <top (required)>'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/gems/bundler-1.16.3/exe/bundle:22:in `<top (required)>'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/bin/bundle:23:in `load'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/bin/bundle:23:in `<main>'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/bin/ruby_executable_hooks:24:in `eval'

/home/xxxxuser/.rvm/gems/ruby-2.4.2@global/bin/ruby_executable_hooks:24:in `<main>'

DEBUG [b79779f0] &nbsp;&nbsp;

Caused by:

DEBUG [b79779f0] ArgumentError: invalid base64

DEBUG [b79779f0] 

 

Let me clarify deploy and run a rails app:

The deploy term is that using capistrano to push your rails app from local and development environment machine to remote and production machine.

The run term is that perform an app at production machine.

 

How do I fix deploy problem?

Before doing solution steps, make sure you have done following:

  1. Add somethings to Capfile
require 'capistrano/rails'
require 'capistrano/passenger'
require "capistrano/scm/git"
require "capistrano/rvm"
require "capistrano/bundler"
require "capistrano/rails/assets"

 

  1. Add somethings to Gemfile and then execute command:
bundle install
group :development do
  gem 'capistrano'
  gem 'capistrano-passenger'
  gem 'capistrano-rails'
  gem 'capistrano-bundler'
  gem 'capistrano-rvm'
  gem 'highline'
end

gem 'dotenv-rails'

  3. Add somethings to .gitignore

/config/master.key
/config/credentials.yml.enc
/.env
/.DS_store
/config/database.yml

 

  1. Make sure deploy account has permission to create directories at /var/www/ directory,which is usually to be create ones for rails apps, of rails remote production machine.

  2. Ensure have installed yarn software, which will be used to precomile assets for rails 5.2.0, at remote production machine and can be used by deploy account.

 

Solution steps:
  1. Add dotenv gem to Gemfile and bundle install at local machine

  2. Create a file named: .env at home directory of the rails app. Ensure

SECRET_KEY_BASE = 'YOU_SECRET_KEY_BASE'

is in the file and replace YOU_SECRET_KEY_BASE value to content when you type command: EDITOR=vim rails credentials:edit on terminal screen hint in local machine.

  1. Add this line: /.env to file: .gitigore inside the rails app

  2. Add this line:

config.require_master_key = true

to scope of Rails.application.configure do-block in config/environments/production.rb;

  1. Add this line:
append :linked_files, "config/database.yml", "config/credentials.yml.enc", "config/master.key", ".env"

to config/deploy.rb. Also put files: master.key and credentials.yml.enc to shared/config directory of the rails app remote production. Besides, put the file: .env to shared directory of the rails app remote production.

  1. Add following lines:
set :rvm_custom_path, '/usr/local/rvm'
set :rvm_ruby_version, '[email protected]'
set :default_env, { path: "/usr/share/rvm/rubies/ruby-2.4.2/bin/ruby:$PATH" }

to config/deploy.rb. You can change numbers of versions according to you own production machine.

  1. Execute this deploy command: bundle exec cap production deploy --trace at local machine

 

1. https://www.engineyard.com/blog/rails-encrypted-credentials-on-rails-5.2