Sunday, October 2, 2016

Setting up a CUPS server with Docker on a Synology NAS for my Brother printer

My Brother Printer made for Windows


I made the unfortunate mistake of purchasing a cheap brother printer, the Brother HL-L2300D, which is USB only. And not only is it a USB printer, it is a Winprinter which makes it very limited in anything other than Windows. The laser printer is great for printing, but purchasing the cheapest feature-limited version was a bad decision. If I could go back in time, I would tell myself to purchase a Brother network printer and save myself the trouble and hassle trying to network share a USB printer. I encourage you to do the same. But if you are reading this page, you probably made the same mistake I did, so read on...


Since I have my Synology DS916+, which supports acting as a print server, I wanted to use that in order to share my printer across my networked devices. Unfortunately, Synology is very limited in what USB printer it supports. The Synology support list is very small with only a few Brother printers approved. Winprinters, or technically GDI printers, have little support outside of Windows. But wait a minute, Brother provides linux drivers, no? Why not just install that on the Synology NAS?

The Brother linux drivers are not easily installed on Synology due to the different platform and library requirements not available, although it is linux. The solution that remains is using those Brother linux drivers on a Docker container with an actual linux framework that is compatible with the drivers.

Preparing the Synology NAS


Easy Bootstrap Installer



The first thing I set up was the Easy Bootstrap Installer, which provides the ipkg structure for installing linux packages. The easiest way is adding the source https://www.cphub.net to your Package Source under the Package Center settings. Easy Bootstrap Installer should now be available to install from the Community package list.

Once I SSH into the machine, ipkg should be available from /opt/bin/ipkg

Install lsusb with ipkg


We need lsusb in order to determine the device address of the printer for Docker to access. A simple command ipkg install usbutils is all that is needed in order to install lsusb.

Docker Container docker-debian-cups


I found the Docker container docker-debian-cups to be a good starting point for this setup.


Docker Container Files


Brother Driver Installer


The Brother Driver Installer will be executed every time the Docker container is started, so it needs to be somewhere accessible. I downloaded the linux installer script linux-brprinter-installer-2.0.0-1 from the Brother website and placed it under /volume1/docker/cups which is the directory that will be mounted on the Docker container. This script is universal, which should work with any Brother printer.

Avahi Config Files for AirPrint


If you are not interested in AirPrint, you can skip this step. Since I have many Apple products in my home, I really wanted AirPrint set up and Avahi provides this service. In the directory /volume1/docker/cups I placed two files:


My Docker Startup Bash Script


I created a Bash script that I can execute every time I want to run the cups docker and have everything set up automatically. Let's break down the script:

#!/bin/sh

# Stop CUPSD if it is running
echo "Stopping cupsd on Synology..."
/usr/syno/sbin/synoservicecfg --hard-stop cupsd

# Get Printer location
echo "Getting printer info..."
BUS=$(/opt/sbin/lsusb|grep Brother|awk '{print $2}')
DEV=$(/opt/sbin/lsusb|grep Brother|awk '{print $4}')
DEV="${DEV%?}"
PRINTER="/dev/bus/usb/$BUS/$DEV"

# Stop Container
echo "Stopping current container..."
/usr/local/bin/docker kill cups-server
/usr/local/bin/docker rm cups-server

# Run Docker
echo "Running container..."
containerID=$(/usr/local/bin/docker run -d -p 631:631 -p 5353:5353 --name cups-server --net=host --device=$PRINTER -v /volume1/docker/cups/:/home/print -v /volume1/docker/cups/avahi-daemon.conf:/etc/avahi/avahi-daemon.conf -v /volume1/docker/cups/AirPrint-HLL2300D.service:/etc/avahi/services/AirPrint-HLL2300D.service olbat/docker-debian-cups)

# Run Setup script
echo "Executing container setup script..."
/usr/local/bin/docker exec $containerID /bin/sh -c "/home/print/setup.sh" &

echo "Done!"

exit 0

The first part is stopping the cups daemon that Synology includes as part of it's DSM system. The next part uses the lsusb program we installed earlier in order to grab the printer device address to pass to Docker. The third section stops any currently running cups Docker container that may already be running. The docker execution command grabs the container ID as it launches the container olbat/docker-debian-cups. Two ports are forwarded from the container, 631 which is used for cups and 5353 which is used for Avahi services. The device address from $PRINTER is passed on to the container. Other than the home directory link /volume2/docker/cups/ to /home/print, the rest map the Avahi config files that were mentioned previously.

If you are not needing Avahi, you can safely strip out those parts meant for Avahi setup.

Finally, the script /home/print/setup.sh is executed within the container which does the debian setup.

Container Setup Script


The setup script /home/print/setup.sh is ran from within the Docker Container to install the Brother drivers and also install/setup Avahi for Airprint.

#!/bin/sh

echo "Running apt-get update/upgrade..."
apt-get update

echo "Installing Brother install requirements..."
apt-get install lib32gcc1 libc6-i386 lib32stdc++6 -y

echo "Running Brother printer setup..."
printf 'y\nn\nn\n' | /home/print/linux-brprinter-installer-2.0.0-1 HL-L2300D

echo "Enabling printer sharing for CUPS..."
cupsctl --share-printers
cupsctl --remote-admin

echo "Installing Avahi..."
DEBIAN_FRONTEND=noninteractive apt-get install avahi-daemon -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"

echo "Starting Avahi..."
/etc/init.d/avahi-daemon start

We install some required libraries for the Brother drivers which do not come standard in the container. We then execute the Brother install script from the /home/print directory which is mounted to the Synology /volume1/docker/cups side. I set it to install the drivers for HL-L2300D. If you have a different printer, here is where you would place it's proper name. CUPS is then set to allow printer sharing and remote admin access. Finally, Avahi is installed and started for AirPrint.


Verification through CUPS page


Now if the initial script /volume1/docker/cups/cups_start.sh is executed, everything should successfully start. If you navigate to port 631 of your Synology NAS address, http://192.168.1.2:631, you should see the CUPS server page and the Printer section should have your printer set up and ready.


I can now successfully see and print from my Windows, macOS and Apple mobile devices to my Brother USB printer hooked up to my Synology NAS. One issue that this cheap Winprinter has is that eventually it stops responding overnight and will no longer print. So what I needed to do was have the Task Scheduler execute cups_start.sh every night in order to keep my printer working.

Hopefully using this guide you too can configure your Synology NAS to act as a CUPS print server.

1 comment:

  1. Works pretty well with Brother printer driver after contacting brother printer contact number. The only minor problem I have for the moment is that the margins are larger than announced.

    ReplyDelete