Dockerize CMS 和 NextJS 并处理依赖关系(NextJS 需要运行 CMS 才能构建)。

huangapple go评论67阅读模式
英文:

Dockerize CMS and NextJS and handle depedencies (NextJS needs CMS running to build)

问题

Context

我正在尝试将我的应用程序容器化,该应用程序由一个无界面的 CMS(Strapi)和一个 NextJS 客户端组成。

NextJS 需要我的 CMS 在运行时才能构建(它会在端口 1337 上获取内容)。

Code

我的 docker-compose.yaml

version: "3.8"

services:
  db:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=root
      - MYSQL_PASSWORD=root
      - DATABASE_SSL=false
    ports:
      - "3306:3306"
    volumes:
      - ./server/strapi_portfolio.sql:/docker-entrypoint-initdb.d/strapi_portfolio.sql
    networks:
      - portfolio-network

  portfolio-strapi:
    build:
      context: ./server
    ports:
      - "1337:1337"
    volumes:
      - ./portfolio-strapi:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network

    depends_on:
      - db

  portfolio-nextjs:
    build:
      context: ./client
    ports:
      - "3000:3000"
    volumes:
      - ./portfolio-nextjs:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - portfolio-strapi

networks:
  portfolio-network:
    driver: bridge

NextJS Dockerfile

FROM node:18-alpine as builder

WORKDIR "/app"

COPY package.json package-lock.json ./
RUN npm install --frozen-lockfile --production=true

COPY . .
RUN npm run build-prod

EXPOSE 3000

CMD ["npm", "start"]

Strapi(CMS)Dockerfile

FROM node:18-alpine AS builder

WORKDIR "/app"
COPY package.json package-lock.json ./

RUN npm install --frozen-lockfile

COPY . .
RUN npm run build


FROM node:18-alpine AS runner

COPY --from=builder /app/package.json /app/package-lock.json ./
COPY --from=builder /app/dist ./

RUN npm install --frozen-lockfile --omit=dev

EXPOSE 1337

CMD ["npm", "start"]

What I tried

  • 我尝试了 Docker 的 depends_on 功能,但它不起作用,即使使用了健康检查也不行。
    是的,CMS 构建会在之前触发,但我的 NextJS 应用程序在构建之前并不等待它提供服务。
  • 我尝试创建一个 npm 脚本,在运行构建脚本之前等待我的 API 可用:
const MAX_RETRIES = 10;
let retries = 0;

const waitForStrapi = async () => {
  while (retries < MAX_RETRIES) {
    console.log(`[ATTEMPT ${retries}] Trying to reach Strapi...`);
    try {
      await fetch("http://localhost:1337");
      console.log("Strapi is ready!");
      break;
    } catch (e) {
      console.log("Waiting for Strapi...");
      await new Promise((resolve) => setTimeout(resolve, 30000));
    }
    retries++;
  }
};

waitForStrapi();
console.log("[ERROR - Couldn't connect to Strapi]");

