Setting up OctoPrint on Ubuntu 20.04 with Python 3

Post by:



June 5, 2020


Note: This post was originally on my personal blog. I have moved it here as it relates to what we do.


I had been running OctoPrint on a small embedded PC that I had, but it was not running as well as I would have liked. This original build was kinda slapped together and not quite as streamlined as I had intended it to be. It worked, mostly, but wasn’t running OctoPrint as a service, and required a manual start of the webcam software on reboot, so just kinda meh.

I decided to kick it up a notch with a more powerful embedded PC that I had laying around, with more disk space, RAM and processing power. Not that the other unit was under-powered (I mean you can run this on a Pi), but I had the hardware, so why not?! Here is how it all went together, for posterity, and for anyone else looking to do this. I will list the sources that I followed at the end of the post.

This guide assumes that you have some familiarity with working in command line LINUX. If you don’t, google may be your friend. Additionally, anywhere you see me use either my username “alex” or “[USER]” you should replace that with your user name.

Install the OS

First off, I started with a fresh download of Ubuntu Server 20.04 LTS. You can download that right from the Ubuntu Site. I use Balena Etcher to write out my live USB stick, it is available for both Mac and Windows. Of course you can use your favorite image writing tool as well.

This install and initial setup is down with a local keyboard and display. once you are set up with the OS, you can switch to your favorite SSH client.

I set the BIOS on my embedded PC to defaults, and the OS type to LINUX. This step will vary depending on the hardware that you install on.

Once booted to the live USB, I did a pretty vanilla install of Ubuntu server. It is worth noting that I needed to have a network connection for the install, or my networking didn’t seem to work right after, so you may need to make sure you have an active network connection. I just did a basic install without any extra software, and with OpenSSH installed. Set your user name, computer name, short name, and password, and let it do it’s thing.

After the OS installation was complete, a reboot brings you into the command prompt. As with any new install, I recommend doing a quick update check and install any updates (this code will update your package list and install any available upgrades):

sudo apt update && sudo apt upgrade -y

I also recommend installing net-tools so that you can use commands like ifconfig to get your IP address:

sudo apt install net-tools

At this point, it is a pretty good idea to reboot your computer. I mean, you just did updates and install new software, so it can’t hurt.

sudo reboot

At this point, you can switch to connecting to your machine via SSH from your favorite SSH client. On a mac, you can just use Terminal. On windows, use a program like PuTTy. Of course, you can also continue to work locally on the machine as well. I just like working in an SSH client because I can keep the client side-by-side with the guide, and I can copy and paste all the commands rather than typing them out!

Installing OctoPrint

Once your computer reboots, it is time to start getting ready for the actual OctoPrint install. While Ubuntu 20.04 does come with Python 3, you still need a few other bits for everything to work right. You could do this before the reboot above if you wanted. You can install the needed components with the following command:

sudo apt-get install python3-pip python3-dev python3-setuptools python3-virtualenv git libyaml-dev build-essential

Now we have to set up the Python virtual environment in the correct directories. For now you should be in your user home directory “/home/[USER]” or the “~” directory. If you are not then just:

cd ~

You can check the absolute path to the current directory with:


So, we need to make the OctoPrint directory and get into it:

mkdir OctoPrint && cd OctoPrint

Next we are going to setup the virtual environment running Python 3:

virtualenv --python=python3 venv

Now we are going to activate the virtual environment:

source venv/bin/activate

Once you do this step, your command line should be preceded by “(venv)” This indicates that you are working in the virtual environment, which is what we want.

Then we are going to install the latest version of PIP:

pip install pip --upgrade

Next we are going to use PIP to install OctoPrint. This will download the necessary files from the OctoPrint repository and set it up in the virtual environment.

pip install

Once the install is completed, we need to make sure that your user is a member of the tty and dialout groups in the system. This makes sure that OctoPrint can use serial connections to talk to your printer! Remember to use your user name, not mine!

sudo usermod -a -G tty alex
sudo usermod -a -G dialout alex

Now you should have OctoPrint installed and ready to use. You can test it by issuing the following command:

~/OctoPrint/venv/bin/octoprint serve

When you use the above command, you will see the server start to run. If you open a web browser and point it at the IP address of your OctoPrint device and port 5000, you should see the OctoPrint Setup screen! For me, for this device i used: Your IP address will depend on your network settings.

You can go through the setup now, if you would like, but I did it later. Back in your terminal, lets stop the server. This can be done by pressing control-c. This will terminate the server process and return you to a command line.

Automating OctoPrint Startup

Now that we have OctoPrint installed and working, it is time to set it up so that it will start automatically when the computer boots up. Fortunately, there are sample scripts available from the OctoPrint GitHub. All we have to do is download them and update them to match our install. We are going to download the scripts and move them to the correct locations. We also need to make sure that they are executable.

wget && sudo mv octoprint.init /etc/init.d/octoprint

wget && sudo mv octoprint.default /etc/default/octoprint

sudo chmod +x /etc/init.d/octoprint

You can check that your script is executable by listing the contents of /etc/init.d. If the script shows up in green, it is executable.

ls /etc/init.d

Now we need to tweak the scripts to match our installation. This means that we need to uncomment a couple lines in the script and make sure that the user name and file paths are correct. See the example below, just replace my username with yours. Edit the script using nano.

sudo nano /etc/default/octoprint

Your script should look something like this:

# Configuration for /etc/init.d/octoprint

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

# base directory to use

# configuration file to use

# On what port to run daemon, default is 5000

# Path to the OctoPrint executable, you need to set this to match your installation!

# What arguments to pass to octoprint, usually no need to touch this

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

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

# Should we run at startup?

Now we have to add our scripts to autostart. This is done with the following command:

sudo update-rc.d octoprint defaults

Now you should be able to run OctoPrint as a service using the following command:

sudo service octoprint start

You can check if OctoPrint is running by using this command (or visiting the site in a browser):

sudo service octoprint status

We have one last thing to do in order to give the OctoPrint UI the ability to shutown or reboot the computer as well as the ability to restart the OctoPrint service. We will give our user the ability to run a couple sudo commands without requiring a password. We are going to create a simple file in sudoers.d that grants permissions. This is a little safer than directly editing your sudoers file. You can do this with nano, but it will not check your syntax like vi does. I personally like nano better, but make sure your get the syntax right or you might end up locking yourself out of being able to run sudo commands completely. (it is possible to recover from that if you do it…)

First, let’s open a new document in your favorite editor:

sudo nano /etc/sudoers.d/octoprint-shutdown

Then in that document we will put the following:

alex ALL=NOPASSWD: /sbin/shutdown
alex ALL=NOPASSWD: /bin/systemctl restart octoprint.service

Save and close when you are done. As always, make sure that you use your user name or this will not do much for you.

Run OctoPrint on port 80

Now that we have OctoPrint up and running and starting on boot, assuming that OctoPrint is the only web service that you are running, we can make it default to port 80 (the standard http port) so that you don’t have to enter the port number in the URL when you want to access it. We do this with haproxy.

First we need to install haproxy:

sudo apt install haproxy

Next we will make a backup copy of the haproxy config file and delete the original. We are just going to replace it with our own later:

sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg_old
sudo rm /etc/haproxy/haproxy.cfg

Next, open up an editor to make a new config file:

sudo nano /etc/haproxy/haproxy.cfg

Paste the following into the haproxy.cfg file:

        maxconn 4096
        user haproxy
        group haproxy
        log local0 debug

        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor
        maxconn 2000
        timeout connect 5s
        timeout client  15min
        timeout server  15min

frontend public
        bind :::80 v4v6
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

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

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

Next we will enable haproxy. We are just adding “ENABLE=1” to the last line of the file. So open the file:

sudo nano /etc/default/haproxy

Then make sure that your file looks like this:

# Defaults file for HAProxy
# This is sourced by both, the initscript and the systemd unit file, so do not
# treat it as a shell script fragment.

# Change the config file location if needed

# Add extra flags here, see haproxy(1) for a few options
#EXTRAOPTS="-de -m 16"

You then should restart haproxy to make sure that all changes take effect:

sudo service haproxy restart

Of course you can check if haproxy is running using the command below, or you can just try to visit the URL of your server without the port number on the end.

sudo service haproxy status

Setup the WebCam Software

Now we all know that making timelapses of 3D prints is awesome, and one of the great features of OctoPrint is its webcam integration. Let’s get that working now too.

First off, change back to your home directory and then we need to install a handful of software:

cd ~
sudo apt install subversion libjpeg8-dev imagemagick ffmpeg libv4l-dev cmake

When you install those packages, there will be a lot of other dependancies that get installed with them. You do want it all.

Next we will grab mjpg-streamer from github and move into its directory:

git clone
cd mjpg-streamer/mjpg-streamer-experimental

Now we have to export the library and make the software (these steps may take some time):


Once the make is complete, we can test the software:

sudo ./mjpg_streamer -i "./" -o "./"

Of course we want the webcam software to start automatically as well, so we need to make a couple more scripts to do this. We are going to make a scripts folder in your home folder and then create a script to start and stop MJPEG-Streamer called “webcam.” As always, make sure to change the user name to match yours! DO NOT USE sudo when executing these commands.

cd ~
mkdir scripts
nano /home/alex/scripts/webcam

Here is the start/stop script, go ahead and paste this script into the editor, remember to change user names!

# Start / stop streamer daemon

case "$1" in
        /home/alex/scripts/webcamDaemon >/dev/null 2>&1 &
        echo "$0: started"
        pkill -x webcamDaemon
        pkill -x mjpg_streamer
        echo "$0: stopped"
        echo "Usage: $0 {start|stop}" >&2

Now create a second script “webcamDaemon” (note again, not using sudo):

nano /home/alex/scripts/webcamDaemon

And paste the following into the editor, updating for your user. You can also change the default video resolution and framerate in this script:



# init configuration
camera_usb_options="-r 640x480 -f 10"
camera_raspi_options="-fps 10"

if [ -e "/boot/octopi.txt" ]; then
    source "/boot/octopi.txt"

# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
    echo Running ./mjpg_streamer -o " -w ./www" -i "$input"
    LD_LIBRARY_PATH=. ./mjpg_streamer -o " -w ./www" -i "$input"

