声明:所有的实验示例大部分来自《learn-docker-in-a-month-of-lunches》的作者Elton Stoneman,但运行结果并不都是照搬,大部分实验结果可能与原书不同
一、前言
前面几章讲了怎么启动一个单容器的应用以及怎么使用自定义的配置启动容器,仔细想想,要配置的东西还挺多,如环境变量、网络、端口、Docker Volume、容器名等等,如果是单容器应用这还不算什么负担,如果是由多个服务组合而成的应用,这些繁杂的配置项瞬间就成了负担,你可能仅仅就因为配错了一个端口号,而导致整个应用崩溃,那么有什么办法解决这个问题呢?解决办法有很多,如Docker Swarm、K8s,但我们今天介绍的并不是这些“重量级”的大家伙,我们介绍一下同样可以达到目的的“小家伙”---Docker Compose,也算是为未来理解Docker Swarm、K8s这些应用做一个铺垫。
Docker Compose主要原理就是依据一个名为docker-compose.yml
的应用描述文件来使得应用达到文件中所描述的状态(具体细节掠过),那么docker-compose.yml
描述了一些什么样的状态呢?docker-compose.yml
描述了一个应用应该包含几个服务,每个服务应该有几个实例(容器),每个实例的配置如何,服务与服务之间的关系如何,除此之外,还描述了包括网络、Docker Volume等在内的应用所需模块。记住,千万不要把Docker Compose理解为一个帮助应用启动的工具,而应该把它理解为一个应用状态维护工具(当然了,有点瑕疵,不是完全的实时维护),启动只是维护的一种。
二、Docker Compose安装
如果你是Windows用户,恭喜你,Docker Compose已经集成在你的Docker Desktop中了,所以你可以跳过本节,而对于Linux用户,就需要稍微耗费几分钟安装一下了。
- 安装步骤:
$ curl -L --fail https://github.com/docker/compose/releases/download/1.25.3/run.sh -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
第一次使用,可能会出现下载docker-compose镜像的界面,因为该安装方式的Docker Compose就是运行在容器内的
三、docker-compose.yml
version: "3.7"
services:
todo-db:
image: diamol/postgres:11.5
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- type: bind
source: /data/postgres
target: /var/lib/postgresql/data
networks:
- app-net
todo-web:
image: diamol/ch06-todo-list
ports:
- "8000:80"
environment:
- Database:Provider=Postgres
depends_on:
- todo-db
secrets:
- source: postgres-connection
target: /app/config/secrets.json
secrets:
postgres-connection:
file: postgres-connection.json
networks:
app-net:
external:
name: nat
version
表明了该Docker Compose的语法版本
service
标签表明应用所需要启动的服务(容器)有哪些,比如todo-db
、todo-web
就是两个服务的名字,image
表明要使用的镜像,environment
表明要特殊配置的环境变量,ports
表明要开放的端口,volumes
配置要绑定给容器的外部目录,depends_on
表明了服务的启动关系,这里todo-db
将先于todo-web
启动,networks
配置容器所属的虚拟网络,secrets
配置一些隐私文件的位置及来源
secrets
顶级标签配置所有隐私文件的位置
networks
顶级标签配置所有需要的虚拟网络,external
表明使用的是Docker中已经存在的虚拟网络(配置了external后,该虚拟网络与该应用是独立的,不会随着该应用的关闭而移除,当然也不会因为没有该虚拟网络而创建一个)
四、通过ToDoList应用来学习使用Docker Compose
- 进入到含有
docker-compose.yml
的目录,使用docker-compose up -d
命令启动应用(-d
表示detach
)
$ cd diamol/ch07/exercises/todo-list-postgres
$ docker-compose up -d
Creating todo-list-postgres_todo-db_1 ... done
Creating todo-list-postgres_todo-web_1 ... done
- 查看当前运行的容器
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
67ebd1794da7 diamol/ch06-todo-list "dotnet ToDoList.dll" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp todo-list-postgres_todo-web_1
d4d36eec3e95 diamol/postgres:11.5 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:5433->5432/tcp todo-list-postgres_todo-db_1
- 关闭掉容器
todo-list-postgres_todo-web_1
,然后再次使用docker-compose up
启动应用
$ docker container rm -f 67e
67e
$ docker-compose up -d
todo-list-postgres_todo-db_1 is up-to-date
Creating todo-list-postgres_todo-web_1 ... done
可以看到todo-list-postgres_todo-db_1因为已经存在了,所以会跳过
- 使用
docker-compose stop
停止应用,并查看当前的容器
$ docker-compose stop
Stopping todo-list-postgres_todo-web_1 ... done
Stopping todo-list-postgres_todo-db_1 ... done
$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb8ae606f7b3 diamol/ch06-todo-list "dotnet ToDoList.dll" 2 minutes ago Exited (139) 27 seconds ago todo-list-postgres_todo-web_1
d4d36eec3e95 diamol/postgres:11.5 "docker-entrypoint.s…" 9 minutes ago Exited (0) 27 seconds ago todo-list-postgres_todo-db_1
可以看到容器都还存在没有被移除
- 使用
docker-compose start
启动停止的应用,并查看运行的容器
$ docker-compose start
Starting todo-db ... done
Starting todo-web ... done
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb8ae606f7b3 diamol/ch06-todo-list "dotnet ToDoList.dll" 5 minutes ago Up 27 seconds 0.0.0.0:8000->80/tcp todo-list-postgres_todo-web_1
d4d36eec3e95 diamol/postgres:11.5 "docker-entrypoint.s…" 12 minutes ago Up 29 seconds 0.0.0.0:5433->5432/tcp todo-list-postgres_todo-db_1
- Docker Compose也收集了所有服务的日志信息,你可以使用
docker-compose logs <文件中定义的服务名>
来查看指定服务的日志
$ docker-compose logs --tail 3 todo-web
Attaching to todo-list-postgres_todo-web_1
todo-web_1 | Hosting environment: Production
todo-web_1 | info: Microsoft.Hosting.Lifetime[0]
todo-web_1 | Content root path: /app
这里查看
todo-web
服务的最后三行日志
- 使用
docker-compose ps
来查看当前应用的个容器的运行情况
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------
todo-list-postgres_todo-db_1 docker-entrypoint.sh postgres Up 0.0.0.0:5433->5432/tcp
todo-list-postgres_todo-web_1 dotnet ToDoList.dll Up 0.0.0.0:8000->80/tcp
- 使用
docker-compose down
来关闭应用,与stop
不同是,该命令会移除容器
$ docker-compose down
Stopping todo-list-postgres_todo-web_1 ... done
Stopping todo-list-postgres_todo-db_1 ... done
Removing todo-list-postgres_todo-web_1 ... done
Removing todo-list-postgres_todo-db_1 ... done
Network nat is external, skipping
$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
可以看到一个容器都不存在,包括停止状态的
五、总结
切记,Docker Compose是一个维持应用指定状态(docker-compose.yml所描述的)的工具,所以它必须基于一个docker-compose.yml,其所有的命令才有意义并且有效。
参考文档:
[1] learn-docker-in-a-month-of-lunches
[2] 官方文档
[3] Compose file version 3 reference
附:
[1] Elton Stoneman的github项目
网友评论