Project

General

Profile

Actions

HowTo configure Nginx to run Redmine

This has configurations for Nginx and Thin that are working well for me. It is not an exhaustive installation guide; it is assumed that you have read the installation instructions and installed the appropriate packages for your distribution.

This setup gives you four Thin processes for concurrent handling of requests, and forwards to SSL at appropriate places to keep logins secure.

First, Thin -- here's what is in my /etc/thin/redmine.yml:

--- 
pid: tmp/pids/thin.pid
group: redmine
wait: 30
timeout: 30
log: log/thin.log
max_conns: 1024
require: []

environment: production
max_persistent_conns: 512
servers: 4
daemonize: true
user: redmine
socket: /tmp/thin.sock
chdir: /var/lib/redmine/redmine 

You'll have to change the user/group/chdir to appropriate values for your setup.

Next, the nginx configuration. This isn't an exhaustive configuration, just the relevant server{} bits. First, my standard proxy include file proxy.include, which you'll see referenced in the Redmine-specific part:

    proxy_set_header   Host $http_host;                                                                                                                     
    proxy_set_header   X-Real-IP $remote_addr;                                                                                                                   
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;

    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;

Next, the actual nginx configuration:

# Upstream Ruby process cluster for load balancing
upstream thin_cluster {
    server unix:/tmp/thin.0.sock;
    server unix:/tmp/thin.1.sock;
    server unix:/tmp/thin.2.sock;
    server unix:/tmp/thin.3.sock;
}

server {
    listen       your.ip.address.here:80;
    server_name  your.domain.name;

    access_log  /var/log/nginx/redmine-proxy-access;
    error_log   /var/log/nginx/redmine-proxy-error;

    include sites/proxy.include;
    root /var/lib/redmine/redmine/public;
    proxy_redirect off;

    # Send sensitive stuff via https
    rewrite ^/login(.*) https://your.domain.here$request_uri permanent;
    rewrite ^/my/account(.*) https://your.domain.here$request_uri permanent;
    rewrite ^/my/password(.*) https://your.domain.here$request_uri permanent;
    rewrite ^/admin(.*) https://your.domain.here$request_uri permanent;

    location / {
        try_files $uri/index.html $uri.html $uri @cluster;
    }

    location @cluster {
        proxy_pass http://thin_cluster;
    }
}

server {
    listen       your.ip.address.here:443;
    server_name  your.domain.here;

    access_log  /var/log/nginx/redmine-ssl-proxy-access;
    error_log   /var/log/nginx/redmine-ssl-proxy-error;

    ssl on;

    ssl_certificate /etc/ssl/startssl/your.domain.here.pem.full;
    ssl_certificate_key /etc/ssl/startssl/your.domain.here.key;

    include sites/proxy.include;
    proxy_redirect off;
    root /var/lib/redmine/redmine/public;

    # When we're back to non-sensitive things, send back to http
    rewrite ^/$ http://your.domain.here$request_uri permanent;

    # Examples of URLs we don't want to rewrite (otherwise 404 errors occur):
    # /projects/PROJECTNAME/archive?status=
    # /projects/copy/PROJECTNAME
    # /projects/PROJECTNAME/destroy

    # This should exclude those (tested here: http://www.regextester.com/ )
    if ($uri !~* "^/projects/.*(copy|destroy|archive)") {
        rewrite ^/projects(.*) http://your.domain.here$request_uri permanent;
    }

    rewrite ^/guide(.*) http://your.domain.here$request_uri permanent;
    rewrite ^/users(.*) http://your.domain.here$request_uri permanent;
    rewrite ^/my/page(.*) http://your.domain.here$request_uri permanent;
    rewrite ^/logout(.*) http://your.domain.here$request_uri permanent;

    location / {
        try_files $uri/index.html $uri.html $uri @cluster;
    }

    location @cluster {
        proxy_pass http://thin_cluster;
    }
}

Updated by Deoren Moor about 14 years ago · 3 revisions