Repository navigation
Expand file tree
/
Copy pathdocker-entrypoint.cjs
More file actions
54 lines (44 loc) 路 1.63 KB
/
Copy pathdocker-entrypoint.cjs
File metadata and controls
54 lines (44 loc) 路 1.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env node
'use strict';
/**
* Container entrypoint for both runtime images.
*
* It boots in two steps:
*
* 1. `directus bootstrap` - idempotent DB install/migrate + ensure admin.
* 2. Hand off to pm2-runtime as the long-lived process supervisor.
*
* Doing this in Node rather than a shell command is what lets the hardened
* (distroless) image, which ships no shell, run the same boot as the regular
* one.
*
* pm2 comes from @directus/api's own dependencies rather than a separate copy
* installed into the image, so it is subject to the workspace's
* `pnpm.overrides`. It gets resolved rather than hardcoded because its only
* literal path in the deployed bundle contains the pm2 version.
*/
const { spawnSync, spawn } = require('node:child_process');
const { createRequire } = require('node:module');
const { realpathSync } = require('node:fs');
const node = process.execPath;
const api = realpathSync(require.resolve('./node_modules/@directus/api/package.json'));
const pm2Runtime = createRequire(api).resolve('pm2/bin/pm2-runtime');
const bootstrap = spawnSync(node, ['cli.js', 'bootstrap'], { stdio: 'inherit' });
if (bootstrap.status !== 0) {
process.exit(bootstrap.status ?? 1);
}
const pm2 = spawn(node, [pm2Runtime, 'start', 'ecosystem.config.cjs'], { stdio: 'inherit' });
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT']) {
process.on(signal, () => pm2.kill(signal));
}
pm2.on('exit', (code, signal) => {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code ?? 0);
}
});
pm2.on('error', (err) => {
console.error('Failed to start pm2-runtime:', err);
process.exit(1);
});