How to Build a NetBox Lab on Ubuntu 24.04 Using Docker (Step-by-Step)

NetBox is an open-source tool widely considered the industry's go-to "Source of Truth" for IP Address Management (IPAM) and Data Center Infrastructure Management (DCIM). It allows network administrators and engineers to maintain dynamic, centralized documentation of a network's current state, unlocking the ability to automate device configuration, provisioning, and deployment. Whether you are a student exploring network management or an engineer building an emulation lab, having a safe sandbox to experiment in is invaluable. This guide will demonstrate how to successfully deploy an isolated NetBox lab environment on Ubuntu 24.04 using Docker.

Prerequisites 

To follow along with this guide, make sure you have the following ready:
  • Host Environment: A local hypervisor (like VMware or VirtualBox) or a cloud VPS. (Tip: If you need a cloud host, you can use my DigitalOcean referral link to sign up and get $200 in free credits!)
  • Operating System: A fresh installation of Ubuntu 24.04 Server.
  • Hardware/Resource Allocation:
    • Small Environment (Development/Lab): 4 vCPU, 4GB RAM, 50GB SSD.
    • Medium/Large Environment (Production): 8+ vCPU, 24GB+ RAM, 100GB+ SSD.

Setting Up The Environment

Step 01: Installing Docker Engine

First, we need to make sure Docker is installed on your system. You can verify this using the following command:
docker --version
If you get an output similar to Docker version 29.3.1, build c2be9cc, Docker is already installed. Otherwise, use the following commands to grab the modern Docker Engine and the Docker Compose v2 plugin directly from the standard Ubuntu repositories:
sudo apt update
sudo apt install -y docker.io docker-compose-v2 git

Step 02: Installing Git

We will be downloading the NetBox deployment files from their official GitHub repository. To do that, we need Git installed on our system. Verify Git is installed using the following command:
git --version 
If the command returns a version number (like git version 2.43.0), you are good to go. Otherwise, install it using:
sudo apt install git   

Setting Up NetBox

Step 01: Clone NetBox Repository

Now that we have finished setting up the environment, we are going to pull down the official Docker configurations built by the NetBox community. We use the release branch to ensure we get a stable version, not bleeding-edge developer code. 
cd ~
git clone -b release https://github.com/netbox-community/netbox-docker.git
cd netbox-docker    

Step 02:Expose the Web Interface & Set Restart Policies

By default, the netbox-docker stack has two behaviors we need to change for our lab environment:
  1. Hidden Web Ports: It does not expose its web ports to the outside world. This is a deliberate security feature, as production environments typically place NetBox behind a dedicated reverse proxy (like Nginx or Apache).
  2. No Auto-Restart: If your Ubuntu host server reboots, the NetBox containers will stay powered off until you manually start them.
We can fix both of these issues at once by creating a simple override file (docker-compose.override.yml) to force Docker to publish NetBox on port 8000 and ensure our containers automatically restart.

Ensure you are inside the netbox-docker directory, then create and open the file using a text editor like Nano:
cd ~/netbox-docker
nano docker-compose.override.yml   
Copy and paste the following lines into the file (In YML indentation matters, be careful when copying and pasting):
services: postgres: restart: unless-stopped redis: restart: unless-stopped redis-cache: restart: unless-stopped netbox: restart: unless-stopped ports: - 8000:8080 netbox-worker: restart: unless-stopped

Save and close the file (in Nano, press Ctrl+O, Enter, then Ctrl+X).

Note: The docker-compose.override.yml file allows us to make custom configurations to match our local environment without directly altering the core docker-compose.yml file. During initialization, Docker will automatically combine both files, and the default values will be safely overridden by the custom ports and restart policies we just specified.

Step 3: Ignite the Stack

NetBox uses a combination of containers (PgSQL, Redis, NetBox) to function properly. First we will download all the required images from Docker using the following command. 
sudo docker compose pull 
After all the images have been downloaded run the following command to initialize the container stack
sudo docker compose up -d
This process may take a while depending on your Ubuntu instance's hardware specifications. Wait till the process is completed.

