diff --git a/server/apps/immich/src/api-v1/server-info/server-info.service.ts b/server/apps/immich/src/api-v1/server-info/server-info.service.ts
index 23de4123ea..6d88932f1a 100644
--- a/server/apps/immich/src/api-v1/server-info/server-info.service.ts
+++ b/server/apps/immich/src/api-v1/server-info/server-info.service.ts
@@ -1,7 +1,7 @@
+import { APP_UPLOAD_LOCATION } from '@app/common/constants';
 import { Injectable } from '@nestjs/common';
 import { ServerInfoResponseDto } from './response-dto/server-info-response.dto';
 import diskusage from 'diskusage';
-import { APP_UPLOAD_LOCATION } from '../../constants/upload_location.constant';
 
 @Injectable()
 export class ServerInfoService {
diff --git a/server/apps/immich/src/app.module.ts b/server/apps/immich/src/app.module.ts
index 42d20c3e23..9814fd54f0 100644
--- a/server/apps/immich/src/app.module.ts
+++ b/server/apps/immich/src/app.module.ts
@@ -1,3 +1,4 @@
+import { immichAppConfig } from '@app/common/config';
 import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
 import { UserModule } from './api-v1/user/user.module';
 import { AssetModule } from './api-v1/asset/asset.module';
@@ -5,7 +6,6 @@ import { AuthModule } from './api-v1/auth/auth.module';
 import { ImmichJwtModule } from './modules/immich-jwt/immich-jwt.module';
 import { DeviceInfoModule } from './api-v1/device-info/device-info.module';
 import { ConfigModule } from '@nestjs/config';
-import { immichAppConfig } from './config/app.config';
 import { BullModule } from '@nestjs/bull';
 import { ServerInfoModule } from './api-v1/server-info/server-info.module';
 import { BackgroundTaskModule } from './modules/background-task/background-task.module';
diff --git a/server/apps/immich/src/config/asset-upload.config.ts b/server/apps/immich/src/config/asset-upload.config.ts
index fd5185ed2d..aab36c5be4 100644
--- a/server/apps/immich/src/config/asset-upload.config.ts
+++ b/server/apps/immich/src/config/asset-upload.config.ts
@@ -1,10 +1,10 @@
+import { APP_UPLOAD_LOCATION } from '@app/common/constants';
 import { HttpException, HttpStatus } from '@nestjs/common';
 import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
 import { existsSync, mkdirSync } from 'fs';
 import { diskStorage } from 'multer';
 import { extname } from 'path';
 import { Request } from 'express';
-import { APP_UPLOAD_LOCATION } from '../constants/upload_location.constant';
 import { randomUUID } from 'crypto';
 
 export const assetUploadOption: MulterOptions = {
diff --git a/server/apps/immich/src/config/profile-image-upload.config.ts b/server/apps/immich/src/config/profile-image-upload.config.ts
index 98ff0587ab..939a518fe5 100644
--- a/server/apps/immich/src/config/profile-image-upload.config.ts
+++ b/server/apps/immich/src/config/profile-image-upload.config.ts
@@ -1,10 +1,10 @@
+import { APP_UPLOAD_LOCATION } from '@app/common/constants';
 import { HttpException, HttpStatus } from '@nestjs/common';
 import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
 import { existsSync, mkdirSync } from 'fs';
 import { diskStorage } from 'multer';
 import { extname } from 'path';
 import { Request } from 'express';
-import { APP_UPLOAD_LOCATION } from '../constants/upload_location.constant';
 
 export const profileImageUploadOption: MulterOptions = {
   fileFilter: (req: Request, file: any, cb: any) => {
diff --git a/server/apps/immich/test/jest-e2e.json b/server/apps/immich/test/jest-e2e.json
index 7358e01b4f..e120e7635a 100644
--- a/server/apps/immich/test/jest-e2e.json
+++ b/server/apps/immich/test/jest-e2e.json
@@ -7,6 +7,7 @@
     "^.+\\.(t|j)s$": "ts-jest"
   },
   "moduleNameMapper": {
+    "@app/common/(.*)": "<rootDir>../../../libs/common/src/$1",
     "@app/database/config/(.*)": "<rootDir>../../../libs/database/src/config/$1",
     "@app/database/entities/(.*)": "<rootDir>../../../libs/database/src/entities/$1"
   }
diff --git a/server/apps/microservices/src/microservices.module.ts b/server/apps/microservices/src/microservices.module.ts
index dccea32324..cb2e38d1b9 100644
--- a/server/apps/microservices/src/microservices.module.ts
+++ b/server/apps/microservices/src/microservices.module.ts
@@ -1,26 +1,29 @@
-import { BullModule } from '@nestjs/bull';
-import { Module } from '@nestjs/common';
-import { TypeOrmModule } from '@nestjs/typeorm';
+import { immichAppConfig } from '@app/common/config';
 import { DatabaseModule } from '@app/database';
 import { AssetEntity } from '@app/database/entities/asset.entity';
 import { ExifEntity } from '@app/database/entities/exif.entity';
 import { SmartInfoEntity } from '@app/database/entities/smart-info.entity';
 import { UserEntity } from '@app/database/entities/user.entity';
-import { MicroservicesService } from './microservices.service';
-import { AssetUploadedProcessor } from './processors/asset-uploaded.processor';
-import { ThumbnailGeneratorProcessor } from './processors/thumbnail.processor';
-import { MetadataExtractionProcessor } from './processors/metadata-extraction.processor';
-import { VideoTranscodeProcessor } from './processors/video-transcode.processor';
-import { CommunicationModule } from '../../immich/src/api-v1/communication/communication.module';
 import {
   assetUploadedQueueName,
   metadataExtractionQueueName,
   thumbnailGeneratorQueueName,
   videoConversionQueueName,
 } from '@app/job/constants/queue-name.constant';
+import { BullModule } from '@nestjs/bull';
+import { Module } from '@nestjs/common';
+import { ConfigModule } from '@nestjs/config';
+import { TypeOrmModule } from '@nestjs/typeorm';
+import { CommunicationModule } from '../../immich/src/api-v1/communication/communication.module';
+import { MicroservicesService } from './microservices.service';
+import { AssetUploadedProcessor } from './processors/asset-uploaded.processor';
+import { MetadataExtractionProcessor } from './processors/metadata-extraction.processor';
+import { ThumbnailGeneratorProcessor } from './processors/thumbnail.processor';
+import { VideoTranscodeProcessor } from './processors/video-transcode.processor';
 
 @Module({
   imports: [
+    ConfigModule.forRoot(immichAppConfig),
     DatabaseModule,
     TypeOrmModule.forFeature([UserEntity, ExifEntity, AssetEntity, SmartInfoEntity]),
     BullModule.forRootAsync({
diff --git a/server/apps/microservices/src/processors/asset-uploaded.processor.ts b/server/apps/microservices/src/processors/asset-uploaded.processor.ts
index d26507b5ee..d4dbfe6a17 100644
--- a/server/apps/microservices/src/processors/asset-uploaded.processor.ts
+++ b/server/apps/microservices/src/processors/asset-uploaded.processor.ts
@@ -1,7 +1,4 @@
-import { InjectQueue, Process, Processor } from '@nestjs/bull';
-import { Job, Queue } from 'bull';
 import { AssetType } from '@app/database/entities/asset.entity';
-import { randomUUID } from 'crypto';
 import {
   IAssetUploadedJob,
   IMetadataExtractionJob,
@@ -17,6 +14,9 @@ import {
   mp4ConversionProcessorName,
   videoMetadataExtractionProcessorName,
 } from '@app/job';
+import { InjectQueue, Process, Processor } from '@nestjs/bull';
+import { Job, Queue } from 'bull';
+import { randomUUID } from 'crypto';
 
 @Processor(assetUploadedQueueName)
 export class AssetUploadedProcessor {
diff --git a/server/apps/microservices/src/processors/metadata-extraction.processor.ts b/server/apps/microservices/src/processors/metadata-extraction.processor.ts
index e3f9161797..f8a22bb7b1 100644
--- a/server/apps/microservices/src/processors/metadata-extraction.processor.ts
+++ b/server/apps/microservices/src/processors/metadata-extraction.processor.ts
@@ -1,18 +1,6 @@
-import { Process, Processor } from '@nestjs/bull';
-import { Job } from 'bull';
 import { AssetEntity } from '@app/database/entities/asset.entity';
-import { Repository } from 'typeorm/repository/Repository';
-import { InjectRepository } from '@nestjs/typeorm';
 import { ExifEntity } from '@app/database/entities/exif.entity';
-import exifr from 'exifr';
-import mapboxGeocoding, { GeocodeService } from '@mapbox/mapbox-sdk/services/geocoding';
-import { MapiResponse } from '@mapbox/mapbox-sdk/lib/classes/mapi-response';
-import { readFile } from 'fs/promises';
-import { Logger } from '@nestjs/common';
-import axios from 'axios';
 import { SmartInfoEntity } from '@app/database/entities/smart-info.entity';
-import ffmpeg from 'fluent-ffmpeg';
-import path from 'path';
 import {
   IExifExtractionProcessor,
   IVideoLengthExtractionProcessor,
@@ -24,6 +12,18 @@ import {
   reverseGeocodingProcessorName,
   IReverseGeocodingProcessor,
 } from '@app/job';
+import { MapiResponse } from '@mapbox/mapbox-sdk/lib/classes/mapi-response';
+import mapboxGeocoding, { GeocodeService } from '@mapbox/mapbox-sdk/services/geocoding';
+import { Process, Processor } from '@nestjs/bull';
+import { Logger } from '@nestjs/common';
+import { InjectRepository } from '@nestjs/typeorm';
+import axios from 'axios';
+import { Job } from 'bull';
+import exifr from 'exifr';
+import ffmpeg from 'fluent-ffmpeg';
+import { readFile } from 'fs/promises';
+import path from 'path';
+import { Repository } from 'typeorm/repository/Repository';
 
 @Processor(metadataExtractionQueueName)
 export class MetadataExtractionProcessor {
diff --git a/server/apps/microservices/src/processors/thumbnail.processor.ts b/server/apps/microservices/src/processors/thumbnail.processor.ts
index 086542353a..c4bb211136 100644
--- a/server/apps/microservices/src/processors/thumbnail.processor.ts
+++ b/server/apps/microservices/src/processors/thumbnail.processor.ts
@@ -1,14 +1,4 @@
-import { InjectQueue, Process, Processor } from '@nestjs/bull';
-import { Job, Queue } from 'bull';
 import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
-import { Repository } from 'typeorm/repository/Repository';
-import { InjectRepository } from '@nestjs/typeorm';
-import sharp from 'sharp';
-import { existsSync, mkdirSync } from 'node:fs';
-import { randomUUID } from 'node:crypto';
-import { CommunicationGateway } from '../../../immich/src/api-v1/communication/communication.gateway';
-import ffmpeg from 'fluent-ffmpeg';
-import { Logger } from '@nestjs/common';
 import {
   WebpGeneratorProcessor,
   generateJPEGThumbnailProcessorName,
@@ -19,7 +9,17 @@ import {
   thumbnailGeneratorQueueName,
   JpegGeneratorProcessor,
 } from '@app/job';
+import { InjectQueue, Process, Processor } from '@nestjs/bull';
+import { Logger } from '@nestjs/common';
+import { InjectRepository } from '@nestjs/typeorm';
 import { mapAsset } from 'apps/immich/src/api-v1/asset/response-dto/asset-response.dto';
+import { Job, Queue } from 'bull';
+import ffmpeg from 'fluent-ffmpeg';
+import { randomUUID } from 'node:crypto';
+import { existsSync, mkdirSync } from 'node:fs';
+import sharp from 'sharp';
+import { Repository } from 'typeorm/repository/Repository';
+import { CommunicationGateway } from '../../../immich/src/api-v1/communication/communication.gateway';
 
 @Processor(thumbnailGeneratorQueueName)
 export class ThumbnailGeneratorProcessor {
diff --git a/server/apps/microservices/src/processors/video-transcode.processor.ts b/server/apps/microservices/src/processors/video-transcode.processor.ts
index d75628c1af..45ea17ab09 100644
--- a/server/apps/microservices/src/processors/video-transcode.processor.ts
+++ b/server/apps/microservices/src/processors/video-transcode.processor.ts
@@ -1,3 +1,5 @@
+import { APP_UPLOAD_LOCATION } from '@app/common/constants';
+import { AssetEntity } from '@app/database/entities/asset.entity';
 import { mp4ConversionProcessorName } from '@app/job/constants/job-name.constant';
 import { videoConversionQueueName } from '@app/job/constants/queue-name.constant';
 import { IMp4ConversionProcessor } from '@app/job/interfaces/video-transcode.interface';
@@ -8,8 +10,6 @@ import { Job } from 'bull';
 import ffmpeg from 'fluent-ffmpeg';
 import { existsSync, mkdirSync } from 'fs';
 import { Repository } from 'typeorm';
-import { AssetEntity } from '../../../../libs/database/src/entities/asset.entity';
-import { APP_UPLOAD_LOCATION } from '../../../immich/src/constants/upload_location.constant';
 
 @Processor(videoConversionQueueName)
 export class VideoTranscodeProcessor {
diff --git a/server/apps/immich/src/config/app.config.ts b/server/libs/common/src/config/app.config.ts
similarity index 100%
rename from server/apps/immich/src/config/app.config.ts
rename to server/libs/common/src/config/app.config.ts
diff --git a/server/libs/common/src/config/index.ts b/server/libs/common/src/config/index.ts
new file mode 100644
index 0000000000..41e7ed15eb
--- /dev/null
+++ b/server/libs/common/src/config/index.ts
@@ -0,0 +1 @@
+export * from './app.config';
diff --git a/server/libs/common/src/constants/index.ts b/server/libs/common/src/constants/index.ts
new file mode 100644
index 0000000000..0751fea60d
--- /dev/null
+++ b/server/libs/common/src/constants/index.ts
@@ -0,0 +1 @@
+export * from './upload_location.constant';
diff --git a/server/apps/immich/src/constants/upload_location.constant.ts b/server/libs/common/src/constants/upload_location.constant.ts
similarity index 100%
rename from server/apps/immich/src/constants/upload_location.constant.ts
rename to server/libs/common/src/constants/upload_location.constant.ts
diff --git a/server/libs/common/src/index.ts b/server/libs/common/src/index.ts
new file mode 100644
index 0000000000..a1be68099c
--- /dev/null
+++ b/server/libs/common/src/index.ts
@@ -0,0 +1,2 @@
+export * from './config';
+export * from './constants';
diff --git a/server/libs/common/tsconfig.lib.json b/server/libs/common/tsconfig.lib.json
new file mode 100644
index 0000000000..8fdbf52b4a
--- /dev/null
+++ b/server/libs/common/tsconfig.lib.json
@@ -0,0 +1,9 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "declaration": true,
+    "outDir": "../../dist/libs/common"
+  },
+  "include": ["src/**/*"],
+  "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
+}
diff --git a/server/nest-cli.json b/server/nest-cli.json
index 564b61f011..87362af421 100644
--- a/server/nest-cli.json
+++ b/server/nest-cli.json
@@ -33,6 +33,15 @@
         "tsConfigPath": "apps/microservices/tsconfig.app.json"
       }
     },
+    "common": {
+      "type": "library",
+      "root": "libs/common",
+      "entryFile": "index",
+      "sourceRoot": "libs/common/src",
+      "compilerOptions": {
+        "tsConfigPath": "libs/common/tsconfig.lib.json"
+      }
+    },
     "database": {
       "type": "library",
       "root": "libs/database",
diff --git a/server/tsconfig.json b/server/tsconfig.json
index fae99fd5f1..ced2fc7dae 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -16,6 +16,12 @@
     "esModuleInterop": true,
     "baseUrl": "./",
     "paths": {
+      "@app/common": [
+        "libs/common/src"
+      ],
+      "@app/common/*": [
+        "libs/common/src/*"
+      ],
       "@app/database": [
         "libs/database/src"
       ],