Ruby on Rails 구동을 위한 Nginx와 Unicorn 설정

Ruby on Rails (이하 ROR)에는 WEBrick이라는 웹서버가 기본으로 탑재된다.

하지만 이놈을 Production 환경에서 그대로 사용하는 경우는 거의 보지 못했다.

뭔가 이유가 있겠지만 자세히 찾아 보지는 않았다.

기존에 사용하던 Nginx에서 ROR을 구동시키기 위해 구글신의 도움을 받은 결과

Passenger와 Unicorn 두 놈이 후보에 올랐다.

(Nginx 자체 만으로는 정적인 웹페이지만을 제공하지 못한다. Application 구동을 위해서는 추가적인 프로그램이 필요하다.)

구글링을 해가며 두 가지를 모두 설치해본 결과, Unicorn을 선택하기로 결정했다.

이유는 단 하나. 기존에 깔려 있던 Nginx에서 Unicorn을 연동하는 게 더 쉬웠다는 것.

현재 ROR 만으로도 많은 삽질을 하고 있기 때문에 여기에 들이는 시간은 최소화하고 싶다.

자세한 건 나중에 비교해 보지 뭐 ㅋ

한 블로그 포스트를 보며 Unicorn 설정을 하니 5분만에 ROR Application이 구동이 된다.

아싸~ 하고 새로운 ROR App을 만들고 동일한 설정을 반복하니.. 안된다..

한 번에 쉽게 될 때 뭔가 불안했어…

로그랑 이것저것 뒤져 보니 Unicorn 설정 파일에 있던 아래의 코드가 문제였다.

listen "/tmp/.sock

같은 이름의 Unix domain socket을 두 ROR App이 사용하려고 하기 때문에 문제가 되었던 것이다.

인터넷에 있는 내용들은 주로 하나의 Application을 구동할 때의 얘기 뿐이고, 간혹 있는 여러 Application을 위한 내용이 나와 있는 블로그 포스트들은 아예 첨부터 다 다시 해야 될것만 같은 불안감이… 그래서 맨땅에 헤딩하는 심정으로 열심히 로그 봐가며 개고생한 결과 드디어 찾아 냈다..ㅠㅠ

편의상 두 개의 App 이름을 first, second라고 하겠다.

(내가 보고 따라했던 블로그 기준으로 설정이 되어 있다고 가정할 때)

Unicorn config file (unicorn.rb – first)

before

listen "/tmp/.sock", :backlog => 64

after

listen "/tmp/unicorn.first.sock", :backlog => 64

Unicorn config file (unicorn.rb – second)

BEFORE

listen "/tmp/.sock", :backlog => 64
listen 8080, :tcp_nopush => true

AFTER

listen "/tmp/unicorn.second.sock", :backlog => 64
listen 8090, :tcp_nopush => true

 Nginx config file (nginx.conf)

comment out

# upstream app_server {
# server unix:/tmp/.sock fail_timeout=0;
# }

Configuration for First App

upstream unicorn-first {
  server unix:/tmp/unicorn.first.sock;
}
server {
  listen 10000;
  server_name localhost;
  client_max_body_size 4G;
  keepalive_timeout 5;
  root /path/to/first/public;
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn-first;
  }
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /path/to/first/public;
  }
}

CONFIGURATION FOR second APP

upstream unicorn-second {
  server unix:/tmp/unicorn.second.sock;
}
server {
  listen 20000;
  server_name localhost;
  client_max_body_size 4G;
  keepalive_timeout 5;
  root /path/to/second/public;
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn-second;
  }
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /path/to/second/public;
  }
}

이제 http://localhost:10000에선 first app이, http://localhost:20000에선 second app이 구동되게 되었다.

Application이 추가되면, 위 설정을 참고해 Nginx 설정 파일에 upstream과 server를 각각 하나씩 추가해 주면 된다.

(Nginx의 upstream이란, HTTP Proxy를 위한 모듈이다.)

정리하자면, 핵심은 다음과 같다.

  • upstream 모듈의 이름이 겹치지 않아야 한다.
  • upstream이 사용하는 socket의 이름이 unicorn 설정 파일 내의 이름과 같아야 한다.
  • 추가된 server에서는 이 upstream을 Proxy로 사용하도록 설정한다.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s