Home Entertainment

Deploying JellyFin via Docker on Ubuntu 18.04 LTS

As a long-time Plex Pass user I had become increasingly frustrated with three core issues:

  • The abysmal Amazon FireStick App – namely the need to constantly switch off the ‘new’ player due to its inability to play certain content.
  • The Docker containers insatiable appetite for memory, and its recent second course of /tmp storage to boot.
  • Content, that I don’t want and isn’t young kid friendly, especially when I’m paying for the platform.

Couple the above with a couple of ‘epic’ failures in consuming synchronized content offline (imagine a 3 year old, getting onto an 11 hour flight unable to access *anything*)… it’s safe to say I was ready to move on to pastures new.

I’d come across Jellyfin 12+ months back, but has dismissed it because there was no FireStick App, and with a young family ease of use is a must. Well… all that changed at some point in the last year as there is now an ‘approved’ FireStick app. After a couple of months of use, I’m pleased to have made the move, experiencing only a couple of minor niggles.

I opted to deploy Jellyfin using Docker, so the steps below assume you are already running Docker CE on your host/ media server. I also chose to enable Hardware Accelerated Encoding, using VAAPI.

First, create required directories, note, you may want to adjust for your environment.

mkdir -p ~/jellyfin/config
mkdir -p ~/jellyfin/cache
mkdir -p ~/jellyfin/transcode

sudo chown -R 1000:44 ~/jellyfin/

Now create the docker-compose.yml:

vi ~/jellyfin/docker-compose.yml

Paste contents as below, ensure you update volumes to reflect locations of your media:

version: '3.2'

    user: 1000:44
    image: jellyfin/jellyfin
    container_name: jellyfin
    network_mode: "host"
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped

    - /mnt/media:/media:shared:ro

      # VAAPI Devices
      - /dev/dri/renderD128:/dev/dri/renderD128
      - /dev/dri/card0:/dev/dri/card0

Note that user 1000:44 enables access to the VAAPI devices required for Hardware Accelerated Encoding.

You can now bring-up your Jellyfin environment:

sudo docker-compose up -d

Finally, browse to http://<server-name/IP>:8096 to access your Jellyfin instance.

You can enable Hardware Acceleration by browsing to Dashboard | Playback (tested on Intel QuickSync-enabled CPU):


Setting up Prometheus on Ubuntu 18.04 LTS

I recently set out to get Prometheus setup, capturing metrics across ‘traditional’ VM (Ubuntu 18.04) and containerised workloads whilst enabling visibility of captured metrics in Grafana. The steps captured below outlines the approach/ configuration I used to get Prometheus, Node-Exporter and cAdvsor up and running. I’ll follow-up with the Grafan Integration/ Configuration in a separate post.

Note this guide assumes you have Docker CE running on the machine you intend to deploy and run Prometheus.

First, create the required user accounts:

sudo useradd -rs /bin/false prometheus
sudo useradd -rs /bin/false node_exporter

Make a note of the ‘prometheus’ account user and group id’s from /etc/passwd, you’ll need these later:

cat /etc/passwd | grep prometheus

Create the required directory structure, in order to ensure configuration and metric data persists container redeployment:

mkdir -p ~/prometheus/config
mkdir -p ~/prometheus/data

Create Prometheus configuration file:

sudo vi ~/prometheus/config/prometheus.yml

Contents (note that ‘localhost’ is used for targets):

# A scrape configuration scraping a Node Exporter and the Prometheus server
# itself.
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Scrape Prometheus itself every 5 seconds.
  - job_name: 'prometheus'
    scrape_interval: 5s
      - targets: 
        - 'localhost:9090'

  - job_name: 'node'
    scrape_interval: 5s
      - targets:
        - 'localhost:9100'

  - job_name: 'cadvisor'
    scrape_interval: 5s
      - targets:
        - 'localhost:9080'

Set required filesystem permissions:

sudo chown -R prometheus:prometheus ~/prometheus/

Create docker-compose.yaml:

vi ~/prometheus/docker-compose.yaml

Contents as below, remember to set the correct user id and group id for the ‘prometheus’ user , as captured earlier:

version: '3.2'

    user: 999:998
    image: prom/prometheus:latest
    container_name: prometheus
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped
    - 9090:9090
    - --config.file=/etc/prometheus/prometheus.yml
    - --storage.tsdb.path="/data/prometheus" 
    - ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    - ./data:/data/prometheus:rw
    - cadvisor

    image: google/cadvisor:latest
    container_name: cadvisor
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped
    - 8080:8080
    - /:/rootfs:ro
    - /var/run:/var/run:rw
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro
    - redis

    image: redis:latest
    container_name: redis
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped
    - 6379:6379

I ran into issues with the containerised version of node-exporter, where instances in Grafana would persistently show ‘N/A’ or no-data, despite metrics being captured as expected in Prometheus itself.

Moving to a ‘natively’ installed node-exporter fixed these issues.

