Arch linux + emby + Kodi + nginx: The Ultimate Media Server

November 30, 2015

I’ve been using Arch Linux as my media server/htpc for several years now and it’s been incredibly reliable. Some people prefer a versioned distribution with an LTS release for something like a media server, but I want the freshest packages, and I don’t want to deal with the headache of upgrading/reinstalling when an LTS release outlives its usefulness or won’t allow me to get the new packages I want. Recently, I decided to give emby a try, after hearing about it on one of my favorite podcasts, the Linux Action Show.

This guide assumes you have a working Arch Linux installation. If you’re starting completely from scratch, then consult the excellent Arch Beginner’s Guide. And if you don’t have time to go through a full Arch installation (thought I highly recommend it as you’ll learn a lot about Linux in the process), then you can always just go with Antergos, which is basically Arch with a nice installer and some sane defaults.

emby

emby is a media server that can manage and stream your movies, tv shows, music, home videos to a plethora of devices. It’s a lot like Plex, but it comes with all of the best features free to use. It works with a server/client set up. You install and configure emby server, in our case on an Arch Linux rig (though they have support for many distributions and operating systems), and then access it from a client like your Web browser, a DLNA client like a PlayStation 4, Kodi media center, the Android or iOS apps, or any number of other options. Check out their download page to see what I mean. Their cross-platform support is some of the best for any app I’ve seen in a while, let alone a media server.

emby

Installing emby

First, let’s create a user account for emby:

sudo useradd -r -s /bin/false emby

emby is available in the community repos. Install it with:

sudo pacman -S emby-server

Now that it’s installed, we’ll need to start the emby service with systemd:

sudo systemctl start emby-server
sudo systemctl enable emby-server

Check to make sure the emby-server service started properly:

