简体   繁体   English

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

[英]Docker: Best practice for development and production environment

Suppeose I have a simple node.js app. 我有一个简单的node.js应用程序。 I can build a container to run the app with a simple Dockerfile like this: 我可以使用一个简单的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

This will copy the source code into the container and I can ship it off to a registry no problem. 这会将源代码复制到容器中,我可以将它发送到注册表没问题。

But for development I don't want to rebuild the container for every change in my code. 但是对于开发,我不想为我的代码中的每个更改重建容器。 So naturally, I use a volume in combination to nodemon. 很自然地,我将一个音量组合用于nodemon。 Here's my questions: 这是我的问题:

  • How do I keep the different configurations? 如何保持不同的配置? Two dockerfiles? 两个dockerfiles? Use compose with two different compose files? 使用compose与两个不同的撰写文件?
  • The node_nodules folder on my host is different from the one I need in the container (ie some packages are installed globally on the host). 我的主机上的node_nodules文件夹与我在容器中需要的文件夹不同(即一些软件包全局安装在主机上)。 Can I exclude it from the volume? 我可以将其从卷中排除吗? If so, I need to run npm install after mounting the volume. 如果是这样,我需要在安装卷后运行npm install。 How do I do this? 我该怎么做呢?

So my question is really: How do I keep dev and deploy environments separate. 所以我的问题是:我如何将开发和部署环境分开。 Two Dockerfiles? 两个Dockerfiles? Two compose-files? 两个撰写文件? Are there any best practices? 有没有最佳做法?

So the way I handle it is I have 2 Docker files ( Dockerfile and Dockerfile.dev ). 所以我处理它的方式是我有2个Docker文件( DockerfileDockerfile.dev )。

In the Dockerfile.dev I have: 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

My NPM scripts look like this 我的NPM脚本看起来像这样

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

You will notice it uses supervisor for start so any changes to any file under src will cause it to restart the server without requiring a restart to docker. 您将注意到它使用supervisor启动,因此对src下的任何文件的任何更改都将导致它重新启动服务器而无需重新启动到docker。

Last is the 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"

So you see in a dev mode it loads and mounts the current directory's src folder to the container at /usr/src/app/src and also the node_modules directory to the /usr/src/node_modules . 所以你在开发模式下看到它加载并将当前目录的src文件夹加载到/usr/src/app/src的容器,并将node_modules目录node_modules/usr/src/node_modules

This makes it so that I can make changes locally and save, the volume will update the container's file, then supervisor will see that change and restart the server. 这使得我可以在本地进行更改并保存,卷将更新容器的文件,然后主管将看到更改并重新启动服务器。

** Note as it doesn't watch the node_modules folder you have to change another file in the src directory to do the restart ** **注意,因为它不会观察node_modules文件夹,你必须更改src目录中的另一个文件才能重启**

Use environment variables. 使用环境变量。 See the documentation Docker env . 请参阅文档Docker env This is the recommended way, also for use in the production. 这是推荐的方式,也适用于生产。

You can use single Dockerfile in which you'll just declare VOLUME section. 您可以使用单个Dockerfile,您只需在其中声明VOLUME部分。

Remember that volume won't get mounted unless you'll specify that explicitly during docker run with -v <path>:<path> option. 请记住,除非您在使用-v <path>:<path>选项docker run -v <path>:<path>期间明确指定卷,否则不会挂载卷。 Having that given, you can declare multiple VOLUME s even in your prod environment. 有了这个,你甚至可以在prod环境中声明多个VOLUME

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM