Standalone – James Batchelor https://james-batchelor.com Useful I.T & VoIP Ramblings Mon, 29 Dec 2025 18:07:40 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.5 https://james-batchelor.com/wp-content/uploads/2025/05/cropped-cropped-logo-jb-202505-32x32.png Standalone – James Batchelor https://james-batchelor.com 32 32 Grafana Static Displays https://james-batchelor.com/index.php/2025/12/29/grafana-static-displays/ Mon, 29 Dec 2025 18:07:40 +0000 https://james-batchelor.com/?p=1080 Continue reading "Grafana Static Displays"]]> In the last post I migrated a Grafana database to a new server and took the opportunity to upgrade the Grafana version in the process.

This created a new issue, since Grafana’s supported browser list moves with the times, my two “NOC” screens consisting each of a Raspberry Pi 3A running Raspbian Buster and Hyperpixel 4.0 screens no longer worked. Instead, the outdated Chromium browsers now displayed the “If you’re seeing this Grafana has failed to load its application files” page when visiting the Grafana web interface.

Bringing the OS on the Pi’s up to date is the logical resolution, however, there are a couple of issues with this:

  • One of the Hyperpixel 4.0 screens is an early revision model, meaning the official and legacy drivers do not work.
  • Even with working screen drivers, compatible browsers will not load on the 512MB RAM available to the Pi 3A.

Not wanting to obsolete a pair of Pi 3A’s with a now unique form factor, instead a workaround was found to continue displaying Grafana dashboards on this older hardware. The solution even gave a slight benefit over the original URL…

To achieve this, Grafana has released grafana-image-renderer, essentially a binary with a self-contained and headless Chromium instance that will load a dashboard and capture an image of the output.

Until recently, this was available as a Grafana plugin, however this plugin has since been depreciated in favour of it being a standalone application or docker container. A lot of online documentation still refers to it in its plugin form and so is now outdated.

The current iteration of grafana-image-renderer recommends using it within a docker container due to the potential resource usage it can generate. However, for this guide, only the standalone binary will be used as its only generating two images, and I find resource usage is at a minimum.

Installation

Firstly, grab the binary and store it in a easy but sensible location:

cd /opt
wget https://github.com/grafana/grafana-image-renderer/releases/download/v5.0.6/grafana-image-renderer-linux-amd64

Then make the file executable:

chmod +x grafana-image-renderer-linux-amd64

To have it run as a service, create a service file for it:

nano /etc/systemd/system/grafana-image-renderer.service

And populate the file with the following:

[Unit]
Description=Grafana Image Renderer service
After=network.target

[Service]
ExecStart=/opt/grafana-image-renderer-linux-amd64 server --
WorkingDirectory=/opt/
Restart=on-failure
User=root
Environment=GRAFANA_RENDERER_PLUGIN_STARTUP_TIMEOUT=30s 
[Install]
WantedBy=multi-user.target

Reload the service daemon, start the new service, and check it is running:

systemctl daemon-reload
systemctl start grafana-image-renderer.service
systemctl status grafana-image-renderer.service

You can check If the service is running by visiting the web page of the server on port 8081:

Authentication

A default Grafana server install requires login before being able to see any dashboards, this extends to the image renderer. As we can’t login to the web interface interactively within the service, a service account needs to be created.

In the main Grafana web interface, login and navigate to Home > Administration > Users and access > Service accounts, then click “Add service account”.

Give it a display name and set the role to viewer:

Now in the newly created service account, click “Add service token”, then on the popup dialog, click “Generate Token”.

A token with a “glsa_” prefix is displayed, make a copy of this as it will not be available to view after closing this dialog box:

This will be used as authentication when generating our dashboard images…

Generating Images

With the renderer installed, and authentication available, images can now be generated.

Images are generated by requesting a URL from the service with the dashboard within the variables, the syntax is:

http://{grafana-image-renderer}:8081/render?encoding=png&url=http://{grafana-dashboard}?{options}

Where:
Grafana-image-renderer – The IP of the machine the renderer is running on.
Grafana-dashboard – The URL of the dashboard you’d like to capture.
Options – Options to manipulate the output/how the dashboard is displayed.

However, the authentication header is needed to successfully access the dashboard. For this reason its easier to use a curl command to set the headers and grab the image

For example, if the renderer is running on the same machine as the main Grafana, a dashboard can be generated by executing:

curl -H "X-Auth-Token: {glsa_token}" "http://localhost:8081/render?encoding=png&url=http://localhost:3000/d/{id}/{dashboad}?kiosk&width=800&height=600" -o image.png

