Self-Hosting NetBox with Docker Compose

What Is NetBox?

NetBox is the industry-standard open-source platform for modeling and documenting computer networks. Built by DigitalOcean and now maintained by the NetBox community, it tracks IP addresses, racks, devices, circuits, connections, and virtually every other piece of network infrastructure you manage. Think of it as a single source of truth for your entire network — from physical rack layouts to IP assignments to cable connections.

For self-hosters running anything beyond a couple of Docker containers, NetBox eliminates the “which IP did I assign to what?” spreadsheet problem. It has a full REST API, GraphQL endpoint, and webhook support, making it the backbone for network automation workflows.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 2 GB of free RAM (NetBox + PostgreSQL + Redis)
  • 1 GB of free disk space
  • A domain name (optional, for HTTPS access)

Docker Compose Configuration

Create a directory for NetBox:

mkdir -p /opt/netbox && cd /opt/netbox

Create a docker-compose.yml:

services:
  netbox:
    image: netboxcommunity/netbox:v4.5.4
    container_name: netbox
    ports:
      - "8000:8080"
    environment:
      DB_HOST: postgres
      DB_NAME: netbox
      DB_USER: netbox
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_HOST: redis
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      REDIS_CACHE_HOST: redis-cache
      REDIS_CACHE_PASSWORD: ${REDIS_CACHE_PASSWORD}
      SECRET_KEY: ${SECRET_KEY}
      SUPERUSER_NAME: admin
      SUPERUSER_EMAIL: [email protected]
      SUPERUSER_PASSWORD: ${SUPERUSER_PASSWORD}
      SKIP_SUPERUSER: "false"
      GRAPHQL_ENABLED: "true"
      WEBHOOKS_ENABLED: "true"
      CORS_ORIGIN_ALLOW_ALL: "true"
    volumes:
      - netbox-media:/opt/netbox/netbox/media
      - netbox-reports:/opt/netbox/netbox/reports
      - netbox-scripts:/opt/netbox/netbox/scripts
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      redis-cache:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/login/"]
      interval: 15s
      timeout: 3s
      start_period: 90s
      retries: 5
    restart: unless-stopped

  netbox-worker:
    image: netboxcommunity/netbox:v4.5.4
    container_name: netbox-worker
    command: /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py rqworker
    environment:
      DB_HOST: postgres
      DB_NAME: netbox
      DB_USER: netbox
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_HOST: redis
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      REDIS_CACHE_HOST: redis-cache
      REDIS_CACHE_PASSWORD: ${REDIS_CACHE_PASSWORD}
      SECRET_KEY: ${SECRET_KEY}
    volumes:
      - netbox-media:/opt/netbox/netbox/media
      - netbox-reports:/opt/netbox/netbox/reports
      - netbox-scripts:/opt/netbox/netbox/scripts
    depends_on:
      netbox:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "ps -aux | grep -v grep | grep -q rqworker || exit 1"]
      interval: 15s
      timeout: 3s
      start_period: 20s
    restart: unless-stopped

  postgres:
    image: postgres:17-alpine
    container_name: netbox-postgres
    environment:
      POSTGRES_USER: netbox
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: netbox
    volumes:
      - netbox-postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -q -t 2 -d netbox -U netbox"]
      interval: 10s
      timeout: 5s
      start_period: 20s
      retries: 5
    restart: unless-stopped

  redis:
    image: valkey/valkey:9.0-alpine
    container_name: netbox-redis
    command: valkey-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - netbox-redis:/data
    healthcheck:
      test: ["CMD-SHELL", "valkey-cli --pass ${REDIS_PASSWORD} ping | grep -q PONG"]
      interval: 10s
      timeout: 3s
      start_period: 5s
      retries: 5
    restart: unless-stopped

  redis-cache:
    image: valkey/valkey:9.0-alpine
    container_name: netbox-redis-cache
    command: valkey-server --requirepass ${REDIS_CACHE_PASSWORD}
    volumes:
      - netbox-redis-cache:/data
    healthcheck:
      test: ["CMD-SHELL", "valkey-cli --pass ${REDIS_CACHE_PASSWORD} ping | grep -q PONG"]
      interval: 10s
      timeout: 3s
      start_period: 5s
      retries: 5
    restart: unless-stopped

volumes:
  netbox-media:
  netbox-reports:
  netbox-scripts:
  netbox-postgres:
  netbox-redis:
  netbox-redis-cache:

Create the .env file:

cat > /opt/netbox/.env << 'EOF'
# CHANGE ALL OF THESE VALUES
DB_PASSWORD=change-this-strong-db-password
REDIS_PASSWORD=change-this-redis-password
REDIS_CACHE_PASSWORD=change-this-cache-password
SECRET_KEY=change-this-to-a-random-50-char-string-use-openssl-rand
SUPERUSER_PASSWORD=change-this-admin-password
EOF

Generate a proper secret key:

# Replace the SECRET_KEY line in .env with a generated value
SECRET_KEY=$(openssl rand -hex 25)
sed -i "s/^SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" /opt/netbox/.env

Start the stack:

docker compose up -d

The first start takes 60-90 seconds for database migrations. Check readiness:

docker compose logs -f netbox
# Wait for: "Listening at: http://0.0.0.0:8080"

Initial Setup

1. Log In

Open http://your-server-ip:8000 and log in with the credentials you set in .env:

  • Username: admin
  • Password: the value of SUPERUSER_PASSWORD

2. Configure Sites

Navigate to Organization > Sites and create your first site (e.g., “Home Lab”, “Office Rack”). Sites are the top-level organizational unit.

3. Add IP Prefixes

Go to IPAM > Prefixes and add your network ranges:

  • 192.168.1.0/24 — Home LAN
  • 10.0.0.0/8 — Docker internal
  • 172.16.0.0/12 — VPN range

