Docker:开发和生产环境的最佳实践

时间:2016-08-10 15:13:25

标签: node.js docker docker-compose dockerfile

Suppeose我有一个简单的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。这是我的问题:

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

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

3 个答案:

答案 0 :(得分:5)

所以我处理它的方式是我有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。

最后是码头组成。

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的{​​{1}}目录。

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

**注意,因为它不会观察node_modules文件夹,你必须更改src目录中的另一个文件才能重启**

答案 1 :(得分:4)

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

答案 2 :(得分:1)

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

请注意,除非您在使用docker run选项的-v <path>:<path>期间指定明确,否则无法启动音量。有了这个,你甚至可以在你的生产环境中声明多个VOLUME