Download and extract the latest version of node-exporter, this is an X66_64 example:

cd ~


tar -xvf node_exporter-1.0.0.linux-amd64.tar.gz
cd node_exporter-1.0.0.linux-amd64

Copy the node-exporter binary to /usr/sbin:

sudo mv node_exporter /usr/sbin/

Create systemd service:

sudo touch /etc/systemd/system/node_exporter.service

sudo tee -a /etc/systemd/system/node_exporter.service > /dev/null <<EOT
Description=Node Exporter

ExecStart=/usr/sbin/node_exporter $OPTIONS


sudo mkdir -p /etc/sysconfig
sudo touch /etc/sysconfig/node_exporter

sudo tee -a /etc/sysconfig/node_exporter > /dev/null <<EOT
OPTIONS=" /var/lib/node_exporter/textfile_collector"

Create required folder structure for node-exporter, note the use of the ‘node_exporter’ account we created earlier:

sudo mkdir -p /var/lib/node_exporter/textfile_collector
sudo chown node_exporter:node_exporter /var/lib/node_exporter/textfile_collector

Reload systemd daemons and start node-exporter:

sudo systemctl daemon-reload

sudo systemctl enable node_exporter

sudo systemctl start node_exporter

You should now be able to view node-exporter metrics via: https://localhost:9100

Now, we can start Prometheus and cAdvisor, as defined in our Docker Compose file:

cd ~/prometheus
sudo docker-compose up -d

You should now be able to browse Promethus itself via: http://localhost:9090

Browse to http://localhost:9090/targets and ensure that cAdvisor, Node and Prometheus show as ‘1/1 up’ – assuming that they do, you have a working Promethus installation.

Adding new nodes to Node-Exporter is as simple as deploying Node-Exporter as above, on each required ‘target’ or node you wise to monitor, then editing the prometheus.yml file to include the new ‘target’ – for example:


  - job_name: 'node'
    scrape_interval: 5s
      - targets:
        - 'localhost:9100'
        - 'newserver:9100'


Add additional targets to the ‘node’ job (rather than creating new jobs for each host) as this will make viewing the data in Grafana easier.

Once you have updated and saved the configuration file, restart Prometheus:

cd ~/prometheus
sudo docker-compose restart

Raspberry Pi

Raspberry Pi PoE Hat

I was really excited (sad… I know) to get my Raspberry Pi PoE Hat in the post. My intention here was to de-clutter power cables and make my home automation setup more “wife friendly.”

Fitting the thing was surprisingly easy – ensure you attach the standoffs prior to fitting, you risk damaging the PoE hat each time you remove it. Once fitted I connected the network cable into my PoE switch and everything worked as expected – you’d expect it to be simple to be fair! Then came the noise!

If you’re looking to run this anywhere that noise could be an issue, don’t bother buying the PoE Hat. Even in the cool / early UK Spring I found the fan to run regularly and for extended periods. It’s a small fan so when it gets going it is noisy! Definitely not wife friendly… even less so than the cables!

I’d be interested to hear if your experiences are different!

Raspberry Pi

Raspberry Pi Router on a Stick

Updated June 2020 to allow NTP via iptables when VPN not established.

I recently setup a new SSID to enable quick and easy access to a VPN protected network when I needed it, also making this easily accessible for family members who are not computer-savvy.

I used a Raspberry Pi 3 for the task, as a router on a stick. This guide shares the configuration/ commands used to set this up so that:

  • All traffic sent to the Raspberry Pi (from devices using it as their default gateway) will be routed via the VPN
  • DNS requests sent to the Raspberry Pi (again, where clients are set to use it as DNS server) will be routed via the VPN
  • When the VPN disconnects all traffic, including DNS is dropped until such time as the VPN reconnects
Smart Home

A Wi-Fi MQTT Multi-Sensor

Old but gold, I came across the Bruh Automation Multi-sensor video about 12 months ago. Intrigued, I set forth and built a couple of these Wi-Fi devices. Over the year I have iterated on the design and software – getting to a place where the sensors themselves are reliable for use in environment monitoring and automation flows.

Smart Home

Node-RED Smart Home Control Update Q1 2019

It’s been a while since I’ve posted anything about the Node-RED Smart Home Control device bridge. In fact, my last update was inOctober. That said, there has been ongoing effort to develop and add new features, some of which I want to share.

Whilst the service is still “in development” the most significant updates for Q1 include:

  • Google Home support added. You can now use the same devices across both smart home platforms (some device type restrictions apply).
  • Service branding/ name changed to “Node-RED Smart Home Control.” URLs and service endpoints updated to reflect multi-platform nature of the service.
  • Device state is retrievable in the Alexa and Google Home App, both Apps reflect real-time state changes fro either platform.
  • You can now send “out-of-band” state updates to the service (i.e. from an MQTT subscription node). Changes sent will then update state in Alexa and Google Home app.
  • New device types and capabilities added. You can find a full break-down in the GitHub Wiki.

If you’d like access to the service, in order to help with testing, or to simply try it out, follow these instructions.


