Installing NetBox on Rocky Linux 9.7

NetBox: v4.5.4
Operation System: Rocky Linux 9.7

System Settings

~]$ sudo dnf check-update
~]$ sudo dnf -y upgrade

~]$ sudo setenforce 0
~]$ sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

Installing PostgreSQL 18

# Install the repository RPM:
~]$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# Install PostgreSQL:
~]$ sudo dnf install -y postgresql18-server

# Optionally initialize the database and enable automatic start:
~]$ sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
~]$ sudo systemctl enable postgresql-18
~]$ sudo systemctl start postgresql-18

~]$ psql -V
psql (PostgreSQL) 18.3

~]$ sudo --login -u postgres psql
[sudo] password for netbox:
psql (18.3)
Type "help" for help.

postgres=# CREATE DATABASE netbox;
postgres=# CREATE USER netbox WITH PASSWORD 'J5brHrAXFLQSif0K';
postgres=# ALTER DATABASE netbox OWNER TO netbox;

postgres=# \connect netbox;
netbox=# GRANT CREATE ON SCHEMA public TO netbox;
netbox=# \q

~]$ psql --username netbox --password --host localhost netbox
netbox=> \conninfo
netbox=> \q

Installing Redis

~]$ sudo dnf -y install redis
~]$ sudo systemctl enable --now redis

~]$ redis-cli ping
PONG

Installing System Packages

~]$ sudo dnf -y install gcc libxml2-devel libxslt-devel libffi-devel libpq-devel openssl-devel redhat-rpm-config git
~]$ sudo dnf -y install python3.12 python3.12-devel

~]$ python3.12 -V
Python 3.12.12

Installing NetBox

~]$ sudo mkdir -p /opt/netbox/
~]$ sudo git clone -b main --depth 1 https://github.com/netbox-community/netbox.git /opt/netbox/

~]$ sudo git checkout v4.5.4

# NetBox System User
~]$ sudo groupadd --system netbox
~]$ sudo adduser --system -g netbox netbox
~]$ sudo chown --recursive netbox /opt/netbox/netbox/media/
~]$ sudo chown --recursive netbox /opt/netbox/netbox/reports/
~]$ sudo chown --recursive netbox /opt/netbox/netbox/scripts/

# Configuration
~]$ sudo cp /opt/netbox/netbox/netbox/configuration_example.py /opt/netbox/netbox/netbox/configuration.py

# ALLOWED_HOSTS
~]$ sudo sed -i "/^ALLOWED_HOSTS/s/\[.*]/\['*']/" /opt/netbox/netbox/netbox/configuration.py

# DATABASE
~]$ sudo sed -i "/PostgreSQL username/s/'USER': '.*'/'USER': 'netbox'/" /opt/netbox/netbox/netbox/configuration.py
~]$ sudo sed -i "/PostgreSQL password/s/'PASSWORD': '.*'/'PASSWORD': 'J5brHrAXFLQSif0K'/" /opt/netbox/netbox/netbox/configuration.py

# GENERATE_SECRET_KEY
~]$ GENERATE_SECRET_KEY=`python3.12 /opt/netbox/netbox/generate_secret_key.py`

# API_TOKEN_PEPPERS
~]$ sudo sed -i "s|^API_TOKEN_PEPPERS.*|API_TOKEN_PEPPERS = {\n 1: \'${GENERATE_SECRET_KEY}\',\n}|" /opt/netbox/netbox/netbox/configuration.py

# SECRET_KEY
~]$ sudo sed -i "s|^SECRET_KEY.*|SECRET_KEY = \'${GENERATE_SECRET_KEY}\'|" /opt/netbox/netbox/netbox/configuration.py

~]$ grep -Ev '^#|^$|^ *#' /opt/netbox/netbox/netbox/configuration.py

# Run the Upgrade Script
~]$ sudo PYTHON=/usr/bin/python3.12 /opt/netbox/upgrade.sh

# Create a Super User (e.g. admin/admin)
~]$ source /opt/netbox/venv/bin/activate
(venv) $ python3.12 /opt/netbox/netbox/manage.py createsuperuser
(venv) $ deactivate

# (Option) Test the Application
~]$ sudo firewall-cmd --zone=public --add-port=8000/tcp

~]$ source /opt/netbox/venv/bin/activate
(venv) $ python3.12 /opt/netbox/netbox/manage.py runserver 0.0.0.0:8000 --insecure
(venv) $ deactivate

Gunicorn and systemd Setup

~]$ sudo cp /opt/netbox/contrib/gunicorn.py /opt/netbox/gunicorn.py