The options used here is kiosk; to remove the menus from the output, and height and width to match the intended displays.

Automation:

One minute updates are fine for this use case, so the easiest way automate this is via cron. Using crontab -e, add the following line:

/usr/bin/curl -H "X-Auth-Token: {glsa_token}" "http://localhost:8081/render?encoding=png&url=http://localhost:3000/d/{id}/{dashboard}?kiosk&width=800&height=600" -o /var/www/html/dash1.png

This line generates the dashboard every minute and stores it on the default web server directory, allowing it to be viewed on the network via an installed web server.

But this will only create a static image, to allow the image to update on a display, a simple webpage can be created and stored on the webserver for easier access and reference.

Create a new webpage:

nano /var/www/html/dashboard.html

And paste the following:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Grafana Dashboard</title>
  <style>
    body {
      margin: 0;
      background-color: black;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
  </style>
</head>
<body>
  <img id="liveImage" src="dash1.png" alt="Live Image">
  <script>
    const img = document.getElementById("liveImage");
    setInterval(() => {
      const timestamp = new Date().getTime(); // avoid browser cache
      img.src = "dash1.png?t=" + timestamp;
    }, 60000); // 60 seconds
  </script>
</body>
</html>

When visited, this webpage will update the same image (dash1.png) every 60 seconds to ensure the browser updates with the latest available image instead of caching.

Displays

Viewing this on the display is as simple as visiting the above webpage. As the html is served from the Grafana server and where the auto refresh is taken care of, as long as the display is able to load the page, all is taken care of at the Grafana server.

Summary

Since all that is required from a display is being able to load and render a static image, this allows the oldest and slowest machines to be able to display a Grafana dashboard, negating the need to keep the displays up to date with Grafana’s evolving browser support.

I wish I learnt of this sooner, as it gives more standardised control of the layout of a dashboard. The HyperPixel displays are quite high resolution for their size, and loading a dashboard natively often lead to frustrations with the layout of panels not matching that displyed on a laptop/desktop screen. Presumably due to scaling. Using the image render allows you to test and fix the layout before deploying to a screen, and with a higher panel density too.

Another benefit is that most processing is taken away from the Pi 3A’s, as it is now only responsible for displaying a simple webpage with a single image, rather than loading the full Grafana UI. The Pis have been running on this new method for over a month without any lockups, which was previously seen on a weekly basis.

]]>
Raspberry Pi Torrent Server – From Scratch https://james-batchelor.com/index.php/2016/06/28/raspberry-pi-torrent-server-from-scratch/ Tue, 28 Jun 2016 11:19:27 +0000 http://james-batchelor.com/?p=413 Continue reading "Raspberry Pi Torrent Server – From Scratch"]]> As requested, this is a guide to taking a Raspberry Pi and turning it into an always on Torrent box, complete and self-sufficient with its own mass storage meaning it needs no help from other computers. Also, as the Pi consumes such little power compared to a full desktop PC, money can be saved by using the Pi for overnight transfers while other computers can remain off.

piserver1

For this project I recommend a RPi 2, as its powerful enough to perform the transfers up to its maximum 100Mbps network speed, and is a cheaper choice since the RPi 3 superseded it last year. To get started, you need the following hardware:

  • Raspberry Pi 2 board.
  • Micro USB wall adaptor – Needs to be capable of 2Amp output.
  • Micro SD card – Minimum of 8GB, class 6 or above, plus SD adaptor for connecting to a PC.
  • USB Portable Hard drive – USB powered is preferred, I use a Toshiba Canvio Basics 1TB.
  • Ethernet Cable – And spare port on the modem/router for internet connection.
  • A PC – On the same network as the Pi for connection and configuring.

The Pi was designed to as low cost as possible to the user, so apart from the Pi board you may already have everything to run a Pi, and if not these are cheap and easily available online.

With a RPi 2 at hand, let’s get started…

Setup

Before powering on, an operating system is needed on the micro SD card.

Download the latest version of Debian onto a PC and extract the ISO from the Zip file, then download Win32Imager that will transfer the image to a SD card.

Run Win32Imager as an Administrator by right clicking the icon, Win32IMGAdminbrowse and choose the Debain ISO for the image, select the drive letter for the micro SD card, and click write. When complete, move the micro SD card to the Pi and its ready to boot for the first time.Win32Img

Connecting

To make the Pi less obtrusive in the home, it will be configured and run as a headless server, therefore no monitor or Human Interface Devices needed.

Follow this guide I created earlier to get connected and into a terminal window.

Housekeeping

Once connected it’s a fully functional computer, but it’s worth the extra effort to perform some housekeeping to make it easier to connect to by assigning it a static IP, and changing the password for that extra layer of security.

