mirror of
https://github.com/immich-app/immich.git
synced 2024-12-28 22:51:59 +00:00
refactor(server): database config (#13730)
This commit is contained in:
parent
151ba9f1d9
commit
fb995816a1
10 changed files with 87 additions and 84 deletions
|
@ -24,10 +24,10 @@
|
|||
"typeorm": "typeorm",
|
||||
"lifecycle": "node ./dist/utils/lifecycle.js",
|
||||
"typeorm:migrations:create": "typeorm migration:create",
|
||||
"typeorm:migrations:generate": "typeorm migration:generate -d ./dist/database.config.js",
|
||||
"typeorm:migrations:run": "typeorm migration:run -d ./dist/database.config.js",
|
||||
"typeorm:migrations:revert": "typeorm migration:revert -d ./dist/database.config.js",
|
||||
"typeorm:schema:drop": "typeorm query -d ./dist/database.config.js 'DROP schema public cascade; CREATE schema public;'",
|
||||
"typeorm:migrations:generate": "typeorm migration:generate -d ./dist/bin/database.js",
|
||||
"typeorm:migrations:run": "typeorm migration:run -d ./dist/bin/database.js",
|
||||
"typeorm:migrations:revert": "typeorm migration:revert -d ./dist/bin/database.js",
|
||||
"typeorm:schema:drop": "typeorm query -d ./dist/bin/database.js 'DROP schema public cascade; CREATE schema public;'",
|
||||
"typeorm:schema:reset": "npm run typeorm:schema:drop && npm run typeorm:migrations:run",
|
||||
"sync:open-api": "node ./dist/bin/sync-open-api.js",
|
||||
"sync:sql": "node ./dist/bin/sync-sql.js",
|
||||
|
|
|
@ -9,7 +9,6 @@ import { OpenTelemetryModule } from 'nestjs-otel';
|
|||
import { commands } from 'src/commands';
|
||||
import { clsConfig, immichAppConfig } from 'src/config';
|
||||
import { controllers } from 'src/controllers';
|
||||
import { databaseConfig } from 'src/database.config';
|
||||
import { entities } from 'src/entities';
|
||||
import { ImmichWorker } from 'src/enum';
|
||||
import { IEventRepository } from 'src/interfaces/event.interface';
|
||||
|
@ -38,7 +37,7 @@ const middleware = [
|
|||
];
|
||||
|
||||
const configRepository = new ConfigRepository();
|
||||
const { bull, otel } = configRepository.getEnv();
|
||||
const { bull, database, otel } = configRepository.getEnv();
|
||||
|
||||
const imports = [
|
||||
BullModule.forRoot(bull.config),
|
||||
|
@ -50,7 +49,7 @@ const imports = [
|
|||
inject: [ModuleRef],
|
||||
useFactory: (moduleRef: ModuleRef) => {
|
||||
return {
|
||||
...databaseConfig,
|
||||
...database.config,
|
||||
poolErrorHandler: (error) => {
|
||||
moduleRef.get(DatabaseService, { strict: false }).handleConnectionError(error);
|
||||
},
|
||||
|
|
11
server/src/bin/database.ts
Normal file
11
server/src/bin/database.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
const { database } = new ConfigRepository().getEnv();
|
||||
|
||||
/**
|
||||
* @deprecated - DO NOT USE THIS
|
||||
*
|
||||
* this export is ONLY to be used for TypeORM commands in package.json#scripts
|
||||
*/
|
||||
export const dataSource = new DataSource({ ...database.config, host: 'localhost' });
|
|
@ -8,7 +8,6 @@ import { OpenTelemetryModule } from 'nestjs-otel';
|
|||
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { format } from 'sql-formatter';
|
||||
import { databaseConfig } from 'src/database.config';
|
||||
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
||||
import { entities } from 'src/entities';
|
||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||
|
@ -74,12 +73,12 @@ class SqlGenerator {
|
|||
await rm(this.options.targetDir, { force: true, recursive: true });
|
||||
await mkdir(this.options.targetDir);
|
||||
|
||||
const { otel } = new ConfigRepository().getEnv();
|
||||
const { database, otel } = new ConfigRepository().getEnv();
|
||||
|
||||
const moduleFixture = await Test.createTestingModule({
|
||||
imports: [
|
||||
TypeOrmModule.forRoot({
|
||||
...databaseConfig,
|
||||
...database.config,
|
||||
host: 'localhost',
|
||||
entities,
|
||||
logging: ['query'],
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';
|
||||
|
||||
const { database } = new ConfigRepository().getEnv();
|
||||
const { url, host, port, username, password, name } = database;
|
||||
const urlOrParts = url
|
||||
? { url }
|
||||
: {
|
||||
host,
|
||||
port,
|
||||
username,
|
||||
password,
|
||||
database: name,
|
||||
};
|
||||
|
||||
/* eslint unicorn/prefer-module: "off" -- We can fix this when migrating to ESM*/
|
||||
export const databaseConfig: PostgresConnectionOptions = {
|
||||
type: 'postgres',
|
||||
entities: [__dirname + '/entities/*.entity.{js,ts}'],
|
||||
migrations: [__dirname + '/migrations/*.{js,ts}'],
|
||||
subscribers: [__dirname + '/subscribers/*.{js,ts}'],
|
||||
migrationsRun: false,
|
||||
synchronize: false,
|
||||
connectTimeoutMS: 10_000, // 10 seconds
|
||||
parseInt8: true,
|
||||
...urlOrParts,
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated - DO NOT USE THIS
|
||||
*
|
||||
* this export is ONLY to be used for TypeORM commands in package.json#scripts
|
||||
*/
|
||||
export const dataSource = new DataSource({ ...databaseConfig, host: 'localhost' });
|
|
@ -4,6 +4,7 @@ import { RedisOptions } from 'ioredis';
|
|||
import { OpenTelemetryModuleOptions } from 'nestjs-otel/lib/interfaces';
|
||||
import { ImmichEnvironment, ImmichTelemetry, ImmichWorker, LogLevel } from 'src/enum';
|
||||
import { VectorExtension } from 'src/interfaces/database.interface';
|
||||
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';
|
||||
|
||||
export const IConfigRepository = 'IConfigRepository';
|
||||
|
||||
|
@ -36,12 +37,7 @@ export interface EnvData {
|
|||
};
|
||||
|
||||
database: {
|
||||
url?: string;
|
||||
host: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
name: string;
|
||||
config: PostgresConnectionOptions;
|
||||
skipMigrations: boolean;
|
||||
vectorExtension: VectorExtension;
|
||||
};
|
||||
|
|
|
@ -66,12 +66,14 @@ describe('getEnv', () => {
|
|||
it('should use defaults', () => {
|
||||
const { database } = getEnv();
|
||||
expect(database).toEqual({
|
||||
url: undefined,
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
name: 'immich',
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
config: expect.objectContaining({
|
||||
type: 'postgres',
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
database: 'immich',
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
}),
|
||||
skipMigrations: false,
|
||||
vectorExtension: 'vectors',
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { join } from 'node:path';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { citiesFile, excludePaths } from 'src/constants';
|
||||
import { Telemetry } from 'src/decorators';
|
||||
import { ImmichEnvironment, ImmichTelemetry, ImmichWorker, LogLevel } from 'src/enum';
|
||||
|
@ -46,10 +46,14 @@ const getEnv = (): EnvData => {
|
|||
const isProd = environment === ImmichEnvironment.PRODUCTION;
|
||||
const buildFolder = process.env.IMMICH_BUILD_DATA || '/build';
|
||||
const folders = {
|
||||
// eslint-disable-next-line unicorn/prefer-module
|
||||
dist: resolve(`${__dirname}/..`),
|
||||
geodata: join(buildFolder, 'geodata'),
|
||||
web: join(buildFolder, 'www'),
|
||||
};
|
||||
|
||||
const databaseUrl = process.env.DB_URL;
|
||||
|
||||
let redisConfig = {
|
||||
host: process.env.REDIS_HOSTNAME || 'redis',
|
||||
port: Number.parseInt(process.env.REDIS_PORT || '') || 6379,
|
||||
|
@ -118,12 +122,25 @@ const getEnv = (): EnvData => {
|
|||
},
|
||||
|
||||
database: {
|
||||
url: process.env.DB_URL,
|
||||
host: process.env.DB_HOSTNAME || 'database',
|
||||
port: Number(process.env.DB_PORT) || 5432,
|
||||
username: process.env.DB_USERNAME || 'postgres',
|
||||
password: process.env.DB_PASSWORD || 'postgres',
|
||||
name: process.env.DB_DATABASE_NAME || 'immich',
|
||||
config: {
|
||||
type: 'postgres',
|
||||
entities: [`${folders.dist}/entities` + '/*.entity.{js,ts}'],
|
||||
migrations: [`${folders.dist}/migrations` + '/*.{js,ts}'],
|
||||
subscribers: [`${folders.dist}/subscribers` + '/*.{js,ts}'],
|
||||
migrationsRun: false,
|
||||
synchronize: false,
|
||||
connectTimeoutMS: 10_000, // 10 seconds
|
||||
parseInt8: true,
|
||||
...(databaseUrl
|
||||
? { url: databaseUrl }
|
||||
: {
|
||||
host: process.env.DB_HOSTNAME || 'database',
|
||||
port: Number(process.env.DB_PORT) || 5432,
|
||||
username: process.env.DB_USERNAME || 'postgres',
|
||||
password: process.env.DB_PASSWORD || 'postgres',
|
||||
database: process.env.DB_DATABASE_NAME || 'immich',
|
||||
}),
|
||||
},
|
||||
|
||||
skipMigrations: process.env.DB_SKIP_MIGRATIONS === 'true',
|
||||
vectorExtension:
|
||||
|
|
|
@ -60,11 +60,14 @@ describe(DatabaseService.name, () => {
|
|||
configMock.getEnv.mockReturnValue(
|
||||
mockEnvData({
|
||||
database: {
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
name: 'immich',
|
||||
config: {
|
||||
type: 'postgres',
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
database: 'immich',
|
||||
},
|
||||
skipMigrations: false,
|
||||
vectorExtension: extension,
|
||||
},
|
||||
|
@ -286,11 +289,14 @@ describe(DatabaseService.name, () => {
|
|||
configMock.getEnv.mockReturnValue(
|
||||
mockEnvData({
|
||||
database: {
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
name: 'immich',
|
||||
config: {
|
||||
type: 'postgres',
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
database: 'immich',
|
||||
},
|
||||
skipMigrations: true,
|
||||
vectorExtension: DatabaseExtension.VECTORS,
|
||||
},
|
||||
|
@ -306,11 +312,14 @@ describe(DatabaseService.name, () => {
|
|||
configMock.getEnv.mockReturnValue(
|
||||
mockEnvData({
|
||||
database: {
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
name: 'immich',
|
||||
config: {
|
||||
type: 'postgres',
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
database: 'immich',
|
||||
},
|
||||
skipMigrations: true,
|
||||
vectorExtension: DatabaseExtension.VECTOR,
|
||||
},
|
||||
|
|
|
@ -16,11 +16,16 @@ const envData: EnvData = {
|
|||
},
|
||||
|
||||
database: {
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
name: 'immich',
|
||||
config: {
|
||||
type: 'postgres',
|
||||
host: 'database',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'postgres',
|
||||
name: 'immich',
|
||||
synchronize: false,
|
||||
migrationsRun: true,
|
||||
},
|
||||
|
||||
skipMigrations: false,
|
||||
vectorExtension: DatabaseExtension.VECTORS,
|
||||
|
|
Loading…
Reference in a new issue