[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fjEyr0kzCs_eS2mf0E2RkF9Q60U22L05fSsGGKrbUE3s":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":28,"notice":28,"visitCount":29,"commentCount":30,"keywords":31},177,"2026-02-03T04:47:58.856Z","nextjs项目的打包、docker部署、脚本等","这篇文章记录一下我最近写的`NextJs`项目的简单打包、部署以及一些脚本，留作记录以及供大家参考。\n\n最近我写了一个彩票类的小程序：`好彩管家`(支付宝小程序)/`彩号管家`(微信小程序)，小程序使用的taro用作跨平台的小程序开发，h5方面为了seo友好，我选择了使用`NextJs`进行改写并丰富功能，使用nextjs开发的体验还是很不错的，毕竟这么多AI公司都选择了NextJs做前端。所以我觉得广大的开发者还是应该去体验一下NextJs，还是很不错的。\n\n话不多说，我来介绍一下我的工程。\n\n## 一、工程的性能情况介绍\n网页是：[https://lottery.xinwei.ltd](https://lottery.xinwei.ltd)\n\n![lottery lighthouse测试](https://image.xinwei.ltd/image1770091084545.png)\n\n从这张图可以看出，我这个工程性能还是可以的，在SEO上基本比较优秀了，当然在渲染上还是有优化的空间，这里不做赘述，大家关注点可以放在如何打包部署上。\n\n\n## 二、工程打包\n下面是我的NextJs的脚本命令配置。\n\n![nextjs工程的脚本](https://image.xinwei.ltd/image1770091403089.png)\n\n截图中已经给出了一些解释，我稍微列一下：\n- dev 脚本命令就是本地开发的\n- -p 是可选的命令，nextJs默认使用3000端口，使用-p xxx端口号，可以自定义监听的端口号\n- start 是生产环境下，执行这个命令就可以监听，同样可以使用-p指定端口号\n- deploy 是我增加的脚本命令，我在工程中写了一个bash脚本，通过npm命令就可以执行这个bash脚本，这个bash脚本就是用来打包，并上传内容到云服务器上，进行docker的相关操作。\n\n## 三、我的docker-compose文件\n我个人比较喜欢使用docker-compose文件来部署项目，因为文件结构清晰，配置一一对应设置就好，我这里留一下我的docker-compose文件内容。\n\n![docker-compose文件位置](https://image.xinwei.ltd/image1770091909884.png)\n\n直接在项目`根目录`下创建这个文件。\n```docker-compose.yml\nversion: '2.2'\n\nservices:\n  lottery:\n    image: 'node:latest'\n    container_name: xxx\n    working_dir: /app\n    environment:\n      - NODE_ENV=production\n    volumes:\n      - ./dist:/app\n    ports:\n      - 3000:3000 # 根据自己暴露的主机防火墙端口来设置\n    command: >\n      sh -c \"npm install && NODE_ENV=production npm run start\"\n```\n\n这个文件比较简单，就指定了一个容器的配置，使用node镜像，然后容器启动时，会执行command脚本中的命令。\n\n## 四、bash脚本\nbash脚本的作用就是用来执行npm相关命令删除旧打包产物、生成新产物，然后通过云服务器的scp授权证书远程ssh访问，操作云服务器文件、文件夹、docker等。\n\nbash脚本内容：\n```web.sh\n#bin/sh\n\necho \"当前路径：\"\necho \"\"\npwd\n\necho \"删除旧产物\"\nrm -rf .next\n\necho \"打包项目，生成新产物\"\nnpm run build\n\necho \"加权限\"\nchmod 777 .next\n\n# 这是在云服务器厂商管理后台生成的ssh操作授权证书，可以放在本地电脑上，执行命令时带入即可操作云服务器资源\nSSH_KEY=\"/Users/hamry/xxx/ssh_visit.pem\"\n# 这是主机访问的username和IP，这里不是我的实际IP，你需要改成你自己云服务器的ip地址\nSERVER=\"root@1.2.3.4\"\n\necho \"连接服务器&删除旧产物\"\nssh -i $SSH_KEY $SERVER '\necho \"当前目录：\";\npwd;\necho \"删除旧产物\";\nrm -rf /root/lottery_nextjs/dist/*;\nrm -rf /root/lottery_nextjs/dist/.[^.]*;\n'\n\necho \"拷贝产物到服务器\"\necho \"拷贝 .next、package、package-lock、public 到服务器\"\nscp -q -i $SSH_KEY -r .next package.json package-lock.json public $SERVER:/root/lottery_nextjs/dist/\necho \"拷贝 docker-compose 到服务器\"\nscp -q -i $SSH_KEY docker-compose.yml $SERVER:/root/lottery_nextjs/\necho \"重启docker\"\nssh -i $SSH_KEY $SERVER '\npwd;\ncd /root/lottery_nextjs/dist;\npwd;\n# docker-compose up  # 这里是第一次执行脚本时，会创建docker容器，第二次不用再次执行，不然每次都覆盖生成新容器。\ndocker restart xxx  # 和上面的命令不要同时执行，第一次生成容器时不要执行这个命令，第二次后就可以注释上面的命令，使用这条命令来重启第一次生成的那个容器ID\n'\n\necho \"容器重启成功\"\n```\n\n脚本的相关内容，我都在上面做了解释，大家如果要参考，要仔细阅读清楚，避免执行出错。\n\n另外，这里要说明一下，我们`不需要把整个NextJs工程拷贝到云服务器`，很占据云服务器空间的，所以我们只需要把重要关键的文件传输到云服务器。关键的文件在上面的脚本中已经有处理，我罗列在这里：\n- .next文件夹，这个是dev或者build时都会生成的隐藏文件夹，产物都放在这里了\n- package.json & package-lock.json，这2个文件也必不可少，最终执行命令也要通过`npm run start`执行package.json中的start命令。\n- public 文件夹，这里存放的是工程的静态资源文件，也是必不可少的，否则静态资源的访问就会出现404.\n\n这里要说一句为什么没有`node_modules`文件夹呢，是不是很奇怪，那说明你可能没看懂docker-compose.yml脚本中的那行命令：\n```docker-compose.yml\n...\ncommand: >\n      sh -c \"npm install && NODE_ENV=production npm run start\"\n...\n```\n这次看清楚了吧，这里有`npm install`命令，因为是node镜像，然后有`package.json`，那么在云服务器上安装依赖就很容易。如果要自己上传node_modules文件夹，一个是上传时间会特别久，另一个原因是有可能终端命令行执行由于文件太多导致EOF问题失败。\n\n## 五、云服务器上的文件内容\n### 5.1 整体文件夹\n![云服务器部署根目录](https://image.xinwei.ltd/image1770093298286.png)\n这里我在云服务器上创建了一个文件夹：lottery_nextjs，我所有的项目都会在云服务器的根路径/root目录下，lottery_nextjs这个文件夹就是我用来部署这个项目的专属文件夹。\n\n这个文件夹下面，放了2个东西：\n- dist：用于存放nextjs工程的打包产物，bash脚本中上传的内容都是到dist文件夹下；\n- docker-compose.yml: docker-compose文件，这个是用来创建docker容器，并让docker启动nextJs服务的，内容在上面已经给大家显示出来了。\n\n### 5.2 dist文件夹\n\n![dist文件夹内容](https://image.xinwei.ltd/image1770093595218.png)\n\n大家看到了吧，上面提到的4个文件/文件夹，就是上传到这里，如果你没看到.next文件夹，因为那是隐藏文件夹，你要点击截图中的红色框部分，可以查看隐藏内容。\n\n这里的node_modules就是通过`npm install`生成的。\n\n\n## 六、图片\n另外我展示一下next.config.ts中的图片配置，因为网络图片访问是需要进行域名配置的，在dev环境下访问没有问题，但是生产环境的安全策略必须要配置图片访问域名，如下：\n![图片配置](https://image.xinwei.ltd/image1770093931735.png)\n\n```next.config.ts\nimport type { NextConfig } from 'next';\n\nconst nextConfig: NextConfig = {\n  /* config options here */\n  images: {\n    remotePatterns: [\n      {\n        protocol: 'https', // 协议：http/https\n        hostname: 'www.baidu.com', // 域名\n        port: '', // 端口（无则留空）\n      },\n    ],\n  },\n  output: 'standalone',\n};\n\nexport default nextConfig;\n\n```\n这里建议设置：`output: 'standalone',`，是优化docker部署的，大家可以试试。\n\n## 七、其他\n大家正常开发完项目后，通过我上述的操作，你可以很快的把nextjs项目部署到自己的服务器上，我这里是为了快速上线，所以怎么快怎么来。如果要更正式点，那么就需要使用工具做一些持续集成了，大家自己可以去摸索一下。\n\n以上。\n\n求关注。\n\n\n\n\n","这篇文章记录一下我最近写的nextjs项目的简单打包、部署以及一些脚本，留作记录以及供大家参考。","https://image.xinwei.ltd/image1770091084545.png",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",32,{"id":24,"name":26,"parentId":21},"前端",[],"",53,0,"nextjs docker, nextjs server, nextjs lottery, nextjs react, nextjs seo, nextjs docker-compose, nextjs,好彩管家,彩号管家,云服务器操作"]