Heroku에 배포시 Devise의 secret_key 에러

최근에 회사 채용을 준비하면서 오랜만에 Ruby on Rails로 프로젝트를 진행해야 되는 과제를 하나 받게 되었다. Heroku에 배포를 하는 것까지 과제였고 그 전에 Heroku를 사용해 본 적이 없긴 하였지만, 문서에 rails로 Heroku에 배포하는 법이 자세하게 잘 나와있어 별 걱정은 하지 않았다.

그. 러. 나.

Heroku에 push하는 명령어를 실행하니,

$ git push heroku master

Heroku의 Build log에 아래와 같은 에러 문구가 나타나면서 Build가 실패하였다.

프로젝트에서 유저와 관련된 기능을 쉽게 구현하기 위해 Devise라는 너무나도 유명한 gem을 쓰고 있었는데, 그 Devise의 secret_key가 설정되지 않았다는 에러였다.
그래서 그냥 Devise의 secret_key를 저렇게 설정하면 되는구나 싶어 config/initializers/devise.rb에서 해당하는 코드(devise.rb를 손 댄적이 없다면 9번째 줄)의 주석을 풀고 config.secret_key에 저 값을 넣어주었다. 물론 secret_key 가 Github에 유출이 되면 안되므로 .env에 따로 넣어두었다.

# config/initializers/devise.rb

# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|  
  # The secret key used by Devise. Devise uses this key to generate
  # random tokens. Changing this key will render invalid all existing
  # confirmation, reset password and unlock tokens in the database.
  # Devise will use the `secret_key_base` as its `secret_key`
  # by default. You can change it below and use your own secret key.
  config.secret_key = ENV['DEVISE_SECRET_KEY']

그리고 다시 push를 하였지만 아까와 똑같은 에러 문구가 나타나면서 Build가 실패하였다.
이번에는 log에 다른 secret_key 값이 나오길래 혹시나 싶어 다시 설정하여 push하였지만 결과는 역시 마찬가지였다. 이 때부터가 본격적인 삽질의 시작이었다.

한참을 삽질하다가, 왜 Heroku에서 Devise의 secret_key를 읽지 못하는 지 알게 되었다.
.env.gitignore에 추가되어 있기 때문에 push를 하더라도 Heroku에는 .env파일이 올라가지 않게 된다. 따라서 .env에 저장되있던 환경변수들을 읽지 못하게 되어 발생한 에러였다.
하지만 그렇다고 .env.gitignore에서 빼게 되면 중요한 정보들(유출되면 안되는 key, token, id, password 등)이 유출되게 되므로 그럴수도 없는 노릇이었다.

그 때 그 부분을 명쾌하게 해결해주는 Figaro라는 gem을 알게 되었다. Figaro는 rails 내의 환경변수들을 편리하게 관리해주는 gem이다. 그리고 Figaro의 문서를 보다가 아래와 같은 문구를 보게 되었다.

Figaro is written with deployment in mind. In fact, Heroku's use of ENV for application configuration was the original inspiration for Figaro.

Heroku가 Figaro의 영향을 받았다할 수 있을만큼, Heroku를 사용함에 있어서 뗄래야 뗄 수가 없는 gem이었다.

문서에서 시키는 대로 Gemfilegem "figaro"를 추가한 후,

$ bundle install
$ bundle exec figaro install

이렇게 실행하면 config/application.yml 파일이 자동으로 생성되고, 이 파일은 .gitignore 에도 자동으로 추가된다. 따라서 application.yml에 환경변수들을 선언해주더라도 Github에는 올라가지 않게 된다.

기존에 .env에 저장돼있던 변수들을 모두 config/application.yml로 옮겼다.(DBMS로 PostgreSQL을 사용하였다.)

# config/application.yml

POSTGRESQL_USERNAME: jupiny  
POSTGRESQL_PASSWORD: password

production:  
  DEVISE_SECRET_KEY: "..."

여기까지만 하면, 기존의 .env에 환경변수들을 저장했을 때와 별반 차이가 없다.
하지만 여기서 아래의 명령어를 실행하게 되면,

$ figaro heroku:set -e production

application.yml에 있던 환경변수들이 production 환경에도 사용할 수 있게 세팅된다.

정상적으로 push가 됐음을 확인한 후, 다시 Heroku 문서를 보며 다음 단계를 진행하면 된다.