写给懒猫微服玩家的容器小书 Docker篇(三):《容器部落生活》

《容器部落生活》讲的是 容器生命周期管理,包括容器的启动、停止、查看、交互、日志、后台运行、重启策略等操作

一直想写一本容器小书,真好懒猫基本都做了容器化,所以把这部分分享出来。不同的是,懒猫微服中使用 pg-docker 来替代 docker 命令,使用 dockge 来执行 docker-compose。以下讲解以标准 docker 为主,这样子既学会了 docker 知识,也能够在懒猫微服上启动 Docker 服务。

镜像旅馆的旅途告一段落,小李的下一站是容器部落

老周牵着他走过一条闪烁着数字光芒的通道,一排排运行中的应用像帐篷一样排列着。有人在调试日志,有人在重启服务,还有人用 bash 正在某个容器里“打补丁”。

老周说:

“镜像只是静态的模板,容器才是它们的生命。容器是镜像运行出来的真实世界。”


🧠 技术基础:容器 vs 镜像

项目 镜像(Image) 容器(Container)
类比 模板、配方 实际的运行实例
特性 只读 可读写
作用 用来创建容器 实际运行中的程序环境
状态 不运行 可运行、停止、销毁

🛫 第一节:容器的启动方式

小李想运行他的 Flask 应用镜像。

老周告诉他:

“运行镜像的命令是 docker run,容器就像是用镜像盖起来的一顶帐篷。”

1. 最常见方式(临时 + 前台):

1
docker run my-flask-app

但程序一执行完就退出了。小李困惑。

老周解释:

“容器会在主进程结束后自动退出,比如 CMD ["python", "main.py"] 一旦结束,容器就结束了。”


2. 保持后台运行(常用)

1
docker run -d --name flask-app -p 5000:5000 my-flask-app

解释:

  • -d:detached 模式,后台运行
  • --name:给容器取个名字,方便管理
  • -p 宿主端口:容器端口:端口映射,把容器内部 5000 暴露到外部

小李可以在浏览器里访问 http://localhost:5000,服务在跑!


3. 设置环境变量

1
docker run -d -e ENV=production my-flask-app

在容器内可通过 os.environ['ENV'] 访问。


4. 设置自动重启策略(生产强烈建议)

1
docker run -d --restart=always my-flask-app

可选策略:

策略名 说明
no 不自动重启(默认)
on-failure 出错时重启
always 永远重启
unless-stopped 除非人为停止

🧭 第二节:查看容器状态

老周说:“运行中的容器就像是火堆,你得学会看它们是否还在烧。”

查看运行中容器:

1
docker ps

如果想看所有容器(包括已退出的):

1
docker ps -a

输出示例:

1
2
CONTAINER ID   IMAGE           STATUS         NAMES
f123abc456 my-flask-app Up 3 minutes flask-app

🔄 第三节:容器的停止与重启

停止容器:

1
docker stop flask-app

启动容器:

1
docker start flask-app

重启容器:

1
docker restart flask-app

⚠️ 容器停止后并不会删除,除非显式用 docker rm


🧰 第四节:进入容器内“远程调试”

有一次小李发现容器里缺了个配置文件,他想进去看看。

使用 exec 进入运行中的容器:

