本地使用docker compose deploy Nextjs+monorepo项目

在文章中,笔者打算使用pnpmworkspaces功能实现monorepo架构。接着使用docker compose来部署Nextjs项目。

monorepo项目搭建

安装pnpm

npm i pnpm -g

创建新项目

mkdir nextjs-monorepo
cd nextjs-monorepo
pnpm init

在根目录创建pnpm-workspace.yaml。参考如下内容:

packages:
  # 存放应用的文件夹
  - 'apps

创建nextjs应用

进入apps目录,创建nextjs应用:

pnpx create-next-app@latest
//根据自己的需求选择
What is your project named? 
Would you like to use TypeScript with this project? 
Would you like to use ESLint with this project? 
Would you like to use Tailwind CSS with this project? Yes 
Would you like to use `src/` directory with this project? 
Use App Router (recommended)? 
Would you like to customize the default import alias? 

这里创建了一个name为web的nextjs应用。接着就可以通过下面命令运行起来了:

cd web
pnpm dev
//或者在根目录
pnpm --filter web dev

创建package

进入packages文件夹,创建一个core文件夹存放一些核心或者公共的代码:

cd packages
mkdir core
cd core
pnpm init

core/src/utils下创建一个common.ts文件,存放一些公共的函数:

export const sayHello = ()=>{
    console.log('hello');
}

由于使用typescript,需要在core目录下创建tsconfig.json文件:

{
  "compilerOptions": {
    

    
    "target": "ESNext" ,
    "lib": [
      "ES6",
      "DOM"
    ] ,
    
    "module": "ESNext" ,
    "rootDir": "./src" ,
    "moduleResolution": "node" ,
    "resolveJsonModule": true ,
    "allowJs": true ,

    "declaration": true ,

    "outDir": "build" ,

    "declarationDir": "./types" ,

    
    "esModuleInterop": true ,
    
    "forceConsistentCasingInFileNames": true ,

    
    "strict": true ,
    "noImplicitAny": true ,

    
    "skipLibCheck": true ,

    "jsx": "react"
  },
  "include": ["src/**/*"]
}

然后安装typescript来编译ts文件:

pnpm add typescript -F core

接着在package.json文件添加相关的script命令:

{
  "name": "core",
  "version": "1.0.0",
  "description": "core code",
  "files": [
    "build"
  ],
  "main": "./build/index.js",
  "types": "./build/index.d.ts",
  "scripts": {
    "build": "tsc",
    "typecheck": "tsc --noEmit"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "typescript": "^5"
  }
}

运行pnpm build就可以编译ts文件到build目录。

web使用core的包

web项目的package.json文件中添加对core的依赖:

dependencies:{
    
    "core":"workspace:*"
}

然后运行pnpm installcore软连接到web中。
最后就可以直接引入使用:


import { sayName } from "core/build/utils/common";
console.log(sayName("world"));

docker compose

安装docker compose

直接去[官网]下载对应系统的安装包即可。

编写yml文件

在项目根目录下新建一个docker-compose.yml文件:

services:
  web:
    container_name: web
    build:
      context: ./
      dockerfile: ./apps/web/Dockerfile
    ports:
      - 3002:3002

编写Dockerfile 文件

FROM node:18-alpine AS base

# apps/web/Dockerfile

# 1. 安装所需要的基础环境
FROM base AS  deps-and-builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache g++ make py3-pip libc6-compat

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable

WORKDIR /app

# 通过package和lock文件来安装依赖
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY ./apps/web ./apps/web
COPY ./packages ./packages

RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile

RUN echo "pnpm install completed"
# 打包
RUN pnpm --filter web build


# 3. 运行阶段,copy所需要的文件
FROM base AS runner
WORKDIR /app

ENV NODE_ENV=production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001



# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
# 这里需要保持standalone的目录结构
COPY --from=deps-and-builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=deps-and-builder /app/apps/web/public ./apps/web/public
COPY --from=deps-and-builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static

#可通过该命令查看是否copy成功
RUN ls -la /app/apps/web

USER nextjs

EXPOSE 3002

ENV PORT=3002

ENV HOSTNAME="0.0.0.0"

CMD ["node", "apps/web/server.js"]

上面的Dockerfile有几点值得注意:

  1. 有时候COPY文件的时候会报错,请确保目录的结构是否保持一致,可能copy的时候放错地方,或者文件路径不存在。可以通过RUN ls -la your path来调试(可以在docker的可视化客户端查看打印日志)。
  2. 在COPY整个项目或者目录的时候,可以通过.dockerignore文件来排除不想COPY的文件或目录。
  3. nextjs应用需要在next.config.mjs文件中配置output类型为standalone。建议先运行build命令然后查看standalone的目录结构,后面COPY public和static的文件夹需要跟standalone的目录结构保持一致。
const nextConfig = {
    output: "standalone",
}

运行docker compose

可以通过下面的命令来启动docker compose:


docker compose -f docker-compose.yml up -d --build

docker compose -f docker-compose.yml down

或者创建一个Makefile文件,编写以下内容:

.PHONY: docker-start
docker-start:
	docker compose -f docker-compose.yml up -d --build

.PHONY: docker-stop
docker-stop:
	docker compose -f docker-compose.yml down

make docker-start

make docker-stop

启动后可以通过docker ps来查看是否成功

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=20874,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?