Docker Compose · DevOps:容器、CI 与 Kubernetes
一个需要数据库、缓存和后台任务的应用,怎么跑起来?
课程目录为什么需要它
真实的应用由好几个程序组成:Web 服务器、数据库、缓存、后台任务。用正确的设置一个一个手动启动,很容易出错。Docker Compose 用一个文件描述所有服务,在任何机器上一条命令就能把整套系统启动起来。
直觉理解
compose.yaml 里列出了服务。每个服务就是一个容器:
services:
web:
build: . # 用这里的 Dockerfile 构建
ports:
- "8080:8000" # 你电脑的 8080 → 容器的 8000
environment:
DATABASE_URL: postgres://shop:shop@db:5432/shop
depends_on: [db] # 先启动 db
db:
image: postgres:16 # 用现成的镜像
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:- 服务之间用服务名互相访问:在
web里,数据库的主机名是db,而不是localhost(每个容器都有自己的 localhost)。 ports把端口发布到你的电脑上:"主机端口:容器端口"。- 命名的卷(volume)在容器重建时保留数据。
depends_on控制启动顺序。(它只等容器启动,不等数据库准备好接受连接;要等就得加健康检查。)
docker compose up 启动全部服务;docker compose down 停止它们。
YAML 对缩进很敏感:用空格,永远不要用 Tab。
定义
服务
One container in a Compose file, with its image or build, ports, environment and volumes.Compose 文件里的一个容器,带着它的镜像或构建方式、端口、环境变量和卷。
卷
Storage that lives outside a container, so data survives when the container is replaced.存在容器之外的存储,容器被替换时数据仍然保留。
端口映射
"8080:8000" forwards port 8080 on your machine to port 8000 inside the container."8080:8000" 把你电脑上的 8080 端口转发到容器里的 8000 端口。
示例
一个 Web 应用和它的数据库
在互动课里运行运行它,查看启动顺序和解析后的文件。
services:
web:
build: .
ports:
- "8080:8000"
environment:
DATABASE_URL: postgres://shop:shop@db:5432/shop
depends_on: [db]
db:
image: postgres:16
environment:
POSTGRES_USER: shop
POSTGRES_PASSWORD: shop
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:逐步执行
- L3web 用这个目录里的 Dockerfile 构建。
- L5在你的电脑上打开 http://localhost:8080,就能访问容器里的 8000 端口。
- L7主机名是服务名 db。
- L8db 先于 web 启动。
- L15数据库文件放在命名卷里,重启后还在。
常见错误
在容器里用 localhost
在容器里,localhost 指的是这个容器自己。用另一个服务的名字(db、redis)作为主机名。
数据没放进卷
没有卷的数据库,容器一重建,数据就全没了。在它的数据目录上挂一个命名卷。
以为 depends_on 会等服务就绪
depends_on 只管启动顺序。应用应该重试数据库连接,或者配合健康检查使用 condition: service_healthy。
小测验
1. 在 `api` 容器里,用什么主机名访问 `redis` 服务?
查看答案
答案:A
Compose 给每个服务一个名字,其他服务可以把它当主机名用。
2. `ports: ["5000:80"]`。浏览器要访问哪里?
查看答案
答案:A
主机:容器:你电脑的 5000 转发到容器的 80。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出启动顺序
Compose 会按什么顺序启动这些服务?(几个服务同时可以启动时,这里按字母顺序启动。)
- 改需求web 连不上数据库
web连接数据库时报错 "connection refused"。修好DATABASE_URL里的数据库主机名,并确保db先于web启动。 - 从零写三个服务的系统
写一个有三个服务的 Compose 文件:
web:用.构建,发布8080:8000,在api之后启动api:镜像shop-api:1.4,环境变量DB_HOST: db,在db之后启动db:镜像postgres:16,把命名卷dbdata挂到/var/lib/postgresql/data
在顶层也要声明
dbdata这个卷。
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| Docker Compose | Docker Compose | Runs several containers described in one YAML file. |
| Volume | 卷 | Storage that outlives a container. |
| YAML | YAML | An indentation-based text format for configuration. |