欢迎你的到来,神圣知识宝库将为你的成长保驾护航~~

熟悉docker-compose


熟悉docker-compose

场景: 一个复杂的应用,不是启动一个容器就能完成的

app = nginx + web + mysql +redis

以后只要启动app,创建app。都得run 4个,保证网络畅通+挂载ok

docker-compose

不懂yaml????????????

application.yaml

可以写一个yaml文件。指定所有需要启动的内容。docker-compose up/down

1、基础

安装
docker compose 官网地址

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 镜像的情况下,平滑更新到最新版本并验证服务状态,最大限度减少停机时间。


文章作者: 天际星空
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 天际星空 !
评论
  目录