Setting up OctoPrint on a computer running Fedora, CentOS, AlmaLinux or RockyLinux

Step by step guide to installing OctoPrint on RHEL-like distributions

Disclaimer

:warning: WARNING
The instruction provided in this guide are provided as is. They were performed on VMs or real computers so they should work on newly installed computer. If your computer already runs one of the target distributions, your mileage may vary, although, you're most likely to run into already installed packages than anything else.
Also, the guide is valid at the time of writing (September 14th, 2021). Revisions and corrections may be carried out as long as I can afford to, but it may become obsolete. Regarding Fedora, release cycle is 6-month long, so if the last modified date is more than a year ago, you may run into commands that won't work as intended. CentOS based distributions follow a longer release cycle and the instructions should be valid until the EOL date of the release.

Contents

  1. Target distributions and versions
  2. What's covered in the guide, and what's not
  3. Thanks and contributors
  4. Installing required packages and activating SSH
  5. Setting up the OctoPrint instance
  6. Optional: Setting up webcam stream
    6.a. Using mjpg-streamer
    6.b. Using µstreamer
    6.c. Adjusting firewall rules and streaming test
  7. Optional: Using a reverse proxy to make OctoPrint available on port 80 (default HTTP port)
    7.a. Preparing the OctoPrint configuration and adjusting firewall rules
    7.b. Using HAProxy
    7.c. Using Apache HTTPd and mod_proxy
  8. Create the relevant service files and make services start on boot
    8.a. Octoprint service
    8.b. Optional: Webcam streaming service
    8.c. Optional: Reverse Proxy
  9. OctoPrint first run wizard configuration
  10. Changelog

1. Target distributions and versions

At the time of writing, this guide is intended and works for the following distributions and versions :

Fedora

Workstation and Server edition: version 34
Where to get it: https://getfedora.org

CentOS Linux and CentOS Stream

Linux: version 8.x
Stream: version 8
Where to get it: https://www.centos.org/

AlmaLinux

Version: 8.x
Where to get it: https://almalinux.org/

RockyLinux

Version: 8.x
Where to get it: https://rockylinux.org/

The instruction provided in this guide should work on other distributions based on RHEL (Red Hat Enterprise Linux) or CentOS, but have not been tested, so again, your mileage may vary... Please bear in mind that setting up a VM and testing (and sometimes adapting) the commands and steps carried out in this guide is time-consuming, that's why it's limited to the distributions stated above.

2. How to read this guide? What's covered in the guide, and what's not?

How to read this guide?

Formatting info:

  • Blockquotes denotes text that is important to read. These may seem long, but there are some crucial information in those texts, please read them.

  • Commands that you need to run will appear in code blocks such as these, one command per line:
    cd /opt/octoprint
    mv source destination
    systemctl restart octoprint.service
    
  • Unless otherwise specified the commands apply for all the distributions and versions listed here. If any distribution or version needs a specific command, it will appear this way:
    Fedora 34
    command specific to Fedora 34
    
    Other distributions and versions
    common command
    
  • File contents will also be shown in code blocks, with the filename between brackets ([]), as shown below:
    [filename]
    File contents go here
    
    and may spread
    
    many lines
    
  • If a specific version or distributions needs specific file contents, those will be shown the same way specific commands are.

Assumptions made during the guide:

  • Commands throughout this guide will make heavy use of sudo as configuration files are usually not editable by an unprivileged user. Make sure the user you use to run these commands can use sudo, by making sure that the user belongs to the wheel group.

  • OctoPrint will be installed to the /opt/octoprint directory. Should you wish to install it to another directory, replace with the full path in command where it appears. There should be enough space to store your data in this directory. Ideally the directory should be a mount point for a separate partition on the hard drive, so that OctoPrint's data does not clutter the system, and so that you may easily monitor space taken up by its files.

  • Any <IP-ADDRESS> placeholder occurring in commands or file contents should be replaced with the computer's IP address. You can determine this address by running the following command

    ip a s
    
  • An unprivileged user will be created, using the username octoprint. If a user already has that username, either choose another username such as octoserver and adapt the commands user throughout this guide, or make sure that the already existing user belongs only to the octoprint, tty, dialout and video groups, has its shell set to /sbin/nologin, and its home directory set to /opt/octoprint.

  • Any <WEBCAM-ID> placeholder occurring in commands or file contents should be replaced with the appropriate webcam ID. How to find this ID will be covered in Optional: Setting up webcam streaming.

What does this guide covers and what it doesn't:

