@nocobase/cli 2.2.0-beta.8 → 2.2.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/env-proxy/nginx/app.conf.tpl +23 -0
- package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
- package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
- package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
- package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
- package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +18 -0
- package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +21 -0
- package/dist/commands/app/start.js +4 -1
- package/dist/commands/install.js +53 -128
- package/dist/commands/proxy/caddy/generate.js +93 -7
- package/dist/commands/proxy/nginx/generate.js +98 -7
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/source/download.js +16 -12
- package/dist/lib/app-managed-resources.js +3 -2
- package/dist/lib/auth-store.js +68 -0
- package/dist/lib/cli-config.js +52 -1
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-config.js +5 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +164 -58
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/locale/en-US.json +1 -1
- package/dist/locale/zh-CN.json +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Rendered by `nb env proxy`.
|
|
2
|
+
# Context:
|
|
3
|
+
# publicBasePath={{publicBasePath}}
|
|
4
|
+
# apiBasePath={{apiBasePath}}
|
|
5
|
+
# wsPath={{wsPath}}
|
|
6
|
+
# v2PublicPath={{v2PublicPath}}
|
|
7
|
+
# backendUrl={{backendUrl}}
|
|
8
|
+
# snippetsDir={{snippetsDir}}
|
|
9
|
+
# uploadsDir={{uploadsDir}}
|
|
10
|
+
# distRootDir={{distRootDir}}
|
|
11
|
+
# entryDir={{entryDir}}
|
|
12
|
+
# publicDir={{publicDir}}
|
|
13
|
+
|
|
14
|
+
server {
|
|
15
|
+
listen 80;
|
|
16
|
+
server_name _;
|
|
17
|
+
|
|
18
|
+
# Add custom directives or locations above the managed block as needed.
|
|
19
|
+
|
|
20
|
+
{{managedConfigBlock}}
|
|
21
|
+
|
|
22
|
+
# Add custom directives or locations below the managed block as needed.
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
gzip on;
|
|
2
|
+
gzip_types
|
|
3
|
+
text/plain
|
|
4
|
+
text/css
|
|
5
|
+
text/xml
|
|
6
|
+
text/markdown
|
|
7
|
+
text/javascript
|
|
8
|
+
application/javascript
|
|
9
|
+
application/json
|
|
10
|
+
application/manifest+json
|
|
11
|
+
application/atom+xml
|
|
12
|
+
application/rss+xml
|
|
13
|
+
application/xml
|
|
14
|
+
application/xml+rss
|
|
15
|
+
application/xhtml+xml
|
|
16
|
+
application/wasm
|
|
17
|
+
image/svg+xml;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
log_format apm '"$time_local" client=$remote_addr '
|
|
2
|
+
'method=$request_method request="$request" '
|
|
3
|
+
'request_length=$request_length '
|
|
4
|
+
'status=$status bytes_sent=$bytes_sent '
|
|
5
|
+
'body_bytes_sent=$body_bytes_sent '
|
|
6
|
+
'referer=$http_referer '
|
|
7
|
+
'user_agent="$http_user_agent" '
|
|
8
|
+
'upstream_addr=$upstream_addr '
|
|
9
|
+
'upstream_status=$upstream_status '
|
|
10
|
+
'request_time=$request_time '
|
|
11
|
+
'upstream_response_time=$upstream_response_time '
|
|
12
|
+
'upstream_connect_time=$upstream_connect_time '
|
|
13
|
+
'upstream_header_time=$upstream_header_time';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
map $http_upgrade $connection_upgrade {
|
|
2
|
+
default upgrade;
|
|
3
|
+
"" close;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
map $http_x_forwarded_proto $upstream_x_forwarded_proto {
|
|
7
|
+
default $http_x_forwarded_proto;
|
|
8
|
+
"" $scheme;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
map $http_host $final_host {
|
|
12
|
+
default $http_host;
|
|
13
|
+
"" $host;
|
|
14
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
types {
|
|
2
|
+
text/html html htm shtml;
|
|
3
|
+
text/css css;
|
|
4
|
+
text/xml xml;
|
|
5
|
+
image/gif gif;
|
|
6
|
+
image/jpeg jpeg jpg;
|
|
7
|
+
application/javascript js mjs;
|
|
8
|
+
application/atom+xml atom;
|
|
9
|
+
application/rss+xml rss;
|
|
10
|
+
|
|
11
|
+
text/mathml mml;
|
|
12
|
+
text/plain txt;
|
|
13
|
+
text/vnd.sun.j2me.app-descriptor jad;
|
|
14
|
+
text/vnd.wap.wml wml;
|
|
15
|
+
text/x-component htc;
|
|
16
|
+
|
|
17
|
+
image/avif avif;
|
|
18
|
+
image/png png;
|
|
19
|
+
image/svg+xml svg svgz;
|
|
20
|
+
image/tiff tif tiff;
|
|
21
|
+
image/vnd.wap.wbmp wbmp;
|
|
22
|
+
image/webp webp;
|
|
23
|
+
image/x-icon ico;
|
|
24
|
+
image/x-jng jng;
|
|
25
|
+
image/x-ms-bmp bmp;
|
|
26
|
+
|
|
27
|
+
font/woff woff;
|
|
28
|
+
font/woff2 woff2;
|
|
29
|
+
|
|
30
|
+
application/java-archive jar war ear;
|
|
31
|
+
application/json json;
|
|
32
|
+
application/mac-binhex40 hqx;
|
|
33
|
+
application/msword doc;
|
|
34
|
+
application/pdf pdf;
|
|
35
|
+
application/postscript ps eps ai;
|
|
36
|
+
application/rtf rtf;
|
|
37
|
+
application/vnd.apple.mpegurl m3u8;
|
|
38
|
+
application/vnd.google-earth.kml+xml kml;
|
|
39
|
+
application/vnd.google-earth.kmz kmz;
|
|
40
|
+
application/vnd.ms-excel xls;
|
|
41
|
+
application/vnd.ms-fontobject eot;
|
|
42
|
+
application/vnd.ms-powerpoint ppt;
|
|
43
|
+
application/vnd.oasis.opendocument.graphics odg;
|
|
44
|
+
application/vnd.oasis.opendocument.presentation odp;
|
|
45
|
+
application/vnd.oasis.opendocument.spreadsheet ods;
|
|
46
|
+
application/vnd.oasis.opendocument.text odt;
|
|
47
|
+
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
|
48
|
+
pptx;
|
|
49
|
+
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
|
50
|
+
xlsx;
|
|
51
|
+
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
|
52
|
+
docx;
|
|
53
|
+
application/vnd.wap.wmlc wmlc;
|
|
54
|
+
application/wasm wasm;
|
|
55
|
+
application/x-7z-compressed 7z;
|
|
56
|
+
application/x-cocoa cco;
|
|
57
|
+
application/x-java-archive-diff jardiff;
|
|
58
|
+
application/x-java-jnlp-file jnlp;
|
|
59
|
+
application/x-makeself run;
|
|
60
|
+
application/x-perl pl pm;
|
|
61
|
+
application/x-pilot prc pdb;
|
|
62
|
+
application/x-rar-compressed rar;
|
|
63
|
+
application/x-redhat-package-manager rpm;
|
|
64
|
+
application/x-sea sea;
|
|
65
|
+
application/x-shockwave-flash swf;
|
|
66
|
+
application/x-stuffit sit;
|
|
67
|
+
application/x-tcl tcl tk;
|
|
68
|
+
application/x-x509-ca-cert der pem crt;
|
|
69
|
+
application/x-xpinstall xpi;
|
|
70
|
+
application/xhtml+xml xhtml;
|
|
71
|
+
application/xspf+xml xspf;
|
|
72
|
+
application/zip zip;
|
|
73
|
+
|
|
74
|
+
application/octet-stream bin exe dll;
|
|
75
|
+
application/octet-stream deb;
|
|
76
|
+
application/octet-stream dmg;
|
|
77
|
+
application/octet-stream iso img;
|
|
78
|
+
application/octet-stream msi msp msm;
|
|
79
|
+
|
|
80
|
+
audio/midi mid midi kar;
|
|
81
|
+
audio/mpeg mp3;
|
|
82
|
+
audio/ogg ogg;
|
|
83
|
+
audio/x-m4a m4a;
|
|
84
|
+
audio/x-realaudio ra;
|
|
85
|
+
|
|
86
|
+
video/3gpp 3gpp 3gp;
|
|
87
|
+
video/mp2t ts;
|
|
88
|
+
video/mp4 mp4;
|
|
89
|
+
video/mpeg mpeg mpg;
|
|
90
|
+
video/quicktime mov;
|
|
91
|
+
video/webm webm;
|
|
92
|
+
video/x-flv flv;
|
|
93
|
+
video/x-m4v m4v;
|
|
94
|
+
video/x-mng mng;
|
|
95
|
+
video/x-ms-asf asx asf;
|
|
96
|
+
video/x-ms-wmv wmv;
|
|
97
|
+
video/x-msvideo avi;
|
|
98
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
proxy_http_version 1.1;
|
|
2
|
+
|
|
3
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
4
|
+
proxy_set_header Connection $connection_upgrade;
|
|
5
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
6
|
+
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
7
|
+
proxy_set_header Host $final_host;
|
|
8
|
+
proxy_set_header Referer $http_referer;
|
|
9
|
+
proxy_set_header User-Agent $http_user_agent;
|
|
10
|
+
|
|
11
|
+
add_header Cache-Control "no-cache, no-store" always;
|
|
12
|
+
proxy_cache_bypass $http_upgrade;
|
|
13
|
+
|
|
14
|
+
proxy_connect_timeout 600;
|
|
15
|
+
proxy_send_timeout 600;
|
|
16
|
+
proxy_read_timeout 600;
|
|
17
|
+
send_timeout 600;
|
|
18
|
+
proxy_buffering off;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
add_header Cache-Control "public" always;
|
|
2
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
3
|
+
|
|
4
|
+
access_log off;
|
|
5
|
+
autoindex off;
|
|
6
|
+
|
|
7
|
+
# Force potentially renderable uploaded files to download.
|
|
8
|
+
location ~* \.(?:htm|html|svg|svgz|xhtml)$ {
|
|
9
|
+
add_header Cache-Control "public" always;
|
|
10
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
11
|
+
add_header Content-Disposition "attachment" always;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
# Let Markdown files render as plain Markdown text.
|
|
15
|
+
location ~* \.md$ {
|
|
16
|
+
default_type text/markdown;
|
|
17
|
+
|
|
18
|
+
add_header Cache-Control "public" always;
|
|
19
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
20
|
+
add_header Content-Disposition "inline" always;
|
|
21
|
+
}
|
|
@@ -37,6 +37,9 @@ function buildLicenseSyncArgv(envName, options) {
|
|
|
37
37
|
}
|
|
38
38
|
function resolveHookCommand(value) {
|
|
39
39
|
const text = String(value ?? '').trim();
|
|
40
|
+
if (text === 'init') {
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
40
43
|
if (text === 'app:restart' || text === 'app:upgrade') {
|
|
41
44
|
return text;
|
|
42
45
|
}
|
|
@@ -225,7 +228,7 @@ export default class AppStart extends Command {
|
|
|
225
228
|
}),
|
|
226
229
|
'hook-command': Flags.string({
|
|
227
230
|
hidden: true,
|
|
228
|
-
options: ['app:start', 'app:restart', 'app:upgrade'],
|
|
231
|
+
options: ['init', 'app:start', 'app:restart', 'app:upgrade'],
|
|
229
232
|
}),
|
|
230
233
|
};
|
|
231
234
|
async run() {
|
package/dist/commands/install.js
CHANGED
|
@@ -13,11 +13,11 @@ import path from 'node:path';
|
|
|
13
13
|
import { exit } from 'node:process';
|
|
14
14
|
import { appendAppPublicPath } from '../lib/app-public-path.js';
|
|
15
15
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
16
|
-
import { applyCliLocale, localeText,
|
|
16
|
+
import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
|
|
17
17
|
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRoot, resolveEnvRelativePath, } from '../lib/cli-home.js';
|
|
18
18
|
import { defaultDockerContainerPrefix, defaultDockerNetworkName, managedAppLifecycleEnvVars, } from '../lib/app-runtime.js';
|
|
19
|
-
import { resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js';
|
|
20
|
-
import { DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from "../lib/docker-image.js";
|
|
19
|
+
import { getCliConfigValue, resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName, } from '../lib/cli-config.js';
|
|
20
|
+
import { DEFAULT_DOCKER_VERSION, DEFAULT_NB_IMAGE_VARIANT, inferNbImageRegistryFromRepository, normalizeNbImageVariant, resolveBuiltinDbImage, resolveDockerImageContainerPort, resolveDockerImageRef, resolveOfficialDockerRegistry, } from "../lib/docker-image.js";
|
|
21
21
|
import { findAvailableTcpPort, validateAppPublicPath, validateAvailableTcpPort, validateTcpPort, validateEnvKey, } from "../lib/prompt-validators.js";
|
|
22
22
|
import { validateExternalDbConfig, validateMysqlLowerCaseTableNamesCompatibility } from "../lib/db-connection-check.js";
|
|
23
23
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
@@ -31,7 +31,7 @@ import { startDockerLogFollower } from '../lib/docker-log-stream.js';
|
|
|
31
31
|
import { buildInitAppEnvVarsFromConfig } from '../lib/managed-init-env.js';
|
|
32
32
|
import { buildHookContext, persistHookScript, resolveHookScriptPath, runHookScriptHook, } from '../lib/hook-script.js';
|
|
33
33
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
34
|
-
import Download
|
|
34
|
+
import Download from './download.js';
|
|
35
35
|
import EnvAdd from "./env/add.js";
|
|
36
36
|
import { resolveAppUrlFromApiBaseUrl } from "./env/shared.js";
|
|
37
37
|
const DEFAULT_INSTALL_ENV_NAME = 'local';
|
|
@@ -45,18 +45,6 @@ const DEFAULT_INSTALL_DB_PORTS = {
|
|
|
45
45
|
mariadb: '3306',
|
|
46
46
|
kingbase: '54321',
|
|
47
47
|
};
|
|
48
|
-
const DEFAULT_INSTALL_BUILTIN_DB_IMAGES = {
|
|
49
|
-
postgres: 'postgres:16',
|
|
50
|
-
mysql: 'mysql:8',
|
|
51
|
-
mariadb: 'mariadb:11',
|
|
52
|
-
kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86',
|
|
53
|
-
};
|
|
54
|
-
const DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN = {
|
|
55
|
-
postgres: 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16',
|
|
56
|
-
mysql: 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8',
|
|
57
|
-
mariadb: 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11',
|
|
58
|
-
kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86',
|
|
59
|
-
};
|
|
60
48
|
const DEFAULT_INSTALL_DB_DATABASE = 'nocobase';
|
|
61
49
|
const DEFAULT_INSTALL_DB_USER = 'nocobase';
|
|
62
50
|
const DEFAULT_INSTALL_DB_PASSWORD = 'nocobase';
|
|
@@ -179,18 +167,15 @@ function downloadVersionPromptValue(version) {
|
|
|
179
167
|
}
|
|
180
168
|
function supportsBuiltinDbDialect(value) {
|
|
181
169
|
const dialect = String(value ?? '').trim();
|
|
182
|
-
return
|
|
170
|
+
return INSTALL_DB_DIALECTS.includes(dialect);
|
|
183
171
|
}
|
|
184
172
|
export function defaultDbPortForDialect(value) {
|
|
185
173
|
const dialect = String(value ?? 'postgres').trim();
|
|
186
174
|
return DEFAULT_INSTALL_DB_PORTS[isInstallDbDialect(dialect) ? dialect : 'postgres'];
|
|
187
175
|
}
|
|
188
|
-
function defaultBuiltinDbImageForDialect(value) {
|
|
176
|
+
function defaultBuiltinDbImageForDialect(value, options) {
|
|
189
177
|
const dialect = String(value ?? 'postgres').trim();
|
|
190
|
-
|
|
191
|
-
? DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN
|
|
192
|
-
: DEFAULT_INSTALL_BUILTIN_DB_IMAGES;
|
|
193
|
-
return supportsBuiltinDbDialect(dialect) ? defaults[dialect] : defaults.postgres;
|
|
178
|
+
return resolveBuiltinDbImage(dialect, { registry: options?.registry });
|
|
194
179
|
}
|
|
195
180
|
function defaultDbDatabaseForDialect(value) {
|
|
196
181
|
return String(value ?? '').trim() === 'kingbase' ? 'kingbase' : DEFAULT_INSTALL_DB_DATABASE;
|
|
@@ -1279,19 +1264,25 @@ export default class Install extends Command {
|
|
|
1279
1264
|
return builtinDb && Install.shouldPublishBuiltinDbPort(values.source);
|
|
1280
1265
|
}
|
|
1281
1266
|
static async buildDbPromptInitialValues(params) {
|
|
1282
|
-
|
|
1283
|
-
return {};
|
|
1284
|
-
}
|
|
1267
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1285
1268
|
const values = {
|
|
1286
1269
|
...params.downloadResults,
|
|
1287
1270
|
...params.dbPreset,
|
|
1288
1271
|
};
|
|
1272
|
+
const dockerRegistry = String(values.dockerRegistry ?? '').trim() || resolveOfficialDockerRegistry(configuredRegistry);
|
|
1273
|
+
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1274
|
+
const initialValues = values.builtinDb !== false && params.dbPreset.builtinDbImage === undefined
|
|
1275
|
+
? { builtinDbImage: defaultBuiltinDbImageForDialect(dialect, { registry: dockerRegistry }) }
|
|
1276
|
+
: {};
|
|
1277
|
+
if (params.flags['db-port'] !== undefined) {
|
|
1278
|
+
return initialValues;
|
|
1279
|
+
}
|
|
1289
1280
|
if (!Install.shouldPublishBuiltinDbPortForValues(values)) {
|
|
1290
|
-
return
|
|
1281
|
+
return initialValues;
|
|
1291
1282
|
}
|
|
1292
|
-
const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres';
|
|
1293
1283
|
const defaultPort = defaultDbPortForDialect(dialect);
|
|
1294
1284
|
return {
|
|
1285
|
+
...initialValues,
|
|
1295
1286
|
dbPort: await Install.resolveAvailableDefaultPort(defaultPort, {
|
|
1296
1287
|
label: `Default ${dialect} port`,
|
|
1297
1288
|
warn: params.warnOnPortFallback ?? true,
|
|
@@ -1302,12 +1293,13 @@ export default class Install extends Command {
|
|
|
1302
1293
|
* When install runs {@link Download.prompts} after app prompts, align the download
|
|
1303
1294
|
* output directory with app settings, while Docker registry defaults follow the CLI locale.
|
|
1304
1295
|
*/
|
|
1305
|
-
static buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1296
|
+
static async buildDownloadPromptOptionsForInstall(appResults, envName) {
|
|
1306
1297
|
const appRoot = resolveConfiguredSourcePathValue(appResults, envName);
|
|
1307
1298
|
const lang = String(appResults.lang ?? DEFAULT_INSTALL_LANG).trim() || DEFAULT_INSTALL_LANG;
|
|
1299
|
+
const dockerRegistry = resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
1308
1300
|
const initialValues = {
|
|
1309
1301
|
lang,
|
|
1310
|
-
dockerRegistry
|
|
1302
|
+
dockerRegistry,
|
|
1311
1303
|
outputDir: appRoot,
|
|
1312
1304
|
};
|
|
1313
1305
|
const values = {
|
|
@@ -1760,12 +1752,15 @@ export default class Install extends Command {
|
|
|
1760
1752
|
return plan;
|
|
1761
1753
|
}
|
|
1762
1754
|
static async buildDockerAppPlan(params) {
|
|
1755
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1756
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1763
1757
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1764
|
-
|
|
1758
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1765
1759
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1766
1760
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1767
|
-
defaultRegistry:
|
|
1761
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1768
1762
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
1763
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1769
1764
|
});
|
|
1770
1765
|
const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT;
|
|
1771
1766
|
const configuredStoragePath = resolveConfiguredStoragePathValue(params.appResults, params.envName);
|
|
@@ -1792,6 +1787,7 @@ export default class Install extends Command {
|
|
|
1792
1787
|
appResults: params.appResults,
|
|
1793
1788
|
rootResults: params.rootResults,
|
|
1794
1789
|
});
|
|
1790
|
+
const containerPort = resolveDockerImageContainerPort(imageRef);
|
|
1795
1791
|
const args = [
|
|
1796
1792
|
'run',
|
|
1797
1793
|
'-d',
|
|
@@ -1800,7 +1796,7 @@ export default class Install extends Command {
|
|
|
1800
1796
|
'--network',
|
|
1801
1797
|
params.networkName,
|
|
1802
1798
|
'-p',
|
|
1803
|
-
`${appPort}
|
|
1799
|
+
`${appPort}:${containerPort}`,
|
|
1804
1800
|
];
|
|
1805
1801
|
if (envFile) {
|
|
1806
1802
|
args.push('--env-file', envFile);
|
|
@@ -1990,12 +1986,15 @@ export default class Install extends Command {
|
|
|
1990
1986
|
}
|
|
1991
1987
|
async ensureSkippedDownloadInputsReady(params) {
|
|
1992
1988
|
if (params.source === 'docker') {
|
|
1989
|
+
const configuredRegistry = await getCliConfigValue('nb-image-registry');
|
|
1990
|
+
const configuredVariant = normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT;
|
|
1993
1991
|
const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() ||
|
|
1994
|
-
|
|
1992
|
+
resolveOfficialDockerRegistry(configuredRegistry);
|
|
1995
1993
|
const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION;
|
|
1996
1994
|
const imageRef = resolveDockerImageRef(dockerRegistry, version, {
|
|
1997
|
-
defaultRegistry:
|
|
1995
|
+
defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry),
|
|
1998
1996
|
defaultVersion: DEFAULT_DOCKER_VERSION,
|
|
1997
|
+
variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined,
|
|
1999
1998
|
});
|
|
2000
1999
|
const imageExists = await commandSucceeds('docker', ['image', 'inspect', imageRef]);
|
|
2001
2000
|
if (!imageExists) {
|
|
@@ -2254,6 +2253,13 @@ export default class Install extends Command {
|
|
|
2254
2253
|
}
|
|
2255
2254
|
await this.config.runCommand('env:update', [params.envName]);
|
|
2256
2255
|
}
|
|
2256
|
+
buildAppStartArgv(params) {
|
|
2257
|
+
const argv = ['--env', params.envName, '--yes', '--no-sync-licensed-plugins', '--hook-command', 'init'];
|
|
2258
|
+
if (params.verbose) {
|
|
2259
|
+
argv.push('--verbose');
|
|
2260
|
+
}
|
|
2261
|
+
return argv;
|
|
2262
|
+
}
|
|
2257
2263
|
async runInstallHookIfNeeded(params) {
|
|
2258
2264
|
const appPath = Install.resolveAbsoluteAppPath(params.envName, params.appResults);
|
|
2259
2265
|
const savedHookScript = Install.toOptionalPromptString(params.appResults.hookScript);
|
|
@@ -2391,7 +2397,7 @@ export default class Install extends Command {
|
|
|
2391
2397
|
if (resumePreset?.appPreset?.hookScript !== undefined && appResults.hookScript === undefined) {
|
|
2392
2398
|
appResults.hookScript = resumePreset.appPreset.hookScript;
|
|
2393
2399
|
}
|
|
2394
|
-
const downloadOpts = Install.buildDownloadPromptOptionsForInstall(appResults, envName);
|
|
2400
|
+
const downloadOpts = await Install.buildDownloadPromptOptionsForInstall(appResults, envName);
|
|
2395
2401
|
downloadOpts.values = {
|
|
2396
2402
|
...(resumePreset?.downloadPreset ?? {}),
|
|
2397
2403
|
...downloadOpts.values,
|
|
@@ -2498,7 +2504,6 @@ export default class Install extends Command {
|
|
|
2498
2504
|
const parsed = {
|
|
2499
2505
|
...flags,
|
|
2500
2506
|
};
|
|
2501
|
-
const defaultApiHost = await resolveDefaultApiHost();
|
|
2502
2507
|
if (parsed['skip-auth'] && (parsed['access-token'] !== undefined || parsed.token !== undefined)) {
|
|
2503
2508
|
this.error('--skip-auth cannot be used with --access-token or --token.');
|
|
2504
2509
|
}
|
|
@@ -2578,8 +2583,7 @@ export default class Install extends Command {
|
|
|
2578
2583
|
dbResults.dbUser = builtinDbPlan.dbUser;
|
|
2579
2584
|
dbResults.dbPassword = builtinDbPlan.dbPassword;
|
|
2580
2585
|
}
|
|
2581
|
-
let
|
|
2582
|
-
let localAppPlan;
|
|
2586
|
+
let shouldStartApp = false;
|
|
2583
2587
|
if (source === 'docker' || source === 'npm' || source === 'git') {
|
|
2584
2588
|
this.logStage('Preparing application');
|
|
2585
2589
|
if (source === 'docker') {
|
|
@@ -2591,111 +2595,28 @@ export default class Install extends Command {
|
|
|
2591
2595
|
printInfo('Application image ready.');
|
|
2592
2596
|
}
|
|
2593
2597
|
if (!parsed['prepare-only']) {
|
|
2594
|
-
|
|
2595
|
-
hookName: 'beforeAppInstall',
|
|
2596
|
-
envName,
|
|
2597
|
-
source,
|
|
2598
|
-
appResults,
|
|
2599
|
-
downloadResults,
|
|
2600
|
-
dbResults,
|
|
2601
|
-
rootResults,
|
|
2602
|
-
envAddResults,
|
|
2603
|
-
defaultApiHost,
|
|
2604
|
-
});
|
|
2605
|
-
dockerAppPlan = await this.installDockerApp({
|
|
2606
|
-
envName,
|
|
2607
|
-
dockerNetworkName,
|
|
2608
|
-
dockerContainerPrefix,
|
|
2609
|
-
appResults,
|
|
2610
|
-
downloadResults,
|
|
2611
|
-
dbResults,
|
|
2612
|
-
rootResults,
|
|
2613
|
-
builtinDbPlan,
|
|
2614
|
-
force: parsed.force,
|
|
2615
|
-
commandStdio,
|
|
2616
|
-
});
|
|
2617
|
-
appResults.appKey = dockerAppPlan.appKey;
|
|
2618
|
-
appResults.timeZone = dockerAppPlan.timeZone;
|
|
2598
|
+
shouldStartApp = true;
|
|
2619
2599
|
}
|
|
2620
2600
|
}
|
|
2621
2601
|
else if (source === 'npm' || source === 'git') {
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
? Install.resolveLocalProjectRoot({
|
|
2625
|
-
envName,
|
|
2626
|
-
appResults,
|
|
2627
|
-
downloadResults,
|
|
2628
|
-
})
|
|
2629
|
-
: await this.downloadLocalApp({
|
|
2602
|
+
if (!parsed['skip-download'] && !parsed['prepare-only']) {
|
|
2603
|
+
await this.downloadLocalApp({
|
|
2630
2604
|
envName,
|
|
2631
2605
|
appResults,
|
|
2632
2606
|
downloadResults,
|
|
2633
2607
|
verbose: parsed.verbose,
|
|
2634
2608
|
});
|
|
2635
|
-
if (!parsed['skip-download'] && !parsed['prepare-only']) {
|
|
2636
2609
|
printInfo('Application files ready.');
|
|
2637
2610
|
}
|
|
2638
2611
|
if (!parsed['prepare-only']) {
|
|
2639
|
-
|
|
2640
|
-
hookName: 'beforeAppInstall',
|
|
2641
|
-
envName,
|
|
2642
|
-
source,
|
|
2643
|
-
appResults,
|
|
2644
|
-
downloadResults,
|
|
2645
|
-
dbResults,
|
|
2646
|
-
rootResults,
|
|
2647
|
-
envAddResults,
|
|
2648
|
-
projectRoot,
|
|
2649
|
-
defaultApiHost,
|
|
2650
|
-
});
|
|
2651
|
-
localAppPlan = await this.startLocalApp({
|
|
2652
|
-
envName,
|
|
2653
|
-
source: localSource,
|
|
2654
|
-
projectRoot,
|
|
2655
|
-
appResults,
|
|
2656
|
-
dbResults,
|
|
2657
|
-
rootResults,
|
|
2658
|
-
commandStdio,
|
|
2659
|
-
});
|
|
2660
|
-
appResults.appKey = localAppPlan.appKey;
|
|
2661
|
-
appResults.timeZone = localAppPlan.timeZone;
|
|
2612
|
+
shouldStartApp = true;
|
|
2662
2613
|
}
|
|
2663
2614
|
}
|
|
2664
2615
|
}
|
|
2665
2616
|
else {
|
|
2666
2617
|
this.logDetail('Skipped app download and install.');
|
|
2667
2618
|
}
|
|
2668
|
-
if (
|
|
2669
|
-
this.logStage('Starting NocoBase');
|
|
2670
|
-
await this.waitForAppHealthCheck(Install.resolveApiBaseUrl({
|
|
2671
|
-
appResults,
|
|
2672
|
-
envAddResults,
|
|
2673
|
-
defaultApiHost,
|
|
2674
|
-
}), {
|
|
2675
|
-
containerName: dockerAppPlan?.containerName,
|
|
2676
|
-
verbose: parsed.verbose,
|
|
2677
|
-
});
|
|
2678
|
-
const displayApiBaseUrl = Install.resolveApiBaseUrl({
|
|
2679
|
-
appResults,
|
|
2680
|
-
envAddResults,
|
|
2681
|
-
defaultApiHost,
|
|
2682
|
-
});
|
|
2683
|
-
printInfo(`NocoBase is ready at ${formatInstallDisplayUrl(displayApiBaseUrl)}`);
|
|
2684
|
-
appResults.setupState = 'installed';
|
|
2685
|
-
await this.runInstallHookIfNeeded({
|
|
2686
|
-
hookName: 'afterAppStart',
|
|
2687
|
-
envName,
|
|
2688
|
-
source,
|
|
2689
|
-
appResults,
|
|
2690
|
-
downloadResults,
|
|
2691
|
-
dbResults,
|
|
2692
|
-
rootResults,
|
|
2693
|
-
envAddResults,
|
|
2694
|
-
projectRoot: localAppPlan?.projectRoot,
|
|
2695
|
-
defaultApiHost,
|
|
2696
|
-
});
|
|
2697
|
-
}
|
|
2698
|
-
if (dockerAppPlan || localAppPlan || builtinDbPlan) {
|
|
2619
|
+
if (shouldStartApp || builtinDbPlan) {
|
|
2699
2620
|
await this.saveInstalledEnv({
|
|
2700
2621
|
envName,
|
|
2701
2622
|
appResults,
|
|
@@ -2705,10 +2626,14 @@ export default class Install extends Command {
|
|
|
2705
2626
|
envAddResults,
|
|
2706
2627
|
});
|
|
2707
2628
|
}
|
|
2629
|
+
if (shouldStartApp) {
|
|
2630
|
+
this.logStage('Starting NocoBase');
|
|
2631
|
+
await this.config.runCommand('app:start', this.buildAppStartArgv({ envName, verbose: parsed.verbose }));
|
|
2632
|
+
}
|
|
2708
2633
|
await this.syncInstalledEnvConnection({
|
|
2709
2634
|
envName,
|
|
2710
2635
|
envAddResults,
|
|
2711
|
-
appReady:
|
|
2636
|
+
appReady: shouldStartApp,
|
|
2712
2637
|
skipAuth: Boolean(parsed['skip-auth']),
|
|
2713
2638
|
});
|
|
2714
2639
|
if (!parsed['prepare-only']) {
|
|
@@ -2717,7 +2642,7 @@ export default class Install extends Command {
|
|
|
2717
2642
|
if (parsed['prepare-only']) {
|
|
2718
2643
|
printInfo(`Preparation complete for "${envName}". Activate the license, then run \`nb app start --env ${envName}\`.`);
|
|
2719
2644
|
}
|
|
2720
|
-
else if (!
|
|
2645
|
+
else if (!shouldStartApp) {
|
|
2721
2646
|
printInfo(`Install config for "${envName}" has been saved.`);
|
|
2722
2647
|
}
|
|
2723
2648
|
}
|