1 May 2021
Docker 4 -- Docker Compose项目示例visits
by Jerry Zhang
创建nodejs项目
创建一个package.json文件
{
"dependencies": {
"express": "*",
"redis": "2.8.0"
},
"scripts": {
"start": "node index.js"
}
}
创建index.js文件
const express = require('express');
const redis = require('redis');
const app = express();
const client = redis.createClient({
host: 'redis-server',
port: 6379
});
client.set('visits', 0);
app.get('/', (req, res) => {
client.get('visits', (err, visits) => {
res.send('Number of visits is ' + visits);
client.set('visits', parseInt(visits) + 1);
});
});
app.listen(8081, () => {
console.log('Listening on port 8081');
});
创建Dockerfile
FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "start"]
此时,运行命令
docker build -t jerry4013/visits .
即可构建这个docker image
不同容器之间的沟通问题
image 构建成功后,如果我们运行这个容器:
docker run jerry4013/visits
会报错,无法连接redis。
那如果我们再另外运行一个redis容器行不行呢?
docker run redis
也会报同样的错。这是由于两个容器之间,是完全隔离的。它们之间无法直接沟通。因此我们需要给它们之间建立网络连接。
Docker Compose
使用Docker Compose可以非常方便地同时运行多个容器,并且使它们之间自动建立连接,互相沟通。
docker compose 是随着docker一起安装好的。在命令行中输入docker-compose
即可显示所有相关命令。
创建一个docker-compose.yml
文件
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
ports:
- "4001:8081"
- version是指定要使用的docker-compose的版本。
- services一般都指的就是container容器,或者说是一类容器。
build: .
是说编译当前目录的Dockerfile,生成一个image,并且用这个image来创建这个node-app
容器。ports:
指定了所有的端口映射。
现在我们希望要让node-app中的redis client能与redis-server沟通,只需要在js代码中,给redis client指定一个host。
const client = redis.createClient({
host: 'redis-server',
port: 6379
});
通常来说,这个host是一个真实的主机名,比如https://***,但在这里,我们只需要根据docker-compose.yml文件中的service名称,来指定host,就能找到想要的container。
启动/停止Docker Compose
启动所有容器:
docker-compose up
编译并启动所有容器:
docker-compose up --build
以前,我们想在后台运行某个容器,只需要加个-d
,比如:
docker run -d redis
类似地,如果我们用docker-compose来启动多个容器,只需要加个-d
,比如:
docker-compose up -d
停止全部容器:
docker-compose down
自动重启
为了测试自动重启功能,我们在index.js代码中加入一些故意使它崩溃的代码。
const process = require('process');
app.get('/', (req, res) => {
process.exit(0);
client.get('visits', (err, visits) => {
res.send('Number of visits is ' + visits);
client.set('visits', parseInt(visits) + 1);
});
});
此时,我们重新编译并启动这两个容器:
docker-compose up --build
这时,docker ps
可以看到有两个容器正在运行。然后打开浏览器,输入http://localhost:4001/
,就可以发现页面崩溃了。然后再用docker ps
可以看到,只剩下redis一个容器了。那么,如何才让能这个容器在崩溃后自动重启呢?
错误状态码
exit(0) 代表正常退出。其他数字代表出了错误。
重启策略Restart policies
- 默认是”no”
- always
- on-failure 只有当错误码不是0时,才重启
- unless-stopped 只有当用docker CLI 输入
docker stop
时才不会重启,其他情况都重启。
比如:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
restart: always
build: .
ports:
- "4001:8081"
注意,如果要输入”no”,必须加引号,因为在yml文件中,no 表示false。其实”no”是默认值,不需要写的。
查看docker-compose的容器状态
docker-compose ps
注意,这个命令必须在包含docker-compose.yml的文件夹中使用。
tags: Docker