pages tagged rubyonrailsNico Schotteliushttps://www.nico.schottelius.org//tags/rubyonrails/Nico Schotteliusikiwiki2016-02-25T13:34:32ZNginx: Use X-Accel with conflicting regular expressionshttps://www.nico.schottelius.org//blog/nginx-prioritise-x-accel-before-regular-expressions/2016-02-25T13:34:32Z2015-02-03T14:47:26Z
<h2>Background</h2>
<p>At <a href="http://www.ungleich.ch">ungleich</a> we use <a href="http://nginx.org/">nginx</a> for <a href="http://rubyonrails.org/">Ruby on Rails</a>
hostings of our customers. Nginx is configured to
deliver static files using <a href="http://wiki.nginx.org/X-accel">X-Accel</a>.
We also want to have a longer expiry time for static files,
which is configured seperately in nginx.</p>
<h2>Configuration Options</h2>
<p>To support X-Accel, we have added this configuration block into nginx:</p>
<pre><code># Support for X-Accel
location /protected/ {
internal;
root /home/app/app/shared;
}
</code></pre>
<p>To support longer expiry times, we have added this configuration
block:</p>
<pre><code>location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
expires 1y;
# Need to enable proxying in this location as well
try_files $uri @unicorn;
}
</code></pre>
<h2>The Problem</h2>
<p>Using the configuration as stated above, we encounter the problem that
if an application wants to send a JPEG using X-Accel, the regular
expression block is selected (it has higher priority and matches
the .jpeg ending) and thus the application delivers it, instead of nginx
directly.</p>
<h2>The Solution</h2>
<p>Luckily though, <a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#location">nginx supports giving the prefix based
location block precedence</a>:
Instead of using <strong>location /protected/</strong>, we can use <strong>location ^~</strong>. Thus our
previous block can be rephrased to:</p>
<pre><code>location ^~ /protected/ {
internal;
root /home/app/app/shared;
}
</code></pre>
<p>And now the application can serve JPEG files via X-Accel.</p>