Skip to content

Instantly share code, notes, and snippets.

@nv6
Forked from Harry-Chen/README.md
Last active March 9, 2025 05:00
Show Gist options
  • Select an option

  • Save nv6/1b1101e7b1b920165165e305b4abcd21 to your computer and use it in GitHub Desktop.

Select an option

Save nv6/1b1101e7b1b920165165e305b4abcd21 to your computer and use it in GitHub Desktop.
NetBox Docker deployment under subdirectory using Caddy

Tested with NetBox Community v4.2.5-Docker-3.2.0

full example

The attached docker-compose.override.yml shows a full working example bundled with Caddy. Running it should make Netbox accessible at https://mydomain.net/netbox.

This variant of Caddy doesn't require a user-defined Caddyfile for configuration. Rather it dynamically derives the Caddyfile from aggregated Docker labels. See https://github.com/lucaslorentz/caddy-docker-proxy for more info.

Otherwise, follow the next section to configure an existing Caddy instance using a regular Caddyfile.

original instructions

Assume your deployment is under /netbox:

Add to configuration/extra.py:

from os import environ
BASE_PATH = environ.get('BASE_PATH', '')

Then merge the following with your own docker-compose.override.yml (or create one if it doesn't exist) to make health checker of Docker happy:

version: '3.4'
services:
  netbox:
    healthcheck:
      test: "curl -f http://localhost:8080/netbox/api/ || exit 1"
    environment:
      BASE_PATH: '/netbox'

Outside Caddy config (standard Caddyfile):

:80 {
  handle /netbox/* {
    encode zstd gzip  # optional
    reverse_proxy 127.0.0.1:8080
  }
  handle /netbox/static/* {
    encode zstd gzip  # optional
    reverse_proxy 127.0.0.1:8080
    uri strip_prefix /netbox
  }
  redir /netbox /netbox/
}

The trick is to strip BASE_PATH on any requests to static resources.

services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
ports:
- 80:80
- 443:443
environment:
CADDY_INGRESS_NETWORKS: "ingress"
networks:
- ingress
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- caddy_data:/data
restart: always
netbox:
environment:
BASE_PATH: '/netbox'
healthcheck:
test: "curl -f http://localhost:8080/netbox/login/ || exit 1"
restart: unless-stopped
labels:
caddy: "mydomain.net"
caddy.tls: "internal" # if mydomain.net isn't a valid domain, generate a self-signed local root CA instead of attempting to get one from a legit CA (e.g. LetsEncrypt)
caddy.redir: "/netbox /netbox/"
caddy.handle_0: "/netbox/static/*"
caddy.handle_0.uri: "strip_prefix /netbox"
caddy.handle_0.reverse_proxy: "{{upstreams 8080}}"
caddy.handle_0.encode: zstd gzip # optional
caddy.handle_1: "/netbox/*"
caddy.handle_1.reverse_proxy: "{{upstreams 8080}}"
caddy.handle_1.encode: zstd gzip # optional
networks:
- dataplane
- ingress
netbox-worker:
restart: unless-stopped
networks:
- dataplane
netbox-housekeeping:
restart: unless-stopped
networks:
- dataplane
postgres:
restart: unless-stopped
networks:
- dataplane
redis:
restart: unless-stopped
networks:
- dataplane
redis-cache:
restart: unless-stopped
networks:
- dataplane
networks:
dataplane:
ingress:
name: ingress
volumes:
caddy_data:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment