Quick start (5 min)
Spreadsheets and fragmented wiki pages make network management a nightmare. Subnet allocations drift, interface descriptions go stale, and routine maintenance turns into guesswork. NetBox eliminates this chaos by serving as an authoritative Single Source of Truth (SSoT) for Data Center Infrastructure Management (DCIM) and IP Address Management (IPAM).
To stand up an instance locally or on an Ubuntu staging VM (2 vCPUs, 4 GB RAM), use the official Docker Compose project.
# 1. Clone the official NetBox Docker repository
git clone -b release https://github.com/netbox-community/netbox-docker.git
cd netbox-docker
# 2. Create an environment override file
touch docker-compose.override.yml
# 3. Pull images and launch services in detached mode
docker compose pull
docker compose up -d
Give PostgreSQL and Redis roughly 60 to 90 seconds to run initial database migrations. Check the stack status with docker compose ps. Once all containers show healthy, provision your administrator account:
docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser \
--username admin \
--email [email protected]
Head to http://<your-server-ip>:8000 in your browser. Sign in with your new superuser account to reach the dashboard.
Deep dive: Modeling DCIM and IPAM
Before writing automation scripts, you need to understand NetBox’s fundamental design principle: it models intended state, not operational telemetry. NetBox documents what your topology should look like. It does not monitor live link metrics, CPU spikes, or BGP neighbor flap counts.
1. Core DCIM Hierarchy
NetBox relies on a strict relational model. Build your infrastructure data bottom-up in this exact sequence to prevent broken foreign key references:
- Organization: Group physical locations into Regions, Site Groups, and Sites (e.g.,
Region: US-East→Site: us-east-dc1). - Racks: Define standard server cabinets (e.g.,
Rack-A01at42Uwith standard 19-inch mounting). - Device Types: Define hardware profiles with exact interface numbering (e.g.,
Cisco Catalyst 9300-48Pwith 48x 1G ports and 4x 10G SFP+ uplinks). - Devices: Instantiate specific serialized assets (e.g.,
sw-leaf-01) mounted at rack unitU24withinRack-A01.
2. IPAM Mapping
Instead of floating in detached spreadsheets, IP addresses in NetBox bind directly to device interfaces. This enforces clean L2/L3 topology mapping:
- RIRs & Aggregates: Allocate top-level CIDR blocks (e.g., RFC 1918 allocations like
10.0.0.0/8or172.16.0.0/12). - VRFs: Segment routing tables when running multi-tenant networks or dedicated out-of-band management fabrics.
- Prefixes: Carve out functional subnets mapped to specific VLANs (e.g.,
10.20.100.0/24mapped toVLAN 100 - OOBM). - IP Addresses: Assign static interface IPs with CIDR masks (e.g., assigning
10.20.100.11/24toGigabitEthernet1/0/1onsw-leaf-01).
Automating Configuration Rendering via Python API
The real payoff of an SSoT arrives when your pipelines query intended state straight from the API. No more manual copy-pasting or brittle static Jinja variables.
Generating an API Token
Click your user profile in the top-right corner of the web UI → API Tokens → Add a Token. Leave expiration empty for service accounts, copy the 40-character hexadecimal token, and export it to your environment:
export NETBOX_URL="http://127.0.0.1:8000"
export NETBOX_TOKEN="0123456789abcdef0123456789abcdef01234567"
Extracting Inventory and Rendering Configs with Python
Use pynetbox to query the REST endpoints and Jinja2 to render vendor-neutral or Cisco IOS configurations.
pip install pynetbox jinja2 netaddr
Save the following script as generate_network_config.py:
import os
import ipaddress
import pynetbox
from jinja2 import Template
NETBOX_URL = os.getenv("NETBOX_URL", "http://127.0.0.1:8000")
NETBOX_TOKEN = os.getenv("NETBOX_TOKEN")
nb = pynetbox.api(NETBOX_URL, token=NETBOX_TOKEN)
# Jinja2 template for switch port configuration
interface_template = Template("""
! Auto-generated configuration for {{ device.name }}
hostname {{ device.name }}
!
{% for iface in interfaces %}
interface {{ iface.name }}
description {{ iface.description or 'Unused Port' }}
{% if iface.ip %}
ip address {{ iface.ip.ip }} {{ iface.ip.netmask }}
{% else %}
no ip address
{% endif %}
{% if iface.enabled %}no shutdown{% else %}shutdown{% endif %}
!
{% endfor %}
""")
def build_config(device_name: str):
device = nb.dcim.devices.get(name=device_name)
if not device:
raise ValueError(f"Device '{device_name}' not found in NetBox inventory.")
# Query all physical and logical interfaces for the target device
interfaces = list(nb.dcim.interfaces.filter(device_id=device.id))
for iface in interfaces:
# Fetch primary IPv4/IPv6 addresses bound to this interface
ip_records = list(nb.ipam.ip_addresses.filter(interface_id=iface.id))
if ip_records:
# Parse CIDR notation (e.g. 10.20.100.11/24) into IP and dotted netmask
parsed_ip = ipaddress.ip_interface(ip_records[0].address)
iface.ip = parsed_ip
else:
iface.ip = None
rendered = interface_template.render(device=device, interfaces=interfaces)
print(rendered)
if __name__ == "__main__":
# Example: Render config for edge switch
build_config("sw-leaf-01")
Run the script to produce clean, ready-to-deploy Cisco CLI snippets in under two seconds. When an engineer updates an interface description or IP allocation in NetBox, the pipeline generates identical changes across 50 switches without human typo risk.
Ansible Dynamic Inventory Integration
You do not need to maintain static hosts.ini files. The official NetBox collection dynamically synchronizes your inventory, roles, and platform tags into Ansible playbooks.
ansible-galaxy collection install netbox.netbox
Create a dynamic inventory plugin file named netbox_inventory.yml:
plugin: netbox.netbox.nb_inventory
api_endpoint: http://127.0.0.1:8000
token: 0123456789abcdef0123456789abcdef01234567
validate_certs: false
config_context: true
group_by:
- site
- device_roles
query_filters:
- status: active
Verify that Ansible builds your host groups correctly:
ansible-inventory -i netbox_inventory.yml --graph
Practical tips for Day-2 Operations
- Store platform variables in Config Contexts: Keep device modeling clean. Define global and site-level variables—such as BGP AS numbers (e.g.,
65001), NTP servers (10.0.0.123), and Syslog targets—inside NetBox Config Contexts. - Trigger GitOps pipelines via Webhooks: Configure NetBox Webhooks to dispatch HTTP POST payloads to GitHub Actions or GitLab CI runners whenever an interface or device updates. This kicks off dry-run diff checks instantly.
- Enforce strict SSoT discipline: Ban ad-hoc CLI changes on production switches. If engineers bypass NetBox to fix an issue manually, your next automated rollout will overwrite their hotfix.
- Automate daily database snapshots: PostgreSQL holds your entire network truth. Set up a daily cron job at
02:00 UTCto dump the database and store compressed archives off-site:
# Automated daily PostgreSQL backup
docker compose exec -T postgres pg_dump -U netbox netbox | gzip > /var/backups/netbox_$(date +%F_%H%M%S).sql.gz