TP-Link EAP225 v3 Experience

I’ve done a 180 on the TP-Link EAP225 v3, going from loving it to loathing it after just a few days. My issues (and decision to return the AP) all spur from introducing IPv6 into my network. However, the issues experienced, I believe, point to a fault in the AP’s firmware that is not specific to IPv6. I thought I’d share my experience as, based on recent reviews/ tests of this device and its price-point, it seemed like the better choice over the UAP-AC-LITE. No doubt others will be considering a similar purchase in future.

Smart Home

Sonoff T1 Wireless Wall Switch

I’ve spent recent weeks (months even!) looking at how I can bring simple automation and voice control to my home. In my quest to create a “Smart Home” I came across the Sonoff T1 UK-specification wall switch. At just ~£15 and when coupled with Tasmota, an Open Source firmware (from what I have read, I wouldn’t consider using the native firmware) that is suitable for a variety of ESP powered devices, this wi-fi connected switch becomes a very compelling product.

I’ve now got a bunch of these around the house, integrated with the Node Red Alexa Smart Skill v3 Bridge. Over the last three months these have proven to be very reliable (faultless actually) and very effective when paired with the custom multi-sensors I have built using ESP8266 NodeMCU boards to drive automation. I figured I would share my experience/ how I got them up and running.

Note that this guide assumes you have a secure MQTT server available for use, and Node-RED deployed should you want to take advantage of the Node Red Alexa Smart Skill v3 Bridge. If you’ve not got either of these in-place watch this space – further guides to follow.

Smart Home

Node-RED Smart Home Control Updated

Last week I posted about the Node-RED Smart Home Control skill / bridge. I’ve spent the week on ensuring the majority of device types or “capabilities” are are now supported by the bridge. It’s now possible to define devices that support:

  • Playback controls (Play, pause, stop)
  • Input changing (such as HDMI1, Audio1)
  • Volume (in steps)
  • Power (on /off)
  • Brightness (in %)
  • Colour (Red, Green, Blue etc)
  • Colour temperature (in Kelvin or warm-white through to daylight)
  • Temperature (in °C or °F)

Hopefully this means you’re now able to use commands that are more “natural” to interact with Node-RED flows that control your Smart Devices.

To further the usability of the service it is now possible (required!) to set minimum and maximum values on thermostats (in °C or °F) and smart bulbs (in Kelvin).  Any commands that fall “out of range” will not be processed by the bridge and you will get the appropriate feedback from Alexa. Again, hopefully this makes interaction with the service more intuitive.

Finally, I’ve simplified the response node. Use logic in your flows to return a “true” or “false” value as an input to this node. Any flow that starts with a Node-RED Alexa v3 node should return a payload of “true” where the command/ request is processed successfully and “false” where it is not.

I’ll be updating the documentation with more flow examples in the coming week.

Want to get involved, contribute or start testing the service as outlined in the documentation!

Smart Home

Node-RED Alexa Home Skill

It’s been a while since I posted, but I’ve been busy… Somehow, despite having no interest in it six months ago, I got into Home Automation, or setting up a “Smart” Home. Over the last 6 months I have:

  • purchased a variety of sensors and electronic components, Fresnel lenses and NodeMCU boards from China
  • designed/ modified circuits, learnt to solder (badly!)
  • written firmware for NodeMCU based multi-sensors
  • modified 3D designs in TinkerCAD
  • printed 3D models via 3D Hubs
  • flashed firmware of wi-fi light switches
  • (re)written a NodeJS/ MQTT and Amazon Lambda function that drive a Node-RED Alexa add-on

Lots more posts to come, but I wanted to share the latter of these activities with you first.

In my quest to enable voice control over a variety of devices I came across a Ben Hardill’s Node Red Alexa Home Skill Bridge. Ben created a Node-RED Alexa Smart Home  Skill API version 2 add-on that enables Alexa interaction with flows. No sooner had I found this and started to use it I wanted more… ! This is where the Smart Home Skill API version 3 comes in – it allows for a swathe of new voice commands to control playback, volume, inputs and other devices that version 2 did not cater for.

Unfortunately (for me at least) the API syntax has fundamentally changed. This meant figuring out Ben’s service and re-writing elements of it to work with the new API. Whilst I was at it I also updated the web interface to Bootstrap 4, and remediated some NodeJS/ Mongoose functions that were no longer supported in the original service.

The net result… My wife and kids love the fact they can turn on/ off the TV, pause, play and stop video, increase/  decrease and mute volume as well as control the lights with their voice. Couple the lighting control with Alexa “room awareness” and the whole system becomes very user friendly – i.e. “Alexa, turn on the lights.” The multi-sensors add some additional functionality/ capabilities, but I’ll save that for another day.

At this point the skill is in “Dev” – meaning it is not a publicly available Alexa Skill – however, get in touch and I can add you to the list of people able to test the service out.

You can read the intricate detail about the service on GitHub, or request access and get testing.