Pin NetBox to 4.6.10 (netbox-docker 5.0.2) + verified upgrade path #1

Merged
doni merged 10 commits from netbox-4.6.10-pin into main 2026-09-29 21:22:38 +00:00
Collaborator

Stops floating on the release branch (was silently tracking 4.7.x). Pins NetBox 4.6.10.

  • netbox-docker repo tags are PACKAGING versions (5.0.2), NOT NetBox versions — pin is two vars that move together (netbox_repo_branch + netbox_version).
  • Image pinned DIRECTLY via override (tested: environment.VERSION does not drive ${VERSION} in compose image line).
  • update-netbox.yml: re-render override after force-checkout; verify /api/status/ reports pinned version, fail on mismatch.
  • backup-netbox.yml: fix hosts (netbox_servers) + pg_dump service (postgres).

All playbooks pass ansible-playbook --syntax-check (ansible 2.21.4); compose override resolution + verify-block Jinja tested against real tools.

Ref: homelab-infra t_8af9ccbb

Stops floating on the `release` branch (was silently tracking 4.7.x). Pins NetBox 4.6.10. - netbox-docker repo tags are PACKAGING versions (5.0.2), NOT NetBox versions — pin is two vars that move together (netbox_repo_branch + netbox_version). - Image pinned DIRECTLY via override (tested: environment.VERSION does not drive ${VERSION} in compose image line). - update-netbox.yml: re-render override after force-checkout; verify /api/status/ reports pinned version, fail on mismatch. - backup-netbox.yml: fix hosts (netbox_servers) + pg_dump service (postgres). All playbooks pass ansible-playbook --syntax-check (ansible 2.21.4); compose override resolution + verify-block Jinja tested against real tools. Ref: homelab-infra t_8af9ccbb
- netbox_repo_branch: release -> 5.0.2 (stop floating on the release branch,
  which tracks NetBox 4.7.x). netbox-docker tags are PACKAGING versions, not
  NetBox versions; the app version comes from the image tag.
- Add netbox_version: v4.6.10-5.0.2, exported to compose via the override
  (environment.VERSION) so the pin survives the force: yes git checkout that
  would clobber a .env file. netbox-worker inherits the image via the
  upstream &netbox anchor.
- update-netbox.yml: re-render docker-compose.override.yml after the git
  checkout; verify /api/status/ reports the pinned version and fail if not.
- backup-netbox.yml: fix hosts (netbox -> netbox_servers, matches inventory
  group) and pg_dump service name (db -> postgres).
- README: version pinning docs + backup-first upgrade runbook.

Ref: homelab-infra t_8af9ccbb
Verified by test: service-level environment.VERSION does NOT control the
${VERSION} in the upstream image line — compose resolves ${VERSION} from
shell env / .env at parse time, before service environment is applied. The
previous approach would have silently run the default image. Overriding the
netbox service's image: directly is reliable and survives the force-checkout.

Also validated: all playbooks pass ansible-playbook --syntax-check; the
/api/status/ verify block's Jinja (split + regex_replace on netbox_version)
executes correctly against real ansible.
backup-netbox.yml uses ansible_date_time.iso8601_basic_short but has
gather_facts: no, so the fact was undefined at runtime (ansible_date_time
comes from the setup module). Add a targeted setup task with
gather_subset=[!all, date_time] so the fact populates without pulling the
full fact set. Verified: fact resolves (iso8601_basic_short=20260929T...)
and playbook passes --syntax-check.
The backup task used community.docker.docker_compose_v2 with command:, which
the module doesn't support (it's stack-lifecycle only) — runtime failure.
Replace with ansible.builtin.shell running docker compose exec -T postgres
pg_dump, redirecting straight to the backup file (no giant register+copy).
Add a non-empty stat check so a failed/empty dump fails loudly.

Verified against real module docs (Context7) + ansible-doc param dump:
docker_compose_v2 accepts project_src/pull/state/recreate, NOT command.

Upgrade path (update-netbox.yml) audited clean: all module params validated
against ansible-doc, docker compose config confirms the image override
resolves the pinned tag, and --hash confirms config-change-driven recreate
works.
The compose-config backup used copy with src=/opt/netbox-docker/ which reads
from the Ansible controller, not the managed host — 'Could not find or access
on the Ansible Controller'. Add remote_src: yes for remote->remote copy, and
create the dest dir first.

Audited all copy/template/fetch/archive src uses across playbooks+roles: only
this one was affected (templates use local role templates correctly, archive
already remote-side).
The override bound /opt/netbox-data/postgres to /var/lib/postgresql/data
(pg<=17 layout). netbox-docker 5.0.2 runs postgres:18, which expects the
mount at /var/lib/postgresql (major-versioned subdirs underneath) and refuses
to start against data in .../data — exactly the failure seen on upgrade.

Repoint the mount to /var/lib/postgresql. NOTE: this changes where the engine
looks, so existing data (at /opt/netbox-data/postgres/PG_VERSION=17) is NOT
picked up automatically — the host-side migration (move 17 data aside, init
fresh 18, reload from pg_dump) runs on the host per the upgrade runbook.
The verify task hit /api/status/ anonymously, but that endpoint uses
IsAuthenticatedOrLoginNotRequired (netbox/api/authentication.py) — with
LOGIN_REQUIRED=true it returns 403 'Authentication credentials were not
provided'. Confirmed against NetBox v4.6.10 source.

Read the authoritative version from the running app instead: exec into the
netbox container and print settings.RELEASE.version via django.conf.settings
(venv python path + working-dir confirmed against netbox-docker 5.0.2
Dockerfile / launch-netbox.sh). Health-check (GET / 200) still proves HTTP
reachability; this proves the running version regardless of LOGIN_REQUIRED.
django.conf.settings raised ImproperlyConfigured — DJANGO_SETTINGS_MODULE is
not set in the container env (granian gets settings via --working-dir, not the
env var), so a bare python can't resolve settings. The version is canonical in
the app's own release.yaml (read by utilities/release.load_release_data with
no Django boot). grep '^version:' from /opt/netbox/netbox/release.yaml and
extract with regex_replace. Regex tested against real ansible -> '4.6.10'.
doni merged commit a3b7c6593c into main 2026-09-29 21:22:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
doni/netbox-ansible!1
No description provided.