Skip to content

Commit

Permalink
feat(server): improve selfhost deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo committed Nov 8, 2024
1 parent 02dbe13 commit b0fbd4a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 12 deletions.
2 changes: 2 additions & 0 deletions packages/backend/server/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# required DATABASE_URL affects app start
schema.prisma
17 changes: 16 additions & 1 deletion packages/backend/server/scripts/self-host-predeploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const SELF_HOST_CONFIG_DIR = '/root/.affine/config';
* @type {Array<{ from: string; to?: string, modifier?: (content: string): string }>}
*/
const configFiles = [
{ from: './.env.example', to: '.env' },
{ from: './dist/config/affine.js', modifier: configCleaner },
{ from: './dist/config/affine.env.js', modifier: configCleaner },
];
Expand All @@ -22,8 +21,24 @@ function configCleaner(content) {
);
}

const datasource = {
user: process.env.DB_USER || 'affine',
password: process.env.DB_PASSWORD || '',
host: process.env.DB_HOST || 'postgres',
port: process.env.DB_PORT || 5432,
databaseName: process.env.DB_DATABASE_NAME || 'affine',
};

function getDatasourceUrl() {
return (
process.env.DATABASE_URL ||
`postgres://${datasource.user}:${datasource.password}@${datasource.host}:${datasource.port}/${datasource.databaseName}`
);
}

function prepare() {
fs.mkdirSync(SELF_HOST_CONFIG_DIR, { recursive: true });
process.env.DATABASE_URL = getDatasourceUrl();

for (const { from, to, modifier } of configFiles) {
const targetFileName = to ?? path.parse(from).base;
Expand Down
7 changes: 6 additions & 1 deletion packages/backend/server/src/config/affine.env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ AFFiNE.ENV_MAP = {
MAILER_PASSWORD: 'mailer.auth.pass',
MAILER_SENDER: 'mailer.from.address',
MAILER_SECURE: ['mailer.secure', 'boolean'],
DATABASE_URL: 'database.datasourceUrl',
DATABASE_URL: 'prisma.database.datasourceUrl',
DB_PASSWORD: 'prisma.database.password',
DB_USER: 'prisma.database.user',
DB_HOST: 'prisma.database.host',
DB_PORT: ['prisma.database.port', 'int'],
DB_DATABASE_NAME: 'prisma.database.databaseName',
OAUTH_GOOGLE_CLIENT_ID: 'plugins.oauth.providers.google.clientId',
OAUTH_GOOGLE_CLIENT_SECRET: 'plugins.oauth.providers.google.clientSecret',
OAUTH_GITHUB_CLIENT_ID: 'plugins.oauth.providers.github.clientId',
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/server/src/core/config/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { RuntimeConfig, RuntimeConfigType } from '@prisma/client';
import { GraphQLJSON, GraphQLJSONObject } from 'graphql-scalars';

import { Config, URLHelper } from '../../fundamentals';
import { Config, getDatasourceUrl, URLHelper } from '../../fundamentals';
import { Public } from '../auth';
import { Admin } from '../common';
import { FeatureType } from '../features';
Expand Down Expand Up @@ -261,7 +261,7 @@ export class ServerServiceConfigResolver {
}

database(): ServerDatabaseConfig {
const url = new URL(this.config.database.datasourceUrl);
const url = new URL(getDatasourceUrl(this.config));

return {
host: url.hostname,
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/server/src/fundamentals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export {
mapSseError,
OptionalModule,
} from './nestjs';
export type { PrismaTransaction } from './prisma';
export { getDatasourceUrl, type PrismaTransaction } from './prisma';
export * from './storage';
export { type StorageProvider, StorageProviderFactory } from './storage';
export { CloudThrottlerGuard, SkipThrottle, Throttle } from './throttler';
Expand Down
27 changes: 22 additions & 5 deletions packages/backend/server/src/fundamentals/prisma/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,33 @@ import type { Prisma } from '@prisma/client';

import { defineStartupConfig, ModuleConfig } from '../config';

interface PrismaStartupConfiguration extends Prisma.PrismaClientOptions {
datasourceUrl: string;
interface PrismaStartupConfiguration {
options?: Prisma.PrismaClientOptions;
database:
| {
host: string;
port: number;
user: string;
password: string;
databaseName: string;
}
| {
datasourceUrl: string;
};
}

declare module '../config' {
interface AppConfig {
database: ModuleConfig<PrismaStartupConfiguration>;
prisma: ModuleConfig<PrismaStartupConfiguration>;
}
}

defineStartupConfig('database', {
datasourceUrl: '',
defineStartupConfig('prisma', {
database: {
host: 'localhost',
port: 5432,
user: 'affine',
password: '',
databaseName: 'affine',
},
});
15 changes: 14 additions & 1 deletion packages/backend/server/src/fundamentals/prisma/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,28 @@ import { PrismaClient } from '@prisma/client';
import { Config } from '../config';
import { PrismaService } from './service';

export function getDatasourceUrl(config: Config) {
const database = config.prisma.database;
if ('datasourceUrl' in database) {
return database.datasourceUrl;
}
console.log(database.user);
return `postgres://${database.user}:${database.password}@${database.host}:${database.port}/${database.databaseName}`;
}

// only `PrismaClient` can be injected
const clientProvider: Provider = {
provide: PrismaClient,
useFactory: (config: Config) => {
if (PrismaService.INSTANCE) {
return PrismaService.INSTANCE;
}
console.log(getDatasourceUrl(config));

return new PrismaService(config.database);
return new PrismaService({
...config.prisma.options,
datasourceUrl: getDatasourceUrl(config),
});
},
inject: [Config],
};
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/server/src/prelude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
applyEnvToConfig,
getAFFiNEConfigModifier,
} from './fundamentals/config';
import { enablePlugin } from './plugins';

const PROJECT_CONFIG_PATH = join(fileURLToPath(import.meta.url), '../config');
async function loadRemote(remoteDir: string, file: string) {
Expand Down Expand Up @@ -46,6 +45,7 @@ async function load() {

// 2. generate AFFiNE default config and assign to `globalThis.AFFiNE`
globalThis.AFFiNE = getAFFiNEConfigModifier();
const { enablePlugin } = await import('./plugins/registry');
globalThis.AFFiNE.use = enablePlugin;
globalThis.AFFiNE.plugins.use = enablePlugin;

Expand Down

0 comments on commit b0fbd4a

Please sign in to comment.