feat(server): support IPv6 Redis instances

This enables automatic family affinity by using `0`, which overwrites
ioredis' default set to `4`. With this change, Immich will be able to
connect to Redis exposed only via IPv6.

Users will still be able to overwrite the default with `REDIS_IP_FAMILY`
or by adding `?family=4` to `REDIS_URL`.
This commit is contained in:
Szymon Łągiewka 2025-10-11 20:17:38 +02:00
parent 8fe54a4de1
commit 718878cad0
No known key found for this signature in database
4 changed files with 20 additions and 11 deletions

View file

@ -101,15 +101,16 @@ When `DB_URL` is defined, the `DB_HOSTNAME`, `DB_PORT`, `DB_USERNAME`, `DB_PASSW
## Redis
| Variable | Description | Default | Containers |
| :--------------- | :------------- | :-----: | :--------- |
| `REDIS_URL` | Redis URL | | server |
| `REDIS_SOCKET` | Redis socket | | server |
| `REDIS_HOSTNAME` | Redis host | `redis` | server |
| `REDIS_PORT` | Redis port | `6379` | server |
| `REDIS_USERNAME` | Redis username | | server |
| `REDIS_PASSWORD` | Redis password | | server |
| `REDIS_DBINDEX` | Redis DB index | `0` | server |
| Variable | Description | Default | Containers |
| :---------------- | :-------------- | :-----: | :--------- |
| `REDIS_URL` | Redis URL | | server |
| `REDIS_SOCKET` | Redis socket | | server |
| `REDIS_HOSTNAME` | Redis host | `redis` | server |
| `REDIS_PORT` | Redis port | `6379` | server |
| `REDIS_USERNAME` | Redis username | | server |
| `REDIS_PASSWORD` | Redis password | | server |
| `REDIS_DBINDEX` | Redis DB index | `0` | server |
| `REDIS_IP_FAMILY` | Redis IP family | `0` | server |
:::info
All `REDIS_` variables must be provided to all Immich workers, including `api` and `microservices`.
@ -117,7 +118,7 @@ All `REDIS_` variables must be provided to all Immich workers, including `api` a
`REDIS_URL` must start with `ioredis://` and then include a `base64` encoded JSON string for the configuration.
More information can be found in the upstream [ioredis] documentation.
When `REDIS_URL` or `REDIS_SOCKET` are defined, the `REDIS_HOSTNAME`, `REDIS_PORT`, `REDIS_USERNAME`, `REDIS_PASSWORD`, and `REDIS_DBINDEX` variables are ignored.
When `REDIS_URL` or `REDIS_SOCKET` are defined, the `REDIS_HOSTNAME`, `REDIS_PORT`, `REDIS_USERNAME`, `REDIS_PASSWORD`, `REDIS_IP_FAMILY`, and `REDIS_DBINDEX` variables are ignored.
:::
Redis (Sentinel) URL example JSON before encoding:

View file

@ -1,5 +1,5 @@
import { Transform, Type } from 'class-transformer';
import { IsEnum, IsInt, IsString, Matches } from 'class-validator';
import { IsEnum, IsIn, IsInt, IsString, Matches } from 'class-validator';
import { DatabaseSslMode, ImmichEnvironment, LogLevel } from 'src/enum';
import { IsIPRange, Optional, ValidateBoolean } from 'src/validation';
@ -195,4 +195,9 @@ export class EnvDto {
@IsString()
@Optional()
REDIS_URL?: string;
@IsIn([0, 4, 6])
@Optional()
@Type(() => Number)
REDIS_IP_FAMILY?: 0 | 4 | 6;
}

View file

@ -35,6 +35,7 @@ const resetEnv = () => {
'REDIS_PASSWORD',
'REDIS_SOCKET',
'REDIS_URL',
'REDIS_IP_FAMILY',
'NO_COLOR',
]) {
@ -138,6 +139,7 @@ describe('getEnv', () => {
username: undefined,
password: undefined,
path: undefined,
family: 0,
});
});

View file

@ -163,6 +163,7 @@ const getEnv = (): EnvData => {
username: dto.REDIS_USERNAME || undefined,
password: dto.REDIS_PASSWORD || undefined,
path: dto.REDIS_SOCKET || undefined,
family: dto.REDIS_IP_FAMILY || 0,
};
const redisUrl = dto.REDIS_URL;