我的 CMS 镜像已完全构建,但从未运行过(因此无法解析 http://localhost:1337),我不知道为什么...

我是不是漏掉了什么东西,还是我可能没有正确的方法来实现这一点?感谢您的帮助。

英文:

Context

I am trying to dockerize my app which is made off a headless CMS (Strpi) and a client NextJS.

NextJS needs to have my CMS running in order to build (it's fetching the content there on port 1337)

Code

My docker-compose.yaml

version: &quot;3.8&quot;

services:
  db:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=root
      - MYSQL_PASSWORD=root
      - DATABASE_SSL=false
    ports:
      - &quot;3306:3306&quot;
    volumes:
      - ./server/strapi_portfolio.sql:/docker-entrypoint-initdb.d/strapi_portfolio.sql
    networks:
      - portfolio-network

  portfolio-strapi:
    build:
      context : ./server
    ports:
      - &quot;1337:1337&quot;
    volumes:
      - ./portfolio-strapi:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network

    depends_on:
      - db

  portfolio-nextjs:
    build:
      context : ./client
    ports:
      - &quot;3000:3000&quot;
    volumes:
      - ./portfolio-nextjs:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - portfolio-strapi

networks:
  portfolio-network:
    driver: bridge

NextJS Dockerfile

FROM node:18-alpine as builder

WORKDIR &quot;/app&quot;

COPY package.json package-lock.json ./
RUN npm install --frozen-lockfile --production=true

COPY . .
RUN npm run build-prod

EXPOSE 3000

CMD [&quot;npm&quot;, &quot;start&quot;]

Strapi (CMS) Dockerfile

FROM node:18-alpine AS builder

WORKDIR &quot;/app&quot;
COPY package.json package-lock.json ./

RUN npm install --frozen-lockfile

COPY . .
RUN npm run build


FROM node:18-alpine AS runner

COPY --from=builder /app/package.json /app/package-lock.json ./
COPY --from=builder /app/dist ./

RUN npm install --frozen-lockfile --omit=dev

EXPOSE 1337

CMD [&quot;npm&quot;, &quot;start&quot;]

What I tried

  • I tried the depends_on functionnality of docker but it's not working, even with healthchecks.
    Yes the CMS build is triggered before but my NextJS app is not waiting for it to be served before building
  • I tried to create a npm script that waits for my api to be available before running the build script :
const MAX_RETRIES = 10;
let retries = 0;

const waitForStrapi = async () =&gt; {
  while (retries &lt; MAX_RETRIES) {
    console.log(`[ATTEMPT ${retries}] Trying to reach Strapi...`);
    try {
      await fetch(&quot;http://localhost:1337&quot;);
      console.log(&quot;Strapi is ready!&quot;);
      break;
    } catch (e) {
      console.log(&quot;Waiting for Strapi...&quot;);
      await new Promise((resolve) =&gt; setTimeout(resolve, 30000));
    }
    retries++;
  }
};

waitForStrapi();
console.log(&quot;[ERROR - Couldn&#39;t connect to Strapi]&quot;);

My CMS image is fully built BUT is never running (so http://localhost:1337 can never be resolved) and I don't know why...

Am I missing something or may I not have the right philosophy to achieve this ?
Thanks for your help

答案1

得分: 0

我认为你缺少了docker-compose文件的"command"部分,所以它应该看起来像这样:

version: "3.8"

services:
  db:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=root
      - MYSQL_PASSWORD=root
      - DATABASE_SSL=false
    ports:
      - "3306:3306"
    volumes:
      - ./server/strapi_portfolio.sql:/docker-entrypoint-initdb.d/strapi_portfolio.sql
    networks:
      - portfolio-network

  portfolio-strapi:
    build:
      context: ./server
    ports:
      - "1337:1337"
    volumes:
      - ./portfolio-strapi:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - db
    command: npm run start

  portfolio-nextjs:
    build:
      context: ./client
    ports:
      - "3000:3000"
    volumes:
      - ./portfolio-nextjs:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - portfolio-strapi
    command: npm run start

networks:
  portfolio-network:
    driver: bridge

希望这有所帮助。

英文:

I think you are missing the "command" section of the docker-compose file, so it would look something like this:

version: &quot;3.8&quot;

services:
  db:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=root
      - MYSQL_PASSWORD=root
      - DATABASE_SSL=false
    ports:
      - &quot;3306:3306&quot;
    volumes:
      - ./server/strapi_portfolio.sql:/docker-entrypoint-initdb.d/strapi_portfolio.sql
    networks:
      - portfolio-network

  portfolio-strapi:
    build:
      context : ./server
    ports:
      - &quot;1337:1337&quot;
    volumes:
      - ./portfolio-strapi:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - db
    command: npm run start

  portfolio-nextjs:
    build:
      context : ./client
    ports:
      - &quot;3000:3000&quot;
    volumes:
      - ./portfolio-nextjs:/usr/src/app
    environment:
      - NODE_ENV=development
    networks:
      - portfolio-network
    depends_on:
      - portfolio-strapi
    command: npm run start

networks:
  portfolio-network:
    driver: bridge

Hope this helps

huangapple
  • 本文由 发表于 2023年6月15日 17:06:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76480892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定