Skip to "Tutorial"
Skip to Script

So a wee while ago I use to run my Octoprint instances all from multiple Raspberry Pi 3 which worked great for a very long time, but also had its drawbacks which the main one for me was the wires… lots of wires… I’ll do a write up regarding my hatred for Wi-Fi at some point in the future but for now… let’s just repeat I DON’T LIKE IT!

So for a single Pi, we need the power and ethernet cables both running to it, then the USB connection to the printer and to top it off a long ribbon cable for the camera if you want to watch your prints, or time-lapse them. Multiply that over 4 printers as I had at the time it gets very messy, especially with my cable management “skills”. I also realised that the interface isn’t that snappy, but I didn’t realise this until experiencing it running on an intel i3 but my gosh! No more hangs, slowdowns, waiting for menus to realise I’d clicked something, just overall a more pleasant experience.

After doing this for around a year I decided to completely re-haul my setup for my printer Farm, which also bred ideas for more projects which I’ll get to writing up. I promise! I had laying around an old motherboard after upgrading my PC and server that had an i3 CPU, 6GB of ram and a spare 1TB HDD which were perfect to put a headless ubuntu server installation on. You could use pretty much any hardware you want here, so long as it’s got USB port, so an intel NUC might do very nicely, play around and tell me in the comments what you're running your setup on. It’s good to hear what other people manage to run all this on, and heck… this isn’t to say you couldn’t run all of this from an RPi, the new 4s have just been released and look very impressive for their size. My main goal here was DIY, and keep cheap and stubborn, so no purchasing of any unnecessary hardware. Since I’ve seen people running 3 printers from a single Pi I think pretty much any old hardware will do.

My i3 server, "skillfully" mounted under my printing table with some 3d printed parts. Saved money on buying a case, and also kept my shelving relatively free. 

Tutorial

Note: As mentioned in the title and comments above, this is for Ubuntu server 18.04. I've tested it on the lasted update as of 05/08/2019, so whatever update applied when I ran the usual update commands. Octoprint is run in Python, so this very well may run on other systems. Heck I've seen people set this up on old Android mobile phones so it's certainly possible it however won't be detailed in here.

System Preperation

We've got to prepare our system with the needed dependancies for Octoprint so run the following commands below logged in as the user you would like to run Octoprint as. I created a user called "octoprint" just to keep things simple but it will run under any standard non-root linux user. You can run it as root, but will require modifications to the commands and the init/default scripts.

sudo apt update && sudo apt install git python-pip python-dev python-setuptools python-virtualenv git libyaml-dev build-essential -y

We need to make sure our user has permissions to to tty and dialout linux user groups so that it may freely access the USB devices and default system links in dev which will be controlling our printers.

Note: Replace {octoprint} in the following commands with your linux user.

sudo usermod -a -G tty {octoprint}
sudo usermod -a -G dialout {octoprint}

Octoprint Initial Installation

Next we will create our installation directory where we will place all of the Octoprint files. I placed mine in the users home directory to keep any permission issues to a minimum. If your running this as I suggest as the linux user your running Octoprint under, then there is no need for any "chmod" or "chown" commands. We will also cd into this newly created directory.

mkdir /home/{octoprint}/OctoFarm
cd /home/{octoprint}/OctoFarm

Grab the latest Octoprint release from linux with the following command:

git clone https://github.com/foosel/OctoPrint.git

Once this has downloaded we can cd into the OctoPrint folder and setup the virtual enviroment to run out Octoprint instance from.

cd OctoPrint/
virtualenv venv

Next we need to make sure python pip is up to date, and also run the initial setup.py for Octoprint.

./venv/bin/pip install pip --upgrade
./venv/bin/python setup.py install

Once these are done, your initial Octoprint instance is all installed and setup, but nothing will be running yet. On the Octoprint github, there are two scripts to create a system command to be able to run Octoprint from "sudo service" just like any other systemctl command. Just place them in the OctoFarm folder for now, we can edit them at our leasure and move them into the correct place for linux to enable them later.

wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.init -P /home/octoprint/OctoFarm
wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.default -P /home/octoprint/OctoFarm

Setup of System Scripts and Multiple Instance Directories

Note: You need to repeat these steps for as many instances you would like running on your system. Each command can be run multiple times changing the indicated part, or just run through this section start to finish for each instance you want to spin up.

  1. Make each instances octoprint folder, this will store plugin settings and anything related to each specific instance like printer information. Remeber or note down these location prepared here, we will need them to prepare the init, and default scripts for systemctl. Anything looking like {*} you can replace with whatever you want to help indicate you to which specific instance you are working on. I just started at "1" and worked my way up but you may call it your printer name, whatever you want really.  
cd /home/octoprint/OctoFarm/
mkdir .octoprint-{*}

2. Edit the previously downloaded scripts to point to the specific instance. Check for anything in "{}" as those are what you will need to change. Do not include the brackets.

I'm a nano guy, but you can use your favorite editor here. I won't be detailing editor commands so please use your Google-fu to find out how to save.

nano /home/octoprint/OctoFarm/octoprint.init
Edit the init script as depicted below, and make sure to save it the same as your package name.
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="OctoPrint Daemon-{*}"
NAME="OctoPrint-{*}"
PKGNAME=octoprint-{*}
PIDFILE=/var/run/$PKGNAME.pid
SCRIPTNAME=/etc/init.d/$PKGNAME
DEFAULTS=/etc/default/$PKGNAME
This is the only part of the script you will need to change, just make sure to save it as octoprint-{*}.init
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="OctoPrint Daemon-1"
NAME="OctoPrint-1"
PKGNAME=octoprint-1
PIDFILE=/var/run/$PKGNAME.pid
SCRIPTNAME=/etc/init.d/$PKGNAME
DEFAULTS=/etc/default/$PKGNAME
Example of my init script for the initial instance. This was saved the same as the package name so "octoprint-1.init"
nano /home/octoprint/OctoFarm/octoprint.default
Edit the default script as depicted below. Again, make sure to save it the same as your package name above. 

