Part 2: Setting up nginx, php and ruTorrent on LEDE/OpenWrt

In this part we will prepare our environment for ruTorrent, the nice WebUI that enables easy control of rtorrent.
One thing to keep in mind: in Part 1 we completed a light setup, rtorrent by itself performs surprisingly well on low-end hardware.
To enable the ruTorrent webUI we will install many supporting apps, adding a substantial overhead.
If you have a beefy router then it will handle all this just fine, but if you are doing this on a single core SoC, then we may be testing its limits.

With that said, lets begin by installing the big stuff:

opkg update && opkg install nginx php7-cli php7-cgi php7-fpm php7-mod-curl php7-mod-json php7-mod-mbstring

We installed nginx, php and a few mods. If you wonder why those mods, ruTorrent has many plugins, they are not necessary for core functionality, but I figured why not go all out and enable all the bells and whistles? 🙂

We will run both rtorrent (bittorrent client) and nginx (webserver) under the user we created in part 1, rtorrent. With this, we avoid permission headaches.

Open nginx’s configuration file:

vi /etc/nginx/nginx.conf

And modify it as follows (link below if you want to wget file directly) :

user rtorrent rtorrent;
worker_processes  1;

events {
	worker_connections  768;

http {
	include		mime.types;
	default_type	application/octet-stream;
	sendfile        on;
	keepalive_timeout  65;

	server {
		listen		8000;
		server_name	rutorrent;
		root		/mnt/storage/.ruTorrent;
		index		index.html index.htm index.php;

		# serve static files directly
		location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ {
			access_log	off;
			expires		max;

		location /RPC2 {
			include scgi_params;
			scgi_pass unix:/tmp/rtorrent.sock;

		location ~ \.php$ {
			try_files $uri =404;
			fastcgi_intercept_errors on;
			fastcgi_split_path_info ^(.+\.php)(/.+)$;
                	fastcgi_pass unix:/var/run/php7-fpm.sock;
                	fastcgi_index index.php;
			include /etc/nginx/fastcgi_params;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;


Alternatively, you can grab a copy off our website directly into your router:

cd /etc/nginx
wget -O nginx.conf

You will need another file, scgi_params:

scgi_param  REQUEST_METHOD     $request_method;
scgi_param  REQUEST_URI        $request_uri;
scgi_param  QUERY_STRING       $query_string;
scgi_param  CONTENT_TYPE       $content_type;

scgi_param  DOCUMENT_URI       $document_uri;
scgi_param  DOCUMENT_ROOT      $document_root;
scgi_param  SCGI               1;
scgi_param  SERVER_PROTOCOL    $server_protocol;
scgi_param  HTTPS              $https if_not_empty;

scgi_param  REMOTE_ADDR        $remote_addr;
scgi_param  REMOTE_PORT        $remote_port;
scgi_param  SERVER_PORT        $server_port;
scgi_param  SERVER_NAME        $server_name;

Again, to copy directly into router:

cd /etc/nginx
wget -O scgi_params

Let’s see if nginx starts up, first restart it so it loads the new config files:

/etc/init.d/nginx restart

And now point your browser to <your_routers_lan_IP>:8000, so if you are using the default, then the address would be:

Note its http, not https. If all went well you should see nginx’s 404 Not Found page (nginx version at bottom of page), which is fine since we are yet to copy the ruTorrent files into our storage.

We are done with nginx, next we make some changes to php/php-fpm.

Edit php.ini (vi /etc/php.ini), and change this:

doc_root = "/www"


doc_root = 

And save the file. As usual you can overwrite the file with a copy from our website:

cd /etc
wget -O php.ini

Next is www.conf, where we only need to change ownership (again to user rtorrent), and a few tweaks to minimize idle usage. The file is big so I won’t paste it here, only linking to it. You can compare (diff) the files to see what changed. So:

cd /etc/php7-fpm.d
wget -O www.conf

Restart php7-fpm (or reboot router) for changes to take effect:

/etc/init.d/php7-fpm restart

Nginx and php are ready. We can finally clone ruTorrent.
If you’ve been reading the config file changes instead of just copying them 😉 , then you will notice that we set the nginx root to /mnt/storage/.ruTorrent. That is where we will clone ruTorrent directly from the author’s github. Let’s install git:

opkg update && opkg install git

Now move to external storage and clone ruTorrent then change ownership:

cd /mnt/storage
git clone git:// .ruTorrent
chown -R rtorrent:rtorrent .ruTorrent

At this point if you refresh your browser’s page (<router_IP>:8000) then you will see the ruTorrent webUI, but its not yet linked to your rtorrent instance.

ruTorrent before config. The log tells us what needs to be fixed.

Needless to say, for the next step to succeed, rtorrent needs to be running, so I assume you followed part 1 and have rtorrent started within a tmux session. If yes then we simply need to make a small change to ruTorrent’s config to tell it where to look for the rtorrent socket (which we specified in the config file).

We need to adjust ruTorrent’s configuration, two main things we need to change: point ruTorrent to the right socket, and then tell it where to find the binaries for various utilities like php-cli. I will post a modified file, but it will be better if you go along with this one to see what needs to change, since you most likely will need to do similar things to enable future plugins to work.

vi /mnt/storage/.ruTorrent/conf/config.php

Find these two lines:

$scgi_port = 5000;
$scgi_host = "";

And change them to:

$scgi_port = 0;
$scgi_host = "unix:///tmp/rtorrent.sock";

Now in the same file, find the section:

$pathToExternals = array(
                "php"   => '',        // Something like /usr/bin/php. If empty, will be found in PATH.
                "curl"  => '',        // Something like /usr/bin/curl. If empty, will be found in PATH.
                "gzip"  => '',        // Something like /usr/bin/gzip. If empty, will be found in PATH.
                "id"    => '',        // Something like /usr/bin/id. If empty, will be found in PATH.
                "stat"  => '',        // Something like /usr/bin/stat. If empty, will be found in PATH.

And specify the full paths so ruTorrent can find the utilities it needs, like so:

        $pathToExternals = array(
                "php"   => '/usr/bin/php-cli',          // Something like /usr/bin/php. If empty, will be found in PATH.        
                "curl"  => '/usr/bin/curl',             // Something like /usr/bin/curl. If empty, will be found in PATH.        
                "gzip"  => '/bin/gzip',                 // Something like /usr/bin/gzip. If empty, will be found in PATH.
                "id"    => '/usr/bin/id',               // Something like /usr/bin/id. If empty, will be found in PATH.        
                "stat"  => '/bin/stat',                 // Something like /usr/bin/stat. If empty, will be found in PATH.
                "pgrep" => '/usr/bin/pgrep',                                                                                     

If you want to grab a copy of the ruTorrent config, here it is:

cd /mnt/storage/.ruTorrent/conf
wget -O config.php

You’ll notice we added a new entry (for pgrep), along with it, some of these utilities are not available by default on a LEDE/OpenWrt, we need to install them:

opkg update && opkg install curl procps-ng-pgrep coreutils-stat

Now if you go back to your browser and refresh the page, ruTorrent should show a successful connection:

Connection successful, ready to download.

The log shows ruTorrent still complaining about some plugins (eg missing unrar utility to enable unpack plugin..etc), those are not essential, but we will still cover them in the next part.

This concludes part 2.

Leave a Reply