Node + Docker Compose: 开发和生产环境设置

14

我正在寻找一种使用 Docker、Docker Compose 和 Node.js 在我的项目中同时拥有开发和生产环境的解决方案。

我应该如何处理这个问题呢?

基本上,我想要一个命令来启动我的 Docker 生产环境,以及一个命令来启动我的开发环境(可以使用 nodemon 等工具)。

这是我的 Dockerfile:

FROM node:13-alpine

RUN mkdir /app

WORKDIR /app

COPY . /app

RUN npm install

RUN npm run build

EXPOSE 1234

CMD ["npm", "run", "prod"] # <--- Have a possibility to run something like "npm run dev" here instead

docker-compose.yml

Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。该工具使用 YAML 文件来配置应用程序的服务,并可以在单个命令中启动、停止和重建所有服务。

version: "3"
services:
    findus:
        build: .
        ports:
            - "1234:1234"
        links:
            - mongo
        container_name: myapp
    mongo:
        image: mongo
        restart: always
        ports:
            - "4444:4444"

包描述文件(package.json)

// ...
    "scripts": {
        "build": "tsc",
        "dev": "nodemon source/index.ts",
        "prod": "node build/index.js"
    },
// ...
3个回答

13
你可以使用entrypoint并将命令传递给docker容器。然后,您可以使用docker-compose继承来启动所需的环境,并将命令附加到entrypoint。 Dockerfile
FROM node:13-alpine

RUN mkdir /app

WORKDIR /app

COPY . /app

RUN npm install

RUN npm run build

EXPOSE 1234

ENTRYPOINT ["npm", "run"]

主要的 docker-compose.yml 文件:

version: "3"
services:
    findus:
        build: .
        ports:
            - "1234:1234"
        links:
            - mongo
        container_name: myapp
    mongo:
        image: mongo
        restart: always
        ports:
            - "4444:4444"

同时需要创建两个 docker-compose 文件,用以追加传递给镜像入口点的命令。针对开发环境的文件为 docker-compose.dev.yml :

version: "3"
services:
    findus:
        command: dev

还有 docker-compose.prod.yml 文件:

version: "3"
services:
    findus:
        command: prod

然后启动开发环境:

docker-compose  -f docker-compose.yml -f docker-compose.dev.yml up    

对于生产环境:

docker-compose  -f docker-compose.yml -f docker-compose.prod.yml up   

因此,command将被追加到ENTRYPOINT指令。


如果您想将命令作为环境变量传递,这种方法也可以使用环境变量。您可以在文档中找到更多信息。


2
一种方法是在Dockerfile中创建两个“目标”如下所示:
Dockerfile:
FROM node:13-alpine As development

RUN mkdir /app

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

FROM node:13-alpine as production

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /app

COPY package*.json ./

RUN npm install --only=production

COPY . .

COPY --from=development /app/dist ./dist

CMD ["node", "dist/index.js"]

然后在您的docker-compose中仅运行开发版本:

version: '3.7'

services:
  main:
    container_name: main
    build:
      context: .
      target: development
    command: npm run dev
...

在您的开发环境中,您可以运行:

docker-compose up

然后在生产环境中,您可以直接运行 Docker:

docker run --target production

我假设当您运行“npm run build”时,会生成一个dist/production文件夹,因此最好在那里运行node,而不是直接在根文件夹的index.js上运行。


1
你可以创建这样的结构:

docker-compose.yml -->
      docker-compose.dev.yml
      docker-compose.prod.yml

基础配置位于docker-compose.yml中,而特定于环境的信息(例如端口或用户凭据)将位于docker-compose.dev.ymldocker-compose.prod.yml中。

然后,您可以使用以下命令运行开发环境:

docker-compose \
    -f docker-compose.yml \
    -f docker-compose.dev.yml \
    up -d

在生产环境中使用以下代码:
docker-compose \
    -f docker-compose.yml \
    -f docker-compose.prod.yml \
    up -d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接