Note: While you technically can download the images and initialize the containers all at once using just the second command, doing it in two distinct steps is a best practice for troubleshooting. If there is a network timeout or an issue grabbing a specific image version, it is much easier to spot the error during an isolated pull rather than hunting through the startup logs of a compose up command.

Troubleshooting Issues

If you are running this lab on an Ubuntu instance with limited compute resources (for example, fewer than 4GB of RAM), there is a high chance the initial startup might time out or fail.

When this happens, you will typically receive an error prompt stating that Docker failed to initialize the core application container (often named netbox or netbox-1). If you check your running containers using docker ps, you will see this specific container explicitly marked with an "unhealthy" status instead of "running."



The absolute easiest method to fix this issue is to simply power down your VM and allocate more RAM. However, if you are using a host with strict resource limits (like a budget cloud VPS or an older laptop), you can work around this by increasing the system's Swap memory.

Swap memory acts as a safety net, allowing your server to use a portion of the hard drive as temporary RAM when the physical memory maxes out during the heavy Docker initialization process.

Run the following commands sequentially to create, secure, and enable a 4GB Swap file on your Ubuntu instance:

1. Create a 4GB swap file
sudo fallocate -l 4G /swapfile
2. Secure the file so only the root user can read/write to it
sudo chmod 600 /swapfile  
3. Mark the file as Swap space
sudo mkswap /swapfile
4. Enable the Swap file
sudo swapon /swapfile
5. Verify Available Swap memory 
sudo free -h

After increasing the Swap memory of your instance, you can restart the specific application container that was marked as unhealthy. Run the following command:
sudo docker compose restart netbox
Wait a few minutes for the backend processes to fully boot up, and then confirm that all containers are now running and healthy by checking their status:
sudo docker compose ps -a

If you check the status and notice that any of the containers are still hanging in a "Created" state, don't panic! You can easily nudge them into initialization using the standard startup command:
sudo docker compose up -d
Because Docker is smart about state management, this command will only initialize the containers that are stuck in the "Created" state without restarting or affecting the containers that are already running perfectly.

Step 4: Creating Admin Account & Signin

Now that all the containers are running, NetBox is technically alive, but it doesn't have any users yet. We need to trigger the built-in Django superuser creation script by injecting the following command directly into the running netbox container:
sudo docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser
The script will prompt you for a few details. (Note: For security reasons, the password characters will not appear on the screen as you type).
  • Username: (e.g., admin)
  • Email address: (e.g., admin@local.lab or leave blank)
  • Password: (It will not show characters as you type)
  • Password confirmation:
After creating the superuser account, open a web browser on your Windows machine and navigate to the IP address of your Ubuntu VM on port 8000:
http://<your-ubuntu-vm-ip>:8000
You will be greeted by the NetBox login screen. Simply log in with the superuser credentials you just created.

Adding Your First Device

Now it is time to start documenting the devices in your network. In NetBox, you can populate your inventory either manually via the Web GUI or dynamically using automation tools like REST API calls or Ansible playbooks.

For this introductory lab, we will use the manual method to help you get familiar with the interface. Either way, the core information you need to provide to build your "Source of Truth" remains exactly the same.

NetBox relies on a strict organizational hierarchy to keep your data perfectly clean. Before the system will allow you to successfully add a physical piece of hardware (a "Device"), you must first navigate the Web GUI to create five foundational elements:
  1. A Site (Where the device lives physically)
  2. A Manufacturer (Who built the device, e.g., Cisco or Juniper)
  3. A Device Type (The specific hardware model, e.g., "Catalyst 9300" — Note: This requires the Manufacturer to be created first!)
  4. A Device Role (What the device does, e.g., Core Router or Access Switch)
  5. A Platform (The operating system running on the device, e.g., Cisco IOS or Junos — Crucial for Ansible automation!)

Step 01: Create a site

Expand the section "Organization" in the left side-pane and click on "Sites"


Then click on the "+ Add" button on the top right corner of the interface.


Then give a site name, and make sure that the "Status" is set to Active and click Create. (You can add other information if you like).

Step 02: Create a Manufacturer

Expand the Devices section in the left side-pane and click on Manufacturers under Device Types


