cmyr-template-cli 1.21.1 → 1.22.0

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/dist/plopfile.js CHANGED
@@ -47,6 +47,204 @@ var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
47
47
  process.env;
48
48
  const PACKAGE_MANAGER = 'pnpm';
49
49
 
50
+ const TEMPLATES_META_LIST = [
51
+ {
52
+ name: 'vite4-template',
53
+ language: 'vue',
54
+ runtime: 'browser',
55
+ vueVersion: 3,
56
+ docker: false,
57
+ priority: 0,
58
+ },
59
+ {
60
+ name: 'vite3-template',
61
+ language: 'vue',
62
+ runtime: 'browser',
63
+ vueVersion: 3,
64
+ docker: false,
65
+ priority: 0,
66
+ },
67
+ {
68
+ name: 'vite2-vue2-template',
69
+ language: 'vue',
70
+ runtime: 'browser',
71
+ vueVersion: 2,
72
+ docker: false,
73
+ priority: 0,
74
+ },
75
+ {
76
+ name: 'vite2-template',
77
+ language: 'vue',
78
+ runtime: 'browser',
79
+ vueVersion: 3,
80
+ docker: false,
81
+ priority: 0,
82
+ },
83
+ {
84
+ name: 'electron-vite-template',
85
+ language: 'vue',
86
+ runtime: 'browser',
87
+ vueVersion: 3,
88
+ docker: false,
89
+ priority: 0,
90
+ },
91
+ {
92
+ name: 'electron-vue-template',
93
+ language: 'vue',
94
+ runtime: 'browser',
95
+ vueVersion: 3,
96
+ docker: false,
97
+ priority: 0,
98
+ },
99
+ {
100
+ name: 'nuxt-template',
101
+ language: 'vue',
102
+ runtime: 'browser',
103
+ vueVersion: 2,
104
+ docker: false,
105
+ priority: 0,
106
+ },
107
+ {
108
+ name: 'uni-template',
109
+ language: 'vue',
110
+ runtime: 'browser',
111
+ vueVersion: 2,
112
+ docker: false,
113
+ priority: 0,
114
+ },
115
+ {
116
+ name: 'uni-vite2-template',
117
+ language: 'vue',
118
+ runtime: 'browser',
119
+ vueVersion: 3,
120
+ docker: false,
121
+ priority: 0,
122
+ },
123
+ {
124
+ name: 'react-template',
125
+ language: 'react',
126
+ runtime: 'browser',
127
+ vueVersion: 0,
128
+ docker: false,
129
+ priority: 0,
130
+ },
131
+ {
132
+ name: 'react16-template',
133
+ language: 'react',
134
+ runtime: 'browser',
135
+ vueVersion: 0,
136
+ docker: false,
137
+ priority: 0,
138
+ },
139
+ {
140
+ name: 'ts-template',
141
+ language: 'typescript',
142
+ runtime: 'nodejs',
143
+ vueVersion: 0,
144
+ docker: true,
145
+ priority: 0,
146
+ },
147
+ {
148
+ name: 'express-template',
149
+ language: 'typescript',
150
+ runtime: 'nodejs',
151
+ vueVersion: 0,
152
+ docker: true,
153
+ priority: 0,
154
+ },
155
+ {
156
+ name: 'koa2-template',
157
+ language: 'typescript',
158
+ runtime: 'nodejs',
159
+ vueVersion: 0,
160
+ docker: true,
161
+ priority: 0,
162
+ },
163
+ {
164
+ name: 'nest-template',
165
+ language: 'typescript',
166
+ runtime: 'nodejs',
167
+ vueVersion: 0,
168
+ docker: true,
169
+ priority: 0,
170
+ },
171
+ {
172
+ name: 'auto-release-template',
173
+ language: 'typescript',
174
+ runtime: 'nodejs',
175
+ vueVersion: 0,
176
+ docker: false,
177
+ npm: true,
178
+ priority: 0,
179
+ },
180
+ {
181
+ name: 'rollup-template',
182
+ language: 'typescript',
183
+ runtime: 'nodejs',
184
+ vueVersion: 0,
185
+ docker: false,
186
+ npm: true,
187
+ priority: 0,
188
+ },
189
+ {
190
+ name: 'webpack-template',
191
+ language: 'typescript',
192
+ runtime: 'nodejs',
193
+ vueVersion: 0,
194
+ docker: false,
195
+ npm: true,
196
+ priority: 0,
197
+ },
198
+ {
199
+ name: 'github-action-template',
200
+ language: 'typescript',
201
+ runtime: 'nodejs',
202
+ vueVersion: 0,
203
+ docker: false,
204
+ priority: 0,
205
+ },
206
+ {
207
+ name: 'vue-template',
208
+ language: 'vue',
209
+ runtime: 'browser',
210
+ vueVersion: 2,
211
+ docker: false,
212
+ priority: 0,
213
+ },
214
+ {
215
+ name: 'vue3-template',
216
+ language: 'vue',
217
+ runtime: 'browser',
218
+ vueVersion: 3,
219
+ docker: false,
220
+ priority: 0,
221
+ },
222
+ {
223
+ name: 'python-flask-template',
224
+ language: 'python',
225
+ runtime: 'python',
226
+ vueVersion: 0,
227
+ docker: true,
228
+ priority: 0,
229
+ },
230
+ {
231
+ name: 'go-gin-template',
232
+ language: 'golang',
233
+ runtime: 'golang',
234
+ vueVersion: 0,
235
+ docker: true,
236
+ priority: 0,
237
+ },
238
+ {
239
+ name: 'spring-boot-template',
240
+ language: 'java',
241
+ runtime: 'java',
242
+ vueVersion: 0,
243
+ docker: true,
244
+ priority: 0,
245
+ },
246
+ ];
247
+
50
248
  const fix = (markdown, rules) => { var _a, _b; return (_b = (_a = core.lintMarkdown(markdown, rules, true)) === null || _a === void 0 ? void 0 : _a.fixedResult) === null || _b === void 0 ? void 0 : _b.result; };