:warning: WARNING: Read carefully
This guide supposes that you already have a working installation of any of the distribution listed in the Target distributions and versions section. This guide won't explain how to install those distributions on any computer. There are far better written guides on the Internet that already serve that purpose. This guide also expects you to have more than a basic understanding of how to run commands in a Linux, and mostly a Command Line Interface environment, especially, you need to know how to edit files, even privileged ones. This guide also expects you to have a priviledged user on the system, a user (whose username is not octoprint) that is able to run the sudo command. Alternatively, you may use the root account to carry out commands, although this is not recommended.

This guide will cover the installation of an OctoPrint instance, starting at the mot basic installation possible. This guide will not cover the installation of any other plugin or software than described in the Contents. Some steps are completely optional and not completing these steps will not put you in a state where the OctoPrint instance is not reachable. The steps are supposed to be followed in the order they are written in this guide. Failing to complete a step may alter how the following step should be carried out, so please follow the steps in their intended order. Obviously, steps that are advertised as Advanced require a more thorough understanding of how a Linux, and more particularly RHEL-like Linux environment works. Do not attempt to follow them if you don't feel up to it. You'll have a working OctoPrint instance even if you do not complete these steps.

This guide won't explain in details what the commands are doing, other than the explanations given. This is why you are expected to have a basic understanding of Linux and also RHEL. This guide assumes that you know how to connect to the computer through SSH (i.e. using PuTTY in Windows)

:question: GUI or not GUI?
This guide will work whether you would like to install a Graphical User Interface (ie GNOME desktop, KDE, LXDE...) or not. All the instructions and commands given in this guide can be run over SSH. As a matter of fact, this guide is even intended to work on headless systems, meaning without screen, keyboard and mouse. Should you want to use graphical equivalents to the commands given, this guide assumes that you now which utilities to substitute for each command. I will not tell you which graphical software may accomplish what each command does. That is entirely up to you, since there are a lot of desktop environments, each with its specific utilities to carry out specific tasks, and I can only know so much...

:question: What to do if you have any questions ?
Should you have any questions concerning the contents of the guide, you may ask them below, I'll try to answer it to the best of my knowledge. Other users may also answer the question. Please keep the questions to the subject. I will not answer questions regarding any other distributions and versions than those listed here. Other users having knowledge about the distribution you're using may answer your question. Please also refer to the specific section of this guide your question is about, that will help us better answer your question. Also, should you encounter an error running a specific command in the guide, please indicate, in addition to the section, the command you're trying to run, and also the error that was encountered. This will also help us solve your problem more quickly.

:lock: Concerns about security
This guide expects you to have a secured LAN to which the computer connects. Should some ports be opened in the firewall (:warning: SPOILER ALERT: at least one port will need to be opened), this guide will tell you how to do so. These systems follow the principle of the least opened port. After installation, only ports relevant to SSH access, DNS queries, DHCP queries, and possibly remote control interface are opened. I will only add to the list ports necessary to the use of the OctoPrint instance. As is already stated in multiple posts: YOU SHOULD NOT UNDER ANY CIRCUMSTANCE MAKE YOUR OCTOPRINT INSTANCE OPEN ON THE INTERNET (I.E. THROUGH NAT, VIRTUAL IP, ETC.). It will get hacked one way or another. Consequences may include, but not limited to: someone remotely starting a print, canceling a print, controlling your 3D printer, including heaters (thus creating a fire hazard), using the computer as part of a botnet, using the computer as a backdoor to your network... There are already numerous guides and posts relating to remotely accessing your OctoPrint instance. Please follow their instructions. Should you have any questions about those instructions, please post questions in the relevant threads. This guide also follows the principle of least privileges, it will create and use a specific user whose permissions are tailored to the needs of this guide. This guide also assumes that SELinux is enabled in enforcing mode. You DO NOT NEED to set it to permissive mode or deactivate it to run OctoPrint, and you shouldn't.

3. Thanks and contributors

This guide is heavily adapted from the guide named Setting up OctoPrint on a Raspberry Pi running Raspbian or Raspberry Pi OS by @foosel.

Contributors to this guide:

:question: How to contribute to this guide ?
Should you want to add instructions about setting up Octoprint on another distribution not listed here, feel free to write the needed instruction while following the steps in this guide. Should you want to add instructions for other software that can be part of this guide, please also make sure that the software is available for the target distributions and versions, or provide instruction to compile them as a last resort. Please also test those software on all the target distributions and versions. You can then send those instruction in a PM mentioning the title of this guide, and I'll include them, and list you here as a contributor. Please bear in mind that you would be responsible for answering questions pertaining to the section you've written.

4. Installing required packages and activating SSH

Making sure the system is up to date