# starts up the RasPiCam
function startRaspi {
    logger "Starting Raspberry Pi camera"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"

# starts up the USB webcam
function startUsb {
    logger "Starting USB webcam"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"

# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version

# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
echo raspi options: $camera_raspi_options

# keep mjpg streamer running if some camera is attached
while true; do
    if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
    elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; }; then

    sleep 120

We now have to make these scripts executable, so run the following commands (update for your user):

sudo chmod +x /home/alex/scripts/webcam
sudo chmod +x /home/alex/scripts/webcamDaemon

To get the webcam to start on reboot, we are going to make an rc.local file. This will just execute the camera startup script. Create the file using nano:

sudo nano /etc/rc.local

Then paste this simple script into it (change user names):

#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.

/home/alex/scripts/webcam start

exit 0

Now we need to make rc.local executable:

sudo chmod +x /etc/rc.local

Finally, we can start the webcam (change user names):

sudo /home/alex/scripts/webcam start

Use a URL not IP address

If you want a clean way to access your OctoPrint server so that you don’t have to remember the IP address of it, we can do that with Avahi (aka Bonjour). First, we need to install Avahi:

sudo apt install avahi-daemon

Then we are going to create a file with the hostname that we would like to use:

sudo nano /etc/hostname

In the editor, just type the hostname you want on the first line. then save and exit. Mine is “icewolf3d”

Then we need to edit the hosts file to use that host name. Open the hosts file in nano:

sudo nano /etc/hosts

You need to either include the hostname on the line for or add a line. My hosts file looks like this: localhost icewolf-3dsrv icewolf3d

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Of course, save and close the file when you are done.

Lastly, it is time to reboot the system:

sudo reboot now

Configuring OctoPrint

I am not going to go into too much detail on how to set up OctoPrint as it is pretty straight forward, and a little different depending on your printer. However, there are a couple things that are useful. Once you go through the initial setup you may need to fill in the following information:

Shutdown commands (I don’t actually use the shutdown command as my system is not designed for that):

Restart OctoPrint: sudo /bin/systemctl restart octoprint.service
Restart System: sudo shutdown -r now
Shutdown System: sudo shutdown -h now

Webcam links:

Stream URL: /webcam/?action=stream
Snapshot URL:
Path to FFMPEG: /usr/bin/ffmpeg

Onward Ever Upward…

…oh faithful followers of Waldo!

At this point you should have a functional install of OctoPrint that starts on boot and is web-cam ready. Since this runs in Python 3, not all plugins are compatible yet, but many are. I definitely recommend the OctoPod plugin along with the iOS app (I think there is an Android one as well). It gives you all the great functionality of OctoPrint in an app along with notifications.

My next plans for this system are to get it connected to my NAS for storage of timelapse videos as well as my gcode repository. The HDD of the server is plenty big for it all, but it seems like it would be convenient if I got it all in one place and easily accessible anywhere on my network.

My printer setup now

Ender-3 with Micro-Swiss Direct Drive and all-metal hotend, satsana fanduct with 5015 blower, spring steel PEI plate, Wyze cam converted to webcam, and my OctoPrint server on the shelf below.


I used the following sources to aid in this journey. Credit where credit is due:


  1. Frenchy

    Great guide! However, I don’t think that you need to install subversion 🙂

    • Alex

      I believe you are correct. It may be a holdover from earlier testing that I was doing, and just held on to the commands.

  2. Tod Wulff

    Good day.

    The guide seems to be missing the step/command to open the hosts file: sudo nano /etc/hosts

    Otherwise, you’ve crafted a wicked good guide. Thank you, kind sir!


    • Alex

      MHz- You are absolutely correct, I totally missed the command for editing the hosts file. I shall add that in! Thanks!

  3. Kail

    I went through the steps. However, when I used “~/OctoPrint/venv/bin/octoprint serve” it said “No such file or directory”

  4. Kail

    Disregard that message and forgive my ignorance haha. I’m brand new to linux, but I figured it out! 🙂 Thanks so much for this guide!!

  5. Ryan

    Thank you for making this awesome guide! I followed it completely, but do not know how to access my server from the hostname I set up. For your example, icewolf3d was the hostname, so what do you put in your web browser to connect using this hostname? Thanks again!

    • Alex

      You should be able to use *.local as the URL. So, in my case it is “icewolf3d.local”

  6. Angelo

    Almost there…

    here I got stuck at:

    sudo service haproxy restart

    Job for haproxy.service failed because the control process exited with error code.
    See “systemctl status haproxy.service” and “journalctl -xe” for details.

    • AMG

      you need to replace ‘reqrep’ with ‘http-request replace path’ in the .cfg file

      • Andy

        I actually found I needed more changes to get it working with HaProxy 2.1+:

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

        backend webcam
        http-request replace-path /webcam/(.*) /\1
        server webcam1

  7. evi

    Hi! Great guide!! You are a GOD! Thank you sooo much. I need to add something because I had only one issue and I found out how to solve it, so it might help others.

    For me Stream URL: /webcam/?action=stream didn’t work. Screenshot was working fine though. In octoprint settings under Webcam and timelapse there is a note. Note: Please note that OctoPrint merely embeds a webcam stream & access a snapshot URL. It does not actually run its own webcam server or interact directly with your camera. It thus can’t impose access restrictions on it or enable/disable the stream for you. Please see this FAQ entry for more explanation.

    So in order for the webcam to stream successfully you have to access Octoprint from another computer and test it (or your mobile phone). So, used this stream URL and I got it working (replace with your linux server IP)

    • wiiizbe

      hi, thank you for your sharing, i had the same problem and your comment help to solve it.
      Thank you for taking the time to share

  8. Erik Middeldorp

    I was having problems with octoprint not being able to restart itself after updates and the “Restart Octoprint” controls not working. I fixed it by changing /etc/sudoers.d/octoprint-shutdown from
    erik ALL=NOPASSWD: /bin/systemctl restart octoprint.service
    erik ALL=NOPASSWD: /usr/sbin/service
    I guess I might’ve also been able to fix it by changing the Restart Octoprint command in the Octoprint Settings.

  9. graffx

    Thank you for convenient guide!
    Can’t get the stream to work in Octoprint –
    It’s working on 192.168.x.x/webcam/?action=stream (without the port :5000) – but not in Octoprint and not on 192.168.x.x:5000/webcam/?action=stream
    Double checked all the scripts and configs.. I’m noob at linux, can you help me please?

  10. Drew

    Hey so I’m a relative noob to Linux here but I’ve followed this guide and managed to get everything up and running, so kudos for the great guide. The only thing I’m missing out on is the ability to restart octoprint from within the web client, I get the success message, and I can see in the terminal on the webpage that it attempted to send the “sudo bin/systemctl restart octoprint.service” but octoprint doesn’t actually restart. Any advice would be helpful, as I really have no idea what has happened here.

  11. wiiizbe

    just incredibly clear !
    you hepled me a lot !

    Thank you for your work and for your sharing 🙂
    Hopefully people like you continue to exist

  12. Dan Pro

    I was doing fine until editing scripts using nano. I clicked where I wanted to edit with my mouse and started backspacing. I’ve not worked in this environment before. I now know that arrow keys move me around. I replaced what I thought was removed (part of my username) and continued. In the end sudo update-rc.d octoprint default, sudo service octoprint start and sudo service octoprint status commands didn’t appear to do anything and I can’t open octoprint in my browser. How would I delete the octoprint directory so I could take another run at it?

    • Alex

      All the text editors in the command line won’t be happy about trying to use your mouse. It takes a little getting used to, but at least Nano is a bit more intuitive than VI. That said, there are a bunch of people who like VI…

      As far as getting rid of your OctoPrint directory, you can use the following command: rm -r ~/OctoPrint/ This will remove the directory you crated everything inside of and all subdirectories.

      • Dan Pro

        Thanks for the command it did the trick.
        After editing you should mention Ctrl X ,Y and enter to save.
        I figured that out reviewing Chris’s Basement video to see what else I was doing wrong.
        I have never used linux before and have no idea what I’m doing.
        Do you mind helping me next time I get stuck?

        • Logan

          Hi, was wondering if you could help me. The server and everything is good but it can’t seem to connect to my printer. I’ve tried different cables and USB ports on my server. The error code 13 keeps coming up in the octoprint terminal.

          Changing monitoring state from “Offline” to “Error: Connection error, see Terminal tab”
          Unexpected error while connecting to serial port: /dev/ttyUSB0 SerialException: ‘[Errno 13] could not open port /dev/ttyUSB0: [Errno 13] Permission denied: ‘/dev/ttyUSB0” @ (hook default)

  13. MMarty64

    Just wanted to say thanks for the great walkthrough. I used it to install on Octoprint on Proxmox VM with USB passed through. Worked Perfectly.

    Did I say the walkthrough was excellent? I’m a Linux Hack and this was just what I needed.


    • Alex

      Glad you found it helpful!

  14. Yohan51

    Good job guy, it was really helpfull for me.
    As Evi said, “For me Stream URL: /webcam/?action=stream didn’t work” but I solved it by using “http://192.168.1.***:8080/?action=stream” instead. But the stream is from my laptop cam and I wan’t to use an action cam plugged with USB. How can I manage it please ?
    Does anyone has an idea ?

    • Alex

      There is a way to specify which camera to use, I don’t remember it offhand. I will try to look it up. It is just a matter of getting the device ID and putting it in the config for the streaming software.

  15. adam

    legit followed this too the T…. get to the

    “Of course you can check if haproxy is running using the command below, or you can just try to visit the URL of your server without the port number on the end.

    sudo service haproxy status”

    services are running but no matter how hard i try i cant access the octoprint UI…… im going crazy please help bout to go back to windows!!!

    • Alex

      If I understand you correctly, you are saying that from another computer on your network you cannot get to the OctoPrint UI? Have you tried using the IP address of the octoprint server instead of the URL? If you can access the UI using the IP address, it would indicate an issue with HAProxy. If you cannot access the UI using the IP address, then it may indicate that either octoprint is not running, or is not quite configured correctly.

  16. Andrew

    Excellent guide…used it to repurpose an old Surface Pro (1st-gen) to be a beefier OctoPrint server (was running OctoPi on a Pi 3, with a TFT screen, and it was great for remote use, but pretty terrible for local control).

    Haven’t set up camera yet, but it’ll be interesting to see how that works given the built-in front/back cameras in the surface (I’ve also got a logitech C270 that’s been my main camera on this printer.

    One tip from my experience…if you’ve used the Snap install of OctoPrint (don’t, but I did), it may hold onto port 5000 even if you uninstalled it. My simple workaround was to use port 5001 in the config file.

  17. David Green

    Where do i get the vcgencmd utility? I can’t find it in the Ubuntu repos and it appears to be part of the Raspberry Pi packages.


Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.


We are located in Mt. Gretna, PA. If you are doing local pickup, we will send you an address.

Social Media