1
docker exec -it flask-app /bin/bash
  • -i:保持输入
  • -t:分配终端
  • /bin/bash:使用 bash shell(Alpine 镜像可能要用 /bin/sh

现在他能像 SSH 进服务器一样,在容器里操作文件、日志、环境变量。


📜 第五节:查看容器日志

某天应用崩溃了,小李要调日志。

老周提醒他:“容器日志直接走标准输出和错误输出。”

1
docker logs flask-app

可以加参数看最近内容:

1
docker logs --tail 100 flask-app

实时滚动输出(调试很有用):

1
docker logs -f flask-app

🧽 第六节:删除容器

小李尝试重建容器时,系统提示名字重复。

老周告诉他要先删除原来的:

1
docker rm flask-app

如果容器还在运行,先 stoprm,或直接强制:

1
docker rm -f flask-app

🔄 第七节:容器生命周期一览表

操作 命令
创建 + 运行容器 docker run
后台运行 docker run -d
设置名字 docker run --name name
设置端口映射 -p 外:内
查看容器 docker ps [-a]
停止容器 docker stop name
启动容器 docker start name
重启容器 docker restart name
删除容器 docker rm [-f] name
查看日志 docker logs [-f] name
进入容器 docker exec -it name /bin/bash

🧪 小李的实战练习任务

老周布置了一个练习:

“请你写一个脚本,构建镜像,运行容器,设置环境变量和端口,再用日志确认 Flask 成功启动。”

小李完成如下步骤:

1
2
3
4
docker build -t flask-test .
docker run -d --name flask-run -p 8080:5000 -e MODE=debug flask-test
docker logs -f flask-run
docker exec -it flask-run /bin/bash

🧬 衍生补充:容器的状态码解释

容器退出时,可以用 docker ps -a 查看 STATUS 栏:

  • Exited (0):正常退出
  • Exited (1):出错退出
  • Up:正在运行

调试时很有用。


🎬 尾声:容器部落里的秩序

小李现在已经能够用容器完成:

  • 应用部署
  • 环境隔离
  • 日志查看
  • 重启容错
  • 在线修复问题

他看着容器部落中灯火通明的帐篷,知道自己终于从一个“只会打包镜像”的新人,成长为能驾驭容器生命周期的工程师。

老周拍拍他肩膀说:

“你已经能掌控容器的生死了,下一步——掌控它们的数据。”

好嘞,我们来拓展第三章《容器部落生活》,新增三大实战内容:

🚀 Nginx 容器部署
🔗 多个容器配合运行(应用 + 数据库)
🩺 容器的服务探针(健康检查)

这部分会继续以故事+实战命令+讲解的方式展开,帮助你更贴近真实工作中的容器部署流程。


🧱 实战一:Nginx 容器部署小站点

小李想搭个静态站点测试,老周给他出了一个练习:

“用 Nginx 容器部署一个 HTML 网站,只通过 Docker 完成。”

1. 准备文件结构:

1
2
3
nginx-site/
├── index.html
└── Dockerfile

index.html 示例:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<title>Hello from Nginx</title>
</head>
<body>
<h1>Hello Docker + Nginx!</h1>
</body>
</html>

2. Dockerfile 内容(基于官方 Nginx):

1
2
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html

✅ 把自己的网页文件覆盖掉默认首页。

3. 构建 + 运行:

1
2
docker build -t nginx-site .
docker run -d --name my-nginx -p 8080:80 nginx-site

打开浏览器访问 http://localhost:8080,小李看到页面显示成功,笑得像个孩子。


🔗 实战二:应用容器 + 数据库容器组合运行

接着老周出了第二个任务:

“把你的 Flask 应用和一个 MySQL 数据库用两个容器跑起来,实现数据连接。”

方法一:手动网络 + 多容器连接

1. 创建网络(容器间通信):

1
docker network create flask-net

2. 启动 MySQL 容器:

1
2
3
4
5
docker run -d --name my-mysql \
--network flask-net \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=mydb \
mysql:5.7

3. 启动 Flask 应用容器(连接到 MySQL):

假设 Flask 连接数据库时使用:

1
host = 'my-mysql'  # 容器名就是主机名

启动命令:

1
2
3
4
5
docker run -d --name flask-app \
--network flask-net \
-e DB_HOST=my-mysql \
-p 5000:5000 \
my-flask-app

🔗 容器间在同一个网络中,通过名字直接通信,像局域网一样!


方法二:使用 docker-compose(下一章会详细讲)


🩺 实战三:为容器添加“健康探针”

老周问小李:“如果你的服务挂了,但容器还在运行,你怎么知道?”

小李摇头:这不就是“僵尸容器”吗?

老周笑了:

“那就给它加一个健康探针(HEALTHCHECK),定期检测服务状态。”

为 Flask 容器加健康检查:

修改 Dockerfile

1
2
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5000/health || exit 1

在 Flask 代码中添加一个健康检查路由:

1
2
3
@app.route('/health')
def health():
return "OK", 200

构建镜像,运行容器后,通过命令查看健康状态:

1
docker inspect flask-app | grep -i health

输出示例:

1
2
3
4
"Health": {
"Status": "healthy",
...
}

如果 /health 接口返回失败状态码,容器会标记为 "unhealthy",可配合自动重启策略联动修复。


🧭 实战拓展总结表

场景 命令 / 技术
部署静态站点 Nginx + COPY index.html
容器间通信 docker network create + --network 参数
多容器组合 应用容器连接数据库容器
服务探针 Dockerfile 添加 HEALTHCHECK,应用实现 /health
探针状态查看 `docker inspect 容器名

🎬 尾声 · 容器集群的微光

小李站在容器部落的山丘上,看着成百上千个容器像城市灯火一样运转。

Nginx 做前端代理,Flask 作为后端逻辑,MySQL 管理数据,每个服务都是一块积木,有秩序、有协作。

老周淡淡说:

“这只是单机的容器调度,真正的战场——在云上。”

小李的眼里闪起光芒:“那我下次要学的就是——Compose,K8s,还有 CI/CD,对吧?”

老周点头:“没错,下一站——数据卷与共享、Compose 编排,再之后……你就要去打云原生的战了。”

写给懒猫微服玩家的容器小书 Docker篇(三):《容器部落生活》

https://xu-hardy.github.io/写给懒猫微服玩家的容器小书-docker篇(三):《容器部落生活》/

作者

Xu

发布于

2025-07-02

更新于

2025-07-01

许可协议

评论