51
249
  axios__default["default"].defaults.timeout = 10 * 1000;
52
250
  if (!Promise.any) {
@@ -91,11 +289,18 @@ const COMMON_DEPENDENCIES = {
91
289
  'isomorphic-unfetch': '^3.1.0',
92
290
  lodash: '^4.17.20',
93
291
  'lodash-es': '^4.17.21',
94
- md5: '^2.3.0',
95
292
  'push-all-in-one': '^2.2.0',
96
293
  'leancloud-storage': '^4.15.0',
97
294
  },
98
295
  };
296
+ const NODE_DEPENDENCIES = {
297
+ devDependencies: {},
298
+ dependencies: {
299
+ dotenv: '^16.3.1',
300
+ rimraf: '^5.0.0',
301
+ log4js: '^6.9.1',
302
+ },
303
+ };
99
304
  const VUE2_DEPENDENCIES = {
100
305
  devDependencies: {},
101
306
  dependencies: {
@@ -185,16 +390,19 @@ async function downloadGitRepo(repository, destination, options = {}) {
185
390
  const fastRepo = await getFastGitRepo(repository);
186
391
  const loading = ora__default["default"](`正在下载模板 - ${repository}`);
187
392
  loading.start();
188
- return new Promise((resolve) => {
189
- download__default["default"](fastRepo, destination, options, (err) => {
190
- if (err) {
191
- loading.fail('下载模板失败!');
192
- process.exit(1);
193
- }
194
- loading.succeed(`成功下载模板 - ${repository}`);
195
- resolve(true);
196
- });
197
- });
393
+ return Promise.any([
394
+ new Promise((resolve) => {
395
+ download__default["default"](fastRepo, destination, options, (err) => {
396
+ if (err) {
397
+ loading.fail('下载模板失败!');
398
+ process.exit(1);
399
+ }
400
+ loading.succeed(`成功下载模板 - ${repository}`);
401
+ resolve(true);
402
+ });
403
+ }),
404
+ new Promise((resolve, reject) => setTimeout(reject, 60 * 1000)),
405
+ ]);
198
406
  }
199
407
  async function getFastGitRepo(repository) {
200
408
  const loading = ora__default["default"](`正在选择镜像源 - ${repository}`);
@@ -238,62 +446,131 @@ async function initProject(answers) {
238
446
  }
239
447
  async function init(projectPath, answers) {
240
448
  var _a;
241
- const { isOpenSource, isInitReadme, isInitContributing, isInitHusky, isInitSemanticRelease, isInitDocker } = answers;
449
+ const { template, isOpenSource, isInitReadme, isInitContributing, isInitHusky, isInitSemanticRelease, isInitDocker } = answers;
242
450
  try {
451
+ const templateMeta = getTemplateMeta(template);
243
452
  await asyncExec('git --version', {
244
453
  cwd: projectPath,
245
454
  });
246
- await asyncExec(`${PACKAGE_MANAGER} -v`, {
247
- cwd: projectPath,
248
- });
249
455
  await asyncExec('git init', {
250
456
  cwd: projectPath,
251
457
  });
252
- const newPkg = await initProjectJson(projectPath, answers);
253
- await initConfig(projectPath);
254
- await initCommitizen(projectPath);
255
- if (isInitDocker) {
256
- await initDocker(projectPath);
257
- }
258
- if (isOpenSource) {
259
- const info = await getProjectInfo(projectPath, answers);
260
- if (info) {
261
- if (isInitReadme) {
262
- await initReadme(projectPath, info);
263
- }
264
- if (isInitContributing) {
265
- await initContributing(projectPath, info);
458
+ if (['nodejs', 'browser'].includes(templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime)) {
459
+ await asyncExec('node -v', {
460
+ cwd: projectPath,
461
+ });
462
+ await asyncExec(`${PACKAGE_MANAGER} -v`, {
463
+ cwd: projectPath,
464
+ });
465
+ const newPkg = await initProjectJson(projectPath, answers);
466
+ await initConfig(projectPath);
467
+ await initCommitizen(projectPath);
468
+ if (isOpenSource) {
469
+ const info = await getProjectInfo(projectPath, answers);
470
+ if (info) {
471
+ if (isInitReadme) {
472
+ await initReadme(projectPath, info);
473
+ }
474
+ if (isInitContributing) {
475
+ await initContributing(projectPath, info);
476
+ }
477
+ await initLicense(projectPath, info);
266
478
  }
267
- await initLicense(projectPath, info);
479
+ await initGithubWorkflows(projectPath, answers);
480
+ }
481
+ if (isInitSemanticRelease) {
482
+ await initSemanticRelease(projectPath);
483
+ }
484
+ if (isInitHusky) {
485
+ await initHusky(projectPath);
486
+ }
487
+ await initCommonDependencies(projectPath, answers);
488
+ await initTsconfig(projectPath);
489
+ await initEslint(projectPath);
490
+ await initStylelint(projectPath);
491
+ await sortProjectJson(projectPath);
492
+ await initYarn(projectPath, answers);
493
+ await asyncExec('git add .', {
494
+ cwd: projectPath,
495
+ });
496
+ await installNpmPackages(projectPath);
497
+ await asyncExec('git add .', {
498
+ cwd: projectPath,
499
+ });
500
+ if ((_a = newPkg === null || newPkg === void 0 ? void 0 : newPkg.scripts) === null || _a === void 0 ? void 0 : _a.lint) {
501
+ await asyncExec(`${PACKAGE_MANAGER} run lint`, {
502
+ cwd: projectPath,
503
+ });
268
504
  }
269
- await initGithubWorkflows(projectPath, answers);
270
505
  }
271
- await initRemoteGitRepo(projectPath, answers);
272
- if (isInitSemanticRelease) {
273
- await initSemanticRelease(projectPath);
506
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) === 'java') {
507
+ try {
508
+ await asyncExec('java -version', {
509
+ cwd: projectPath,
510
+ });
511
+ }
512
+ catch (error) {
513
+ if (!(typeof error === 'string' && error.includes('java version'))) {
514
+ throw error;
515
+ }
516
+ }
517
+ await asyncExec('mvn -version', {
518
+ cwd: projectPath,
519
+ });
520
+ await asyncExec('git add .', {
521
+ cwd: projectPath,
522
+ });
523
+ try {
524
+ await asyncExec('mvn clean package -Dmaven.test.skip=true', {
525
+ cwd: projectPath,
526
+ });
527
+ }
528
+ catch (error) {
529
+ console.error(error);
530
+ }
274
531
  }
275
- if (isInitHusky) {
276
- await initHusky(projectPath);
532
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) === 'python') {
533
+ await asyncExec('python -V', {
534
+ cwd: projectPath,
535
+ });
536
+ await asyncExec('pip -V', {
537
+ cwd: projectPath,
538
+ });
539
+ await asyncExec('git add .', {
540
+ cwd: projectPath,
541
+ });
542
+ try {
543
+ await asyncExec('pip install -r requirements.txt', {
544
+ cwd: projectPath,
545
+ });
546
+ }
547
+ catch (error) {
548
+ if (!(typeof error === 'string' && error.includes('[notice]'))) {
549
+ throw error;
550
+ }
551
+ }
277
552
  }
278
- await initCommonDependencies(projectPath, answers);
279
- await initTsconfig(projectPath);
280
- await initEslint(projectPath);
281
- await initStylelint(projectPath);
282
- await sortProjectJson(projectPath);
283
- await initDependabot(projectPath, answers);
284
- await initYarn(projectPath, answers);
285
- await asyncExec('git add .', {
286
- cwd: projectPath,
287
- });
288
- await installNpmPackages(projectPath);
289
- await asyncExec('git add .', {
290
- cwd: projectPath,
291
- });
292
- if ((_a = newPkg === null || newPkg === void 0 ? void 0 : newPkg.scripts) === null || _a === void 0 ? void 0 : _a.lint) {
293
- await asyncExec(`${PACKAGE_MANAGER} run lint`, {
553
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) === 'golang') {
554
+ await asyncExec('go version', {
555
+ cwd: projectPath,
556
+ });
557
+ await asyncExec('git add .', {
294
558
  cwd: projectPath,
295
559
  });
560
+ try {
561
+ await asyncExec('go get', {
562
+ cwd: projectPath,
563
+ });
564
+ }
565
+ catch (error) {
566
+ console.error(error);
567
+ }
568
+ }
569
+ await initRemoteGitRepo(projectPath, answers);
570
+ if (isInitDocker) {
571
+ await initDocker(projectPath, answers);
296
572
  }
573
+ await initDependabot(projectPath, answers);
297
574
  await asyncExec('git add .', {
298
575
  cwd: projectPath,
299
576
  });
@@ -302,7 +579,7 @@ async function init(projectPath, answers) {
302
579
  });
303
580
  }
304
581
  catch (error) {
305
- console.error(error);
582
+ console.error(colors__default["default"].red(error));
306
583
  }
307
584
  }
308
585
  async function getGitUserName() {
@@ -413,7 +690,7 @@ async function initCommonDependencies(projectPath, answers) {
413
690
  ])));
414
691
  const devDependencies = Object.fromEntries(await Promise.all(commonDependencies
415
692
  .map((name) => `@types/${name}`)
416
- .filter((name) => { var _a; return (_a = COMMON_DEPENDENCIES === null || COMMON_DEPENDENCIES === void 0 ? void 0 : COMMON_DEPENDENCIES.devDependencies) === null || _a === void 0 ? void 0 : _a[name]; })
693
+ .filter((name) => { var _a, _b; return ((_a = COMMON_DEPENDENCIES === null || COMMON_DEPENDENCIES === void 0 ? void 0 : COMMON_DEPENDENCIES.devDependencies) === null || _a === void 0 ? void 0 : _a[name]) || ((_b = NODE_DEPENDENCIES === null || NODE_DEPENDENCIES === void 0 ? void 0 : NODE_DEPENDENCIES.devDependencies) === null || _b === void 0 ? void 0 : _b[name]); })
417
694
  .map(async (name) => [
418
695
  name,
419
696
  `^${await getNpmPackageVersion(name)}`,
@@ -975,11 +1252,31 @@ async function initCommitizen(projectPath) {
975
1252
  loading.fail('commitizen 初始化失败!');
976
1253
  }
977
1254
  }
978
- async function initDocker(projectPath) {
1255
+ async function initDocker(projectPath, answers) {
979
1256
  const loading = ora__default["default"]('正在初始化 Docker ……').start();
980
1257
  try {
1258
+ const templateMeta = getTemplateMeta(answers.template);
981
1259
  const files = ['.dockerignore', 'docker-compose.yml', 'Dockerfile'];
982
1260
  await copyFilesFromTemplates(projectPath, files);
1261
+ let dockerfilePath = '';
1262
+ switch (templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) {
1263
+ case 'java':
1264
+ dockerfilePath = 'java/Dockerfile';
1265
+ break;
1266
+ case 'python':
1267
+ dockerfilePath = 'python/Dockerfile';
1268
+ break;
1269
+ case 'golang':
1270
+ dockerfilePath = 'golang/Dockerfile';
1271
+ break;
1272
+ default:
1273
+ break;
1274
+ }
1275
+ const newPath = path__default["default"].join(projectPath, 'Dockerfile');
1276
+ if (await fs__default["default"].pathExists(newPath)) {
1277
+ await fs__default["default"].remove(newPath);
1278
+ }
1279
+ await fs__default["default"].copyFile(path__default["default"].join(__dirname, '../templates/', dockerfilePath), newPath);
983
1280
  loading.succeed('Docker 初始化成功!');
984
1281
  }
985
1282
  catch (error) {
@@ -1134,6 +1431,9 @@ async function removeFiles(projectPath, files) {
1134
1431
  function kebabCase(str) {
1135
1432
  return str.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/_+/g, '-').replace(/\s+/g, '-').toLowerCase();
1136
1433
  }
1434
+ function getTemplateMeta(template) {
1435
+ return TEMPLATES_META_LIST.find((e) => e.name === template);
1436
+ }
1137
1437
 
1138
1438
  module.exports = function (plop) {
1139
1439
  plop.setActionType('initProject', initProject);
@@ -1181,29 +1481,7 @@ module.exports = function (plop) {
1181
1481
  name: 'template',
1182
1482
  message: '请选择项目模板',
1183
1483
  choices() {
1184
- return [
1185
- 'vite4',
1186
- 'vite3',
1187
- 'vite2-vue2',
1188
- 'vite2',
1189
- 'electron-vite',
1190
- 'electron-vue',
1191
- 'nuxt',
1192
- 'uni',
1193
- 'uni-vite2',
1194
- 'react',
1195
- 'react16',
1196
- 'ts',
1197
- 'express',
1198
- 'koa2',
1199
- 'nest',
1200
- 'auto-release',
1201
- 'rollup',
1202
- 'webpack',
1203
- 'github-action',
1204
- 'vue',
1205
- 'vue3',
1206
- ].map((e) => `${e}-template`);
1484
+ return TEMPLATES_META_LIST.map((e) => e.name);
1207
1485
  },
1208
1486
  default: '',
1209
1487
  },
@@ -1213,19 +1491,26 @@ module.exports = function (plop) {
1213
1491
  message: '请选择需要安装的常见依赖',
1214
1492
  default: [],
1215
1493
  choices(answers) {
1494
+ const templateMeta = getTemplateMeta(answers.template);
1216
1495
  const choices = Object.keys(COMMON_DEPENDENCIES.dependencies);
1217
- const vue2List = ['vite2-vue2', 'nuxt', 'uni', 'vue'].map((e) => `${e}-template`);
1218
- if (vue2List.includes(answers.template)) {
1496
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) === 'nodejs') {
1497
+ choices.push(...Object.keys(NODE_DEPENDENCIES.dependencies));
1498
+ }
1499
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime) === 'browser') {
1500
+ choices.push(...Object.keys(WEB_DEPENDENCIES.dependencies));
1501
+ }
1502
+ if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.vueVersion) === 2) {
1219
1503
  choices.push(...Object.keys(VUE2_DEPENDENCIES.dependencies));
1220
1504
  }
1221
- else if (/(vue|vite)/.test(answers.template)) {
1505
+ else if ((templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.vueVersion) === 3) {
1222
1506
  choices.push(...Object.keys(VUE3_DEPENDENCIES.dependencies));
1223
1507
  }
1224
- if (/(vue|vite|react|nuxt)/.test(answers.template)) {
1225
- choices.push(...Object.keys(WEB_DEPENDENCIES.dependencies));
1226
- }
1227
1508
  return choices;
1228
1509
  },
1510
+ when(answers) {
1511
+ const templateMeta = getTemplateMeta(answers.template);
1512
+ return ['nodejs', 'browser'].includes(templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.runtime);
1513
+ },
1229
1514
  },
1230
1515
  {
1231
1516
  type: 'confirm',
@@ -1233,11 +1518,8 @@ module.exports = function (plop) {
1233
1518
  message: '是否初始化 Docker?',
1234
1519
  default: false,
1235
1520
  when(answers) {
1236
- return [
1237
- 'express',
1238
- 'koa2',
1239
- 'nest',
1240
- ].map((e) => `${e}-template`).includes(answers.template);
1521
+ const templateMeta = getTemplateMeta(answers.template);
1522
+ return templateMeta === null || templateMeta === void 0 ? void 0 : templateMeta.docker;
1241
1523
  },
1242
1524
  },
1243
1525
  {
@@ -1280,7 +1562,8 @@ module.exports = function (plop) {
1280
1562
  message: '是否发布到 npm?',
1281
1563
  default: false,
1282
1564
  when(answers) {
1283
- return answers.isOpenSource;
1565
+ const templateMeta = getTemplateMeta(answers.template);
1566
+ return answers.isOpenSource && templateMeta.npm;
1284
1567
  },
1285
1568
  },
1286
1569
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cmyr-template-cli",
3
- "version": "1.21.1",
3
+ "version": "1.22.0",
4
4
  "description": "草梅友仁自制的项目模板创建器",
5
5
  "author": "CaoMeiYouRen",
6
6
  "license": "MIT",
@@ -46,8 +46,8 @@
46
46
  "@types/lodash": "^4.14.165",
47
47
  "@types/node": "^20.0.0",
48
48
  "@types/promise.any": "^2.0.0",
49
- "@typescript-eslint/eslint-plugin": "6.7.2",
50
- "@typescript-eslint/parser": "6.7.2",
49
+ "@typescript-eslint/eslint-plugin": "6.7.4",
50
+ "@typescript-eslint/parser": "6.7.4",
51
51
  "commitizen": "^4.2.2",
52
52
  "conventional-changelog-cli": "^4.0.0",
53
53
  "conventional-changelog-cmyr-config": "^2.1.1",
@@ -0,0 +1,9 @@
1
+ FROM scratch
2
+
3
+ WORKDIR /home/app
4
+
5
+ COPY ./main /home/app
6
+
7
+ EXPOSE 8080
8
+
9
+ CMD ["./main"]
@@ -0,0 +1,16 @@
1
+ FROM alpine:latest
2
+
3
+ # 安装java环境
4
+ RUN echo "http://mirrors.aliyun.com/alpine/edge/main/" > /etc/apk/repositories \
5
+ && echo "http://mirrors.aliyun.com/alpine/edge/community/" >> /etc/apk/repositories \
6
+ && apk update \
7
+ && apk add --no-cache --update openjdk8 \
8
+ && java -version
9
+
10
+ WORKDIR /home/app
11
+
12
+ COPY . /home/app
13
+
14
+ EXPOSE 8080
15
+
16
+ CMD ["java", "-jar","./target/main.jar"]
@@ -0,0 +1,27 @@
1
+ FROM alpine:latest
2
+
3
+ # 安装python环境
4
+ RUN echo "http://mirrors.aliyun.com/alpine/edge/main/" > /etc/apk/repositories \
5
+ && echo "http://mirrors.aliyun.com/alpine/edge/community/" >> /etc/apk/repositories \
6
+ && apk update \
7
+ && apk add --no-cache --update python3 py3-pip \
8
+ && python3 -V && pip3 -V \
9
+ && ln -sf /usr/bin/pip3 /usr/bin/pip \
10
+ && mkdir -p ~/.pip \
11
+ && echo "[global]" > ~/.pip/pip.conf \
12
+ && echo "index-url=http://mirrors.cloud.aliyuncs.com/pypi/simple/" >> ~/.pip/pip.conf \
13
+ && echo "[install]" >> ~/.pip/pip.conf \
14
+ && echo "trusted-host=mirrors.cloud.aliyuncs.com" >> ~/.pip/pip.conf \
15
+ && pip install --upgrade pip && pip install wheel
16
+
17
+ WORKDIR /home/app
18
+
19
+ COPY ./requirements.txt /home/app
20
+
21
+ RUN pip install -r requirements.txt
22
+
23
+ COPY . /home/app
24
+
25
+ EXPOSE 8080
26
+
27
+ CMD ["gunicorn", "app:app", "-p", "app.pid", "-b", "0.0.0.0:8080"]