Note, that there is a newer version of this article available.
This is a “work in progress”, which I have tested for a few months. It workes fine, but there could be issues not yet found. Especially when installing or removing additional Python packages.
Recently, I got a second 3D printer and since OctoPrint works very nicely with the first one, I wanted the same for both of them. Officially OctoPrint doesn’t support using multiple printers at the same time. Still, it is possible to run multiple instances of the (Python-based) OctoPrint software using different directories and port numbers. The main goal is to keep them separated from each other.
There is a very detailed article from Thomas Messmer about running multiple OctoPrint instances on an OctoPi image/installation on a Raspberry Pi 4. Even if you don’t use a RasPi, I still recommend to check it out, since most changes are the same for a regular system! Here, I will only concentrate on the systemd part, since OctoPi doesn’t use it by default and therefore it isn’t explained in the article.
systemd unit file templates
systemd supports running multiple instances of the same software, by using so called Template Unit Files. These files only differ from regular unit files by using an instance parameter (
%i). The unit files using such a parameter, are named, for example,
octoprint@.service (Note the @ right before the file name extension!). Actual instances of these units need to use an unique identifier, like a name or a number. They are simply created by enabling a new service:
# systemctl enable --now email@example.com (This will create a systemd symlink for this service)
In this example, every
%i, inside the unit file, will be replaced by
OctoPrint unit template
The pattern I want to implement looks like this. Note, that the suffix for the directory and the last digit of the port number are the same:
- Instance #1 uses folder
.octoprint1and runs on port 5001
- Instance #2 uses folder
.octoprint2and runs on port 5002
- Instance #3 uses folder
.octoprint3and runs on port 5003
First the running “single” OctoPrint service should be stopped and removed, since it will get a new unit file:
# systemctl stop octoprint.service # systemctl disable octoprint.service
You may also remove the
octoprint.service file in
/etc/systemd/system (or rename and reuse it, see below).
To keep things simple, my basic idea was to use incrementing integer numbers as parameters and simply run these different instances, starting at port 5001 (or 5000 with 0 as the first number). To do this, it’s necessary to explicitly set a individual base dir path and a path to the individual configuration file (
config.yaml), as well as a unique port number for instance to bind to. This is the template file I came up with. The parameter
%i will be replaced by a individual number, when the service is created/started:
[Unit] Description=OctoPrint (Instance #%i) - Open Source Printing Interface for 3D Printers Documentation=https://docs.octoprint.org After=network.target [Service] User=octoprint Environment=HOME=/home/octoprint WorkingDirectory=/home/octoprint/.octoprint%i ExecStart=/usr/bin/python2 /home/octoprint/.local/bin/octoprint --basedir /home/octoprint/.octoprint%i --config /home/octoprint/.octoprint%i/config.yaml --port 500%i serve Restart=always RestartSec=120 [Install] WantedBy=multi-user.target
For this to work, I renamed the existing
.octoprint configuration directory in
.octoprint1 and then made a copy of the same folder for a second instance called
# cd /home/octoprint # mv .octoprint .octoprint1 # cp -R .octoprint1 .octoprint2 [...] # chown -R octoprint:octoprint .octoprint*
For more than two instances, I would simply create more copies of this directory and enable more services (see below) using the same number suffix.
After that, the actual instances can be created/enabled and started:
# systemctl enable --now firstname.lastname@example.org (This will create a link and start the service.) # systemctl enable --now email@example.com (The same thing for the second instance.) # systemctl status firstname.lastname@example.org (Optional. Will show some information about the service #1)
If everything else is setup correctly, the multiple OctoPrint services should be available at ports 5001 and 5002. You should login and change the printer configuration, name and default serial port and maybe also select a individual theme color for the GUI, to keep them apart more easily.
If the service is allowed to restart itself, the command entered in the OctoPrint configuration menu needs to be changed and the sudoers file needs to be updated accordingly:
octoprint ALL = NOPASSWD: /bin/systemctl start octoprint@[0-9].service octoprint ALL = NOPASSWD: /bin/systemctl stop octoprint@[0-9].service octoprint ALL = NOPASSWD: /bin/systemctl restart octoprint@[0-9].service [...]
This will allow the user
octoprint to start, restart and stop up to ten instances of OctoPrint (nine, if you don’t count the zero).
For now, this setup works fine for me. One minor issue I found, is, that all instances share the same Python installation and libraries. So if a Plug-In is installed or updated, the other won’t know about this and will (re)install the same package(s) again. I also don’t know yet what happens if OctoPrint itself gets updated.