diff --git a/server/src/interfaces/config.interface.ts b/server/src/interfaces/config.interface.ts
index 544e63d771..bad4a83222 100644
--- a/server/src/interfaces/config.interface.ts
+++ b/server/src/interfaces/config.interface.ts
@@ -41,6 +41,7 @@ export interface EnvData {
 
   workers: ImmichWorker[];
 
+  noColor: boolean;
   nodeVersion?: string;
 }
 
diff --git a/server/src/repositories/config.repository.spec.ts b/server/src/repositories/config.repository.spec.ts
index 2fbd76cefb..83d89c6e01 100644
--- a/server/src/repositories/config.repository.spec.ts
+++ b/server/src/repositories/config.repository.spec.ts
@@ -1,51 +1,76 @@
 import { ConfigRepository } from 'src/repositories/config.repository';
 
-const getWorkers = () => new ConfigRepository().getEnv().workers;
+const getEnv = () => new ConfigRepository().getEnv();
 
-describe('getWorkers', () => {
+describe('getEnv', () => {
   beforeEach(() => {
-    process.env.IMMICH_WORKERS_INCLUDE = '';
-    process.env.IMMICH_WORKERS_EXCLUDE = '';
+    delete process.env.IMMICH_WORKERS_INCLUDE;
+    delete process.env.IMMICH_WORKERS_EXCLUDE;
+    delete process.env.NO_COLOR;
   });
 
   it('should return default workers', () => {
-    expect(getWorkers()).toEqual(['api', 'microservices']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['api', 'microservices']);
   });
 
   it('should return included workers', () => {
     process.env.IMMICH_WORKERS_INCLUDE = 'api';
-    expect(getWorkers()).toEqual(['api']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['api']);
   });
 
   it('should excluded workers from defaults', () => {
     process.env.IMMICH_WORKERS_EXCLUDE = 'api';
-    expect(getWorkers()).toEqual(['microservices']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['microservices']);
   });
 
   it('should exclude workers from include list', () => {
     process.env.IMMICH_WORKERS_INCLUDE = 'api,microservices,randomservice';
     process.env.IMMICH_WORKERS_EXCLUDE = 'randomservice,microservices';
-    expect(getWorkers()).toEqual(['api']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['api']);
   });
 
   it('should remove whitespace from included workers before parsing', () => {
     process.env.IMMICH_WORKERS_INCLUDE = 'api, microservices';
-    expect(getWorkers()).toEqual(['api', 'microservices']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['api', 'microservices']);
   });
 
   it('should remove whitespace from excluded workers before parsing', () => {
     process.env.IMMICH_WORKERS_EXCLUDE = 'api, microservices';
-    expect(getWorkers()).toEqual([]);
+    const { workers } = getEnv();
+    expect(workers).toEqual([]);
   });
 
   it('should remove whitespace from included and excluded workers before parsing', () => {
     process.env.IMMICH_WORKERS_INCLUDE = 'api, microservices, randomservice,randomservice2';
     process.env.IMMICH_WORKERS_EXCLUDE = 'randomservice,microservices, randomservice2';
-    expect(getWorkers()).toEqual(['api']);
+    const { workers } = getEnv();
+    expect(workers).toEqual(['api']);
   });
 
   it('should throw error for invalid workers', () => {
     process.env.IMMICH_WORKERS_INCLUDE = 'api,microservices,randomservice';
-    expect(getWorkers).toThrowError('Invalid worker(s) found: api,microservices,randomservice');
+    expect(getEnv).toThrowError('Invalid worker(s) found: api,microservices,randomservice');
+  });
+
+  it('should default noColor to false', () => {
+    const { noColor } = getEnv();
+    expect(noColor).toBe(false);
+  });
+
+  it('should map NO_COLOR=1 to true', () => {
+    process.env.NO_COLOR = '1';
+    const { noColor } = getEnv();
+    expect(noColor).toBe(true);
+  });
+
+  it('should map NO_COLOR=true to true', () => {
+    process.env.NO_COLOR = 'true';
+    const { noColor } = getEnv();
+    expect(noColor).toBe(true);
   });
 });
diff --git a/server/src/repositories/config.repository.ts b/server/src/repositories/config.repository.ts
index ec80ed4db4..37013d8512 100644
--- a/server/src/repositories/config.repository.ts
+++ b/server/src/repositories/config.repository.ts
@@ -68,11 +68,16 @@ export class ConfigRepository implements IConfigRepository {
         skipMigrations: process.env.DB_SKIP_MIGRATIONS === 'true',
         vectorExtension: getVectorExtension(),
       },
+
       licensePublicKey: isProd ? productionKeys : stagingKeys,
+
       storage: {
         ignoreMountCheckErrors: process.env.IMMICH_IGNORE_MOUNT_CHECK_ERRORS === 'true',
       },
+
       workers,
+
+      noColor: !!process.env.NO_COLOR,
     };
   }
 }
