From b0ec803b0c5796313d751eff33bf10960221ea9d Mon Sep 17 00:00:00 2001 From: Rijk van Zanten Date: Tue, 27 Jul 2021 01:10:17 +0200 Subject: [PATCH] Wait for the database to be ready in bootstrap step (#6987) --- api/src/cli/commands/bootstrap/index.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/api/src/cli/commands/bootstrap/index.ts b/api/src/cli/commands/bootstrap/index.ts index fbcd4f7726..75ebd55a55 100644 --- a/api/src/cli/commands/bootstrap/index.ts +++ b/api/src/cli/commands/bootstrap/index.ts @@ -1,3 +1,4 @@ +import { Knex } from 'knex'; import { nanoid } from 'nanoid'; import runMigrations from '../../../database/migrations/run'; import installDatabase from '../../../database/seeds/run'; @@ -5,7 +6,7 @@ import env from '../../../env'; import logger from '../../../logger'; import { getSchema } from '../../../utils/get-schema'; import { RolesService, UsersService, SettingsService } from '../../../services'; -import getDatabase, { isInstalled, validateDBConnection } from '../../../database'; +import getDatabase, { isInstalled, validateDBConnection, hasDatabaseConnection } from '../../../database'; import { SchemaOverview } from '../../../types'; export default async function bootstrap({ skipAdminInit }: { skipAdminInit?: boolean }): Promise { @@ -13,7 +14,7 @@ export default async function bootstrap({ skipAdminInit }: { skipAdminInit?: boo const database = getDatabase(); - await validateDBConnection(database); + await waitForDatabase(database); if ((await isInstalled()) === false) { logger.info('Installing Directus system tables...'); @@ -45,6 +46,22 @@ export default async function bootstrap({ skipAdminInit }: { skipAdminInit?: boo process.exit(0); } +async function waitForDatabase(database: Knex) { + const tries = 5; + const secondsBetweenTries = 5; + + for (let i = 0; i < tries; i++) { + if (await hasDatabaseConnection(database)) { + return true; + } + + await new Promise((resolve) => setTimeout(resolve, secondsBetweenTries * 1000)); + } + + // This will throw and exit the process if the database is not available + await validateDBConnection(database); +} + async function createDefaultAdmin(schema: SchemaOverview) { logger.info('Setting up first admin role...'); const rolesService = new RolesService({ schema });