~]$ sudo cp -v /opt/netbox/contrib/*.service /etc/systemd/system/
~]$ sudo systemctl daemon-reload
~]$ sudo systemctl enable --now netbox netbox-rq
~]$ systemctl status netbox netbox-rq

Installing HTTP Server

# Obtain an SSL Certificate
~]$ sudo mkdir -p /etc/ssl/private/
~]$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/netbox.key \
-out /etc/ssl/certs/netbox.crt

# Install nginx
~]$ sudo dnf -y install nginx
~]$ sudo cp /etc/nginx/nginx.conf{,.bak}
~]$ sudo sed -i '/^ server {/,/^ }/s/^/#/' /etc/nginx/nginx.conf
~]$ sudo cp /opt/netbox/contrib/nginx.conf /etc/nginx/conf.d/netbox.conf
~]$ sudo systemctl enable --now nginx
~]$ systemctl status nginx

# Allow https
~]$ sudo firewall-cmd --zone=public --add-service=https --permanent
~]$ sudo firewall-cmd --reload

Installing Plugins

Attachments
Documents
Inventory
Topology Views
QR Code
Reorder Rack
Secrets

~]$ source /opt/netbox/venv/bin/activate

(venv) $ sudo /opt/netbox/venv/bin/pip install netbox-attachments netbox-documents netbox-inventory \
netbox-topology-views netbox-qrcode netbox-reorder-rack netbox-secrets
(venv) $ sudo bash -c "echo 'netbox-attachments' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-documents' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-inventory' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-topology-views' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-qrcode' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-reorder-rack' >> /opt/netbox/local_requirements.txt"
(venv) $ sudo bash -c "echo 'netbox-secrets' >> /opt/netbox/local_requirements.txt"

(venv) $ sudo bash -c "cat >> /opt/netbox/netbox/netbox/configuration.py << EOF

# Plugins
PLUGINS = ['netbox_attachments','netbox_documents','netbox_inventory','netbox_topology_views','netbox_qrcode','netbox_reorder_rack','netbox_secrets']
PLUGINS_CONFIG = {
'netbox_attachments': {
'apps': ['dcim', 'ipam', 'circuits', 'tenancy', 'virtualization', 'wireless', 'inventory_monitor'],
'display_default': 'right_page',
'display_setting': {
'ipam.vlan': 'left_page',
'dcim.device': 'full_width_page',
'dcim.devicerole': 'full_width_page',
'inventory_monitor.probe': 'additional_tab',
},
},

'netbox_documents': {
'enable_navigation_menu': True,
'documents_location': 'left',
'custom_doc_types': [],
'allowed_doc_types': {},
},

'netbox_inventory': {
'used_status_name': 'used',
'stored_status_name': 'stored',
'sync_hardware_serial_asset_tag': True,
},

'netbox_topology_views': {
'static_image_directory': 'netbox_topology_views/img',
'allow_coordinates_saving': True,
'always_save_coordinates': True
}

'netbox_secrets': {
'apps': ['dcim.device', 'virtualization.virtualmachine'],
'display_default': 'tab_view',
'display_setting': {
'dcim.device': 'full_width_page',
'virtualization.virtualmachine': 'right_page',
},
}
}
EOF"

(venv) $ sudo mkdir -p /opt/netbox/netbox/media/netbox-attachments
(venv) $ sudo chown netbox /opt/netbox/netbox/media/netbox-attachments

(venv) $ sudo mkdir -p /opt/netbox/netbox/static/netbox_topology_views
(venv) $ sudo chown netbox /opt/netbox/netbox/static/netbox_topology_views

(venv) $ sudo mkdir -p /opt/netbox/netbox/static/netbox_reorder_rack
(venv) $ sudo chown netbox /opt/netbox/netbox/static/netbox_reorder_rack
(venv) $ sudo mkdir -p /opt/netbox/netbox/static/api/plugins/reorder/save/
(venv) $ sudo chown netbox /opt/netbox/netbox/static/api/plugins/reorder/save/

(venv) $ python3.12 /opt/netbox/netbox/manage.py migrate
(venv) $ python3.12 /opt/netbox/netbox/manage.py reindex --lazy
(venv) $ python3.12 /opt/netbox/netbox/manage.py collectstatic --no-input
(venv) $ deactivate

~]$ sudo systemctl restart netbox
~]$ systemctl status netbox

Troubleshooting

CSRF verification failed. Request aborted.

Comment the django.middleware.csrf.CsrfViewMiddleware option.

"/opt/netbox/netbox/netbox/settings.py"
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django_htmx.middleware.HtmxMiddleware',
'netbox.middleware.RemoteUserMiddleware',
'netbox.middleware.CoreMiddleware',
'netbox.middleware.MaintenanceModeMiddleware',
]

PUT https://netbox.sakurayumeno.top/api/plugins/reorder/save/1/ 403 (Forbidden)
rack.js:3 Error: {detail: "CSRF Failed: CSRF token from the 'X-Csrftoken' HTTP header incorrect."}
rack.js:3 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'trim')