fix: keep hardware acceleration mounts in rootless mode (#758)

This commit is contained in:
bo0tzz
2026-09-01 15:55:25 -04:00
committed by GitHub
parent 6fd74ac454
commit 2b023e2899
2 changed files with 22 additions and 7 deletions
@@ -209,6 +209,23 @@ describe('buildCompose', () => {
expect(spec.networks).toBeUndefined();
});
it('keeps hardware acceleration mounts in rootless mode', () => {
const config = structuredClone(DEFAULT_CONFIG);
config.hwaccel.ml = 'openvino';
config.rootless = { enabled: true, uid: 1000, gid: 1000 };
const spec = parse(buildCompose(config, VERSION));
expect(spec.services['immich-machine-learning'].volumes).toEqual([
'./ml-model-cache:/cache',
'./ml-dotcache:/.cache',
'./ml-config:/.config',
'/dev/bus/usb:/dev/bus/usb',
]);
expect(spec.services.redis.volumes).toEqual(['./redis:/data']);
// the named cache volume is no longer mounted, so it is not declared
expect(spec.volumes).toBeUndefined();
});
it('applies a custom uid and gid to every service', () => {
const config = structuredClone(DEFAULT_CONFIG);
config.rootless = { enabled: true, uid: 99, gid: 100 };
@@ -71,6 +71,8 @@ export const buildComposeSpec = (config: ImmichConfig, version: string): Compose
.filter(({ path }) => path.trim())
.map(({ path, readOnly }) => `${path.trim()}:${path.trim()}${readOnly ? ':ro' : ''}`);
const rootlessVolumes = (name: string) => (rootless.enabled ? ROOTLESS_VOLUMES.get(name) : undefined);
const backingServices: Record<string, ComposeService> = {};
if (!config.redis.external) {
@@ -78,6 +80,7 @@ export const buildComposeSpec = (config: ImmichConfig, version: string): Compose
container_name: containerName('immich_redis'),
image: IMAGES.redis,
healthcheck: { test: 'redis-cli ping || exit 1' },
volumes: rootlessVolumes('redis') ?? [],
restart: 'always',
};
}
@@ -132,7 +135,7 @@ export const buildComposeSpec = (config: ImmichConfig, version: string): Compose
{
container_name: containerName('immich_machine_learning'),
image: IMAGES.machineLearning(version + ML_BACKENDS[config.hwaccel.ml].tag),
volumes: [`${NamedVolume.ModelCache}:/cache`],
volumes: rootlessVolumes('immich-machine-learning') ?? [`${NamedVolume.ModelCache}:/cache`],
restart: 'always',
healthcheck: { disable: false },
},
@@ -143,12 +146,7 @@ export const buildComposeSpec = (config: ImmichConfig, version: string): Compose
if (rootless.enabled) {
for (const [name, service] of Object.entries(services)) {
const hardened = deepmerge(service, rootlessHardening(rootless));
const rootlessVolumes = ROOTLESS_VOLUMES.get(name);
if (rootlessVolumes) {
hardened.volumes = rootlessVolumes;
}
services[name] = hardened;
services[name] = deepmerge(service, rootlessHardening(rootless));
}
}