通过创建访客计数器来学习Docker Compose
这是我第三次写有关Docker的文章。
Docker Compose是什么东西?
这是一个用于简单构建由多个容器组成的系统的工具。您可以使用YAML文件来配置应用程序服务,并通过执行一个命令来生成和启动基于配置内容的应用程序服务。
建立系统
尝试构建而不使用Docker Compose
创建 package.json、index.js 和 Dockerfile。
{
"dependencies": {
"express": "*",
"redis": "2.8.0"
},
"scripts": {
"start": "node index.js"
}
}
在index.js文件中的app.get函数中,将访问者数量(visits)保存到redis并进行计数。
const express = require('express');
const redis = require('redis');
const app = express();
const client = redis.createClient();
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中,使用node:alpine作为基础镜像,并指定文件的复制目标为’/app’。
FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "start"]
在运行docker run redis命令后,在终端中打开另一个选项卡,并从已创建的Dockerfile文件构建镜像(docker build -t suzuki0430/visits:latest .),然后启动容器(docker run suzuki0430/visits)。
那么,会出现与redis-server无法连接的错误。
Error: getaddrinfo ENOTFOUND redis-server
如果您想连接每个容器,由于容器进程是独立运行的,您需要进行相应的设置。而在此处使用的是Docker Compose。
使用Docker Compose构建尝试
为了同时启动多个Docker容器,需要按照以下方式编写docker-compose.yml文件。
version: '3' #docker-composeのバージョン
services: #起動したいコンテナの種類
redis-server:
image: 'redis' #redisイメージでコンテナを起動
node-app:
build: . #カレントディレクトリのDockerfileからイメージをビルドしてコンテナを起動
ports: #ポートマッピング([localhostのポート番号]:[コンテナのポート番号])
- '4001:8081'
另外,为了连接redis-server和node-app,我们需要在index.js中添加以下内容。6379是redis的默认端口号。
const client = redis.createClient({
host: 'redis-server',
port: 6379,
});
使用Docker Compose可以通过docker-compose CLI来执行命令操作。
docker-compose up : コンテナ起動
docker-compose up –build : イメージビルド + コンテナ起動
docker-compose up -d : バックグラウンでコンテナ起動
docker-compose down : コンテナ停止
docker-compose ps : プロセス確認
运行docker-compose up,将启动node-app和redis-server容器。
(base) [16:12:32] → docker-compose up ~/Programs/docker/visits
Recreating visits_node-app_1 ... done
Starting visits_redis-server_1 ... done
Attaching to visits_redis-server_1, visits_node-app_1
redis-server_1 | 1:C 06 Mar 2021 07:12:39.624 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server_1 | 1:C 06 Mar 2021 07:12:39.624 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server_1 | 1:C 06 Mar 2021 07:12:39.624 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server_1 | 1:M 06 Mar 2021 07:12:39.626 * Running mode=standalone, port=6379.
redis-server_1 | 1:M 06 Mar 2021 07:12:39.626 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis-server_1 | 1:M 06 Mar 2021 07:12:39.626 # Server initialized
redis-server_1 | 1:M 06 Mar 2021 07:12:39.627 * Loading RDB produced by version 6.0.9
redis-server_1 | 1:M 06 Mar 2021 07:12:39.627 * RDB age 10216869 seconds
redis-server_1 | 1:M 06 Mar 2021 07:12:39.627 * RDB memory usage when created 0.79 Mb
redis-server_1 | 1:M 06 Mar 2021 07:12:39.627 * DB loaded from disk: 0.001 seconds
redis-server_1 | 1:M 06 Mar 2021 07:12:39.627 * Ready to accept connections
node-app_1 |
node-app_1 | > start
node-app_1 | > node index.js
node-app_1 |
node-app_1 | Listening on port 8081
您可以在以下部分中确认容器之间的连接。
Attaching to visits_redis-server_1, visits_node-app_1
当我使用浏览器连接到localhost:4001时,它能够正确打开。
Docker Compose自动重启
系统的构建已经完成,为了深入理解Docker Compose,我也学习了自动重启的方法。
在index.js的app.get中编写process.exit(0),以关闭node-app的进程。
const process = require('process');
app.get('/', (req, res) => {
process.exit(0);
});
接下来,将restart:always的选项添加到docker-compose.yml文件中。
version: '3'
services:
redis-server:
image: 'redis'
node-app:
restart: always
build: .
ports:
- '4001:8081'
当运行 docker-compose up –build 命令时,会重新构建镜像并启动容器,当访问 localhost:4001 时,将尝试重新启动容器,以便在进程结束后继续运行。
node-app_1 |
node-app_1 | > start
node-app_1 | > node index.js
node-app_1 |
node-app_1 | Listening on port 8081
visits_node-app_1 exited with code 0
node-app_1 |
node-app_1 | > start
node-app_1 | > node index.js
node-app_1 |
node-app_1 | Listening on port 8081
visits_node-app_1 exited with code 0
重新启动: 除了始终重启(restart: always)之外,还有以下类似的重启策略。
-
- “no”: 再起動しない
-
- always: コンテナが停止したらいかなる理由でも再起動する
-
- on-failure: コンテナがエラーコードをだして停止したら再起動する
- unless-stopped: ユーザがコンテナを強制終了しない限り常に再起動する
最后
下面我们将学习如何将Docker容器部署到生产环境。