Before installing any packages, or proceeding any further, you should update the system using the following command:

sudo dnf --refresh upgrade

And then reboot the system, in case a kernel update took place:

systemctl reboot

Activating SSH

Only the Fedora Workstation Edition doesn't enable SSH access right after the installation process. To enable SSH access, you need to run the following command:

Fedora Workstation Edition
systemctl enable --now sshd.service

Install required packages

sudo dnf install python3-{pip,devel,setuptools,wheel}

Create the octoprint user and home directory

The following command will create the octoprint user with the needed groups and security restrictions:

sudo useradd -d /opt/octoprint -G tty,dialout,video -M -r -s /sbin/nologin -U octoprint

Then the following commands will create the /opt/octoprint directory and assign it the right owner and permissions:

sudo mkdir /opt/octoprint
sudo chown octoprint:octoprint /opt/octoprint

5. Setting up the OctoPrint instance

Python3 virtual environment setup

The following commands will set up a Python virtual environment in the /opt/octoprint directory:

cd /opt/octoprint
sudo -u octoprint python3 -m venv .
sudo -u octoprint bin/pip --no-cache-dir install --upgrade pip

OctoPrint installation

The followin command will install OctoPrint inside the virtual environment:

sudo -u octoprint bin/pip --no-cache-dir install octoprint

At this moment, the OctoPrint instance will only reachable from the computer it's installed on due to firewall configuration. In order to be able to access it from your network, we'll need to tell the firewall to open port 5000. To do so, a new service will be defined inside the firewall, using the following commands:

sudo firewall-cmd --permanent --new-service=octoprint
sudo firewall-cmd --permanent --service=octoprint --add-port=5000/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --permanent --add-service=octoprint
sudo firewall-cmd --add-service=octoprint

Verify OctoPrint starts

The following command will start the OctoPrint instance:

sudo -u octoprint bin/octoprint serve

You should then see something along those lines showing up on the terminal:

[user@localhost octoprint]$ sudo -u octoprint bin/octoprint serve
2021-09-13 17:39:17,979 - octoprint.startup - INFO - ***************************
2021-09-13 17:39:17,980 - octoprint.startup - INFO - Starting OctoPrint 1.6.1
2021-09-13 17:39:17,980 - octoprint.startup - INFO - ***************************

You can try to access the OctoPrint instance by opening a browser and going to http://<IP-ADDRESS>:5000/ and you should be greeted with OctoPrint's UI and first run wizard. As for now, you should not complete the First Run Wizard, as the configuration is not complete. You can hit ctrl + c to exit the process. Should you want to set up a webcam or a reverse proxy, proceed to the relevant sections. Otherwise please proceed to the 8. Create the relevant service files and make services start on boot section.

6. Optional: Setting up webcam stream

Should you like to monitor your prints, you can plug in a USB webcam. Whichever software you wish to install to stream the camera feed, you'll need to install additional packages using the following commands:

Fedora
sudo dnf install make gcc gcc-c++ git libjpeg-turbo-devel v4l-utils
Other distributions and versions
sudo dnf install make gcc gcc-c++ git libjpeg-turbo-devel

Should you like to create timelapses from your webcam, you'll need FFmpeg. Although it is not in the official repositories for licensing reasons, the RPMFusion repositories do have them. We'll need to enable them on your system, using the following commands:

Fedora
34
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install ffmpeg
Other distributions and versions
sudo dnf install --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm
sudo dnf config-manager --enable powertools
sudo dnf install ffmpeg

We'll also need to find out the ID of your webcam. In order to do this, you need to inspect the output of the following command, after the camera was plugged in:

ls /dev/v4l/by-id

For example, on the computer I have OctoPrint set up, and two webcams are plugged, I see the following output:

[silver@octoprint octoprint]$ ls /dev/v4l/by-id
usb-GENERAL_GENERAL_WEBCAM_JH0809_20201204_v002-video-index0  usb-Microsoft_Microsoft®_LifeCam_HD-5000-video-index0
usb-GENERAL_GENERAL_WEBCAM_JH0809_20201204_v002-video-index1  usb-Microsoft_Microsoft®_LifeCam_HD-5000-video-index1

Each webcam offers two peripherals to the OS, and from experience, the index0 peripheral give the actual video. The MS camera is the one pointing to the 3D printer, so the ID for this webcam is usb-Microsoft_Microsoft®_LifeCam_HD-5000-video-index0. I would need to replace <WEBCAM-ID> by usb-Microsoft_Microsoft®_LifeCam_HD-5000-video-index0.

Now is the time to choose between the two software offering streaming capabilities. You need to complete either step 6.a. or step 6.b., not both, or you'll end up with a non-functional stream.

