pages tagged railsNico Schotteliushttps://www.nico.schottelius.org//tags/rails/Nico Schotteliusikiwiki2016-02-25T13:34:32ZRailshöck: Ruby on Rails Hostinghttps://www.nico.schottelius.org//dokumentationen/railshoeck-railshosting.ch-2015-05-27/2016-02-25T13:34:30Z2015-05-25T22:00:00Z
<p>Thanks everyone for coming - it was a great evening together with everyone!</p>
<p>Here's <a href="https://www.nico.schottelius.org//dokumentationen/railshoeck-railshosting.ch-2015-05-27/railshoeck-railshosting.ch-2015-05-27.pdf">the presentation of yesterday</a> - to be put on a "big beamer".</p>
Great Rails Hosting: A symlink for an apphttps://www.nico.schottelius.org//blog/great-rails-hosting-a-symlink-for-an-app/2016-02-25T13:34:32Z2015-02-03T14:47:26Z
<h2>Introduction</h2>
<p>As <a href="http://www.ungleich.ch">ungleich</a> focusses on educated customers,
we meet pretty cool infrastructures from time to time.
In some sense I count <a href="http://www.local.ch">local.ch</a>
as a customer: they supported me with one day off
per week so I was able to found <a href="http://www.ungleich.ch">ungleich</a>
and acquire first customers.
This article is dedicated to <a href="http://www.local.ch">local.ch</a> and describes
a very elegant solution for Ruby on Rails hosting.</p>
<h2>Overview</h2>
<p>The setup consists of the following services, glued
together in an elegant way:</p>
<ul>
<li><a href="http://nginx.org/">nginx</a></li>
<li><a href="http://unicorn.bogomips.org/">unicorn</a></li>
<li><a href="https://www.isc.org/downloads/bind/">ISC Bind</a></li>
<li><a href="https://github.com/capistrano/capistrano/wiki">Capistrano</a></li>
<li>Symlinks</li>
</ul>
<h2>Nginx</h2>
<p>The great trick of the setup is that nginx is used to forward requests
to a unix socket that depends on the <strong>hostname</strong>, which is
exposed as <strong>$host</strong> by nginx. The following
configuration snippet contains the important parts:</p>
<pre><code>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;
</code></pre>
<p>As you can see, all paths are dependent on the actual hostname
as setup by nginx.</p>
<h2>Application Deployment</h2>
<p>Applications are deployed under their project name below
<strong>/var/nginx</strong>
(like <strong>ws-locomotive.dev-deploy</strong> or <strong>ws-locomotive.master</strong>).
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 <a href="https://github.com/capistrano/capistrano/wiki">Capistrano</a> to deploy their applications
and don't need to interact (reload/restart) with nginx, as it is
already configured to accept any hostname.</p>
<h2>Name Server Configuration</h2>
<p>As you can imagine, it would be quite cumbersome for developers to
reach a host named <strong>ws-locomotive.dev-deploy</strong>.
That is why a wildcard domain is configured to point
to the host running nginx:</p>
<pre><code>*.play.intra.local.ch. CNAME rails-dev-vm-snr01.intra.local.ch.
</code></pre>
<h2>Give the application a name</h2>
<p>A new hostname can be assigned to an application simply by symlinking
it to the application:</p>
<pre><code>% cd /var/nginx
% ln -s ws-locomotive.dev-deploy my-fancy-name.play.intra.local.ch
</code></pre>
<p>This way, developers can use <strong>any name</strong> below
play.intra.local.ch for their application. Some applications
actually behave differently depending on the name they are accessed
with:</p>
<pre><code>info.ws-locomotive.master.play.intra.local.ch -> ws-locomotive.master
hp.ws-locomotive.master.play.intra.local.ch -> ws-locomotive.master
</code></pre>
<h2>Conclusions</h2>
<p>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
<strong>../../../../etc/</strong> and request the file <strong>passwd</strong>.
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.</p>
Ruby on Rails: Fix the hostname does not match the server certificate errorhttps://www.nico.schottelius.org//blog/ruby-on-rails-fix-hostname-does-not-match-the-server-certificate/2016-02-25T13:34:32Z2015-02-03T14:47:26Z
<h2>The problem</h2>
<p>If you encounter this problem when running Ruby on Rails:</p>
<pre><code>OpenSSL::SSL::SSLError (hostname "localhost" does not match the server certificate)
</code></pre>
<p>it is likely due to
<a href="http://api.rubyonrails.org/classes/ActionMailer/Base.html">ActionMailer</a>
using the <strong>smtp</strong> as the <strong><em>delivery_method</em></strong> and
your local mail server supporting TLS/SSL,
but not having a correct/valid certificate.</p>
<h2>The solution</h2>
<p>You can add a valid certificate, but if the server is just used
for sending out mails, this may not be suited.
In that case, you can change the <strong><em>delivery_method</em></strong> to
<strong>sendmail</strong>, which makes ActionMailer use the sendmail
binary directly.</p>