Kategorien
Ruby on Rails

Rails-Anwendung auf https umleiten

Immer wie­der ste­he ich vor dem glei­chen Pro­blem, der Blog­bei­trag soll also auch gleich­zei­tig als Gedächt­nis­stüt­ze für mich die­nen. Für mein Stan­dard­set­up ver­wen­de ich als Web­ser­ver nginx (Anzahl Worker = Anzahl Cores), als Rails-App­li­ca­ti­on­ser­ver …

Immer wie­der ste­he ich vor dem glei­chen Pro­blem, der Blog­bei­trag soll also auch gleich­zei­tig als Gedächt­nis­stüt­ze für mich die­nen.
Für mein Stan­dard­set­up ver­wen­de ich als Web­ser­ver nginx (Anzahl Worker = Anzahl Cores), als Rails-App­li­ca­ti­on­ser­ver kommt thin mit zwei Workern zum Ein­satz. Eine Stan­dard­kon­fi­gu­ra­ti­on könn­te nun bei­spiels­wei­se so aus­se­hen:

# /etc/nginx/sites-available/my-site.deupstream my-site {  server   unix:/tmp/thin.my-site.0.sock;  server   unix:/tmp/thin.my-site.1.sock;}server {  listen   80;  server_name my-site.de www.my-site.de;  access_log /var/www/my-site.de/www/logs/access.log;  error_log /var/www/my-site.de/www/logs/error.log;  root   /var/www/my-site.de/www/htdocs/public/;  index  index.html;  location / {    proxy_set_header  X-Real-IP  $remote_addr;    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header  Host $http_host;    proxy_redirect    off;    if (-f $request_filename/index.html) {      rewrite (.*) $1/index.html break;    }    if (-f $request_filename.html) {      rewrite (.*) $1.html break;    }    if (!-f $request_filename) {      proxy_pass http://my-site;      break;    }  }}

In Ver­bin­dung mit die­ser /etc/thin/my-site.yml funk­tio­niert eine Rails-Anwen­dung auch ein­wand­frei:

---pid: tmp/pids/thin.pidwait: 30timeout: 30log: log/thin.logmax_conns: 1024require: []environment: productionmax_persistent_conns: 512servers: 2daemonize: truechdir: /var/www/my-site.de/www/htdocssocket: /tmp/thin.sock

Sämt­li­cher Traf­fic läuft bei die­sem Set­up unver­schlüs­selt über Port 80, also Stan­dard-http. Wenn man nun aber ein Log­in, bspw. für ein CMS wie Radi­ant, rea­li­sie­ren möch­te, wäre es natür­lich wün­schens­wert, den Traf­fic ver­schlüs­selt über Port 443, also https, lau­fen zu las­sen. Not­wen­dig ist das aber aus mei­ner Sicht nur bei Zugrif­fen auf das Admin-Backend. Im nach­fol­gen­den Set­up wer­den sämt­li­che Anfra­gen auf http://www.my-site.de/admin/{IRGENDWAS} auf https://www.my-site.de/admin/{IRGENDWAS} umge­lei­tet. Requests auf die Web­site selbst blei­ben von der Umlei­tung also unbe­rührt.