diff --git a/server/src/repositories/logger.repository.spec.ts b/server/src/repositories/logger.repository.spec.ts
new file mode 100644
index 0000000000..3093c090da
--- /dev/null
+++ b/server/src/repositories/logger.repository.spec.ts
@@ -0,0 +1,39 @@
+import { ClsService } from 'nestjs-cls';
+import { IConfigRepository } from 'src/interfaces/config.interface';
+import { LoggerRepository } from 'src/repositories/logger.repository';
+import { mockEnvData, newConfigRepositoryMock } from 'test/repositories/config.repository.mock';
+import { Mocked } from 'vitest';
+
+describe(LoggerRepository.name, () => {
+  let sut: LoggerRepository;
+
+  let configMock: Mocked<IConfigRepository>;
+  let clsMock: Mocked<ClsService>;
+
+  beforeEach(() => {
+    configMock = newConfigRepositoryMock();
+    clsMock = {
+      getId: vitest.fn(),
+    } as unknown as Mocked<ClsService>;
+  });
+
+  describe('formatContext', () => {
+    it('should use colors', () => {
+      configMock.getEnv.mockReturnValue(mockEnvData({ noColor: false }));
+
+      sut = new LoggerRepository(clsMock, configMock);
+      sut.setAppName('api');
+
+      expect(sut['formatContext']('context')).toBe('\u001B[33m[api:context]\u001B[39m ');
+    });
+
+    it('should not use colors when noColor is true', () => {
+      configMock.getEnv.mockReturnValue(mockEnvData({ noColor: true }));
+
+      sut = new LoggerRepository(clsMock, configMock);
+      sut.setAppName('api');
+
+      expect(sut['formatContext']('context')).toBe('[api:context] ');
+    });
+  });
+});
diff --git a/server/src/repositories/logger.repository.ts b/server/src/repositories/logger.repository.ts
index 08fb6e7973..f1a99a85ed 100644
--- a/server/src/repositories/logger.repository.ts
+++ b/server/src/repositories/logger.repository.ts
@@ -1,18 +1,34 @@
-import { ConsoleLogger, Injectable, Scope } from '@nestjs/common';
+import { ConsoleLogger, Inject, Injectable, Scope } from '@nestjs/common';
 import { isLogLevelEnabled } from '@nestjs/common/services/utils/is-log-level-enabled.util';
 import { ClsService } from 'nestjs-cls';
 import { LogLevel } from 'src/enum';
+import { IConfigRepository } from 'src/interfaces/config.interface';
 import { ILoggerRepository } from 'src/interfaces/logger.interface';
-import { LogColor } from 'src/utils/logger';
 
 const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
 
+enum LogColor {
+  RED = 31,
+  GREEN = 32,
+  YELLOW = 33,
+  BLUE = 34,
+  MAGENTA_BRIGHT = 95,
+  CYAN_BRIGHT = 96,
+}
+
 @Injectable({ scope: Scope.TRANSIENT })
 export class LoggerRepository extends ConsoleLogger implements ILoggerRepository {
   private static logLevels: LogLevel[] = [LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
+  private noColor: boolean;
 
-  constructor(private cls: ClsService) {
+  constructor(
+    private cls: ClsService,
+    @Inject(IConfigRepository) configRepository: IConfigRepository,
+  ) {
     super(LoggerRepository.name);
+
+    const { noColor } = configRepository.getEnv();
+    this.noColor = noColor;
   }
 
   private static appName?: string = undefined;
@@ -44,6 +60,19 @@ export class LoggerRepository extends ConsoleLogger implements ILoggerRepository
       return '';
     }
 
-    return LogColor.yellow(`[${prefix}]`) + ' ';
+    return this.colors.yellow(`[${prefix}]`) + ' ';
+  }
+
+  private colors = {
+    red: (text: string) => this.withColor(text, LogColor.RED),
+    green: (text: string) => this.withColor(text, LogColor.GREEN),
+    yellow: (text: string) => this.withColor(text, LogColor.YELLOW),
+    blue: (text: string) => this.withColor(text, LogColor.BLUE),
+    magentaBright: (text: string) => this.withColor(text, LogColor.MAGENTA_BRIGHT),
+    cyanBright: (text: string) => this.withColor(text, LogColor.CYAN_BRIGHT),
+  };
+
+  private withColor(text: string, color: LogColor) {
+    return this.noColor ? text : `\u001B[${color}m${text}\u001B[39m`;
   }
 }
diff --git a/server/src/utils/logger.ts b/server/src/utils/logger.ts
index d4eb02ead2..2e33a7bcb5 100644
--- a/server/src/utils/logger.ts
+++ b/server/src/utils/logger.ts
@@ -2,24 +2,6 @@ import { HttpException } from '@nestjs/common';
 import { ILoggerRepository } from 'src/interfaces/logger.interface';
 import { TypeORMError } from 'typeorm';
 
-type ColorTextFn = (text: string) => string;
-
-const isColorAllowed = () => !process.env.NO_COLOR;
-const colorIfAllowed = (colorFn: ColorTextFn) => (text: string) => (isColorAllowed() ? colorFn(text) : text);
-
-export const LogColor = {
-  red: colorIfAllowed((text: string) => `\u001B[31m${text}\u001B[39m`),
-  green: colorIfAllowed((text: string) => `\u001B[32m${text}\u001B[39m`),
-  yellow: colorIfAllowed((text: string) => `\u001B[33m${text}\u001B[39m`),
-  blue: colorIfAllowed((text: string) => `\u001B[34m${text}\u001B[39m`),
-  magentaBright: colorIfAllowed((text: string) => `\u001B[95m${text}\u001B[39m`),
-  cyanBright: colorIfAllowed((text: string) => `\u001B[96m${text}\u001B[39m`),
-};
-
-export const LogStyle = {
-  bold: colorIfAllowed((text: string) => `\u001B[1m${text}\u001B[0m`),
-};
-
 export const logGlobalError = (logger: ILoggerRepository, error: Error) => {
   if (error instanceof HttpException) {
     const status = error.getStatus();
diff --git a/server/test/repositories/config.repository.mock.ts b/server/test/repositories/config.repository.mock.ts
index 786e9adbcc..42a113534e 100644
--- a/server/test/repositories/config.repository.mock.ts
+++ b/server/test/repositories/config.repository.mock.ts
@@ -24,6 +24,8 @@ const envData: EnvData = {
   },
 
   workers: [ImmichWorker.API, ImmichWorker.MICROSERVICES],
+
+  noColor: false,
 };
 
 export const newConfigRepositoryMock = (): Mocked<IConfigRepository> => {