6.a. Using mjpg-streamer

Since there are no packages in the official repositories, we need to compile this from source. To do so, we need to actually download the sources using git. The following commands will install additional required packages, download the sources, compile them, and place the resulting binaries in a specific place known by the OS.

sudo dnf install ImageMagick cmake
cd ~
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental/
make
sudo make install

If all the commands ran successfully, you can now proceed to 6.c. Adjusting firewall rules and streaming test.

6.b. Using µstreamer

Since there are no packages in the official repositories, we need to compile this from source. To do so, we need to actually download the sources using git. The following commands will install additional required packages, download the sources, compile them, and place the resulting binaries in a specific place known by the OS.

sudo dnf install libevent-devel libbsd-devel
cd ~
git clone https://github.com/pikvm/ustreamer.git
cd ustreamer
make
sudo make install

If all the commands ran successfully, you can now proceed to 6.c. Adjusting firewall rules and streaming test.

6.c. Adjusting firewall rules and streaming test

Adusting the firewall rules

For now, the webcam stream would only be accessible from the computer running OctoPrint. To make accessible to the whole network we need to open an additional port in the firewall. Should you want to proceed to the Optional: Using a reverse proxy to make OctoPrint available on port 80 (default HTTP port) step afterwards, following these instructions is not needed, and you should directly proceed to the streaming test section. Otherwise, please run the following commands to open the port needed for webcam streaming

sudo firewall-cmd --permanent --service=octoprint --add-port=8080/tcp
sudo firewall-cmd --reload

Testing the webcam stream

Depending on whether you installed mjpg-streamer or µstreamer, please follow the appropriate instructions below

mjpg-streamer

You need to run the following command to start the streaming process:

sudo -u octoprint /usr/local/bin/mjpg_streamer -i 'input_uvc.so -d /dev/v4l/by-id/<WEBCAM-ID>' -o 'output_http.so -p 8080 -l 0.0.0.0 -n'

The program should output lines to the terminal similar to this:

[silver@octoprint mjpg-streamer-experimental]$ sudo -u octoprint /usr/local/bin/mjpg_streamer -i 'input_uvc.so -d /dev/v4l/by-id/<WEBCAM-ID>' -o 'output_http.so -p 8080 -l 0.0.0.0 -n'
MJPG Streamer Version: git rev: 310b29f4a94c46652b20c4b7b6e5cf24e532af39
 i: Using V4L2 device.: /dev/video0
 i: Desired Resolution: 1280 x 720
 i: Frames Per Second.: -1
 i: Format............: JPEG
 i: TV-Norm...........: DEFAULT
