From 01d451f72a40f799f4c816d42f08788d268e0670 Mon Sep 17 00:00:00 2001 From: Gavin Mogan Date: Wed, 28 Dec 2022 06:38:30 -0800 Subject: [PATCH] Server: Add in ability to use Postgres connection string in configuration (#6836) --- packages/server/README.md | 11 ++++++++++- packages/server/src/app.ts | 2 +- packages/server/src/config.ts | 22 ++++++++++++++++------ packages/server/src/db.ts | 15 ++++++++++----- packages/server/src/env.ts | 2 ++ packages/server/src/utils/types.ts | 1 + 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/packages/server/README.md b/packages/server/README.md index 743d889865..74cd6f3c85 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -34,7 +34,9 @@ You can setup the container to either use an existing PostgreSQL server, or conn ### Using an existing PostgreSQL server -To use an existing PostgresSQL server, set the following environment variables in the .env file: +To use an existing PostgresSQL server, you can variables in the .env file. Either: + +#### Individual variables ```conf DB_CLIENT=pg @@ -45,6 +47,13 @@ POSTGRES_PORT=5432 POSTGRES_HOST=localhost ``` +#### Connection String + +```conf +DB_CLIENT=pg +POSTGRES_CONNECTION_STRING=postgresql://username:password@your_joplin_postgres_server:5432/joplin +``` + Ensure that the provided database and user exist as Joplin Server will not create them. When running on macOS or Windows through Docker Desktop, a mapping of localhost is made automatically. On Linux, you can add `--net=host --add-host=host.docker.internal:127.0.0.1` to the `docker run` command line to make the mapping happen. Any other `POSTGRES_HOST` than localhost or 127.0.0.1 should work as expected without further action. ### Using docker-compose diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index fb370df857..3c11621b3d 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -70,7 +70,7 @@ function markPasswords(o: Record): Record { const output: Record = {}; for (const k of Object.keys(o)) { - if (k.toLowerCase().includes('password') || k.toLowerCase().includes('secret')) { + if (k.toLowerCase().includes('password') || k.toLowerCase().includes('secret') || k.toLowerCase().includes('connectionstring')) { output[k] = '********'; } else { output[k] = o[k]; diff --git a/packages/server/src/config.ts b/packages/server/src/config.ts index c8336089c5..af4e2ad96e 100644 --- a/packages/server/src/config.ts +++ b/packages/server/src/config.ts @@ -42,15 +42,25 @@ function databaseConfigFromEnv(runningInDocker: boolean, env: EnvVariables): Dat }; if (env.DB_CLIENT === 'pg') { - return { + const databaseConfig: DatabaseConfig = { ...baseConfig, client: DatabaseConfigClient.PostgreSQL, - name: env.POSTGRES_DATABASE, - user: env.POSTGRES_USER, - password: env.POSTGRES_PASSWORD, - port: env.POSTGRES_PORT, - host: databaseHostFromEnv(runningInDocker, env) || 'localhost', }; + if (env.POSTGRES_CONNECTION_STRING) { + return { + ...databaseConfig, + connectionString: env.POSTGRES_CONNECTION_STRING, + }; + } else { + return { + ...databaseConfig, + name: env.POSTGRES_DATABASE, + user: env.POSTGRES_USER, + password: env.POSTGRES_PASSWORD, + port: env.POSTGRES_PORT, + host: databaseHostFromEnv(runningInDocker, env) || 'localhost', + }; + } } return { diff --git a/packages/server/src/db.ts b/packages/server/src/db.ts index aac666bfd5..849bb4098b 100644 --- a/packages/server/src/db.ts +++ b/packages/server/src/db.ts @@ -45,6 +45,7 @@ export interface DbConfigConnection { database?: string; filename?: string; password?: string; + connectionString?: string; } export interface QueryContext { @@ -77,11 +78,15 @@ export function makeKnexConfig(dbConfig: DatabaseConfig): KnexDatabaseConfig { if (dbConfig.client === 'sqlite3') { connection.filename = dbConfig.name; } else { - connection.database = dbConfig.name; - connection.host = dbConfig.host; - connection.port = dbConfig.port; - connection.user = dbConfig.user; - connection.password = dbConfig.password; + if (dbConfig.connectionString) { + connection.connectionString = dbConfig.connectionString; + } else { + connection.database = dbConfig.name; + connection.host = dbConfig.host; + connection.port = dbConfig.port; + connection.user = dbConfig.user; + connection.password = dbConfig.password; + } } return { diff --git a/packages/server/src/env.ts b/packages/server/src/env.ts index 00095b0547..1e6668887d 100644 --- a/packages/server/src/env.ts +++ b/packages/server/src/env.ts @@ -55,6 +55,7 @@ const defaultEnvValues: EnvVariables = { POSTGRES_USER: 'joplin', POSTGRES_HOST: '', POSTGRES_PORT: 5432, + POSTGRES_CONNECTION_STRING: '', // This must be the full path to the database file SQLITE_DATABASE: '', @@ -124,6 +125,7 @@ export interface EnvVariables { POSTGRES_USER: string; POSTGRES_HOST: string; POSTGRES_PORT: number; + POSTGRES_CONNECTION_STRING: string; SQLITE_DATABASE: string; diff --git a/packages/server/src/utils/types.ts b/packages/server/src/utils/types.ts index e2c54f00d4..c54b9809f1 100644 --- a/packages/server/src/utils/types.ts +++ b/packages/server/src/utils/types.ts @@ -65,6 +65,7 @@ export interface DatabaseConfig { port?: number; user?: string; password?: string; + connectionString?: string; asyncStackTraces?: boolean; slowQueryLogEnabled?: boolean; slowQueryLogMinDuration?: number;