sudo systemctl status emby-server
● emby-server.service - Emby brings together your videos, music, photos, and live television.
   Loaded: loaded (/usr/lib/systemd/system/emby-server.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2015-11-29 15:42:16 EST; 23h ago
 Main PID: 15379 (mono)
   CGroup: /system.slice/emby-server.service
           └─15379 /usr/bin/mono /usr/lib/emby-server/MediaBrowser.Server.Mono.exe -programdata /var/lib/emby -ffmpeg /usr/bin/ffmpeg -ffprobe /usr/bin/ffprobe

You should see something like that. If you get errors, check the logs with sudo journalctl -xe. When I first tried to start the service, I got an error saying that emby didn’t have permission to write to the /var/lib/emby/logs directory. If you get an error like that, you can fix it with sudo chown -R emby:emby /var/lib/emby

Once we’ve got the emby-server service started, let’s continue with the set up by pointing your web browser to http://localhost:8096. If you did everything correctly, you’ll see the emby welcome screen. The emby set-up wizard is really very easy to use, so I won’t go over every step, but you basically create a user account and tell emby where your media folders are and what kind of media they contain.

NOTE: emby can only scrape and recognize your media if it is named properly. It supports a number of naming conventions, so you’ll just have to pick one and make sure your media conforms to it. My media was already named properly, so I didn’t have to worry about this step, but there are a few tools, like filebot that can help you get your files in order.

Once you get through the initial set up, take a while to look through the options in the ‘Manager Server’ section:

Emby Manage Server Screen

There are a lot of options you can configure here. Familiarize yourself with all of the options and decide which are best for your set up. You can choose what libraries each user has access to, the max bitrate each user can stream at (useful if you live under the tyrannical rule of Comcast’s data caps), and where to save metadata files (fanart, posters, etc.).

Right now, you have a working emby server set up, you could just open port 8096 in your firewall and access your server from the web with https://your.external.ip.address:8096. emby even has built in ssl (https) support. But I already have nginx web server set up with ssl, and I don’t want the additional security risk and hassle of opening another port in my router.

nginx

nginx (pronounced “engine X”) is an awesome web server that’s fast, configurable and reliable. The configuration can be a little tricky to new users and users coming from Apache, but I actually prefer the nginx syntax now that I’m used to it. In any case, you can just cut and paste my configuration below to simplify the process.

Basically, nginx is going to act as a go-between for clients wanting to access it (and other web services we might be running, like transmission, subsonic, or owncloud). That means, we really only need to have 3 ports open in our router/firewall: http (80), https (443), and ssh (22). It also means, we can set up custom sub-domains, like emby.your-domain.com.

Installing and Configuring Nginx

First, install nginx with:

sudo pacman -S nginx

Once it’s installed, we’ll need to create a configuration file for our emby reverse proxy. Create /etc/nginx/conf.d/emby.conf in your text editor of choice and paste in my configuration below, making sure to change the server name to your own:

server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {
        server_name emby.yourdomain.com; #change this to your domain!
        listen 443 ssl spdy;

        ssl_certificate           /etc/nginx/certs/emby.crt;
    	ssl_certificate_key       /etc/nginx/certs/emby.key;
	ssl_prefer_server_ciphers       On;
        ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                     'AES256+EECDH:AES256+EDH:!aNULL';
        resolver                        8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout                5s;
        ssl_stapling_verify             on;
        keepalive_timeout               180;
        add_header                    Strict-Transport-Security max-age=31536000;
        client_max_body_size 1024M;

        location / {
                # Send traffic to the backend
                proxy_pass http://127.0.0.1:8096;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $remote_addr;
                proxy_set_header X-Forwarded-Protocol $scheme;
                proxy_redirect off;

                # Send websocket data to the backend as well
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
}

There’s a lot going on there, but this configuration takes any http requests to emby.yourdomain.com and redirects them to use https. It then creates a proxy so that any requests to emby.yourdomain.com/ get redirected to http://127.0.0.1:8096. That’s how we can keep the 8096 port closed. The emby clients will connect to nginx, which will then talk to the local emby server at 127.0.0.1:8096. Any data you send to or from your emby server will be encrypted and secured with ssl.

ssl

Our nginx proxy isn’t ready to go yet, we still need to create some self-signed certificates. Now, you could of course purchase an ssl certificate, but that’s sort of overkill for a home media server if you ask me … But if you already have some certs to use, put them in /etc/nginx/certs, Otherwise, let’s make some now.

sudo mkdir /etc/nginx/certs/
cd /etc/nginx/certs/
sudo openssl req -new -x509 -nodes -newkey rsa:4096 -keyout emby.key -out emby.crt -days 1095
sudo chmod 400 emby.*

The -days 1095 will set how long the certificate will be valid, adjust it to suit your needs. If you don’t understand the other settings, don’t mess with them. Running the openssl command will prompt you for some info, you can leave these blank if you want or fill them in, doesn’t really matter. chmod 400 emby.* will set some secure permissions on the certs so that other user accounts can’t mess with them.

Testing our nginx configuration

Once you’ve completed the above steps, let’s test our new set up.

sudo systemctl start nginx
sudo systemctl enable nginx

With the nginx service started, point your browser to emby.yourdomain.com. You should be redirected to https://emby.yourdomain.com and be presented with the emby server log in screen. Your browser may give you a warning about an untrusted certificate, but that’s just because we’re using a self-signed certificate. We just created the damn things so we know it’s safe. Add a security exception for the cert in Firefox or select Proceed anyway in Chrome. Either way, you shouldn’t be bothered with this message again (unless the certificate is changed).

emby login screen

Success! You’ve now got your own personal Netflix. You’ve got access to all of your media wherever you have an internet connection in a secure, encrypted way. You can make user accounts for your friends and family to use and give them an easy to remember url.

But what about in your home theater? emby’s web client is pretty slick, but no one wants to open up a web browser on their tv to view their local media files. That’s where kodi comes in.

kodi

Kodi (formerly known as xbmc) is open source home theater software. It provides a stylish, themeable, easy to use UI to display and organize all of your media. It has great remote control apps for Android and iOS and supports IR devices as well. If you’re serious about creating the ultimate home theater/media server set up, then at the very least you should look into it.

Kodi can play our local media just fine without emby, and in fact that was the set up I had for years. It works great in this regard and it can handle just about any file type you can throw at it. Guests were always amazed by my kodi set up and how I controlled it with my smart phone (using the excellent yatse app). Where kodi falls short is that it while it can do streaming over DLNA, it doesn’t do transcoding. There’s also not a simple way to keep track of your played position/status if you have multiple kodi instances throughout the house. emby can solve these problems in an elegant way by acting as the backend for Kodi, while letting us keep the beautiful and functional Kodi UI for our big screen.

NOTE: The emby add-on for Kodi will replace your existing Kodi metadata database completely. If you have a working Kodi install, then be sure to make a back up of any user data before proceeding. You have been warned.

That being said, I have found emby to be much better at scraping titles and downloading all of the proper meta images (posters, fan art, banners, logos, etc.) Even though I spent years getting my Kodi database just right, a few minutes of work with emby and I’m happy to throw all that away. I’ve still got my backup of course, but I doubt I’ll ever use it. emby really is that good.

Install Kodi with:

sudo pacman -S kodi

As always, the Arch wiki has a ton of useful info on this package. Be sure to read up on the entry for Kodi if you’re unfamiliar with it.

Installing the emby add-on for Kodi

emby provides their own Kodi repository for their add-on, so installing it is just as simple as installing any other Kodi add-on. Download their repository .zip file.

wget http://www.mb3admin.com/downloads/addons/xbmb3c/kodi-repo/repository.emby.kodi-1.0.2.zip

Then open up Kodi and navigate to System > Settings > Add-ons > Install from zip file.

kodi system settings

kodi install from zip

Once the repo is installed, you’ll need to install the emby add-on itself. In Kodi, navigate to Add-ons > Video add-ons > Emby

install emby add on

Launch the add-on by going to Video add-ons > Emby. If your emby-server service is running, then it should auto detect emby-server for you. Just log in and emby will perform a metadata sync with emby-server. Again, this will completely replace any existing metadata that Kodi has collected. There are a few options you can set in the emby add-on, but if you’re running Kodi on the same machine that’s running the emby server the defaults should work for you.

The emby website has some great screen shots of the emby add-on being used with different Kodi skins to give you a taste of the awesomeness to come:

emby kodi screenshots

The emby add-on for Kodi doesn’t yet support streaming over the web, so if you want to run Kodi with the emby add-on set up on a different machine, you’ll have to share the media over the network using samba or nfs and then set up path substitution in emby, so that kodi can find the files on the network to play. You’ll still be able to track played position/status and see all of your metadata, etc., it just requires some more set up. I haven’t had to set that up yet, so I’ll save that for another guide.

In any case, you should now have a bad ass media center/server set up on Arch Linux!