fba4c8795c
Signed-off-by: Nico Schottelius <nico@bento.schottelius.org>
119 lines
3.9 KiB
Markdown
119 lines
3.9 KiB
Markdown
[[!meta title="Great Rails Hosting: A symlink for an app"]]
|
|
|
|
## Introduction
|
|
|
|
As [[!ungleich]] focusses on educated customers,
|
|
we meet pretty cool infrastructures from time to time.
|
|
In some sense I count [[!localch]]
|
|
as a customer: they supported me with one day off
|
|
per week so I was able to found [[!ungleich]]
|
|
and acquire first customers.
|
|
This article is dedicated to [[!localch]] and describes
|
|
a very elegant solution for Ruby on Rails hosting.
|
|
|
|
## Overview
|
|
|
|
The setup consists of the following services, glued
|
|
together in an elegant way:
|
|
|
|
* [[!nginx]]
|
|
* [[!unicorn]]
|
|
* [[!bind]]
|
|
* [[!capistrano]]
|
|
* Symlinks
|
|
|
|
## Nginx
|
|
|
|
The great trick of the setup is that nginx is used to forward requests
|
|
to a unix socket that depends on the **hostname**, which is
|
|
exposed as **$host** by nginx. The following
|
|
configuration snippet contains the important parts:
|
|
|
|
server {
|
|
listen 80;
|
|
|
|
location @error_page {
|
|
root /var/nginx/$host/current/public;
|
|
internal;
|
|
[...]
|
|
|
|
location ~ "^/assets/.*-[a-z0-9]{32}.\w+" {
|
|
root /var/nginx/$host/current/public;
|
|
[...]
|
|
|
|
location ~ ^/assets/ {
|
|
root /var/nginx/$host/current/public;
|
|
[...]
|
|
|
|
root /var/nginx/$host/current/public;
|
|
location @unicorn {
|
|
proxy_pass http://unix:/var/nginx/$host/unicorn.sock;
|
|
|
|
# Forward original host name to be seen in unicorn
|
|
proxy_set_header Host $host;
|
|
|
|
# Server name and address like being available in PHP
|
|
proxy_set_header SERVER_NAME $server_name;
|
|
proxy_set_header SERVER_ADDR $server_addr;
|
|
|
|
# The real client IP address - header has ben setup by Zeus
|
|
proxy_set_header X-Real-IP $http_x_cluster_client_ip;
|
|
|
|
# Needed second header for rails - See SYS-1587
|
|
proxy_set_header X_FORWARDED_FOR $http_x_cluster_client_ip;
|
|
|
|
As you can see, all paths are dependent on the actual hostname
|
|
as setup by nginx.
|
|
|
|
## Application Deployment
|
|
|
|
Applications are deployed under their project name below
|
|
**/var/nginx**
|
|
(like **ws-locomotive.dev-deploy** or **ws-locomotive.master**).
|
|
As you can see from the naming, developers can deploy one application
|
|
from different branches easily (dev-deploy and master branches is this
|
|
case).
|
|
Developers can use [[!capistrano]] to deploy their applications
|
|
and don't need to interact (reload/restart) with nginx, as it is
|
|
already configured to accept any hostname.
|
|
|
|
## Name Server Configuration
|
|
|
|
As you can imagine, it would be quite cumbersome for developers to
|
|
reach a host named **ws-locomotive.dev-deploy**.
|
|
That is why a wildcard domain is configured to point
|
|
to the host running nginx:
|
|
|
|
*.play.intra.local.ch. CNAME rails-dev-vm-snr01.intra.local.ch.
|
|
|
|
## Give the application a name
|
|
|
|
A new hostname can be assigned to an application simply by symlinking
|
|
it to the application:
|
|
|
|
% cd /var/nginx
|
|
% ln -s ws-locomotive.dev-deploy my-fancy-name.play.intra.local.ch
|
|
|
|
This way, developers can use **any name** below
|
|
play.intra.local.ch for their application. Some applications
|
|
actually behave differently depending on the name they are accessed
|
|
with:
|
|
|
|
info.ws-locomotive.master.play.intra.local.ch -> ws-locomotive.master
|
|
hp.ws-locomotive.master.play.intra.local.ch -> ws-locomotive.master
|
|
|
|
## Conclusions
|
|
|
|
The setup is pretty elegant, because it allows developers to
|
|
create new development environments without interacting with any
|
|
sysadmin to configure nginx, bind or whatsoever.
|
|
There is a security drawback though:
|
|
An attacker could try to use hostnames like
|
|
**../../../../etc/** and request the file **passwd**.
|
|
That is the reasion why this service is not exposed
|
|
to the outside world directly, but all external requests
|
|
are filtered (whitelisting) by a load balancer in front
|
|
of the rails hosts.
|
|
|
|
|
|
[[!tag net unix foss ungleich localch rails]]
|