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

Node + Docker Compose: Development and production setup

我正在寻找一种解决方案,以便在我的项目中使用 docker 同时拥有 开发 生产 环境, docker-compose 和 nodejs.

我该如何处理?

基本上我想要的是一个命令来启动我的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

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"
    },
// ...

一种方法是在您的 Dockerfile 上创建两个 "targets",如下所示:

Docker 文件:

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 文件夹所以最好是 运行 节点而不是 运行直接在您的根文件夹上的 index.js。

您可以创建这样的结构:

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

或者 prod 环境:

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

您可以使用入口点并将命令传递给 docker 容器。然后您可以使用 docker-compose inharitance 为您想要的环境启动 compose 并将命令附加到入口点。

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 指令。


如果您想将命令作为环境变量传递,这种方法也可以使用环境变量。您可以在 docs.

中找到更多信息