4. Document Devices

Under Devices > Device Types, create templates for your hardware. Then add actual devices under Devices > Devices, assigning them to sites, racks, and IP addresses.

Configuration

Key Features

FeatureDescription
IPAMIP address management with prefix hierarchies and VLAN tracking
DCIMData center infrastructure modeling — racks, devices, cables
CircuitsWAN circuit and provider tracking
VirtualizationVM and cluster documentation
ContactsOrganizational contacts linked to infrastructure
TenancyMulti-tenant resource assignment
Custom FieldsExtend any model with custom attributes
WebhooksHTTP callbacks on data changes
REST APIFull CRUD API for automation
GraphQLFlexible querying for complex relationships

API Access

NetBox’s REST API is comprehensive. Generate an API token under Admin > API Tokens:

# List all devices
curl -H "Authorization: Token your-api-token" \
  http://localhost:8000/api/dcim/devices/

# Create an IP address
curl -X POST -H "Authorization: Token your-api-token" \
  -H "Content-Type: application/json" \
  http://localhost:8000/api/ipam/ip-addresses/ \
  -d '{"address":"192.168.1.50/24","status":"active","description":"Proxmox host"}'

Custom Fields

Extend any NetBox model with custom fields — useful for tracking self-hosting-specific data:

  1. Navigate to Customization > Custom Fields
  2. Add fields like docker_host, backup_schedule, last_patched
  3. Fields appear on the relevant object forms and API responses

Advanced Configuration

LDAP/SSO Authentication

Mount a custom configuration file for LDAP integration:

volumes:
  - ./configuration/ldap_config.py:/etc/netbox/config/ldap_config.py:ro

Plugins

NetBox supports community plugins (BGP, DNS, access lists, etc.). Install by extending the Docker image:

FROM netboxcommunity/netbox:v4.5.4
RUN /opt/netbox/venv/bin/pip install netbox-bgp netbox-dns

Update your compose file to use the custom image.

Reverse Proxy

For HTTPS access, route through Nginx Proxy Manager or Caddy:

Caddy:

netbox.yourdomain.com {
    reverse_proxy localhost:8000
}

See Reverse Proxy Setup for detailed instructions.

Backup

Critical Data

DataLocationMethod
All configuration, devices, IPsPostgreSQL databasepg_dump
Uploaded images, attachmentsnetbox-media volumeFile copy
Custom reportsnetbox-reports volumeFile copy
Custom scriptsnetbox-scripts volumeFile copy

Backup Script

#!/bin/bash
BACKUP_DIR="/opt/backups/netbox/$(date +%F)"
mkdir -p "$BACKUP_DIR"

# Database dump
docker exec netbox-postgres pg_dump -U netbox netbox > "$BACKUP_DIR/netbox.sql"

# Config and volumes
cp /opt/netbox/.env "$BACKUP_DIR/"
docker run --rm -v netbox-media:/data -v "$BACKUP_DIR":/backup alpine \
  tar czf /backup/media.tar.gz -C /data .

See Backup Strategy for comprehensive approaches.

Troubleshooting

NetBox Stuck on “Applying database migrations”

Symptom: Container health check fails, logs show migration running for 5+ minutes

Fix: First-time migrations on a fresh database can take several minutes. Wait up to 5 minutes. If it persists, check PostgreSQL health:

docker compose logs postgres

Worker Not Processing Jobs

Symptom: Webhooks, reports, or scripts don’t execute

Fix: Check the worker container is running and healthy:

docker compose ps netbox-worker
docker compose logs netbox-worker

“CSRF Verification Failed” on Login

Symptom: Login form returns CSRF error

Fix: If behind a reverse proxy, ensure the proxy forwards the Host header and set CORS_ORIGIN_ALLOW_ALL=true or configure ALLOWED_HOSTS in a custom configuration file.

Redis Connection Refused

Symptom: NetBox can’t connect to Redis, logs show ConnectionRefusedError

Fix: Ensure both Redis containers (broker and cache) are healthy. Verify the passwords in .env match between NetBox and Redis services.

Slow Page Loads

Symptom: Pages take 3+ seconds to render

Fix: Increase worker count. Add to NetBox environment:

GRANIAN_WORKERS: "4"  # Match to CPU cores

Resource Requirements

ResourceValue
RAM~800 MB total (NetBox ~300 MB + PostgreSQL ~200 MB + 2× Redis ~50 MB each + Worker ~200 MB)
CPUModerate — Django ORM is CPU-bound on complex queries
Disk~1 GB for containers + database grows with infrastructure size
NetworkMinimal; web traffic only

Verdict

NetBox is the definitive tool for network documentation and IP address management. If you run more than a handful of devices and services, the structured approach to tracking IPs, VLANs, racks, and connections pays for itself in reduced “wait, what’s on 192.168.1.47?” moments. The REST API makes it the foundation for network automation.

For simple IP tracking without the full DCIM/infrastructure modeling, phpIPAM is lighter. NetBox is the right choice when you want comprehensive infrastructure documentation, not just IP management.

FAQ

Is NetBox an alternative to a DNS server?

No. NetBox documents your network — it doesn’t serve DNS queries. Use it alongside Unbound, CoreDNS, or Pi-hole for DNS resolution. NetBox tracks what IP goes where; DNS servers resolve names to those IPs.

Can NetBox manage my Docker networks?

Not directly. NetBox models physical and virtual networks, IP assignments, and device connections. For Docker-specific management, use Portainer. You can document your Docker host IPs and networks in NetBox for reference.

Why does NetBox need two Redis instances?

One handles the message queue (background jobs, webhooks) with persistence enabled. The other is a cache (page rendering, API responses) that can be safely lost on restart. Separating them prevents cache eviction from disrupting job processing.

Comments