# /etc/nginx/sites-available/my-site.deupstream my-site {  server   unix:/tmp/thin.my-site.0.sock;  server   unix:/tmp/thin.my-site.1.sock;}server {  listen   80;  server_name my-site.de www.my-site.de;  access_log /var/www/my-site.de/www/logs/access.log;  error_log /var/www/my-site.de/www/logs/error.log;  root   /var/www/my-site.de/www/htdocs/public/;  index  index.html;  rewrite ^/admin/(.*) https://www.my-site.de/admin/$1 permanent; # Rewrite-Regel für die Umleitung aller Anfragen auf /admin  location / {    proxy_set_header  X-Real-IP  $remote_addr;    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header  Host $http_host;    proxy_redirect    off;    if (-f $request_filename/index.html) {      rewrite (.*) $1/index.html break;    }    if (-f $request_filename.html) {      rewrite (.*) $1.html break;    }    if (!-f $request_filename) {      proxy_pass http://my-site;      break;    }  }}server {  listen 443;  server_name my-site.de www.my-site.de;  ssl                 on;  ssl_certificate     /etc/ssl/certs/startssl.crt;  ssl_certificate_key /etc/ssl/private/startssl.key;  ssl_ciphers         ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM;  ssl_protocols       SSLv3 TLSv1;  access_log /var/www/my-site.de/www/logs/access.log;  error_log /var/www/my-site.de/www/logs/error.log;  root   /var/www/my-site.de/www/htdocs/public/;  index  index.html;  location / {    proxy_set_header  X-FORWARDED_PROTO https;    proxy_set_header  X-Real-IP  $remote_addr;    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header  Host $http_host;    proxy_redirect    off;    if (-f $request_filename/index.html) {      rewrite (.*) $1/index.html break;    }    if (-f $request_filename.html) {      rewrite (.*) $1.html break;    }    if (!-f $request_filename) {      proxy_pass http://my-site;      break;    }  }}

Mei­ne Zer­ti­fi­ka­te bezie­he ich übri­gens zumeist von StartS­SL. Die Zer­ti­fi­ka­te kos­ten nichts und wer­den trotz­dem von allen aktu­el­len Brow­sern akzep­tiert. Nur den grü­nen Hin­ter­grund bekommt man mit die­sem Zer­ti­fi­kat nicht, was ich per­sön­lich aber als unkri­tisch ein­stu­fe. Goo­g­les Chro­me wird der­zeit aber lei­der nicht für die Erstel­lung der Zer­ti­fi­ka­te unter­stützt, mit der aktu­el­len Ver­si­on von App­les Safa­ri geht’s aber ein­wand­frei.
Kurz noch zur Erklä­rung, wie­so nginx und thin:

  • nginx zie­he ich Apa­che vor, weil er deut­lich schlan­ker und per­for­man­ter ist. Für PHP-Set­ups ver­wen­de ich zumeist wei­ter­hin den Apa­che, weil die­ser sich deut­lich ein­fa­cher mit PHP auf­set­zen lässt, als dies mit nginx der Fall ist.
  • thin ist extrem ein­fach auf­zu­set­zen, ein­fa­cher als Uni­corn oder mongrel_cluster, die im End­ef­fekt genau das Glei­che tun. Und dank der Fähig­keit von thin, auch als UNIX-Socket zu lau­fen, ist er auch extrem schnell.

Von Fall zu Fall mag die Eig­nung der Alter­na­ti­ven eher gege­ben sein, ich habe aber ziem­lich gute Erfah­run­gen mit die­sem Set­up gemacht. Es ist ein­fach zu admi­nis­trie­ren und äußerst per­for­mant.
Ein klei­ner Tipp noch zum Schluss. Um sowohl thin als auch nginx in den aktu­el­len Ver­sio­nen zu fah­ren, benut­ze ich fol­gen­de Wege der Instal­la­ti­on:
nginx instal­lie­re ich über das eigens dafür bereit­ge­stell­te PPA, wel­ches wie folgt in Ubun­tu 10.04 LTS oder neu­er ein­ge­bun­den wer­den kann:

nginx=stable # use nginx=development for latest development versionsudo su -add-apt-repository ppa:nginx/$nginxapt-get update apt-get install nginx

thin instal­lie­re ich aus den Ruby-Gems her­aus und nut­ze dann den kom­for­ta­blen Instal­ler, den die Jungs mit­lie­fern:

sudo gem install thinsudo thin installsudo /usr/sbin/update-rc.d -f thin defaults

Um die Anwen­dungs­um­ge­bun­gen nicht hän­disch erstel­len zu müs­sen, kann man das thin-Kom­man­do benut­zen:

sudo thin config -C /etc/thin/my-site.yml -c /var/www/my-site.de/www/htdocs --servers 2 -socket /tmp/thin.my-site.sock -e production

Die­ser Befehl erstellt eine Kon­fi­gu­ra­ti­ons­da­tei für thin, wie sie wei­ter oben zu sehen ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.