# NetBox — Cloudron Package

[NetBox](https://github.com/netbox-community/netbox) v4.6.10 — open-source
IPAM/DCIM: IP addresses, prefixes, VLANs, sites, racks, devices, circuits,
virtualization, tenancy, REST + GraphQL APIs. Packaged as an
**official-image wrapper** around `netboxcommunity/netbox:v4.6.10`
(built from netbox-docker 5.0.2, served by Granian on :8080), digest-pinned.

## Authentication (auth gate: ✅ OIDC preferred)

NetBox 4.6 authenticates via **python-social-auth** with no legacy
`SOCIAL_AUTH_TYPE` involved:

- `REMOTE_AUTH_BACKEND = social_core.backends.open_id_connect.OpenIdConnectAuth`
- `SOCIAL_AUTH_OIDC_OIDC_ENDPOINT / KEY / SECRET` ← wired by `start.sh`
  from the Cloudron platform OIDC provider (`CLOUDRON_OIDC_*`,
  manifestVersion 2), scopes `openid profile email`.

Two consequences that matter on first boot:

1. **SSO-registered users are created without privileges.** An admin must
   exist first — create it from the Cloudron **terminal**:

   ```sh
   cd /opt/netbox/netbox
   python3 manage.py createsuperuser
   ```

   Then log in on `/login/` with the local form (it stays available
   alongside the SSO button) and grant groups/permissions as needed.

2. The platform OIDC client must register the standard redirect:
   `https://<app-domain>/complete/oidc/` (the Cloudron provider handles
   this when the app is installed).

## Runtime layout

| Concern | How |
|---------|-----|
| Database | Cloudron `postgresql` addon (PG 16 ≥ NetBox 4.6's PG 14 floor; PG 15+ required from 4.7) |
| Cache + tasks | Cloudron `redis` addon — one instance, two logical DBs (tasks=0, caching=1, upstream convention) |
| Migrations | Run automatically by the upstream `docker-entrypoint.sh` (waits for PostgreSQL first) |
| RQ worker | Backgrounded by `start.sh`, started only after the web port answers (i.e. post-migration) — webhooks, scripts, reports, scheduled/housekeeping jobs |
| Persistence | `/app/data` (localstorage): `media/` (attachments), `reports/`, `scripts/` (custom code), `.secret_key` |
| SECRET_KEY | Generated once (64 hex chars), persisted; rotating it invalidates sessions |
| First boot | Allow up to ~10-15 min — `migrate` + `reindex --lazy` run before Granian binds :8080 (observed: ~24 min on a 3x-oversubscribed dev box, minutes on an idle host; subsequent boots are fast) |

## Operator knobs (`.env.example`)

| Variable | Default | Purpose |
|----------|---------|---------|
| `NETBOX_TIME_ZONE` | `UTC` | Django `TIME_ZONE` |
| `NETBOX_GRANIAN_WORKERS` | `4` | Web workers (lower on small installs) |
| `NETBOX_METRICS_ENABLED` | `false` | Prometheus endpoint at `/metrics` |

## Upgrades

The image is pinned by tag **and** digest in the `Dockerfile`. To upgrade,
bump both (verify the new amd64 digest with
`docker manifest inspect netboxcommunity/netbox:<tag>`) and rebuild —
migrations run automatically on first boot.

## Package pattern

Official-image wrapper + `start.sh` env mapping — see the repo
`JOURNAL.md` NetBox section for the full write-up (worker-gating trick,
build-time persistence symlinks, OIDC wiring).
