Migrating OTRS from Apache to Nginx

Installing OTRS on Fedora is quite easy considering it has pre-built RPM packages and clean documentation.
Usually OTRS is used with Apache. It’s stable well-tested solution. But what to do if you have nginx and you don’t want to have Apache? An issue becomes more complicated considering that nginx doesn’t support CGI from a box, and OTRS can’t be deployed as FastCGI application. If you try to use OTRS in FastCGi mode you will get such error messages:

Wide character in FCGI::Stream::PRINT at /opt/otrs/bin/fcgi-bin/../../Kernel/Output/HTML/Layout.pm line 1663.
Wide character in FCGI::Stream::PRINT at /opt/otrs/bin/fcgi-bin/../../Kernel/Output/HTML/Layout.pm line 1663"

And it caused by CGI::Fast Perl library newer than 0.67. Anyway, it’s not a good idea to downgrade it. Fortunately, we can use FastCGI wrapper, so OTRS will be FastCGI application for nginx, but will be launched as CGI.

There are two FastCGI wrappers for using CGI application with nginx. First one can be found on nginx wiki page.  Also you can use modified by Denis S. Filimonov version of this wrapper. It’s written in Pelr and can be found here. The second wrapper is fcgiwrap. It’s writen in C. I have choosen Perl wrapper since  there is no need to compile sources.

Put wrapper to /usr/local/bin/fastcgi-wrapper.pl and change it to open Unix socket at /var/run/otrs/perl_cgi-dispatch.sock:

$socket = FCGI::OpenSocket( "/var/run/otrs/perl_cgi-dispatch.sock", 10 );

Here is systemd configuration file for fast-cgi wrapper:

[Unit]
Description=otrs-index.pl

[Service]
ExecStart=/usr/local/bin/fastcgi-wrapper.pl
Type=forking
User=otrs
Group=nginx
Restart=always

[Install]
WantedBy=multi-user.target

Put it to /lib/systemd/system/perl-fcgi.service. Now we need to enable it:

systemctl enable  perl-fcgi.service

nginx configuration file:

server {
listen 1.2.3.4:80;
server_name otrs.example.com otrs;
root /opt/otrs/var/httpd/htdocs;
index index.html;

location /otrs-web {
gzip on;
alias /opt/otrs/var/httpd/htdocs;
}

location ~ ^/otrs/(.*.pl)(/.*)?$ {
fastcgi_pass unix:/var/run/otrs/perl_cgi-dispatch.sock;
fastcgi_index index.pl;
fastcgi_param SCRIPT_FILENAME   /opt/otrs/bin/fcgi-bin/$1;
fastcgi_param QUERY_STRING      $query_string;
fastcgi_param REQUEST_METHOD    $request_method;
fastcgi_param CONTENT_TYPE      $content_type;
fastcgi_param CONTENT_LENGTH    $content_length;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE   nginx;
fastcgi_param SCRIPT_NAME       $fastcgi_script_name;
fastcgi_param REQUEST_URI       $request_uri;
fastcgi_param DOCUMENT_URI      $document_uri;
fastcgi_param DOCUMENT_ROOT     $document_root;
fastcgi_param SERVER_PROTOCOL   $server_protocol;
fastcgi_param REMOTE_ADDR       $remote_addr;
fastcgi_param REMOTE_PORT       $remote_port;
fastcgi_param SERVER_ADDR       $server_addr;
fastcgi_param SERVER_PORT       $server_port;
fastcgi_param SERVER_NAME       $server_name;
}
}

Restating nginx, startting FastCGI wrapper:

service nginx restart
service perl-fcgi start

Now you can start using your OTRS with nginx.

Future readings

OTRS in Nginx using FCGI (multiple users possible)

OTRS + Nginx + Fcgi howto