diff --git a/README.md b/README.md index 27c64bf..20b66d6 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,25 @@ npm run serve 关于部署等说明请前往项目中查看,后端项目代码位于根目录 [/service](https://github.com/palxiao/poster-design/tree/main/service) 下。 +### 快速启动 +使用[docker-compose.yml](docker/docker-compose.yaml) 文件快速启动。在运行安装命令之前,请确保您的机器上安装了 [Docker](https://docs.docker.com/get-docker/) 和 [Docker Compose](https://docs.docker.com/compose/install/): +> 特别注意⚠️:由于`ghcr.io/puppeteer/puppeteer`镜像,暂不支持Arm64架构。请在Amd64架构下运行。 +``` +docker compose up -d +``` +运行后,可以在浏览器上访问[http://localhost](http://localhost) 直接访问 + +#### 自定义镜像构建 +- 前端构建 +``` +docker build -t heimanba/poster-web -f ./docker/web/Dockerfile . +``` + +- 服务端构建 +``` +docker build -t heimanba/poster-api -f ./docker/api/Dockerfile ./service +``` + ### 付费技术支持 支持基于开源版定制有限功能,帮助开发者节省研发时间和成本,并提供全方位技术指导与答疑。了解/获取技术支持请访问:[迅排 Plus 服务](https://plus.palxp.cn/)。 diff --git a/docker/api/Dockerfile b/docker/api/Dockerfile new file mode 100644 index 0000000..e7cf499 --- /dev/null +++ b/docker/api/Dockerfile @@ -0,0 +1,38 @@ +FROM node:20-alpine AS builder + +WORKDIR /usr/src/app + +# 仅复制 package.json 和 package-lock.json 以利用缓存 +COPY ./package*.json ./ + +# 安装依赖 +RUN npm install --registry=https://registry.npmmirror.com + +# 复制其余的源代码 +COPY ./ ./ + +RUN npm run build && cp -r ./src/mock ./dist + +# 第二阶段: 运行阶段 +FROM ghcr.io/puppeteer/puppeteer:latest + +USER root + +RUN mkdir -p /cache + +# 设置工作目录 +WORKDIR /usr/src/app + + +# 从构建阶段复制构建好的 dist 目录 +COPY --from=builder /usr/src/app/dist ./ + +RUN npm install --registry=https://registry.npmmirror.com + +RUN mkdir -p server && mv -f server.js server/index.js + +# 如果需要暴露端口,例如 3000 +EXPOSE 3000 + +# 定义容器启动时执行的命令 +CMD ["node", "server/index.js"] \ No newline at end of file diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml new file mode 100644 index 0000000..e795128 --- /dev/null +++ b/docker/docker-compose.yaml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + poster-web: + image: heimanba/poster-web + ports: + - "80:80" + depends_on: + - poster-api + network_mode: host + + poster-api: + image: heimanba/poster-api + ports: + - "7001:7001" + network_mode: host \ No newline at end of file diff --git a/docker/web/Dockerfile b/docker/web/Dockerfile new file mode 100644 index 0000000..83068d6 --- /dev/null +++ b/docker/web/Dockerfile @@ -0,0 +1,29 @@ +FROM node:20-alpine AS builder + +WORKDIR /usr/src/app + + +# 复制其余的源代码 +COPY ./ ./ + + +RUN npm i --registry=https://registry.npmmirror.com + + +RUN npm run build + +# 使用官方的nginx基础镜像 +FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized + +# 设置工作目录 +WORKDIR /usr/share/nginx/html + +COPY --from=builder /usr/src/app/dist /usr/share/nginx/html + +COPY ./docker/web/static.conf /etc/nginx/default.d/ + +# 暴露80端口和443端口(如果你使用HTTPS) +EXPOSE 80 443 + +# 使用自定义entrypoint启动 +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/web/static.conf b/docker/web/static.conf new file mode 100644 index 0000000..d514a33 --- /dev/null +++ b/docker/web/static.conf @@ -0,0 +1,14 @@ +location / { + try_files $uri $uri/ /index.html; + add_header Cache-Control no-cache; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; +} + +location ^~/design/ { + proxy_pass http://127.0.0.1:7001; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +} \ No newline at end of file diff --git a/service/webpack.plugin.js b/service/webpack.plugin.js index 4d7fb8f..58244d4 100644 --- a/service/webpack.plugin.js +++ b/service/webpack.plugin.js @@ -1,46 +1,25 @@ -/* - * @Author: ShawnPhang - * @Date: 2024-06-19 23:35:21 - * @Description: - * @LastEditors: ShawnPhang - * @LastEditTime: 2024-09-24 19:30:38 - */ const pkg = require("./package.json"); -const fs = require('fs'); class MyPlugin { - apply(compiler) { - compiler.hooks.emit.tap("BuildPackageJson", async (compilation) => { - console.log("构建 package.json ...."); - const myBuildPackageJson = `{ - name: ${pkg.name+'-builder'}, - version: ${pkg.version}, - dependencies: ${JSON.stringify(pkg.dependencies, null, 2)} - }`; - await checkCreateFolder('./dist') - fs.writeFile('./dist/package.json', myBuildPackageJson, 'utf8', (err) => { - if (err) { - console.error('保存 package.json 文件时发生错误:', err); - } else { - console.log('package.json 文件构建完成!'); - } - }); - }); - } -} + apply(compiler) { + compiler.hooks.emit.tapAsync("BuildPackageJson", (compilation, callback) => { + console.log("构建 package.json ...."); -// 检测目录并创建目录 -function checkCreateFolder(folder) { - try { - const pathArr = splitPath(folder); - let _path = ""; - for (let i = 0; i < pathArr.length; i++) { - if (pathArr[i]) { - _path += `/${pathArr[i]}`; - !fs.existsSync(_path) && fs.mkdirSync(_path); - } - } - } catch (e) {} + const myBuildPackageJson = { + name: `${pkg.name}-builder`, + version: pkg.version, + dependencies: pkg.dependencies + }; + + compilation.assets['package.json'] = { + source: () => JSON.stringify(myBuildPackageJson, null, 2), + size: () => Buffer.byteLength(JSON.stringify(myBuildPackageJson, null, 2), 'utf8') + }; + + console.log('package.json 文件构建完成!'); + callback(); + }); + } } module.exports = MyPlugin;