Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Rails 앱을 프로덕션에 배포하기 위한 설정 가이드

첫 번째 프로덕션 앱을 출시할 준비가 되었고, 이제 외부 서비스와 연동할 차례입니다. 아직 모든 것을 연결해야 하는 상황이죠. 그렇다면 개발 머신을 복잡하게 만들지 않으면서 프로덕션에서 서비스를 설정하는 가장 좋은 방법은 무엇일까요?

환경(Environment) 설정하기

오늘날 프로덕션 앱을 설정하는 모범 사례는 환경 변수(ENV["REDIS_HOST"]처럼 생긴 것들)를 사용하는 것입니다.

그런데 왜 그럴까요?

  • 프로덕션 키를 실수로 커밋할 가능성이 줄어듭니다.

    주의하지 않으면 중요한 시크릿 키가 담긴 파일을 git push해버릴 수 있습니다. 이는 값비싼 실수로 이어질 수 있습니다.

  • 환경 변수는 원래 설정을 위해 존재합니다.

    환경 변수는 거의 모든 종류의 시스템에서 앱을 설정하는 데 사용되는 보편적인 방식입니다. Ruby를 포함한 많은 프로그램이 환경 변수로 설정을 관리하므로, 여러분의 앱에서도 활용하는 것이 자연스럽습니다.

  • 프로덕션에서 환경 변수를 설정하기가 쉽습니다.

    Heroku는 환경 변수를 손쉽게 설정할 수 있는 웹 UI와 CLI 도구를 제공합니다. 직접 서버를 구축하는 경우에도 Chef나 Docker 같은 서버 관리 도구가 환경 변수 설정을 간편하게 만들어 줍니다.

Rails 쪽에서는 어떻게 보일까?

환경 변수에 의존하는 앱은 다음과 같이 자기 자신을 설정할 수 있습니다:

config/my_service.yml
production:
  host: <%= ENV["MY_SERVICE_HOST"] %>
  port: <%= ENV["MY_SERVICE_PORT"] %>
config/initializers/my_service.rb
my_service_config = Rails.application.config_for(:my_service)
    
my_service = MyService.new(my_service_config["host"], my_service_config["port"])

이니셜라이저는 Rails 4.2의 config_for 메서드를 사용해 적절한 .yml 파일을 찾고 올바른 환경을 선택합니다.

그다음 config_formy_service.yml 내부의 ERB 코드를 실행하고, 환경에서 MY_SERVICE_HOSTMY_SERVICE_PORT 값을 가져옵니다. 이 값들은 MyService에 전달됩니다.

물론 이니셜라이저에서 ENV["MY_SERVICE_HOST"]를 직접 읽도록 할 수도 있습니다. 하지만 곧 설명할 이유 때문에 저는 .yml 파일에 값을 유지하는 것을 선호합니다.

개발 환경에서의 앱 설정

환경 변수는 프로덕션에서 훌륭하게 작동합니다. 그런데 프로덕션 설정을 마친 후, 개발 및 테스트 모드는 어떻게 처리해야 할까요?

여러 가지 선택지가 있지만, 저는 보통 Rails의 config/secrets.yml 컨벤션을 따릅니다. 즉, 프로덕션에서는 환경 변수를 사용하고, 개발과 테스트 환경에서는 시크릿이 아닌 값을 하드코딩하는 방식입니다.

개발 및 테스트 환경을 포함하면 config/my_service.yml은 다음과 같이 작성할 수 있습니다:

config/my_service.yml
production:
  host: <%= ENV["MY_SERVICE_HOST"] %>
  port: <%= ENV["MY_SERVICE_PORT"] %>
  
development:
  host: localhost
  port: 8081
  
test:
  host: localhost
  port: 8081

멋진 점은 이니셜라이저를 전혀 수정할 필요가 없다는 것입니다. 이 파일의 값들은 개발과 테스트 환경에서 사용되고, 프로덕션 환경은 환경 변수에서 값을 가져오게 됩니다.

그런데 왜 이 값들을 하드코딩하는 걸까요?

  • 설정 값을 확인하고 변경하기가 더 쉽습니다.

    새로운 기능을 실험하면서 설정을 자유롭게 조정할 수 있습니다. 이는 개발 단계에서는 바람직하지만, 프로덕션에서는 그렇지 않습니다.

  • 새로 합류한 개발자가 시작하기가 쉬워집니다.

    필요한 샘플 설정이 모두 git 저장소에 커밋되어 있다면, 새 개발자는 저장소를 클론하고 앱을 실행하기만 하면 됩니다. 앱이 동작하도록 정확한 값을 일일이 맞추느라 고생할 필요가 없습니다.

  • 환경 변수 충돌을 걱정할 필요가 없습니다.

    개발 머신에서는 하나의 프로덕션 서버에 배포하는 앱보다 훨씬 많은 앱을 다루게 됩니다. 모든 앱을 시스템 전역 환경 변수로 설정하면, 두 앱이 서로의 변수를 덮어쓰는 일이 발생하기 쉽습니다.

결론적으로, 프로덕션에서는 환경 변수를, 개발에서는 하드코딩된 .yml 설정을 사용해 보세요. 간단하고, 읽기 쉽고, Rails가 바로 이런 종류의 설정 파일을 기본적으로 지원합니다.

개발 환경을 위한 또 다른 방법

개발 모드에서 설정을 처리하는 또 다른 방법으로 dotenv가 있습니다. 꽤 흥미로워 보이지만, 아직 제 앱에서 직접 사용해 본 적은 없습니다.

dotenv를 사용하면 Rails 앱 루트 디렉터리에 .env라는 파일을 만들어 환경 변수를 넣을 수 있고, 앱이 해당 값들을 자동으로 불러옵니다. 이 방식의 장점은 개발 환경이 프로덕션 환경과 더 비슷하게 동작한다는 점입니다. 프로덕션에서만 발생하는 버그를 예방하는 좋은 방법이죠.

언젠가 시도해 볼 계획입니다. 하지만 지금까지는 .ymlconfig_for 조합보다 편리한 방법을 찾지 못했습니다.

대부분의 프로덕션 앱은 어떤 형태로든 설정이 필요합니다. 다음 앱을 배포할 때는 프로덕션에서 환경 변수로 채워지는 .yml 파일을 활용해 설정해 보세요. 여러분이 기대하는 유연성, 단순함, 안정성을 모두 얻을 수 있을 것입니다.

프로덕션 앱을 설정하는 나만의 방법이 있으신가요? 댓글로 알려주세요. 여러분의 경험을 듣고 싶습니다!