nodebbs 0.3.0 → 0.3.2

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.
@@ -43,7 +43,7 @@ services:
43
43
  # API 服务
44
44
  api:
45
45
  build:
46
- context: ../../
46
+ context: .
47
47
  dockerfile: apps/api/Dockerfile
48
48
  image: ${API_IMAGE:-nodebbs-api:local}
49
49
  container_name: nodebbs-api
@@ -59,7 +59,6 @@ services:
59
59
  JWT_SECRET: ${JWT_SECRET:-change-this-to-a-secure-random-string-in-production}
60
60
  JWT_ACCESS_TOKEN_EXPIRES_IN: ${JWT_ACCESS_TOKEN_EXPIRES_IN:-1y}
61
61
  CORS_ORIGIN: ${CORS_ORIGIN:-*}
62
- APP_URL: ${APP_URL:-http://localhost:3100}
63
62
  TZ: Asia/Shanghai
64
63
  volumes:
65
64
  - api_uploads:/app/apps/api/uploads
@@ -83,7 +82,7 @@ services:
83
82
  # Web 前端服务
84
83
  web:
85
84
  build:
86
- context: ../../
85
+ context: .
87
86
  dockerfile: apps/web/Dockerfile
88
87
  image: ${WEB_IMAGE:-nodebbs-web:local}
89
88
  container_name: nodebbs-web
@@ -34,10 +34,10 @@ JWT_ACCESS_TOKEN_EXPIRES_IN=1y
34
34
 
35
35
  # CORS 配置
36
36
  # 生产环境建议设置为具体的域名,例如: https://yourdomain.com
37
+ # 支持通配符 * 格式:https://yourdomain.com,https://*.yourdomain.com
37
38
  CORS_ORIGIN=*
38
39
 
39
- # 应用 URL(OAuth 回调使用)
40
- APP_URL=http://localhost:3100
40
+
41
41
 
42
42
  # ========================================
43
43
  # Web 前端配置
@@ -16,7 +16,7 @@ export declare function getComposeFiles(env: string): Promise<{
16
16
  * 检查 Docker 环境是否可用
17
17
  *
18
18
  * 验证 `docker` 和 `docker compose` 命令是否已安装并能正常响应。
19
- * 如果检查失败,会抛出错误并提示用户安装。
19
+ * 如果检查失败,会询问用户是否自动安装。
20
20
  */
21
21
  export declare function checkDocker(): Promise<void>;
22
22
  /**
@@ -1,4 +1,5 @@
1
1
  import { execa } from 'execa';
2
+ import { confirm } from '@inquirer/prompts';
2
3
  import { logger } from './logger.js';
3
4
  import path from 'node:path';
4
5
  import { exists } from 'node:fs';
@@ -83,7 +84,7 @@ export async function getComposeFiles(env) {
83
84
  * 检查 Docker 环境是否可用
84
85
  *
85
86
  * 验证 `docker` 和 `docker compose` 命令是否已安装并能正常响应。
86
- * 如果检查失败,会抛出错误并提示用户安装。
87
+ * 如果检查失败,会询问用户是否自动安装。
87
88
  */
88
89
  export async function checkDocker() {
89
90
  logger.info('正在检查 Docker 环境...');
@@ -93,8 +94,87 @@ export async function checkDocker() {
93
94
  logger.success('Docker 环境检查通过');
94
95
  }
95
96
  catch (error) {
96
- logger.error('未找到 Docker 或 Docker Compose,请先安装。');
97
- throw error;
97
+ logger.warning('未检测到 Docker 或 Docker Compose');
98
+ // 如果是 CI 环境或非交互式环境,直接报错
99
+ if (process.env.CI || !process.stdout.isTTY) {
100
+ throw error;
101
+ }
102
+ const shouldInstall = await confirm({
103
+ message: '检测到未安装 Docker,是否尝试自动安装?',
104
+ default: true
105
+ });
106
+ if (shouldInstall) {
107
+ try {
108
+ await installDocker();
109
+ // 安装后再次检查
110
+ logger.info('安装完成,正在验证...');
111
+ await execa('docker', ['--version']);
112
+ await execa('docker', ['compose', 'version']);
113
+ logger.success('Docker 环境安装并验证通过!');
114
+ return;
115
+ }
116
+ catch (installError) {
117
+ logger.error(`安装失败: ${installError.message}`);
118
+ logger.info('请访问 https://www.docker.com/get-started 手动安装。');
119
+ throw installError;
120
+ }
121
+ }
122
+ // 用户拒绝安装
123
+ logger.error('用户选择不安装 Docker,无法继续。');
124
+ throw new Error('用户拒绝安装 Docker');
125
+ }
126
+ }
127
+ /**
128
+ * 根据操作系统自动安装 Docker
129
+ *
130
+ * 目前仅支持 Linux 平台,使用官方安装脚本 (get.docker.com)。
131
+ * 安装完成后会尝试启动 Docker 服务并清理临时文件。
132
+ */
133
+ async function installDocker() {
134
+ const platform = process.platform;
135
+ if (platform === 'linux') {
136
+ const scriptPath = 'get-docker.sh';
137
+ try {
138
+ // 下载官方安装脚本
139
+ logger.info('正在下载 Docker 官方安装脚本...');
140
+ await execa('curl', ['-fsSL', 'https://get.docker.com', '-o', scriptPath], { stdio: 'inherit' });
141
+ // 执行安装脚本
142
+ logger.info('正在执行安装脚本 (可能需要 sudo 权限)...');
143
+ await execa('sh', [scriptPath], { stdio: 'inherit' });
144
+ // 尝试启动 Docker 服务
145
+ logger.info('正在尝试启动 Docker 服务...');
146
+ try {
147
+ await execa('sudo', ['systemctl', 'start', 'docker']);
148
+ await execa('sudo', ['systemctl', 'enable', 'docker']);
149
+ logger.success('Docker 服务已启动并设置为开机自启');
150
+ }
151
+ catch {
152
+ logger.warning('无法自动启动 Docker 服务');
153
+ logger.info('请手动运行: sudo systemctl start docker');
154
+ }
155
+ // 提示用户可能需要添加到 docker 组
156
+ logger.warning('请确保您的用户已添加到 docker 组:');
157
+ logger.info(' sudo usermod -aG docker $USER');
158
+ logger.info('您可能需要注销并重新登录才能生效。');
159
+ await confirm({ message: '是否已完成必要配置并准备继续?', default: true });
160
+ }
161
+ finally {
162
+ // 清理临时安装脚本
163
+ try {
164
+ const fs = await import('node:fs/promises');
165
+ await fs.unlink(scriptPath);
166
+ logger.info('已清理临时安装脚本');
167
+ }
168
+ catch {
169
+ // 静默忽略清理失败
170
+ }
171
+ }
172
+ }
173
+ else {
174
+ // 不支持的平台 (macOS, Windows 等)
175
+ logger.warning(`暂不支持在 ${platform} 平台自动安装 Docker。`);
176
+ logger.info('请访问 https://www.docker.com/products/docker-desktop/ 下载安装。');
177
+ throw new Error(`不支持在 ${platform} 平台自动安装`);
98
178
  }
99
179
  }
100
180
  /**
package/dist/utils/env.js CHANGED
@@ -95,11 +95,6 @@ export async function initEnv() {
95
95
  default: '7100'
96
96
  });
97
97
  const serverApiUrl = `http://api:${apiPort}`;
98
- const defaultAppUrl = `http://localhost:${webPort}`;
99
- const appUrl = await input({
100
- message: '设置 APP_URL (应用访问地址):',
101
- default: defaultAppUrl
102
- });
103
98
  const corsOrigin = await input({
104
99
  message: '设置 CORS_ORIGIN (允许跨域的域名):',
105
100
  default: '*'
@@ -111,7 +106,6 @@ export async function initEnv() {
111
106
  console.log(`JWT_SECRET: ${jwtSecret.substring(0, 3)}******`);
112
107
  console.log(`WEB_PORT: ${webPort}`);
113
108
  console.log(`API_PORT: ${apiPort}`);
114
- console.log(`APP_URL: ${appUrl}`);
115
109
  console.log(`SERVER_API_URL: ${serverApiUrl}`);
116
110
  console.log(`CORS_ORIGIN: ${corsOrigin}`);
117
111
  console.log('==========================================\n');
@@ -135,7 +129,6 @@ export async function initEnv() {
135
129
  'WEB_PORT': webPort,
136
130
  'API_PORT': apiPort,
137
131
  'SERVER_API_URL': serverApiUrl,
138
- 'APP_URL': appUrl,
139
132
  'CORS_ORIGIN': corsOrigin,
140
133
  };
141
134
  // 针对每个 Key 进行替换。
@@ -250,10 +243,6 @@ export async function checkEnv(envType) {
250
243
  logger.warning('生产环境建议设置具体的 CORS_ORIGIN');
251
244
  warnings++;
252
245
  }
253
- if (!envConfig.APP_URL || envConfig.APP_URL === 'http://localhost:3100') {
254
- logger.warning('生产环境建议设置实际的 APP_URL');
255
- warnings++;
256
- }
257
246
  }
258
247
  if (errors > 0) {
259
248
  logger.error(`发现 ${errors} 个配置错误,无法继续。`);
@@ -781,5 +781,5 @@
781
781
  ]
782
782
  }
783
783
  },
784
- "version": "0.3.0"
784
+ "version": "0.3.2"
785
785
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nodebbs",
3
3
  "description": "NodeBBS 论坛系统专业运维工具",
4
- "version": "0.3.0",
4
+ "version": "0.3.2",
5
5
  "author": "wengqianshan",
6
6
  "bin": {
7
7
  "nodebbs": "./bin/run.js"