简介
Docker Compose是一个基于Docker Engine进行安装的Python工具。该工具使得用户可以在一个声明式的配置文件中定义一个多容器的应用,在Docker节点上,以单引擎模式(Single-Engine Mode)进行多容器应用的部署和生命周期的管理。
背景
Docker Compose的前身是Fig。Fig是一个由Orchard公司开发的强有力的工具,在内部实现上,Fig会解析YAML文件,并通过Docker API进行应用的部署和管理。
在2014年,Docker公司收购了Orchard公司,并将Fig更名为Docker Compose。命令行工具也从fig更名为docker-compose,并自此成为绑定在Docker引擎之上的外部工具。虽然它从未完全集成到Docker引擎中,但是仍然受到广泛关注并得到普遍使用。
安装与卸载
这里介绍在Linux上安装Docker Compose。
1、Docker Compose安装
官网安装介绍链接:https://docs.docker.com/compose/install/
按官网的介绍,我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/release
这里我安装的是1.29.0版本的
下载二进制包
sudo curl \
-L "https://github.com/docker/compose/releases/download/1.29.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
为二进制包添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
测试
$ docker-compose --version
docker-compose version 1.29.0, build 07737305
2、Docker Compose卸载
sudo rm /usr/local/bin/docker-compose
3、Docker Compose安装命令行补全工具(非必须)
安装docker-compose命令行补全工具的前提需确保bash completion已安装了。
bash completion安装
yum install -y bash-completion
docker-compose命令行补全工具安装
curl \
-L https://raw.githubusercontent.com/docker/compose/1.29.0/contrib/completion/bash/docker-compose \
-o /etc/bash_completion.d/docker-compose
重新打开terminal,可以通过terminal键入docker-compose sta 加上tab键查看效果。
使用案例
案例下载地址:https://github.com/nigelpoulton/counter-app.git 这是一个能够对访问者进行计数并将其保存到redis的简单web服务
包含了两个服务:
- web-fe:小型Flask应用
- Redis
案例文件结构
Compose文件
Docker Compose是使用YAML文件来定义多服务应用的,默认使用的文件名为docker-compose.yml,如果需要指定具体文件我们可以使用-f参数来指定。
下面来看下案例文件中的docker-compose.yml
version: "3.5"
services:
web-fe:
build: .
command: python app.py
ports:
- target: 5000
published: 5000
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: "redis:alpine"
networks:
counter-net:
networks:
counter-net:
volumes:
counter-vol:
观察文件的基本结构,首先可以注意到,它包含4个一级key:version
、services
、networks
、volumes
。
version
version是必须指定的,而且总是位于文件的第一行。它定义了Compose文件格式的版本。
services
services用于定义不同的应用服务,上边的例子定义了两个服务:
- web-fe的Web前端服务
- redis内存数据库服务
networks
networks用于指引Docker创建新的网络。默认情况下,Docker Compose会创建bridge网络。这是一种单主机网络,只能够实现同一主机上容器的连接。
volumes
volumes用于指引Docker来创建新的卷。
更多的信息在services中,下面仔细分析一下。
services:
web-fe:
build: .
command: python app.py
ports:
- target: 5000
published: 5000
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: "redis:alpine"
networks:
counter-net:
Compose文件中的services部分定义了两个二级key,它们各自定义了一个应用程序服务。
DockerCompose会将每个服务部署为一个容器,并且会使用key作为容器名字的一部分。
web-fe的服务定义中,包含如下指令:
- build:
.
指定Docker基于当前目录(.
)下Dockerfile中定义的指令来构建一个新镜像。该镜像会被用于启动该服务的容器。 - command:python app.py指定Docker在容器中执行名为app.py的Python脚本作为主程序。因此镜像中必须包含app.py文件以及Python,这一点在Dockerfile中可以得到满足。
- ports:指定Docker将容器内(-target)的5000端口映射到主机(published)的5000端口。这意味着发送到Docker主机5000端口的流量会被转发到容器的5000端口。容器中的应用监听端口5000。
- networks:使得Docker可以将服务连接到指定的网络上。这个网络应该是已经存在的,或者是在networks一级key中定义的网络。
- volumes:指定Docker将counter-vol卷(source:)挂载到容器内的/code(target:)。counter-vol卷应该是已存在的,或者是在文件下方的volumes一级key中定义的。
redis服务的定义:
- image:使得Docker可以基于redis:alpine镜像启动一个独立的名为redis的容器。这个镜像会被从Docker Hub上拉取下来。
- networks:配置redis容器连接到counter-net网络。
了解Compose文件中定义的内容后,下面开始部署实战。
使用Docker Compose部署应用
进入案例counter-app的目录查看文件
root@centos: ~/docker_learn/counter-app # ls
app.py docker-compose.yml Dockerfile README.md requirements.txt
- app.py是应用程序代码(一个Python Flask应用)。
- docker-compose.yml是Compose文件,其中定义了Docker如何部署应用。
- Dockerfile定义了如何构建web-fe服务所使用的镜像。
- requirements.txt列出了应用所依赖的Python包。
请根据需要自行查看文件内容。
app.py显然是应用的核心文件,而docker-compose.yml文件将应用的所有组件组织起来。
使用Docker Compose将应用启动起来
root@centos: ~/docker_learn/counter-app # docker-compose up &
[1] 15337
root@centos: ~/docker_learn/counter-app # Creating network "counter-app_counter-net" with the default driver
Creating volume "counter-app_counter-vol" with default driver
Building web-fe
Sending build context to Docker daemon 6.656kB
Step 1/5 : FROM python:3.4-alpine
3.4-alpine: Pulling from library/python
8e402f1a9c57: Pulling fs layer
cda9ba2397ef: Pulling fs layer
aafecf9bbbfd: Pulling fs layer
bc2e7e266629: Pulling fs layer
e1977129b756: Pulling fs layer
bc2e7e266629: Waiting
e1977129b756: Waiting
cda9ba2397ef: Verifying Checksum
cda9ba2397ef: Download complete
8e402f1a9c57: Verifying Checksum
8e402f1a9c57: Download complete
8e402f1a9c57: Pull complete
cda9ba2397ef: Pull complete
bc2e7e266629: Verifying Checksum
bc2e7e266629: Download complete
e1977129b756: Verifying Checksum
e1977129b756: Download complete
aafecf9bbbfd: Verifying Checksum
aafecf9bbbfd: Download complete
aafecf9bbbfd: Pull complete
bc2e7e266629: Pull complete
e1977129b756: Pull complete
Digest: sha256:c210b660e2ea553a7afa23b41a6ed112f85dbce25cbcb567c75dfe05342a4c4b
Status: Downloaded newer image for python:3.4-alpine
---> c06adcf62f6e
Step 2/5 : ADD . /code
---> 7892fdd84650
Step 3/5 : WORKDIR /code
---> Running in 1e0cf312dcca
Removing intermediate container 1e0cf312dcca
---> 99159e289c92
Step 4/5 : RUN pip install -r requirements.txt
---> Running in 42d4809518a7
DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).
Collecting flask (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/d8/94/7350820ae209ccdba073f83220cea1c376f2621254d1e0e82609c9a65e58/Flask-1.0.4-py2.py3-none-any.whl (92kB)
Collecting redis (from -r requirements.txt (line 2))
Downloading https://files.pythonhosted.org/packages/32/ae/28613a62eea0d53d3db3147f8715f90da07667e99baeedf1010eb400f8c0/redis-3.3.11-py2.py3-none-any.whl (66kB)
Collecting Werkzeug>=0.14 (from flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/c2/e4/a859d2fe516f466642fa5c6054fd9646271f9da26b0cac0d2f37fc858c8f/Werkzeug-0.16.1-py2.py3-none-any.whl (327kB)
Collecting itsdangerous>=0.24 (from flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Jinja2>=2.10 (from flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/65/e0/eb35e762802015cab1ccee04e8a277b03f1d8e53da3ec3106882ec42558b/Jinja2-2.10.3-py2.py3-none-any.whl (125kB)
Collecting click>=5.1 (from flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask->-r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz
Building wheels for collected packages: MarkupSafe
Building wheel for MarkupSafe (setup.py): started
Building wheel for MarkupSafe (setup.py): finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/f2/aa/04/0edf07a1b8a5f5f1aed7580fffb69ce8972edc16a505916a77
Successfully built MarkupSafe
Installing collected packages: Werkzeug, itsdangerous, MarkupSafe, Jinja2, click, flask, redis
Successfully installed Jinja2-2.10.3 MarkupSafe-1.1.1 Werkzeug-0.16.1 click-7.0 flask-1.0.4 itsdangerous-1.1.0 redis-3.3.11
You are using pip version 19.0.3, however version 19.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Removing intermediate container 42d4809518a7
---> 2600a9ea5d6d
Step 5/5 : CMD ["python", "app.py"]
---> Running in e248803bb90b
Removing intermediate container e248803bb90b
---> d1d7338a16dc
Successfully built d1d7338a16dc
Successfully tagged counter-app_web-fe:latest
WARNING: Image for service web-fe was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
540db60ca938: Pull complete
29712d301e8c: Pull complete
8173c12df40f: Pull complete
ce3f2993175f: Pull complete
62cc615d2d57: Pull complete
03f18c6c97e1: Pull complete
Digest: sha256:cd68f7db2caeff01a62bab0cdb5630e86e2a608b0aba3b988b1d13dcf3cfdedb
Status: Downloaded newer image for redis:alpine
Creating counter-app_web-fe_1 ... done
Creating counter-app_redis_1 ... done
Attaching to counter-app_redis_1, counter-app_web-fe_1
redis_1 | 1:C 16 Apr 2021 15:33:23.444 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 16 Apr 2021 15:33:23.444 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 16 Apr 2021 15:33:23.444 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 16 Apr 2021 15:33:23.445 * monotonic clock: POSIX clock_gettime
redis_1 | 1:M 16 Apr 2021 15:33:23.445 * Running mode=standalone, port=6379.
redis_1 | 1:M 16 Apr 2021 15:33:23.445 # 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_1 | 1:M 16 Apr 2021 15:33:23.445 # Server initialized
redis_1 | 1:M 16 Apr 2021 15:33:23.445 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1 | 1:M 16 Apr 2021 15:33:23.454 * Ready to accept connections
web-fe_1 | * Serving Flask app "app" (lazy loading)
web-fe_1 | * Environment: production
web-fe_1 | WARNING: This is a development server. Do not use it in a production deployment.
web-fe_1 | Use a production WSGI server instead.
web-fe_1 | * Debug mode: on
web-fe_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web-fe_1 | * Restarting with stat
web-fe_1 | * Debugger is active!
web-fe_1 | * Debugger PIN: 150-882-136
值得注意的是,Docker Compose会在部署服务之前创建网络和卷。这很合理,因为它们是供服务(容器)使用的底层基础资源。如打印的日志可见,Docker Compose会首先创建网络和卷(甚至先于构建和拉取镜像)。
使用了&将终端窗口返回,所有的日志还是会直接输出到我们后续可能会用的终端窗口上。
使用-d参数在后台启动应用也是常见的用法:
docker-compose up -d
观察终端输出,提示容器已成功启动,下面来验证下
查看容器
root@centos: ~/docker_learn/counter-app # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f81dae5a6e8 redis:alpine "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 6379/tcp counter-app_redis_1
eab24e06ea55 counter-app_web-fe "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp counter-app_web-fe_1
可以看到容器已成功启动了。每个容器的名称都以项目名称(所在目录名称)为前缀,以一个数字为后缀用于标识容器实例序号——因为Docker Compose允许扩缩容。
查看网络和卷
root@centos: ~/docker_learn/counter-app # docker network ls
NETWORK ID NAME DRIVER SCOPE
cacae91f20ca counter-app_counter-net bridge local
...
root@centos: ~/docker_learn/counter-app # docker volume ls
DRIVER VOLUME NAME
local counter-app_counter-vol
...
用Docker主机的浏览器连接5000端口来查看应用的运行效果
每次刷新页面,计数就会增加。
使用Docker Compose管理应用
root@centos: ~/docker_learn/counter-app # docker-compose
Define and run multi-container applications with Docker.
...
Commands:
build Build or rebuild services
config Validate and view the Compose file
create Create services
down Stop and remove resources
events Receive real time events from containers
exec Execute a command in a running container
help Get help on a command
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pull service images
push Push service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
top Display the running processes
unpause Unpause services
up Create and start containers
version Show version information and quit
我们可以通过docker-compose或docker-compose -h来查看帮助文档,其中列出Docker Compose支持用来管理应用的命令:
- docker-compose up命令用于部署一个Compose应用。默认情况下该命令会读取名为docker-compose.yml或docker-compose.yaml的文件,当然用户也可以使用-f指定其他文件名。通常情况下,会使用-d参数令应用在后台启动。
- docker-compose stop命令会停止Compose应用相关的所有容器,但不会删除它们。被停止的应用可以很容易地通过docker-- compose restart命令重新启动。
- docker-compose rm命令用于删除已停止的Compose应用。它会删除容器和网络,但是不会删除卷和镜像。
- docker-compose restart命令会重启已停止的Compose应用。如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中,这时需要重新部署应用使变更生效。
- docker-compose ps命令用于列出Compose应用中的各个容器。输出内容包括当前状态、容器运行的命令以及网络端口。
- docker-compose down会停止并删除运行中的Compose应用。它会删除容器和网络,但是不会删除卷和镜像。
参考:
CentOS Bash 命令补全增强软件包 bash-completion菜鸟教程 Docker Compose