UVCIOC_CTRL_ADD - Error at Pan (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Tilt (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Pan Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Focus (absolute): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Tilt (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Focus (absolute): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at LED1 Mode: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at LED1 Frequency: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Disable video processing: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Raw bits per pixel: Inappropriate ioctl for device (25)
 o: www-folder-path......: disabled
 o: HTTP TCP port........: 8080
 o: HTTP Listen Address..: 0.0.0.0
 o: username:password....: disabled
 o: commands.............: disabled

The UVCIOC_CTRL_ADD - Error at lines do not indicate that the streaming process didn't start, but rather that the camera doesn't support setting the specified control. Should mjpg-streamer fail to start, you shouldn't see the lines starting with o: . Otherwise you should consider your test to be successfull. You can now hit ctrl+c to exit the mjpg-streamer software.

µstreamer

You need to run the following command to start the streaming process

sudo -u octoprint /usr/local/bin/ustreamer -d /dev/v4l/by-id/<WEBCAM-ID> -m MJPEG -s 0.0.0.0 -p 8080 

µstreamer should then output something similar to the terminal:

[silver@octoprint ustreamer]$ sudo -u octoprint /usr/local/bin/ustreamer -d /dev/v4l/by-id/<WEBCAM-ID> -m MJPEG -s 0.0.0.0 -p 8080
-- INFO  [2000164.132      main] -- Using internal blank placeholder
-- INFO  [2000164.133      main] -- Listening HTTP on [0.0.0.0]:8080
-- INFO  [2000164.133    stream] -- Using V4L2 device: /dev/v4l/by-id/<WEBCAM-ID>
-- INFO  [2000164.133    stream] -- Using desired FPS: 0
-- INFO  [2000164.133      http] -- Starting HTTP eventloop ...
==============================================================================================================================================================
-- INFO  [2000164.230    stream] -- Device fd=8 opened
-- INFO  [2000164.230    stream] -- Using input channel: 0
-- INFO  [2000164.235    stream] -- Using resolution: 640x480
-- INFO  [2000164.235    stream] -- Using pixelformat: MJPEG
-- INFO  [2000164.240    stream] -- Using HW FPS: 0 -> 30 (coerced)
-- ERROR [2000164.240    stream] -- Device does not support setting of HW encoding quality parameters
-- INFO  [2000164.240    stream] -- Using IO method: MMAP
-- INFO  [2000164.241    stream] -- Requested 5 device buffers, got 5
-- INFO  [2000164.477    stream] -- Capturing started
-- INFO  [2000164.477    stream] -- Switching to HW encoder: the input is (M)JPEG ...
-- INFO  [2000164.477    stream] -- Using JPEG quality: encoder default
-- INFO  [2000164.477    stream] -- Creating pool JPEG with 1 workers ...
-- INFO  [2000164.477    stream] -- Capturing ...

The ERROR line refers to problems with the webcam, but those do not prevent camera streaming. The important line is the last one which ends in Capturing ...

2 Likes

7. Optional: Using a reverse proxy to make OctoPrint available on port 80 (default HTTP port)

This step will allow you to make OctoPrint available on port 80, which is the default HTTP port, so that you won't have to specifiy the port at the end of the URL (i.e. you'll be able to access OctoPrint with this http://<IP-ADDRESS>/ instead of http://<IP-ADDRESS>:5000/). If you also set up a webcam, the stream will also be available on port 80, thus you won't need to add :8080 in the stream URLs.

There are multiple software that can serve as reverse proxies, although we'll focus on two: HAProxy and Apache HTTPd with mod_proxy. HAProxy is a load balancer and reverse proxy, and it's pretty lightweight as compared to HTTPd. You should use this if you don't want to serve any other web applications, or if those web applications come with their own http server (like OctoPrint). On the other hand, if you need a full-fledged webserver, you might want to turn to HTTPd, which is a battle-tested webserver.

7.a. Preparing the OctoPrint configuration and adjusting firewall rules

We need to adust some of the settings so that OctoPrint will only listen on the localhost, and not on all the IP addresses of the computer. We'll also adjust some of the Discovery plugin settings so that mDNS broadcasts are aligned with the actual setup. You'll need to edit the /opt/octoprint/.octoprint/config.yaml file as the octoprint user (so using sudo -u octoprint). The file will already have some generated content that you SHOULD NOT modify. You should only add some parts under the discovery key and the server key. :warning: This is a YAML file, you should use two spaces when adding a level of identation, not tabs! The file should then look like:

[/opt/octoprint/.octoprint/config.yaml]
api:
  key: <something_already_here>
plugins:
  announcements:
    _config_version: 1
  discovery:
    upnpUuid: <something_already_here>
    publicPort: 80
    useSsl: false
  errortracking:
    unique_id: <something_already_here>
  gcodeviewer:
    _config_version: 1
  softwareupdate:
    _config_version: 9
  tracking:
    unique_id: <something_already_here>
  virtual_printer:
    _config_version: 1
printerProfiles:
  default: _default
server:
  secretKey: <something_already_here>
  host: 127.0.0.1

Also, there is no need to keep the port 5000 (and possibly 8080 if you set up a webcam) open as the reverse proxy will handle those connections. We can then run the following commands to close those ports on the firewall:

sudo firewall-cmd --remove-service=octoprint
sudo firewall-cmd --permanent --remove-service=octoprint

We'll also need to open the http port, as it's not open by default:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --add-service=http

7.b. Using HAProxy

First of all, we need to install the HAProxy package by issuing the following command:

sudo dnf install haproxy

The package will also install a basic configuration file, that we'll backup so that you can come back to it should you need it:

sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

Then you'll need to create a new /etc/haproxy/haproxy.cfg file with the following contents:

Fedora
34
No webcam streaming set up
[/etc/haproxy/haproxy.cfg]
global
        chroot /var/lib/haproxy
        pidfile /var/lib/haproxy.pid
        maxconn 4000
        user haproxy
        group haproxy
        daemon
        log 127.0.0.1 local2
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats

        # utilize system-wide crypto-policies
        ssl-default-bind-ciphers PROFILE=SYSTEM
        ssl-default-server-ciphers PROFILE=SYSTEM

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor except 127.0.0.0/8
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s

frontend public
        bind :::80 v4v6
        option forwardfor except 127.0.0.1
        # use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

backend octoprint
        http-request replace-path ^([^\ :]*)\ /(.*) \1\ /\2
        option forwardfor
        server octoprint1 127.0.0.1:5000
Webcam streaming set up
[/etc/haproxy/haproxy.cfg]
global
        chroot /var/lib/haproxy
        pidfile /var/lib/haproxy.pid
        maxconn 4000
        user haproxy
        group haproxy
        daemon
        log 127.0.0.1 local2
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats

        # utilize system-wide crypto-policies
        ssl-default-bind-ciphers PROFILE=SYSTEM
        ssl-default-server-ciphers PROFILE=SYSTEM

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor except 127.0.0.0/8
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s

frontend public
        bind :::80 v4v6
        option forwardfor except 127.0.0.1
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

backend octoprint
        http-request replace-path ^([^\ :]*)\ /(.*) \1\ /\2
        option forwardfor
        server octoprint1 127.0.0.1:5000

backend webcam
        http-request replace-path /webcam/(.*) /\1
        server webcam1  127.0.0.1:8080
Other distributions and versions
No webcam streaming set up
[/etc/haproxy/haproxy.cfg]
global
        chroot /var/lib/haproxy
        pidfile /var/lib/haproxy.pid
        maxconn 4000
        user haproxy
        group haproxy
        daemon
        log 127.0.0.1 local2
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats

        # utilize system-wide crypto-policies
        ssl-default-bind-ciphers PROFILE=SYSTEM
        ssl-default-server-ciphers PROFILE=SYSTEM

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor except 127.0.0.0/8
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s

frontend public
        bind :::80 v4v6
        option forwardfor except 127.0.0.1
        # use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

backend octoprint
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        option forwardfor
        server octoprint1 127.0.0.1:5000
Webcam streaming set up
[/etc/haproxy/haproxy.cfg]
global
        chroot /var/lib/haproxy
        pidfile /var/lib/haproxy.pid
        maxconn 4000
        user haproxy
        group haproxy
        daemon
        log 127.0.0.1 local2
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats

        # utilize system-wide crypto-policies
        ssl-default-bind-ciphers PROFILE=SYSTEM
        ssl-default-server-ciphers PROFILE=SYSTEM

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor except 127.0.0.0/8
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s

frontend public
        bind :::80 v4v6
        option forwardfor except 127.0.0.1
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

backend octoprint
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        option forwardfor
        server octoprint1 127.0.0.1:5000

backend webcam
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8080

You can now proceed to 8. Create the relevant service files and make services start on boot

7.c. Using Apache HTTPd and mod_proxy

First of all, we need to install the HTTPd package using the following command:

sudo dnf install httpd

Then we need to create a new configuration file for octoprint:

No webcam streaming set up
[/etc/httpd/conf.d/octoprint.conf]
<VirtualHost *:80>
        ServerName <IP−ADDRESS>
        <Location />
                ProxyPass http://127.0.0.1:5000/
                ProxyPassReverse http://127.0.0.1:5000/
                RewriteEngine on
                RewriteCond %{HTTP:UPGRADE} =websocket [NC]
                RewriteRule .* ws://127.0.0.1:5000%{REQUEST_URI} [P,L]
        </Location>
</VirtualHost>
Webcam streaming set up
[/etc/httpd/conf.d/octoprint.conf]
<VirtualHost *:80>
        ServerName <IP−ADDRESS>
        <Location />
                ProxyPass http://127.0.0.1:5000/
                ProxyPassReverse http://127.0.0.1:5000/
                RewriteEngine on
                RewriteCond %{HTTP:UPGRADE} =websocket [NC]
                RewriteRule .* ws://127.0.0.1:5000%{REQUEST_URI} [P,L]
        </Location>
        <Location /webcam/>
                DirectoryIndex disable
                DirectoryIndexRedirect off
                ProxyPass http://127.0.0.1:8080/
                ProxyPassReverse http://127.0.0.1:8080/
        </Location>
</VirtualHost>

Also, we need SELinux to allow HTTPd to talk to other services across the network, using the following command:

sudo setsebool -P httpd_can_network_connect 1

You can now proceed to 8. Create the relevant service files and make services start on boot

8. Create the relevant service files and make services start on boot

Now that all the software is configured, we need to create systemd service files so that each software can be automatically started on boot.

8.a. Octoprint service

OctoPrint doesn't come with a service file, fortunately systemd comes with utilities to create these services files. The following command will open a text editor in which you'll paste the following contents:

sudo systemctl edit --full --force octoprint.service
No reverse proxy

Service file contents:

[/etc/systemd/system/octoprint.service]
[Unit]
Description=Manages the OctoPrint instance
After=network-online.target 
Wants=network-online.target

[Service]
User=octoprint
Group=octoprint
Type=exec
Environment="LC_ALL=C.UTF-8"
Environment="LANG=C.UTF-8"
ExecStart=/opt/octoprint/bin/octoprint serve

[Install]
WantedBy=multi-user.target
HAProxy reverse proxy

Service file contents:

[/etc/systemd/system/octoprint.service]
[Unit]
Description=Manages the OctoPrint instance
After=network-online.target
Wants=network-online.target
Requires=haproxy.service
Before=haproxy.service

[Service]
User=octoprint
Group=octoprint
Type=exec
Environment="LC_ALL=C.UTF-8"
Environment="LANG=C.UTF-8"
ExecStart=/opt/octoprint/bin/octoprint serve

[Install]
WantedBy=multi-user.target
HTTPd reverse proxy

Service file contents:

[/etc/systemd/system/octoprint.service]
[Unit]
Description=Manages the OctoPrint instance
After=network-online.target
Wants=network-online.target
Requires=httpd.service
Before=httpd.service

[Service]
User=octoprint
Group=octoprint
Type=exec
Environment="LC_ALL=C.UTF-8"
Environment="LANG=C.UTF-8"
ExecStart=/opt/octoprint/bin/octoprint serve

[Install]
WantedBy=multi-user.target

Once this is done, you need to enable the service on boot running the following command:

systemctl enable --now octoprint.service

Also, we'll need to allow the octoprint user to reboot the computer and restart the octoprint service if needed. To do so, you need to create the /etc/polkit-1/rules.d/90-octoprint.rules file with the following contents:

[/etc/polkit-1/rules.d/90-octoprint.rules]
polkit.addRule (function (action, subject) {
    if ( subject.user == "octoprint" )
    {
     	// Always accept following actions without authentication as long as they're carried out by the octoserver user
        if ( action.id == "org.freedesktop.login1.reboot" ||  // Reboot the computer
             action.id == "org.freedesktop.login1.reboot-multiple-sessions" || // Reboot the computer even if other users are logged in
             action.id == "org.freedesktop.login1.power-off" || // Power off the computer
             action.id == "org.freedesktop.login1.power-off-multiple-sessions" || // Power off the computer even if others users are loged in
             action.id == "org.freedesktop.login1.set-wall-message" || // Set a wall message (necessary during power off or reboot sequences)
             ( action.id == "org.freedesktop.systemd1.manage-units" && action.lookup("unit") == "octoprint.service" && action.lookup("verb") == "restart" )) // Restart the octoprint instance
        {
            return polkit.Result.YES;
        }
    }
});

At this point, if you haven't completed one of the following steps:

You can proceed to 9. OctoPrint first run wizard configuration, otherwise, please complete the relevant following sections.

8.b. Optional: Webcam streaming service

:warning: WARNING This step is optional, and only needed if you completed either step 6.a. Using mjpg-streamer or 6.b. Using µstreamer.

As for OctoPrint, we need to creat a new service file as those programs don't come with one. But before, we need to check the resolution and framerate your camera can operate at. In order to find that out, you need to run the following command, only available on Fedora for now:

v4l2-ctl -d /dev/v4l/by-id/<WEBCAM-ID> --list-formats-ext

The output should look something like this:

[silver@octoprint ~]$ v4l2-ctl -d /dev/v4l/by-id/<WEBCAM-ID> --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'YUYV' (YUYV 4:2:2)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 424x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 1280x800
			Interval: Discrete 0.100s (10.000 fps)
	[1]: 'MJPG' (Motion-JPEG, compressed)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 416x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.133s (7.500 fps)

This webcam offers two formats, either YUYV or MJPG, we're interested in the MJPG format. Then the Size: lines indicate the resolutions my webcam may operate at, and then the Interval lines indicate the available FPS modes at such resolution. You'll need to replace the and placeholder with the desired settings.

The following command will open an editor where wyou can paste the service file contents:

mjpg-streamer
sudo systemctl edit --full --force mjpg-streamer.service
No reverse proxy

Service file contents:

[/etc/systemd/system/mjpg-streamer.service]
[Unit]
Description=MJPG-streamer instance for octoprint webcam control
Wants=network-online.target
After=network-online.target

[Service]
User=octoprint
Group=octoprint
Type=exec
ExecStart=/usr/local/bin/mjpg_streamer -i 'input_uvc.so -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS>' -o 'output_http.so -p 8080 -l 0.0.0.0 -n'

[Install]
WantedBy=multi-user.target
Reverse proxy configured
HAProxy

Service file contents:

[/etc/systemd/system/mjpg-streamer.service]
[Unit]
Description=MJPG-streamer instance for octoprint webcam control
Requires=haproxy.service
Wants=network-online.target
After=network-online.target
Before=haproxy.service

[Service]
User=octoprint
Group=octoprint
Type=exec
ExecStart=/usr/local/bin/mjpg_streamer -i 'input_uvc.so -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS>' -o 'output_http.so -p 8080 -l 127.0.0.1 -n'

[Install]
WantedBy=multi-user.target
HTTPd with mod_proxy

Service file contents:

[/etc/systemd/system/mjpg-streamer.service]
[Unit]
Description=MJPG-streamer instance for octoprint webcam control
Requires=httpd.service
Wants=network-online.target
After=network-online.target
Before=httpd.service

[Service]
User=octoprint
Group=octoprint
Type=exec
ExecStart=/usr/local/bin/mjpg_streamer -i 'input_uvc.so -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS>' -o 'output_http.so -p 8080 -l 127.0.0.1 -n'

[Install]
WantedBy=multi-user.target

To enable the service on boot, run the following command:

systemctl enable --now mjpg-streamer.service
µstreamer
sudo systemctl edit --full --force ustreamer.service
No reverse proxy configured

Service file contents:

[/etc/systemd/system/ustreamer.service]
[Unit]
Description=µstreamer instance for octoprint webcam control
Wants=network-online.target
After=network-online.target

[Service]
User=octoprint
Group=octoprint
Type=forking
ExecStart=/usr/local/bin/ustreamer -m MJPEG -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS> -s 0.0.0.0 -p 8080

[Install]
WantedBy=multi-user.target
Reverse proxy configured
HAProxy

Service file contents:

[/etc/systemd/system/ustreamer.service]
[Unit]
Description=µstreamer instance for octoprint webcam control
Requires=haproxy.service
Wants=network-online.target
After=network-online.target
Before=haproxy.service

[Service]
User=octoprint
Group=octoprint
Type=forking
ExecStart=/usr/local/bin/ustreamer -m MJPEG -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS> -s 127.0.0.1 -p 8080

[Install]
WantedBy=multi-user.target
HTTPd with mod_proxy

Service file contents:

[/etc/systemd/system/ustreamer.service]
[Unit]
Description=µstreamer instance for octoprint webcam control
Requires=httpd.service
Wants=network-online.target
After=network-online.target
Before=httpd.service

[Service]
User=octoprint
Group=octoprint
Type=forking
ExecStart=/usr/local/bin/ustreamer -m MJPEG -d /dev/v4l/by-id/<WEBCAM-ID> -r <RESOLUTION> -f <FPS> -s 127.0.0.1 -p 8080

[Install]
WantedBy=multi-user.target

To enable the service on boot, run the following command:

systemctl enable --now ustreamer.service

Then please proceed with the next section below.

9. OctoPrint first run wizard configuration

To complete OctoPrint's First Run Wizard, you need to open a browser and access the following:

No reverse proxy configured

http://<IP-ADDRESS>:5000/

Reverse proxy configured

http://<IP-ADDRESS>/

Then you should be greeted with OctoPrint's First Run Wizard. Please complete the steps until Server Commands to your liking. Once the Server Commands step reached, please fill in the fields with the following information:

  • Restart OctoPrint: systemctl restart octoprint.service
  • Restart system: systemctl reboot -i
  • Shutdown system: systemctl poweroff -i

You can then proceed to the next step, Webcam & Timelapse. If you completed either step 6.a. Using mjpg-streamer or 6.b. Using µstreamer, you'll need to fill in the fields with the following info:

mjpg-streamer
No reverse proxy configured
  • Stream URL: http://<IP-ADDRESS>:8080/webcam/?action=stream
  • Snapshot URL: http://<IP-ADDRESS>:8080/webcam/?action=snapshot
Reverse proxy configured
  • Stream URL: webcam/?action=stream
  • Snapshot URL: http://<IP-ADDRESS>/webcam/?action=snapshot
µstreamer
No reverse proxy configured
  • Stream URL: http://<IP-ADDRESS>:8080/webcam/stream
  • Snapshot URL: http://<IP-ADDRESS>:8080/webcam/snapshot
Reverse proxy configured
  • Stream URL: webcam/stream
  • Snapshot URL: http://<IP-ADDRESS>/webcam/snapshot

Then you're free to enjoy printing with OctoPrint.

10. Changelog

  • v1.0.1 - 2022-02-16
    Modified the mjpg-streamer service file contents as the -b flag and forking type don't seem to work very well
  • v1.0.0 - 2021-09-14
    First version of the guide
2 Likes

(reserved by the author)

The service type for µstreamer should be simple instead of forking, µstreamer does not detach automatically.