The below script will use the octoprint user in my example, detailed as {octoprint}. Please enter your user you started the tutorial with, and do not include the brackets. You will also need whatever instance designation you appended to the .octoprint folder above. So {*}, please amend the same as above.

Note: If your running as I am, with a seperate Octoprint user, then make sure to change the UMASK to "000".

Configuration for /etc/init.d/octoprint

# The init.d script will only run if this variable non-empty.
OCTOPRINT_USER={octoprint}

# base directory to use
#BASEDIR=/home/{octoprint}/OctoFarm/.octoprint-{*}

# configuration file to use
#CONFIGFILE=/home/{octoprint}/OctoFarm/.octoprint-{*}/config.yaml

# On what port to run daemon, default is 5000
PORT={Change to a custom port}

# Path to the OctoPrint executable, you need to set this to match your installation!
#DAEMON=/home/{octoprint}/OctoFarm/OctoPrint/venv/bin/octoprint

# What arguments to pass to octoprint, usually no need to touch this
DAEMON_ARGS="--port=$PORT"

# Umask of files octoprint generates, Change this to 000 if running octoprint as its own, separate user
UMASK=022

# Process priority, 0 here will result in a priority 20 process.
# -2 ensures Octoprint has a slight priority over user processes.
NICELEVEL=-2

# Should we run at startup?
START=yes
The entire script, only change what's necessary 
# Configuration for /etc/init.d/octoprint

# The init.d script will only run if this variable non-empty.
OCTOPRINT_USER=octoprint

# base directory to use
BASEDIR=/home/octoprint/OctoFarm/.octoprint-1

# configuration file to use
#CONFIGFILE=/home/pi/.octoprint/config.yaml

# On what port to run daemon, default is 5000
PORT=5001

# Path to the OctoPrint executable, you need to set this to match your installation!
DAEMON=/home/octoprint/OctoFarm/OctoPrint/venv/bin/octoprint

# What arguments to pass to octoprint, usually no need to touch this
DAEMON_ARGS="--port=$PORT"

# Umask of files octoprint generates, Change this to 000 if running octoprint as its own, separate user
UMASK=000

# Process priority, 0 here will result in a priority 20 process.
# -2 ensures Octoprint has a slight priority over user processes.
NICELEVEL=-2

# Should we run at startup?
START=yes
Example of my initial default script. This was saved as stated in package name above. So "octoprint-1.default" 

3. Move the scripts into the corrosponding systemctl folders, and initialise them. Again, just make sure to replace the {*} with whatever you called your instance name.

sudo mv octoprint.init /etc/init.d/octoprint-{*}
sudo mv octoprint.default /etc/default/octoprint-{*}
sudo chmod +x /etc/init.d/octoprint-{*}
sudo systemctl daemon-reload
sudo update-rc.d octoprint-{*} defaults
sudo service octoprint-{*} start

After starting you should be able to access your newly created instance from the Port you specified in the .init file. Don't run through the Wizard just yet though, please read the "Further System Setup" section below that is under the scripted version.

If you can't, run the following command to begin your trouble shooting steps. It will show you a few more details than the standard "sudo service octoprint-{*} status" command.

sudo journalctl -u octoprint-{*}

If you need help with anything, post it in the comments below with the output of the above command, or which step your stuck on.

Scripted version

I have created a very basic script that will run through this entire setup for you. You only need to specify the username and how many instances you would like spun up. This has been tested to work with 100+ instances flawlessly and due to been able to repeat the use of the base Octoprint code with custom config folders you only have to do the lengthy download of Octoprint once! You can find the script at the link below:

https://git.notexpectedyet.com/NotExpectedYet/Octoprint-Scripts

I may expand the script further if I get time, to setup printer names and such but for now you will need to follow the rest of the tutorial.

Note: The script for some reason manages to grab your external IP when displaying the running services. Don't worry, this hasn't opened anything to the outside world, just make sure to access using your local IP.

Further System Setup and Octoprint setup.

There is a little more setup for this to run the same as it would on a RaspberryPi installation.

To enable the Octoprint menu options for shutdown, restart of server and service then we will need to edit the sudoers file to allow passwordless useage for the user you are running octoprint as.

Note: This probably isn't the most secure way to run this, and why I recommend running the service as it's own user. If anyone knows of a better way for linux then I am all ears.

sudo visudo

Replace {octoprint} with your user, without the brackets and save.

{octoprint} ALL=(ALL) NOPASSWD:ALL

You may need to reboot your system to enable this, or at the very least log out and back in as the user.

Next run through the setup as usual, and you are good to go. Below is a screen shot of the system commands you will need to input to activate the menu options within Octoprint.

Make sure to replace the {*} with your instance name. If you used my script this will be "1" for your first instance and incrementing by 1 for the rest.

With this setup, I should probably mention how plugins work. The installation of the plugins happen in the default Octoprint envoroment, so /home/octoprint/OctoFarm/Octoprint folder if following along with the above tutorial. This means, once installed on one of your instances, you can just restart the next octoprint instance and it will get access to the plugins. The plugins settings are saved in the .octoprint-{*}/ folder allowing each to contain it's own settings. Quite handy!

That's it, I hope you've enjoyed yet another "tutorial" and updates/ideas are totally welcome to this process. It's a long one and can totally be daunting for any linux noob.