熟悉docker-compose
场景: 一个复杂的应用,不是启动一个容器就能完成的
app = nginx + web + mysql +redis
以后只要启动app,创建app。都得run 4个,保证网络畅通+挂载ok
docker-compose
不懂yaml????????????
application.yaml
可以写一个yaml文件。指定所有需要启动的内容。docker-compose up/down
1、基础
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/dockercompose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
2、yaml语法
{
"name": "demo",
"url": "http://blog.hzhero.cn",
"page": 88,
"address": {
"street": "大观园",
"city": "山东省济南市",
"country": "中国"
},
"links": [
{
"name": "Google",
"url": "http://www.google.com"
},
{
"name": "Baidu",
"url": "http://www.baidu.com"
}
]
}
3、compose语法
app == wordpress (个人博客) web ---- mysql(存储层)
4、compose示例
hello-world
mkdir composetest
创建app.py 其他.,…,
-
编写compose文件[compose.yaml]
-
compose文件名 docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml
version: "3.9" #指定版本号;查看文档https://docs.docker.com/compose/compose-file/ services: #所有需要启动的服务 web: #第一个服务的名字 build: #docker build -t xxx -f Dockerfile . dockerfile: Dockerfile context: . image: 'hello:py' ports: #指定启动容器暴露的端口 - "5000:5000" redis: #第二个服务的名字 image: "redis:alpine" # mysqlserver: #第三个服务 #怎么执行的 Creating network "composetest_default" with the default driver Building web Sending build context to Docker daemon 5.632kB Step 1/10 : FROM python:3.7-alpine 。。。。。。 Step 10/10 : CMD ["flask", "run"] ---> Running in 01e36491132c Removing intermediate container 01e36491132c ---> 47d09826ac6f Successfully built 47d09826ac6f Successfully tagged hello:py ======web镜像名 hello:py=== WARNING: Image for service web 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)... ....... Status: Downloaded newer image for redis:alpine ##下载成功 Creating composetest_redis_1 ... done Creating composetest_web_1 ... done Attaching to composetest_web_1, composetest_redis_1 redis_1 | 1:C 15 Apr 2021 13:55:27.693 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 15 Apr 2021 13:55:27.693 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 15 Apr 2021 13:55:27.693 # 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 15 Apr 2021 13:55:27.694 * monotonic clock: POSIX clock_gettime redis_1 | 1:M 15 Apr 2021 13:55:27.695 * Running mode=standalone, port=6379. redis_1 | 1:M 15 Apr 2021 13:55:27.695 # 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 15 Apr 2021 13:55:27.695 # Server initialized redis_1 | 1:M 15 Apr 2021 13:55:27.695 # 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 15 Apr 2021 13:55:27.695 * Ready to accept connections web_1 | * Serving Flask app "app.py" web_1 | * Environment: production web_1 | WARNING: This is a development server. Do not use it in a production deployment. web_1 | Use a production WSGI server instead. web_1 | * Debug mode: off web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) #因为compose创建了自定义网络,大家都能通
-
启动命令: docker-compose up -d (一句话后台启动这个)
version: "3.9" #指定版本号;查看文档https://docs.docker.com/compose/compose-file/ services: #所有需要启动的服务 web: #第一个服务的名字 build: #docker build -t xxx -f Dockerfile . dockerfile: Dockerfile context: . image: 'hello:py' ports: #指定启动容器暴露的端口 - "5000:5000" redis: #第二个服务的名字 image: "redis:alpine" mysql: image: "mysql" # 其他volumes,networks等 # compose+docker swarm == 集群部署
version: "3.7" services: app: image: node:12-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos network_mode: bridge networks: - hello - world deploy: #安装docker swarm replicas: 6 #指定副本:处于不同的服务器(负载均衡+高可用) mysql: #可以代表一个容器,ping 服务名 mysql 可以访问 image: mysql:5.7 #负载均衡下,数据一致怎么做???主从同步,读写分离 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos networks: #这个服务加入那个自定义网络 - hello deploy: #安装docker swarm replicas: 6 #指定副本:处于不同的服务器(负载均衡+高可用) redis: image: redis networks: - world volumes: todo-mysql-data: networks: hello: world:
-
5、 优雅更新docker compose服务的最新镜像
一、强制拉取最新镜像
1. 拉取指定服务的最新 latest
镜像
docker compose pull <service_name>
# 示例:更新 app 服务的镜像
docker compose pull app
2. 强制更新所有服务的 latest
镜像
docker compose pull --ignore-pull-failures --no-parallel
-
参数说明:
--ignore-pull-failures
:忽略拉取失败的镜像(继续处理其他服务)。--no-parallel
:串行拉取镜像(避免网络过载)。
二、验证镜像更新
1. 查看本地镜像列表
docker images | grep <image_name>
-
例如:
docker images | grep myapp # 输出示例: # myrepo/myapp latest 12345abc 5 minutes ago 256MB # 新镜像 # myrepo/myapp latest 67890def 2 days ago 250MB # 旧镜像(被标记为 <none>)
2. 检查镜像 ID 和创建时间
docker image inspect <image_name>:latest | grep -E 'Id|Created'
确保 Created
时间是最新的,且 Id
与旧镜像不同。
三、优雅重启服务
1. 滚动更新(无状态服务)
使用 docker compose up
结合 --force-recreate
参数,Docker 会自动执行滚动更新:
docker compose up -d --force-recreate --no-deps <service_name>
# 示例:重启 app 服务
docker compose up -d --force-recreate --no-deps app
-
参数说明:
--force-recreate
:强制重新创建容器(即使配置未变)。--no-deps
:不重新创建依赖服务(如数据库)。
2. 有状态服务的分步更新
对于单节点数据库等有状态服务,建议分步操作:
# 1. 停止旧容器
docker compose stop <service_name>
# 2. 启动新容器(自动使用新镜像)
docker compose up -d <service_name>
四、验证服务状态
1. 检查容器运行状态
docker compose ps
确保服务的 IMAGE
列显示为新镜像的 ID 或标签。
2. 查看服务日志
docker compose logs -f <service_name>
确认服务正常启动且无异常错误。
3. 验证应用功能
访问应用前端或调用 API,确保功能正常。
五、清理旧镜像(可选)
更新成功后,可删除旧的 latest
镜像(已被标记为 <none>
):
docker image prune -f
-
注意:该命令会删除所有未被使用的 dangling 镜像,确保无其他容器依赖这些镜像。
六、最佳实践
1. 避免生产环境使用 latest
标签
使用具体版本号(如 v1.0.0
)替代 latest
,提高环境稳定性。
2. 配置健康检查
在 docker-compose.yml
中添加健康检查,确保新容器就绪后再停止旧容器:
services:
app:
image: myrepo/myapp:latest
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost/health || exit 1"]
interval: 10s
timeout: 5s
retries: 3
3. 灰度发布策略
对于关键服务,可先启动少量新实例,逐步将流量切至新版本,降低风险。
通过以上步骤,可确保在本地已有 latest
镜像的情况下,平滑更新到最新版本并验证服务状态,最大限度减少停机时间。