Click the + Add button in the top right corner. Enter a Name for the hardware vendor (e.g., Cisco, Juniper, or Arista). The "Slug" field will automatically populate based on the name. Click Create.


Step 03: Create a Device Type

Still under the Devices section, click on Device Types.


Click the + Add button. In the creation form, select the Manufacturer you just created from the dropdown menu, and enter a Model name (e.g., Catalyst 9300, c7200 or vMX etc.). Click Create.



Step 04: Create a Device Role

Under the Devices section, click on Device Roles.


Click the + Add button. Enter a logical Name for the function of the device (e.g., Access Switch or Core Router). You can also select a Color tag here, which is highly recommended as it helps visually organize your inventory later. Click Create.

Step 05: Create a Platform

This step is the secret sauce for future automation. Under the Devices section, click on Platforms. (Note: For this guide, we will focus specifically on Cisco devices and preparing them for network automation using Ansible).


Click the + Add button. Enter the following key details:
  • Name: Cisco IOS
  • Slug: ios (This is extremely important! Ansible looks at this slug to set the ansible_network_os variable under the hood. Using ios perfectly matches Ansible's native Cisco IOS modules.)
  • Manufacturer: Select the manufacturer you created in Step 2.
Click Create.

Step 06: Adding a Device

Now that we have added the foundational information and built the hierarchy, it is finally time to add a device. Under the Devices section, click on Devices, then click the + Add button.


Fill in the core details for your new piece of equipment:
  • Name: Give your device a hostname (e.g., SW-Core-01).
  • Device Role: Select the role you created in Step 4.
  • Device Type: Select the type you created in Step 3.
  • Platform: Select the operating system you created in Step 5.
  • Site: Select the site you created earlier.
  • Status: Ensure this is set to Active.
Click Create.


Now you have successfully navigated the NetBox database hierarchy and added your very first piece of documented infrastructure. From here, you can start exploring the interface to add IP addresses, connect virtual cables, and build out your complete network Source of Truth!

Setting Up API Keys

If you are deploying NetBox into an existing environment (a "brownfield" network), you certainly don't want to manually click through the GUI to add hundreds of existing devices. Instead, you will use Python scripts or Ansible playbooks to discover your live network and push that data directly into the NetBox database.

Conversely, once NetBox is populated and acting as your Source of Truth, your automation tools will need to poll NetBox to dynamically pull your device inventory before executing network-wide changes.

To allow external scripts to read (poll) and write (push) data, you need to generate a secure API token.

Step 01: Navigate to API Tokens

Look at the top right corner of the NetBox interface and click on your Username (e.g., admin). From the dropdown menu, click on API Tokens.

Step 02: Add a New Token

Click the + Add button in the top right corner.

Step 03: Configure the Token

Fill in the details for your new API key:
  • Token: NetBox automatically pre-fills this field with a secure, random 40-character string. Crucial Step: You must copy and save this exact string before clicking save/create! Once the token is created, it will be hidden from the GUI forever for security reasons.
  • Write enabled: Check this box! If you leave it unchecked, your token will be "Read-Only." A read-only token is great for polling data (like an Ansible dynamic inventory script), but if you also want your scripts to create new devices (pushing data), write access must be enabled.
  • Description: Give it a clear name so you remember what it is for (e.g., Ansible Automation Token).
Click Create.


Note: Since you can never view this token in the GUI again, ensure the string you just copied is stored somewhere safe immediately (like a secure password manager or an encrypted .env file). This token acts as an administrative password for your automation tools—do not hardcode it directly into your scripts or upload it to GitHub!

And there you have it! You have successfully deployed a production-grade NetBox instance on Ubuntu 24.04 using Docker, configured it to automatically recover from host reboots, and laid the foundational database hierarchy for your network inventory. By generating your API token, you have also officially unlocked the door to network automation.

Your lab now has a powerful, centralized "Source of Truth" ready to act as the brain of your infrastructure. Instead of relying on outdated and messy spreadsheets, you can now start integrating tools like Ansible, Python, and NAPALM to dynamically manage your network state.

If you ran into any issues during the setup, or if you have questions about how to structure your specific network hierarchy in NetBox, drop a comment below.

Happy automating!

Comments