First the essentials, after a fresh install of Debian the filesystem has to be expanded so it can make full use of the micro SD card’s capacity:

In the terminal window, type raspberrypi-config. Then from the menu choose expand filesystem. Reboot the Pi and connect again, now the full capacity is useable.

raspberrypiconfig

Next, and optionally, change the default password:

From the terminal, type sudo passwd, then follow the prompts to change it. No need to reboot.

Next is to assign the Pi a static IP address, allowing it to be found at the same location on the network every time, handy as connecting to the torrent client requires knowing the Pi’s IP address:

From the terminal, type sudonano /etc/network/interfaces to bring up the network config file. In the text editor that opens, find the string beginning eth0, and edit it to look like the following:

staticIP

Where the gateway is the IP address of your router and the address will be the new home of the Pi, for those not familiar with IP addresses, copy the first three numbers from the routers IP address, and for the final number use a number between 150 and 253, this is usually high enough not to interfere with other devices on the network.

Use Ctrl + O to save the file, then Ctrl + X to exit.

Then type sudo reboot to restart the Pi, and now it can be found on the new chosen IP.

Connecting USB Hard Drive

By default the Pi does not supply enough power to the USB ports to power and mechanical drive, but with a little tweak of the settings it can deliver enough to fully power a USB hard drive.

In a terminal, type sudo nano /boot/config.txt

Scroll to the bottom of the file using the F8 key, then add the following new line:

Max_usb_current=1

config.txt

Use Ctrl + O to save the file, then Ctrl + X to exit.

Reboot the Pi by typing sudo reboot.

From a new terminal window, check the drive is connected by typing
sudo blkid, it will appear as dev/sda1

With it recognised, use sudo mkdir /media/HDD to create a folder that will be used as a gateway to the new drive.

Then mount the drive by typing
sudo mount –t auto /dev/sda1  /media/HDD

The Pi can now write to the USB drive for the duration the Pi is powered on, but for simplicity it needs to be available if the Pi reboots…

Configuring & Sharing USB Hard Drive

To allow the drive to automatically mount upon startup, type
sudo nano /etc/fstab to open the file system config file.

Add the following line under the existing entries:

/dev/sda1 /media/USBHDD1 auto noatime 0 0

fstab

Use Ctrl + O to save the file, then Ctrl + X to exit.

Next up is to install samba, it allows the Pi to communicate with windows computers on the network, allowing easy access to downloaded files.

Type sudo apt-get install samba

When installed, open the config file by typing sudo nano /etc/samba/smb.conf

Enter the following information at the bottom of the file:

[Media]
comment = Mass Storage Share
path = /media/HDD
browsable = yes
read only = no
force user = root

Ctrl + O to save the file, then Ctrl + X to exit, then reboot with sudo reboot. When restart completes the Pi can be accessed by typing \\raspberrypi in a folder address bar, or will show as a network device in Windows explorer.

WindowsPi

Installing Transmission

For torrent sharing, Transmission is used as a simple and quick program.

Update the Pi by using sudo apt-get update, followed by sudo apt-get upgrade. These may take a while to complete but ensures the latest software is running, including the latest version of Transmission.

Then type sudo apt-get install transmission-daemon and install the program, pressing Y when prompted.

Configuring Transmission

As you may have guessed, configuring anything in Linux means editing a text file, but first the Transmission service must be stopped to allow changes, by typing sudo server transmission-daemon stop.

Now open the settings by using
sudo nano /etc/transmission-daemon/settings.json

Here are all the settings, but for now scroll (F7&F8 keys) to locate rpc-whitelist, and edit it to include your local ip address range, like below:

torconfig

Then change download-dir and incomplete-dir to point to a folder on the USB hard drive, using /media/HDD/Complete and /media/HDD/Downloading respectively. Be sure to create a Complete and Downloading folder on the hard drive before setting these, this can be done in Windows explorer by navigating to \\raspberrypi .

Also for convenience the password can be switched off by changing
rpc-authentication-required from true to false.

As always, Ctrl + O to save the file, then Ctrl + X to exit.

Using Transmission

The great feature of Transmission is its own web server and that all control is done via a webpage, allowing the Pi to function headless and the torrents managed by any internet capable device.

On another PC, open your favourite browser and navigate to
http://PI-IP:9091 replacing PI-IP with the static address you chose earlier.

From here it’s a fully functional, low cost, low power torrent box. An easy test is to revisit the RPi foundation’s website and download Debian via torrent, then seed it help others discover the wonderful world of Pi.

TorTest

]]>