【问题标题】:Docker: Best practice for development and production environmentDocker:开发和生产环境的最佳实践
【发布时间】:2016-08-10 15:13:24
【问题描述】:

假设我有一个简单的 node.js 应用程序。我可以使用这样的简单 Dockerfile 构建一个容器来运行应用程序:

FROM ubuntu:16.04
RUN apt-get update && apt-get install -y nodejs nodejs-legacy npm
COPY . /app
WORKDIR /app
RUN npm install
CMD node index.js

这会将源代码复制到容器中,我可以将其发送到注册表,这没有问题。

但对于开发,我不想为代码中的每一次更改都重新构建容器。所以很自然地,我将卷与 nodemon 结合使用。这是我的问题:

  • 如何保持不同的配置?两个dockerfile?将撰写与两个不同的撰写文件一起使用?
  • 我主机上的 node_nodules 文件夹与我在容器中需要的文件夹不同(即,一些软件包全局安装在主机上)。我可以从卷中排除它吗?如果是这样,我需要在安装卷后运行 npm install 。我该怎么做呢?

所以我的问题是:我如何将开发环境和部署环境分开。两个 Dockerfile?两个撰写文件?有没有最佳实践?

【问题讨论】:

  • 从开发到生产有什么不同?你可以使用环境吗?

标签: node.js docker docker-compose dockerfile


【解决方案1】:

所以我处理它的方式是我有 2 个 Docker 文件(DockerfileDockerfile.dev)。

Dockerfile.dev我有:

FROM node:6

# Update the repository
RUN apt-get update

# useful tools if need to ssh in or used by other tools
RUN apt-get install -y curl net-tools jq

# app location
ENV ROOT /usr/src/app

COPY package.json /usr/src/app/

# copy over private npm repo access file
ADD .npmrc /usr/src/app/.npmrc

# set working directory
WORKDIR ${ROOT}

# install packages
RUN npm install

# copy all other files over
COPY . ${ROOT}

# start it up
CMD [ "npm", "run", "start" ]

# what port should I have
EXPOSE 3000

我的 NPM 脚本如下所示

"scripts": {
    ....
    "start": "node_modules/.bin/supervisor -e js,json --watch './src/' --no-restart-on error ./index.js",
    "start-production": "node index.js",
    ....
},

您会注意到它使用 supervisor 启动,因此对 src 下任何文件的任何更改都会导致它重新启动服务器,而无需重新启动 docker。

最后是 docker compose。

dev:
  build: .
  dockerfile: Dockerfile.dev
  volumes:
    - "./src:/usr/src/app/src"
    - "./node_modules:/usr/src/node_modules"
  ports:
    - "3000:3000"

prod:
  build: .
  dockerfile: Dockerfile
  ports:
    - "3000:3000"

所以你看到它在开发模式下加载并挂载当前目录的src 文件夹到容器/usr/src/app/src 以及node_modules 目录到/usr/src/node_modules

这样我就可以在本地进行更改并保存,卷将更新容器的文件,然后主管将看到该更改并重新启动服务器。

** 请注意,因为它不监视 node_modules 文件夹,所以您必须更改 src 目录中的另一个文件才能重新启动 **

【讨论】:

    【解决方案2】:

    使用环境变量。请参阅文档Docker env。这是推荐的方式,也可用于生产。

    【讨论】:

    • 例如docker run -e FOO_VAR=$FOO_VAR
    【解决方案3】:

    您可以使用单个 Dockerfile,您只需在其中声明 VOLUME 部分。

    请记住,除非您使用-v <path>:<path> 选项在docker run 期间明确 指定该卷,否则该卷不会被挂载。有了这个,你甚至可以在你的 prod 环境中声明多个VOLUMEs。

    【讨论】:

      猜你喜欢
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 2011-09-28
      • 2021-05-05
      • 2022-01-14
      • 2011-07-14
      • 2016-02-11
      相关资源
      最近更新 更多