Repository: netbox-community/netbox

Issue:
Support Redis Unix sockets
### NetBox version

3.7.5

### Feature type

Change to existing functionality

### Proposed functionality

Support Redis connectivity through Unix sockets

### Use case

Binding to Redis servers on localhost or sidecars without exposing a TCP listener.

### Database changes

_No response_

### External dependencies

_No response_


Discussion:
https://github.com/netbox-community/netbox/issues/15955
https://github.com/netbox-community/netbox/issues/4377
https://github.com/netbox-community/netbox/pull/15590

From previous tickets:

### Proposed Functionality
Implement unix-socket support for Redis cache and webhook

### Use Case
When Redis is installed on the same Server as netbox, then the possible usage of unix sockets for redis would be nice. When using unix sockets, there is no need for localhost loopback with the whole IP-Stack. The usage with unix sockets can improve the performance too (even if it doesn't matter).

### Database Changes
No DB-Changes needed. Just some small changes in settings.py and configuration.py


Hello, I have [a patch](https://github.com/NixOS/nixpkgs/blob/dd1290b0f857782a60b251f89651c831cd3eef9d/pkgs/servers/web-apps/netbox/config.patch) that I'm willing to upstream that was made to support Redis Unix sockets.

(Note: the linked patch also modifies `STATIC_ROOT`, but this modification is not part of the proposed changes)

This patch defines new `REDIS['tasks']['URL']` and `REDIS['caching']['URL']` settings, which take priority if defined by the user. The user can then set this config if they want to use Unix sockets:

```python
REDIS = {
    "tasks": {"URL": "unix:///run/redis-netbox/redis.sock?db=0", "SSL": False},
    "caching": {"URL": "unix:///run/redis-netbox/redis.sock?db=1", "SSL": False},
}
```

In the case of the tasks Redis database, if and only if `URL` is defined, NetBox would use it.

In the case of the caching Redis database, `URL` is always used, but defaults to the value that was used before the patch.

This should be backwards compatible.
@minijackson sounds good, I'll assign this to you for a PR. Thanks!
@minijackson are you still interested in working on this?

Resolving patch:
diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py
--- a/netbox/netbox/settings.py
+++ b/netbox/netbox/settings.py
@@ -241,6 +241,7 @@ def _setting(name, default=None):
 TASKS_REDIS = REDIS['tasks']
 TASKS_REDIS_HOST = TASKS_REDIS.get('HOST', 'localhost')
 TASKS_REDIS_PORT = TASKS_REDIS.get('PORT', 6379)
+TASKS_REDIS_URL = TASKS_REDIS.get('URL')
 TASKS_REDIS_SENTINELS = TASKS_REDIS.get('SENTINELS', [])
 TASKS_REDIS_USING_SENTINEL = all([
     isinstance(TASKS_REDIS_SENTINELS, (list, tuple)),
@@ -269,7 +270,7 @@ def _setting(name, default=None):
 CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis'
 CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False)
 CACHING_REDIS_CA_CERT_PATH = REDIS['caching'].get('CA_CERT_PATH', False)
-CACHING_REDIS_URL = f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_USERNAME_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}'
+CACHING_REDIS_URL = REDIS['caching'].get('URL', f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_USERNAME_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}')
 
 # Configure Django's default cache to use Redis
 CACHES = {
@@ -669,6 +670,12 @@ def _setting(name, default=None):
             'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT
         },
     }
+elif TASKS_REDIS_URL:
+    RQ_PARAMS = {
+        'URL': TASKS_REDIS_URL,
+        'SSL': TASKS_REDIS_SSL,
+        'SSL_CERT_REQS': None if TASKS_REDIS_SKIP_TLS_VERIFY else 'required',
+    }
 else:
     RQ_PARAMS = {
         'HOST': TASKS_REDIS_HOST,


Test patch: