英文:
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: "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
- 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 () => {
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]");
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: "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
Hope this helps
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论