[英]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:
这是我的问题:
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文件(
Dockerfile
和Dockerfile.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.