Dockers Compose常用指令介绍

news2025/5/23 20:48:43

Dockers Compose常用指令

1、常用指令介绍

1.1、version 指令

顶级一级指令,指定 compose 指定文件格式版本

version: "3.8"
services: 

不同版本支持的功能不同。常用版本有 ‘2’, ‘3’, ‘3.8’ 等。

1.2、services 指令

顶级一级指令,定义应用程序的各个服务(容器),每个服务对应一个容器。

version: "3.8"
services: 
  容器1: 
    各种配置项.....
  容器2: 
    各种配置项.....

常用服务配置项:

  • image: 指定使用的镜像,如 nginx:alpine

  • container_name:指定容器名称,如 my_redis

  • build: 指定构建镜像的 Dockerfile 路径

    build 指令用于指定如何构建一个服务所依赖的镜像。你可以通过这个指令来定义构建上下文、Dockerfile 路径以及构建参数等。

    主要用途

    • 自定义镜像构建:允许你从源代码或特定的基础镜像开始构建自己的 Docker 镜像。
    • 灵活的构建配置:可以根据不同的环境或需求调整构建参数和配置。
    build:
      context: ./dir  # Dockerfile 所在目录
      # 多环境构建,可选,指定哪个 Dockerfile 进行构建,默认 Docker 会寻找工作目录下的 Dockerfile 文件。
      dockerfile: Dockerfile-dev  
      # 定义构建时变量,对应Dockerfile中的 ARG 指令,允许你在构建时传递构建参数
      args:       
        buildno: 1
      # 列出可以作为缓存来源的镜像列表,加速构建过程。
      cache_from:
        - user/app:v1
      # 在镜像上添加元数据标签。
      labels:
        - "com.example.description=Accounting webapp"
      # 设置 /dev/shm 的大小,对于某些应用可能需要更大的共享内存空间。
      shm_size: '2gb'
      # 资源限制
      ulimits:             
        nproc: 65535
        nofile:
          soft: 20000
          hard: 40000
      # 可选,多阶段构建目标阶段,用于多阶段构建,指定构建目标阶段,可显著减小最终镜像大小(多层构建,可以指定构建哪一层)
      target: production  
      # 是否禁用缓存
      no_cache: false
      # 安全构建
      security_opt:
        - seccomp=unconfined
      extra_hosts:
        - "somehost:162.242.195.82"
    

    多阶段构建优化

    # Dockerfile
    FROM node:14 as builder
    WORKDIR /app
    COPY . .
    RUN npm install && npm run build
    
    FROM nginx:alpine
    COPY --from=builder /app/dist /usr/share/nginx/html
    
    # docker-compose.yml
    services:
      web:
        build:
          context: .
          target: builder  # 只构建builder阶段
    

    构建控制命令

    # 构建但不启动:
    docker-compose build
    # 强制重建:
    docker-compose build --no-cache
    # 构建特定服务:
    docker-compose build webapp
    # 查看构建参数:
    docker-compose config --services
    

    最佳实践

    1. 上下文优化

      • 使用 .dockerignore 文件减少上下文大小
      • 避免包含 node_modules 等大目录
    2. 构建缓存利用

      build:
        cache_from:
          - myapp:latest
      
    3. 多阶段构建

      • 分离构建环境和运行环境
      • 显著减小最终镜像大小
    4. 参数化构建

      build:
        args:
          - VERSION=${TAG:-latest}
      

    如何查看构建过程输出?

    docker-compose build --no-cache --progress=plain
    

    docker-compose build 本质上是调用 docker build,但提供了更便捷的项目级构建管理。


  • restart: 重启策略

    restart: always  # no, always, on-failure, unless-stopped
    
  • ports: 端口映射,格式 HOST:CONTAINER

    ports:
      - "80:80"       # 映射所有接口的80端口
      - "127.0.0.1:8000:8000"  # 只映射本地回环地址
    
  • volumes

    卷挂载。

    volumes:
      - /var/lib/mysql          # 1、匿名卷
      - ./data:/var/lib/mysql   # 2、主机路径挂载
      - db-data:/var/lib/mysql  # 3、命名卷
    

    实际当中,选择上述3种的1种即可

重要-注意:

截止到文档的这个位置,上述介绍的指令,除了 build 指令外,其它指令是编写docker-compose.yml 文件必写的指令。

如果使用别人制作好的镜像,我们就不需要 build 指令。

下面罗列常用可选的指令。


常用服务可选配置项:

  • environment: 环境变量

    environment:
      RACK_ENV: development
      SHOW: 'true'
    

    或使用文件:

    env_file:
      - .env
    

    Tips:

    简单近似的理解为定义容器性全局的变量,对 Java 来说,可以使用 system.getProperty("pname") 来获取;对于 Python 来说,可以使用 os.getenv("pname") 来获取;对于 MySql 来说,可以设置初始化数据库的 root 密码等等之类的。具体使用见 总结的environment部分

  • depends_on: 服务依赖

    depends_on:
      - db
      - redis
    

    其作用就是,等待 db 和 redis 容器服务启动之后。关闭时,先关闭主服务,再关闭 db 和 redis 服务。

  • networks: 加入的网络

    networks:
      - frontend
      - backend
    

    其作用就是,使用我们自己预先定义好的网络。

  • command: 覆盖默认命令

    command: bundle exec thin -p 3000
    
  • **devices:**指定设备映射列表。

    devices:
      - "/dev/ttyUSB0:/dev/ttyUSB0"
    
  • **dns:**自定义 DNS 服务器,可以是单个值或列表的多个值。

    dns: 8.8.8.8
    
    dns:
      - 8.8.8.8
      - 9.9.9.9
    
  • **dns_search:**自定义 DNS 搜索域。可以是单个值或列表。

    dns_search: example.com
    
    dns_search:
      - dc1.example.com
      - dc2.example.com
    
  • privileged: 覆盖默认命令

    在Docker Compose配置文件中,privileged是一个布尔类型的选项,用于给容器提供扩展权限。当设置为true时,这个选项允许容器获得几乎所有的能力(capabilities),并且禁用了安全机制如AppArmor、SELinux以及seccomp的限制。简单来说,它使得容器内的进程拥有类似宿主机上运行的进程的权限。

    作用

    1. 增强容器权限:通过给予容器更广泛的权限,可以执行需要更高权限的操作,例如直接访问硬件资源或执行系统管理任务。
    2. 支持特定应用需求:某些应用程序可能需要比默认提供的更多权限才能正常工作,比如网络监控工具、虚拟化软件等。
    3. 开发与调试:在开发和调试过程中,有时需要对系统进行深层次的操作,此时使用特权模式可以使这一过程更加方便。
    4. 获得root权限:容器内的root用户拥有宿主机的root权限。
    5. 绕过安全机制:忽略很多默认的Docker安全限制。
    6. 解除大部分限制:容器几乎可以访问宿主机的所有设备和内核功能。

    使用示例

    version: '3.8'
    services:
      myservice:
        image: myimage
        privileged: true
    

    特权模式的作用

    services:
      # 1. 允许访问所有设备
      docker-in-docker:
        image: docker:dind
        privileged: true  # 必须启用才能运行Docker-in-Docker
      # 2. 允许修改内核参数
      network-tool:
        image: network-tools
        privileged: true  # 需要修改网络栈参数
      # 3. 允许加载内核模块
      device-driver:
        image: custom-driver
        privileged: true  # 需要加载内核模块 
    

    安全风险警告:

    特权模式会带来严重安全风险:

    • 容器逃逸:攻击者可能从容器获取宿主机root权限
    • 系统破坏:恶意容器可能破坏宿主机系统
    • 数据泄露:可以访问宿主机的所有数据

    替代方案(更安全的选择)

    services:
      # 1. 精细控制能力
      device-access:
        image: device-tool
        cap_add:
          - SYS_ADMIN     # 只添加需要的权限
          - NET_ADMIN
          - ALL           # 开启全部权限
        cap_drop:
      	  - SYS_PTRACE    # 关闭 ptrace权限
        devices:
          - "/dev/ttyUSB0:/dev/ttyUSB0"  # 只挂载需要的设备
      # 2. 特定设备访问
      gpio-service:
        image: gpio-control
        devices:
          - "/dev/gpiomem:/dev/gpiomem"
    

    实际应用场景

    services:
      # 1. 必须使用特权模式的场景
      kubelet:
        image: kubelet
        privileged: true  # Kubernetes组件需要
        
    # 最佳实践建议
    # 审计特权容器
    docker ps --filter 'label=privileged=true'
    # 结合用户命名空间
    userns_mode: "host"  # 与privileged一起使用更安全
    

    特权模式的技术细节

    privileged: true 时,容器会:

    1. 获得所有Linux capabilities(约40种)
    2. 可以访问所有设备文件(如 /dev/mem
    3. 可以修改AppArmor/SELinux配置
    4. 可以挂载任意文件系统

    检查容器权限:

    # 检查容器是否特权模式运行
    docker inspect --format='{{.HostConfig.Privileged}}' <container>
    # 查看授予的capabilities
    docker inspect --format='{{.HostConfig.CapAdd}}' <container>
    

    企业级安全建议:

    1. 集群部署时:使用PodSecurityPolicy/OPA Gatekeeper禁止特权容器
    2. CI/CD管道中:添加特权模式检查步骤
    3. 监控方面:对特权容器进行特别审计
    4. 替代架构:考虑使用无特权容器设计
  • stdin_open:控制标准输入(STDIN)行为的配置项

    stdin_open 是一个在 Docker Compose 文件中用于服务配置的选项,它保持容器的标准输入(stdin)打开。默认情况下,Docker 容器启动时并不会保持标准输入打开,这意味着一旦启动命令执行完毕,如果没有其他进程继续保持容器运行,容器将会退出。

    通过设置 stdin_open: true,你可以让容器的标准输入保持打开状态,这通常与 -i 参数在 docker run 命令中的作用相似,允许你以交互模式与容器进行通信。

    使用场景

    • 交互式应用程序:如果你的应用程序需要从标准输入读取数据(例如某些CLI工具或交互式的shell),你需要确保容器的标准输入是打开的。
    • 调试:对于开发和调试来说,有时需要保持容器的输入流开放以便手动发送命令或信息到容器内。

    示例

    下面是一个简单的例子展示了如何在 Docker Compose 文件中使用 stdin_open

    version: '3.8'
    services:
      myservice:
        image: ubuntu
        stdin_open: true  # 保持标准输入打开
        tty: true         # 分配一个伪TTY,通常与stdin_open一起使用,提供交互界面
        command: /bin/bash
    

    在这个例子中,我们使用了 Ubuntu 镜像,并且通过设置 stdin_open: truetty: true 来保持标准输入打开并分配一个伪TTY。这样做的结果是当你运行这个 Compose 文件时,它会启动一个可以交互的 Bash shell,让你能够直接与容器内部进行交互。

    核心作用

    services:
      # 1. 启用交互式会话
      python:
        image: python:3
        stdin_open: true  # 允许输入Python代码,例如:docker-compose run python python3(进入交互式Python解释器)
        tty: true
      # 2. 保持后台容器的输入能力
      shell:
        image: alpine
        stdin_open: true
        command: /bin/sh  # 保持shell运行
    

    tty 的区别

    配置项作用典型使用场景
    stdin_open: true保持输入流开放需要向容器发送输入
    tty: true分配伪终端需要终端特性(如clear、Ctrl+C)

    请注意,虽然 stdin_open 可以为你的容器提供更多的交互性,但在生产环境中通常不需要这样做,因为大多数服务应用并不需要直接的用户交互。因此,该选项更多地适用于开发、测试或需要直接与容器交互的场景。

    实际应用场景

    services:
      # 1. 开发环境调试
      dev:
        build: .
        stdin_open: true  # 允许输入测试数据
        tty: true
      # 2. 数据库管理控制台
      mysql-client:
        image: mysql
        command: mysql -uroot -p
        stdin_open: true  # 允许输入密码
      # 3. 交互式教学环境
      tutorial:
        image: learnpython
        stdin_open: true  # 允许学生输入代码
        tty: true
        
    ## 最佳实践
    # 1、生产环境应禁用(除非明确需要):stdin_open: false(显式关闭更安全)
    # 2、开发环境按需启用:stdin_open: ${ENABLE_INTERACTIVE:-false}(通过环境变量控制)
    # 3、结合 docker-compose run 使用:
    docker-compose run --service-ports web bash  # 交互式访问
    

    docker exec -it 的区别?

    • stdin_open 是创建时的配置
    • exec -it 是后期附加到运行中容器
  • tty:虚拟终端

    设置为 true 时,它会为容器分配一个虚拟终端(TTY)。这个选项通常与 stdin_open: true 一起使用,以便提供交互式的 shell 或命令行界面。

    类似于 Dockers 如下命令:

    docker exec -it <container> sh  # 后期附加终端
    
  • security_opt:安全配置

  • security_opt 是 Docker Compose 中用于配置容器安全选项的重要参数,它允许你精细控制容器的安全设置,特别是与 Linux 安全模块(如 SELinux 和 AppArmor)的交互方式。

    security_opt 允许你:设置 SELinux 标签、配置 AppArmor 策略、调整容器能力(capabilities)、禁用默认的安全配置

    基础语法

    services:
      secured-service:
        image: nginx
        security_opt:
          - label:user:USER      # SELinux用户标签
          - label:role:ROLE      # SELinux角色标签
          - label:type:TYPE      # SELinux类型标签
          - label:level:LEVEL    # SELinux级别标签
          - apparmor=PROFILE     # AppArmor配置
          - no-new-privileges    # 禁止特权升级
          - seccomp=PROFILE.json # seccomp配置
    

    核心安全选项

    # 1. SELinux 标签控制
    security_opt:
      - label:user:system_u
      - label:role:object_r
      - label:type:svirt_lxc_net_t
      - label:level:s0:c100,c200
    

    **Tips: **

    可以理解为设置 Linux 系统的SELinux 参数;

    SELinux 选项:

    label:user设置用户标签system_u
    label:role设置角色标签object_r
    label:type设置类型标签svirt_lxc_net_t
    label:level设置MLS/MCS级别s0:c100,c200
  • links:安全配置

    links 字段用于定义服务之间的链接。通过这种方式,可以允许一个服务连接到另一个服务,并且能够使用服务名称作为主机名来访问被连接的服务。这个概念源自于较早版本的 Docker 网络模型,它创建了容器间的依赖关系,并提供了服务发现机制。

    links 在传统 Docker 部署中曾非常重要,但在现代 Docker 网络中,建议优先考虑使用自定义网络实现服务发现和连接。

    作用

    1. 服务发现:通过 links,你可以使用被链接服务的名字作为主机名来访问该服务。这对于那些需要明确知道如何连接到其他服务的应用来说非常有用。
    2. 环境变量注入:链接还会在目标容器中创建一系列环境变量,这些变量包含了关于链接服务的信息(如端口、IP地址等)。不过,这种方法现在被认为不如使用自定义网络那样灵活和透明。
    3. 网络隔离与互通:尽管 Docker 的默认行为是让所有在同一自定义网络上的服务自动相互可见,但 links 可以用来更精细地控制这种可见性,尤其是在使用默认桥接网络时。

    注意事项

    1. 在现代 Docker 使用中,推荐的方式是通过定义自定义网络来实现服务间通信,而不是使用 links。这是因为自定义网络提供了更加灵活的服务发现机制,并且支持更为复杂的网络配置,同时避免了使用 links 带来的某些限制和复杂性。

    2. 自 Docker 网络功能增强以来,links 已经不再推荐用于新的项目中。自定义网络不仅简化了多服务应用的网络配置,还提高了其可维护性和扩展性。

    3. 推荐使用自定义网络,了解即可,老的项目中可能还在使用。

1.3、volumes 指令

在 Docker Compose 文件中,volumes 是一个非常重要的配置项,它用于管理容器与主机之间的数据持久化和共享。

基本概念

volumes (卷) 在 Docker 中有两个主要用途:

  1. 数据持久化:容器停止或删除后,数据不会丢失
  2. 数据共享:在容器之间或容器与主机之间共享数据

三种主要类型

在 docker-compose.yml 中,volumes 可以分为三种类型:

1. 匿名卷 (Anonymous volumes)

volumes:
  - /var/lib/mysql
  • 没有指定名称,由 Docker 自动管理
  • 数据会持久化,但不易查找和管理
  • 容器删除后,需要通过 docker volume prune 清理

Tips:

也就是说,我只是在 容器里内 声明了一个数据卷而已,对应宿主机的位置,由宿主机的 docker 自己管理,

一般是在 宿主机的/var/lib/docker/volumes/<volume_name>/_data 这个地方,

且名字是一串随机哈希(如 3a9f8e8b...),所以不易查找和管理。

2. 命名卷 (Named volumes)

在文件顶部需要先声明:

volumes:
  db-data:

然后才可以在容器服务中使用:

version "3.8"
service: 
  mysql:
    image: mysql:latest
    volumes:
      - db-data:
  • 由 Docker 管理,存储在 /var/lib/docker/volumes/ 目录下
  • 最适合生产环境使用,易于管理和备份

Tips:

可以近似的简单的理解为和 匿名卷 其实是一样的,也是由宿主机的 docker 自己管理,

也是在宿主机的/var/lib/docker/volumes/<volume_name>/_data 这个地方,只不过 匿名卷 的名称是一串 随机哈希值

命名卷 是我们在文件中申明的名称而已,所以易于查找和管理。

3. 主机绑定挂载 (Host bind mounts)

就是直接绑定 宿主机的目录容器里目录 的映射关系。

version "3.8"
service: 
  mysql:
    image: mysql:latest
    volumes:
      - ./data:/var/lib/mysql
  • 直接映射主机文件系统的目录到容器
  • 适合开发环境,可以实时修改代码或配置
  • 路径可以是绝对路径或相对路径(相对于 compose 文件位置)

高级配置选项

  • 只读挂载

    volumes:
      - ./config:/etc/config:ro
    

    添加 :ro 表示容器只能读取不能修改

  • 自定义卷驱动

    volumes:
      db-data:
        driver: local
        driver_opts:
          type: 'nfs'
          o: 'addr=10.40.0.199,nolock,soft,rw'
          device: ':/path/to/dir'
    
  • 卷标签

    volumes:
      db-data:
        labels:
          - "com.example.description=Database volume"
    

1.4、networks 指令

networks 指令用于定义和管理服务之间的网络连接。通过使用 networks,你可以创建自定义的网络来控制哪些服务可以相互通信以及如何通信。这提供了比默认网络配置更高级的网络管理功能,使得容器间的互联更加灵活、安全。

作用

  1. 隔离与分段:允许你根据需要将服务划分为不同的网络,从而实现网络层面的服务隔离。
  2. 自定义网络驱动:支持使用不同的网络驱动(如 bridge, overlay 等),以适应不同的部署场景。
  3. DNS解析:在同一网络中的服务可以通过服务名称自动解析为对应的容器 IP 地址,简化了服务发现过程。
  4. 外部访问:可以将某些网络设置为外部可访问,这样就可以从宿主机或其他非 Docker Compose 定义的容器访问这些服务。

核心网络类型

网络类型特点适用场景
bridge (默认)单主机虚拟网络,自动DNS解析开发环境,单机部署
overlay多主机网络,支持集群Swarm集群部署
host直接使用主机网络栈高性能需求,端口冲突避免
macvlan为容器分配MAC地址需要直接接入物理网络
none完全禁用网络特殊安全需求

基本用法

如何定义和使用自定义网络:

version: '3.8'
services:
  web:
    image: example/web:latest
    networks:
      - frontend
      - backend
  admin:
    image: example/admin:latest
    networks:
      - backend
networks:
  frontend:  # 网络名称
    driver: bridge  # 网络驱动类型
    driver_opts:           # 驱动选项
      com.docker.network.bridge.name: my-bridge
    attachable: true       # 是否允许其他容器附加
    internal: false        # 是否内部网络(无外部访问)
    labels:                # 元数据
      - "com.example.description=Frontend network"
  backend:
    driver: bridge

说明:定义了两个网络:frontendbackendweb 服务同时连接到这两个网络,而 admin 服务仅连接到 backend 网络。这意味着 web 服务可以通过网络名称作为主机名与 admin 服务进行通信,但 admin 服务不能直接与 web 服务通信(除非也加入 frontend 网络)。

高级用法

  • 指定静态IP地址:在某些情况下,你可能希望为服务分配一个静态IP地址。虽然这不是所有网络驱动都支持的功能,但在某些特定环境下是可行的。

    networks:
      app_net1:
        driver: bridge
        ipam:
          config:
            - subnet: 172.20.0.0/16
      app_net2:
        ipam:
          driver: default
          config:
            - subnet: 172.20.0.0/24
              gateway: 172.20.0.1
              ip_range: 172.20.0.128/25
    services:
      app:
        image: example/app:latest
        # 服务特定配置
        networks:
          app_net1:
            ipv4_address: 172.20.1.10
            aliases:       # 额外域名别名
              - database
              - mysql
    
  • 外部网络:如果你想要连接到已经存在的 Docker 网络,可以将网络标记为外部。

    # 这表示该服务将会连接到名为 my-pre-existing-network 的现有 Docker 网络,而不是创建一个新的网络。
    networks:
      default:
        external:
          name: my-pre-existing-network  # 使用已存在的网络
    
  • 别名:你还可以给服务在网络中的名字设置别名,以便于其他服务更容易地找到它。

    services:
      some-service:
        networks:
          some-network:
            aliases:
             - alias1
             - alias3
          other-network:
            aliases:
             - alias2
    

    在这个例子中,some-servicesome-network 网络中有两个别名 alias1alias3,而在 other-network 中有一个别名 alias2

实际应用场景

1. 多网络隔离

services:
  web:
    networks:
      - frontend
  db:
    networks:
      - backend
networks:
  frontend:
  backend:

2. 微服务架构

services:
  gateway:
    networks:
      - ingress
  service1:
    networks:
      - ingress
      - service_net
  service2:
    networks:
      - service_net
networks:
  ingress:
  service_net:

3. 生产环境配置

networks:
  app_net:
    driver: overlay
    attachable: true
    ipam:
      config:
        - subnet: 10.0.1.0/24

网络连接原理

  1. DNS解析

    • 同一网络内可通过服务名容器名访问
    • 自动负载均衡(多个容器实例时)
  2. 端口访问

    • 同一网络内无需发布端口即可相互访问
    • 跨网络或外部访问需要 ports 映射
  3. 连接隔离

    networks:
      secure_net:
        internal: true  # 禁止外部访问
    

操作命令

# 1、查看网络:
docker network ls
docker network inspect <network_name>
# 2、连接/断开容器:
docker network connect <network> <container>
docker network disconnect <network> <container>
# 3、清理未用网络:
docker network prune

最佳实践

# 1、环境隔离:
networks:
  dev_net:
  prod_net:
# 2、安全分层:
services:
  api:
    networks:
      - api_net
  db:
    networks:
      - db_net
# 3、Swarm模式:
networks:
  cluster_net:
    driver: overlay
    attachable: true

Tips:

1、不定义networks会怎样?

Compose会创建默认的bridge网络,所有服务加入其中(不推荐生产环境使用)

2、如何实现容器与主机通信?

使用 host 网络或通过主机IP访问:

services:
app:
 network_mode: host

3、跨Compose项目的网络共享?

networks:
shared_net:
 external: true
 name: project1_shared_net

4、与Kubernetes网络的对比?

Docker网络更简单直接,K8s网络插件(如Calico、Flannel)提供更复杂的策略控制。

总结

通过合理利用 networks 指令,不仅可以更好地组织和隔离应用的不同部分,还能增强安全性并简化服务发现过程。这对于构建复杂的应用架构尤其重要,因为它提供了一种有效的方式来管理和优化容器间的网络交互。

1.5、高级配置

1.5.1、健康检查

在Docker Compose配置文件中,healthcheck指令用于定义容器的健康检查机制。这个机制允许你检查你的服务容器是否已经准备好接受流量,即容器中的应用程序是否正在按预期运行,可以自动检测容器内的应用是否真正"就绪"而不仅仅是容器进程是否运行。通过这种方式,可以确保服务之间的依赖关系只有在相关服务完全准备好之后才进行连接,从而避免了服务启动顺序带来的问题。

健康检查通过定期执行命令来:

  1. 验证服务可用性:比如数据库是否能接受连接
  2. 控制启动依赖:确保一个服务等待另一个服务真正准备好
  3. 自动恢复:与 restart 策略配合可实现故障自愈

基础语法

services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"] # 检查命令
      interval: 30s     # 检查间隔
      timeout: 10s      # 命令超时时间
      retries: 3        # 失败重试次数
      start_period: 5s  # 容器启动后的初始化时间(期间不标记失败)

检查方式

1. 命令检查(推荐)

healthcheck:
  test: ["CMD", "pg_isready", "-U", "postgres"] # PostgreSQL检查
  # 或
  test: ["CMD-SHELL", "mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD}"] # MySQL

2. 禁用健康检查

healthcheck:
  disable: true

3. TCP端口检查

healthcheck:
  test: ["TCP", "8080"]  # 只检查端口是否监听

实际应用示例

  • MySQL 健康检查
services:
  db:
    image: mysql:8.0
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -uroot -p$$MYSQL_ROOT_PASSWORD"]
      interval: 5s
      timeout: 5s
      retries: 3
  • Web 应用健康检查
services:
  web:
    build: .
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      start_period: 10s  # 给应用启动时间

健康状态的影响

  • docker-compose ps 显示状态
Name              Command               State                 Ports
-------------------------------------------------------------------
web   npm start              Up (healthy)   0.0.0.0:3000->3000/tcp
db    docker-entrypoint.sh   Starting (unhealthy)
  • 服务依赖控制
services:
  app:
    depends_on:
      db:
        condition: service_healthy
  • 集群编排:Swarm/K8s 会根据健康状态决定是否路由流量

高级配置技巧

  • 自定义健康端点(Web应用)
// Express示例
app.get('/health', (req, res) => {
  db.ping() // 检查数据库连接
    .then(() => res.status(200).send('OK'))
    .catch(() => res.status(503).send('Service Unavailable'))
})
  • 复合检查
healthcheck:
  test: ["CMD-SHELL", "test -f /tmp/ready && curl -f http://localhost"]
  • 日志调试
docker inspect --format='{{json .State.Health}}' <container>

# 查看健康检查日志?
docker logs <container> 2>&1 | grep healthcheck

# 生产环境建议配置?
healthcheck:
  test: ["CMD", "custom-health-check-script.sh"]
  interval: 30s
  timeout: 15s
  retries: 5
  start_period: 60s  # 给复杂应用足够的启动时间

例子:

version: "3.8"
services:
  web:
    image: my-web-app
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
      interval: 1m30s
      timeout: 10s
      retries: 3
      start_period: 40s

Tips:

用的情况应该比较少和简单。

1.5.2、资源限制

资源限制(resource constraints)是指对服务容器所能够使用的计算资源进行限制。这些资源包括CPU、内存等,通过设置这些限制,可以控制容器的资源使用情况,从而优化性能、避免某个容器过度消耗资源而影响其他容器或主机系统的正常运行。

在Docker Compose文件中,可以通过deploy.resources字段来指定资源限制和预留值,不过请注意,deploy字段主要用于Swarm模式下,如果你不使用Swarm集群而是直接使用Docker Compose,则需要确保你的Compose版本支持这些选项,并且正确地应用它们。

非Swarm模式使用resources而非deploy.resources

例如

services:
  my_service:
    image: my_image
    deploy:
      resources:
      	# 可以使用相对单位如1.0代表单个CPU的核心
        limits:
          memory: 512M  # 限制一个服务最多使用512MB的RAM
          cpus: '0.5'  # 限制一个服务使用不超过0.5个CPU核心
          pids: 100  # 最大进程数
          devices:
            - capabilities: ["gpu"]  # GPU限制
        # 除了限制以外,还可以设置资源预留,确保容器至少有这么多资源可用。这对于保证关键服务的性能非常有用
        reservations:
          cpus: '0.2' # 保证至少0.2个CPU核心
          memory: 256M  # 保证分配的最小内存 

上述deploy字段中的资源管理特性主要针对Docker Swarm环境。如果你仅使用Docker Compose而不打算部署到Swarm集群中,确保你的使用场景与Compose版本相匹配。对于非Swarm环境下的资源限制,可以在创建容器时直接使用resources字段,但具体的语法和支持可能会有所不同。

实际应用场景

1. 生产环境数据库配置

services:
  mysql:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G
          pids: 500
        reservations:
          memory: 2G

2. 微服务资源配额

services:
  api:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
    depends_on:
      redis:
        condition: service_healthy

  redis:
    deploy:
      resources:
        limits:
          memory: 500M

资源限制工作原理

  1. Linux底层机制
    • 内存:cgroups memory subsystem
    • CPU:CFS scheduler
    • 设备:device cgroup controller
  2. Docker实现
    • 限制是硬性的,超用会触发OOM Killer(内存)或节流(CPU)
    • 保留(reservations)是软性的,只在资源争用时生效

查看资源使用情况

# 查看容器资源统计
docker stats
# 详细资源分配信息
docker inspect <container> | grep -i resources -A 20
# 查看cgroup配置
docker exec <container> cat /sys/fs/cgroup/memory/memory.limit_in_bytes

最佳实践建议

# 1、内存限制:始终设置内存限制防止系统崩溃;预留10-20%给系统进程
memory: ${MEM_LIMIT:-500M}

# 2、CPU限制:对计算密集型服务使用小数核心(如0.3);对延迟敏感服务使用cpuset固定CPU核心
cpus: '0.3'
cpuset: '0,1'  # 绑定到特定核心

# 3、混合部署:
services:
  frontend:
    deploy:
      resources:
        limits:
          cpus: '0.2'
          memory: 200M
  backend:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
1.5.3、扩展字段

扩展字段是 Docker Compose 文件中以 x- 开头的自定义配置项,它们允许你在不破坏 Compose 文件规范的情况下添加自己的元数据或配置。

作用

  1. 增强灵活性:扩展字段允许你在Docker Compose文件中包含更多的元数据或配置细节,而不受限于官方指定的格式和结构。
  2. 工具支持:一些第三方工具或脚本可能会解析这些扩展字段,以便执行特定的任务或操作。例如,某些CI/CD管道可能会读取这些字段来决定构建或部署的行为。
  3. 文档与注释:虽然不是其主要用途,但有时也会用扩展字段来为配置添加注释或说明,帮助理解复杂的配置。

直接配置

version: '3.8'
services:
  web:
    image: example/web:latest
    x-custom-labels:
      - "environment": "production"
      - "team": "backend"
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    x-deployment-notes: "This service is critical for production and should always have at least one replica running."

在这个例子中,x-custom-labelsx-deployment-notes都是扩展字段。前者可能被某个自定义脚本用于给服务添加特定标签,后者则可能是对部署过程的一些额外说明或注意事项。

引用配置

version: '3.8'

x-common-env: &common-env  # 定义扩展字段(锚点)
  TZ: Asia/Shanghai
  LANG: en_US.UTF-8

services:
  web:
    image: nginx
    environment:
      <<: *common-env       # 引用扩展字段
      NGINX_PORT: 8080

  db:
    image: postgres
    environment:
      <<: *common-env
      POSTGRES_PASSWORD: example

使用 x- 前缀定义自定义字段:

x-custom:
  foo: bar

services:
  web:
    image: nginx
    x-custom: ${x-custom}

实际应用场景

  • 场景1:统一网络配置
x-network: &network
  aliases:
    - app
  ipv4_address: 172.20.0.100

services:
  frontend:
    networks:
      app_net: *network

networks:
  app_net:
    driver: bridge
  • 场景2:多环境变量管理
x-env: &env
  - .env
  - .env.${DEPLOY_ENV:-development}

services:
  app:
    env_file: *env
  • 场景3:CI/CD 集成
x-gitlab:
  variables:
    DOCKER_DRIVER: overlay2
  only:
    - master
    - tags

services:
  runner:
    image: gitlab/gitlab-runner
  • 文档示例
x-myapp-docs:  # 文档示例
  description: |
    此扩展字段用于定义所有服务的公共健康检查配置
    会被各服务通过YAML锚点引用

其它

# 1、查看扩展字段?
docker-compose config | grep x-

# 2、Kubernetes 使用 annotations(注解)实现类似功能
metadata:
  annotations:
    mycompany.com/description: "自定义描述"
1.5.4、变量与环境替换

在Docker Compose配置文件中,变量与环境替换是一种允许你通过外部变量或环境变量动态地设置配置值的方法。这种方法极大地增强了配置文件的灵活性和可重用性,使得你可以轻松地在不同的环境中(如开发、测试、生产)使用同一份配置文件,只需调整相应的环境变量即可。

变量与环境替换的作用

  1. 提高配置文件的灵活性:允许根据不同的运行环境定制化服务配置,而无需修改Docker Compose文件本身。
  2. 保护敏感信息:避免将密码、API密钥等敏感信息直接写入配置文件中,而是通过环境变量提供。
  3. 简化多环境部署:可以在不同环境下复用同一个Compose文件,仅需改变环境变量的值。

使用方法

1. 使用环境变量

docker-compose.yml文件中,可以通过${VARIABLE}的形式引用环境变量。例如:

version: '3.8'
services:
  db:
    image: "postgres:${POSTGRES_VERSION}"
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
# 在这个例子中,POSTGRES_VERSION, POSTGRES_USER, 和 POSTGRES_PASSWORD都是从环境变量中读取的值。

# 严格模式变量
environment:
  API_KEY: ${API_KEY?err}  # 未设置时报错"err"

2.设置默认值

你还可以为环境变量指定一个默认值,以防它们未被定义。语法如下:${VARIABLE:default_value}。例如:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "${WEB_PORT:80}:${WEB_PORT:80}"
# 如果WEB_PORT环境变量未定义,则会使用默认端口80。

3. 使用.env文件

通常,环境变量会被放置在一个名为.env的文件中,该文件应该位于与docker-compose.yml相同的目录下。Docker Compose会自动加载这个文件中的变量。例如,你的.env文件可能看起来像这样:

POSTGRES_VERSION=13
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword

然后,在docker-compose.yml中可以直接引用这些变量,而不需要额外的操作。

高级用法

# 1. 多环境配置
docker-compose --env-file .env.prod up  # 命令行指定不同环境文件

# 2、复合变量
environment:
  DB_URL: "postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}"
  
# 3、Shell 命令结果
environment:
  BUILD_NUMBER: $(git rev-parse --short HEAD)  # 注入Git提交哈希

实际应用示例

# 生产环境配置
# .env.prod 文件:
APP_ENV=production
DB_PASSWORD=secure123!
# docker-compose.yml 文件:
services:
  app:
    image: myapp:${APP_ENV:-development}
    environment:
      NODE_ENV: ${APP_ENV}
      DATABASE_URL: "mysql://user:${DB_PASSWORD}@db:3306/app"

# 多阶段构建
# docker-compose.yml 文件:
services:
  builder:
    image: builder:${BUILD_TAG:-latest}
    environment:
      - NPM_TOKEN=${NPM_TOKEN}  # 从主机环境注入

变量加载顺序

Docker Compose 按以下顺序加载变量(后面的覆盖前面的):

  1. .env 文件(自动加载)
  2. 主机环境变量
  3. --env-file 指定的文件
  4. environment 部分直接定义的值

最佳实践

# 1、敏感信息管理:
# 从保密管理工具注入
export DB_PASSWORD=$(vault read -field=password secret/db)
docker-compose up

# 2、环境文件组织:
/config
  .env.dev
  .env.test
  .env.prod
docker-compose.yml

# 3、文档化变量:
x-env-docs:
  required:
    - DB_PASSWORD: 数据库密码
  optional:
    - LOG_LEVEL: 日志级别(default=info)

其它

# 1、查看最终替换后的配置?
docker-compose config

# 2、变量未设置会怎样
${VAR}:空字符串
${VAR:-default}:使用默认值
${VAR?error}:显示错误信息并退出

# 3、如何在容器内访问这些变量?
# 在容器内执行
echo $LOG_LEVEL

2、其它指令

2.1、logging

服务的日志记录配置。

driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项

driver: "json-file"
driver: "syslog"
driver: "none"

2.2、deploy

指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。

version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      mode:replicated
      replicas: 6
      endpoint_mode: dnsrr
      labels: 
        description: "This redis service label"
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s

详细可以参考 官方文档 或者 https://www.runoob.com/docker/docker-compose.html 介绍。

3、总结

3.1、environment指令

environment 是 Docker Compose 文件中用于设置容器环境变量的配置项,它允许你向容器内部传递配置参数和运行时设置。

这些环境变量可以用来配置服务的行为、连接字符串、认证信息等,它们对容器内的应用程序来说就像是操作系统的环境变量一样。

基本概念

环境变量在容器中的作用:

  1. 配置应用程序:数据库连接字符串、API密钥等
  2. 控制程序行为:设置开发/生产环境模式
  3. 传递敏感信息:密码、访问令牌(但要注意安全性)

基本语法

1. 直接键值对形式(推荐)

services:
  web:
    image: nginx
    environment:
      NGINX_PORT: 8080
      DEBUG: "true"

2. 数组形式

services:
  web:
    image: nginx
    environment:
      - NGINX_PORT=8080
      - DEBUG=true

高级用法

1. 使用变量扩展

services:
  web:
    image: nginx
    environment:
      HOSTNAME: ${HOSTNAME}  # 使用宿主机的环境变量
      VERSION: ${VERSION:-1.0}  # 默认值

2. 从文件加载(适合敏感信息)

services:
  db:
    image: postgres
    env_file:
      - .env  # 从文件加载环境变量
      - db.env

3. 多环境配置

services:
  app:
    image: myapp
    environment:
      - NODE_ENV=${APP_ENV:-development}
      - API_URL=${API_URL:-http://localhost:3000}

实际应用示例(常用)

1. 数据库配置

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw
      MYSQL_DATABASE: app_db
      MYSQL_USER: app_user
      MYSQL_PASSWORD: user_password

Tips:

意思就是,在启动初始化数据库时候,设置 root 的密码,和 创建一个 app_db 数据库,和 app_user 用户及对应的密码。

如果没有持久化数据库,重启容器后,之前的数据库信息会丢失;如果持久化数据库了,则也就是存在相应的文件,无论怎么重启数据库,一开始初始化数据库的信息都还在。

2. 应用配置

services:
  app:
    build: .
    environment:
      RAILS_ENV: production
      DATABASE_URL: postgres://user:pass@db:5432/app_prod  
      REDIS_URL: redis://redis:6379/1

这里的 db 是我们定义的容器,因为在 Docker 网络内部,服务名称(mysql)会自动解析为容器的IP地址。

Tips:

这是给我们自己的 app 服务定于环境信息,就是说 可以在 app 项目代码里面使用这些信息。

如果是 python:

# Python 示例
import os
db_url = os.getenv("DATABASE_URL")  # 读取环境变量
env = os.getenv('DEBUG') # 读取开发环境变量

如果是 javascript:

// Node.js 示例
const dbUrl = process.env.DATABASE_URL; // 读取环境变量
const env = process.env.DEBUG // 读取开发环境变量

3. 微服务配置

services:
  auth_service:
    image: auth-service
    environment:
      JWT_SECRET: ${JWT_SECRET}
      TOKEN_EXPIRY: 3600

  api_gateway:
    image: api-gateway
    environment:
      AUTH_SERVICE_URL: http://auth:3000
      LOG_LEVEL: debug

安全最佳实践

1.敏感信息处理

environment:
  DB_PASSWORD: ${DB_PASSWORD}  # 从宿主环境读取

然后运行时传入:

DB_PASSWORD=secret docker-compose up

2.使用 secrets(生产环境推荐):

services:
  db:
    image: postgres
    secrets:
      - db_password
secrets:
  db_password:
    file: ./db_password.txt

3.不要硬编码密码

environment:
  DB_PASSWORD: "123456"  # 直接写在文件中不安全

调试技巧

  1. 查看容器的环境变量:

    docker exec -it <container> env
    
  2. 检查变量是否生效:

    docker-compose config  # 查看最终解析的配置
    
  3. 使用 --env-file 覆盖:

    docker-compose --env-file .env.prod up
    

3.2、command 指令

command 是 Docker Compose 文件中用于覆盖容器默认启动命令的配置项,它允许你自定义容器启动时执行的命令。

基本概念

当你在 Docker Compose 文件中使用 command 时,它会:

  1. 覆盖 Docker 镜像中定义的默认 CMD 指令
  2. 替换 容器启动时运行的命令
  3. 不影响 ENTRYPOINT(除非使用 shell 格式)

基本用法

1. 字符串格式

services:
  web:
    image: nginx
    command: nginx -g "daemon off;"

2. 列表格式(推荐)

services:
  web:
    image: nginx
    command: ["nginx", "-g", "daemon off;"]

与 Dockerfile 的关系

Dockerfile 指令是否可被覆盖覆盖方式
ENTRYPOINTentrypoint 配置项
CMDcommand 配置项

实际应用场景

1. 修改默认参数

services:
  redis:
    image: redis
    command: redis-server --appendonly yes

2. 运行不同的可执行文件

services:
  node:
    image: node:14
    command: npm start

3. 调试容器

services:
  web:
    image: myapp
    command: sh -c "while true; do echo 'Debugging...'; sleep 5; done"

3.3、entrypoint指令

entrypoint 指令用于覆盖 Dockerfile 中定义的默认入口点(ENTRYPOINT)。它允许你在启动容器时指定一个自定义的命令或脚本作为容器的第一个进程。通过这种方式,你可以改变容器的行为,使其执行不同的任务或初始化步骤。

作用

  • 改变容器的默认行为:通过 entrypoint,你可以让容器运行不同于其设计初衷的应用程序或脚本。
  • 简化命令传递:与 CMD 不同,entrypoint 设置的是固定的执行命令,而 CMD 可以被 docker run 命令行参数覆盖。通常,entrypoint 定义了可执行文件,而 CMD 提供该可执行文件的默认参数。
  • 预处理和环境设置:可以用来运行一些初始化脚本或进行必要的环境配置,然后再启动主应用程序。
  • 容器角色:区分可执行容器(如CLI工具)与服务容器(如Web服务器)

使用方法

entrypoint 可以接受两种形式的值:字符串(shell 形式)或数组(exec 形式)。推荐使用数组形式,因为它避免了 shell 的额外处理(如变量替换等),提供了更精确的控制。

1. 字符串格式(自动包装为 /bin/sh -c

services:
  myapp:
    entrypoint: /app/start.sh --debug
    entrypoint: "/bin/echo Hello, world"

2. 列表格式(推荐,直接执行)

services:
  web:
    build: .
    entrypoint: /docker-entrypoint.sh  # 初始化脚本
    command: ["nginx", "-g", "daemon off;"]
  redis:
    image: redis
    entrypoint: ["redis-server", "--appendonly", "yes"]  # 覆盖默认入口点
  myapp:
    entrypoint:
      - /app/start.sh
      - "--debug"
    entrypoint: ["/bin/echo", "Hello, world"]
  debug:
    image: node
    entrypoint: ["sleep"]  # 调试容器
    command: ["infinity"]  # 保持容器运行

3.结合 CMD 使用
entrypoint 和 cmd 经常一起使用。entrypoint 定义了要执行的命令,而 cmd 提供了该命令的默认参数。如果只定义了 entrypoint 而没有 cmd,则 entrypoint 后面不需要参数;如果有 cmd,则它的值会被作为 entrypoint 命令的参数。

version: '3.8'
services:
  myservice:
    image: myimage
    entrypoint: ["/bin/echo"]
    cmd: ["Hello, world"]

这里,容器启动时将执行 /bin/echo "Hello, world"

实际应用案例

设你有一个基于 Nginx 的服务,并希望在容器启动前进行一些检查或配置调整,可以通过 entrypoint 来实现:

version: '3.8'
services:
  web:
    image: nginx
    entrypoint: ["/docker-entrypoint.sh"]
    cmd: ["nginx", "-g", "daemon off;"]

在这个例子中,/docker-entrypoint.sh 是一个自定义脚本,它可能包含了对环境变量的检查、日志清理等操作,之后再调用 nginx -g 'daemon off;' 来启动 Nginx 服务器。

高级用法

1. 多命令组合

entrypoint:
  - sh
  - -c
  - |
    echo "Initializing..."
    exec "$@"
  - placeholder  # 会被command替换
command: ["npm", "start"]

2. 环境变量扩展

entrypoint:
  - sh
  - -c
  - 'exec $$0 $$@'  # 使用shell变量
  - /app/main.sh

3. 与用户权限结合

entrypoint:
  - gosu
  - "1000:1000"
  - "/app/start.sh"

调试技巧

# 1、查看最终命令:
docker inspect --format='{{json .Config.Entrypoint}}' <container>
# 2、临时覆盖入口点:
docker-compose run --entrypoint bash myapp
# 3、日志检查:
docker-compose logs --tail=100 myapp

最佳实践

1、生产环境推荐

entrypoint:
  - /docker-entrypoint.sh  # 封装初始化逻辑
command:
  - nginx
  - -g
  - daemon off;

2、开发环境调试

entrypoint: ["sleep", "infinity"]  # 保持容器运行

3、多阶段初始化

# Dockerfile
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

# docker-compose.yml
command: ["--debug"]  # 作为参数传给entrypoint.sh

Tips:

YAML 多行字符串的标记符号的使用。

entrypoint:
  - sh
  - -c
  - |
    echo "Initializing..."
    exec "$@"
  - placeholder

这里的 | 表示:

  1. 保留换行符:竖线后的内容会按原样保留所有换行和缩进
  2. 多行文本块:允许在单个 YAML 字段中编写多行命令或脚本
  3. 末尾无换行:文本块最后一行如果没有空行,则不会添加额外换行符

对比其他 YAML 字符串标记

符号名称特点适用场景
``Literal Block保留所有换行和缩进脚本、配置文件
>Folded Block折叠换行为空格长段落文本
`-`Literal+Strip保留换行但删除末尾空行严格控制的脚本
>-Folded+Strip折叠换行并删除末尾空行紧凑文本

实际应用示例

1. 多行脚本(推荐用 |

command: |
  /bin/sh -c '
  echo "Starting app..."
  exec node server.js
  '

2. 长命令折叠(用 >

description: >
  This is a very long description
  that will be folded into a single
  line when parsed.

3. 严格控制的脚本(用 |-

entrypoint: |-
  #!/bin/sh
  set -e
  exec "$@"

注意

# 1、缩进规则:
- |  # 正确缩进
    Line 1
    Line 2
- |  # 错误!缩进不足
  Line 1
  Line 2
  
# 2、特殊字符转义:
- |
  echo "Hello \"World\""  # 需要转义引号
  
# 3、与 JSON 的兼容性:
// 等效JSON表示
{"command": "line1\nline2\n"}

调试技巧

# 1、验证 YAML 解析:
python -c 'import yaml, sys; print(yaml.safe_load(sys.stdin))' < docker-compose.yml

# 2、查看最终命令:
docker-compose config | grep -A 5 'entrypoint:'

4、常用设置

4.1 MySql 数据库

command: [
  'mysqld',                          # 主命令:启动MySQL服务器
  '--innodb-buffer-pool-size=80M',   # 设置InnoDB缓冲池大小为80MB
  '--character-set-server=utf8mb4',  # 设置默认字符集为utf8mb4
  '--character-set-server=utf8mb4',
  '--collation-server=utf8mb4_unicode_ci', # 设置默认排序规则
  '--collation-server=utf8mb4_general_ci',
  '--default-time-zone=+8:00',       # 设置默认时区为东八区(北京时间)
  '--explicit_defaults_for_timestamp=true',
  '--lower-case-table-names=1',       # 设置表名大小写不敏感(值为1)
  # 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
  '--default-authentication-plugin=mysql_native_password'
]
# 注意:上面设置,根据情况选择,一定不要全部写上

各参数详细说明:

  1. mysqld

    MySQL 服务器的可执行文件名,启动 MySQL 服务的主命令

  2. --innodb-buffer-pool-size=80M

    设置 InnoDB 存储引擎的缓冲池大小为 80MB;这是 MySQL 最重要的性能参数之一,影响缓存表数据和索引的内存大小;适用于内存受限的环境(如小规格容器);通常建议设为可用内存的50-70%;

  3. --character-set-server=utf8mb4

    设置服务器默认字符集为 utf8mb4,支持完整的 Unicode 字符(包括emoji表情),替代旧的 utf8 编码(只支持最多3字节字符)

  4. --collation-server=utf8mb4_unicode_ci

    设置默认排序规则为 utf8mb4_unicode_ci;影响字符串比较和排序行为;ci 表示大小写不敏感(case insensitive)

  5. --default-time-zone=+8:00

    设置数据库默认时区为 UTC+8(北京时间),影响 TIMESTAMP 类型字段的显示和存储,确保应用和数据库时区一致

  6. --lower-case-table-names=1

    设置表名大小写不敏感(值为1);Linux系统上默认区分大小写,设为1使行为与Windows一致,避免因大小写问题导致的查询错误

5、Docker Compose 安装

Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。

直接下载需要的版本即可,比如:docker-compose-linux-x86_64

然后修改名称:mv docker-compose-linux-x86_64 docker-compose

我们放在 /usr/local/bin 目录中。

将可执行权限应用于二进制文件:chmod +x /usr/local/bin/docker-compose

创建软链:ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

测试是否安装成功:

$ docker-compose version
docker-compose version 1.24.1, build 4667896b

6、Docker Compose 常用服务例子

6.1、Java服务

version: "3.8"
services: 
  java-api-server: 
    container_name: my-java-server-name
    image: openjdk:8-jdk
    restart: always
    privileged: true
    ports:
      - "8080:8080"
    volumes:
      - ./app:/home/data  # 工作目录,这里是存放我的jar包
      - ./files:/home/file  # 附件目录,上传我的附件目录
    working_dir: /home/data
    depends_on:
      - redis
    environment:
      TZ: Asia/Shanghai
    command: java -jar app.jar

6.2、Redis 服务

version: "3.8"
services: 
  redis:
    container_name: redis
    image: redis:7.0.0
    restart: always
    privileged: true
    ports:
      - "6379:6379"
    volumes:
      - ./redis:/data
    command: redis-server redis.conf
 # 工作目录和数据目录默认都是 /data
 # 此处没写工作目录,默认的工作目录是/data,所以上述的 redis.conf 也是在 /data 目录下。

redis.conf 配置文件:

# 配置密码
requirepass 123456
# 控制当后台持久化(BGSAVE)失败时 Redis 是否拒绝写入操作,默认yes,拒绝写入直到下一次成功备份
stop-writes-on-bgsave-error no  

6.3、MySql 服务

version: "3.8"
services: 
  mysql:
    container_name: mysql
    image: mysql:8.0.32
    restart: always
    privileged: true
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/var/log
      - ./mysql/data:/var/lib/mysql
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: xxxxx

./mysql/conf/my.conf 文件参考:

[client]
user="root"
password="123456"
port=3306
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4  # 设置mysql客户端默认字符集

[mysqld]
port=3306
max_connections=1000
max_connect_errors=10  # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_allowed_packet=512M  # 允许最大数据包大小
default-storage-engine=INNODB  # 创建新表时将使用的默认存储引擎
interactive_timeout=1800  # MySQL连接闲置超过一定时间后(单位:秒)将会被强行关闭
wait_timeout=1800  # MySQL默认的wait_timeout  值为8个小时, interactive_timeout参数需要同时配置才能生效
# Metadata Lock最大时长(秒), 一般用于控制 alter操作的最大时长sine mysql5.6
# 执行 DML操作时除了增加innodb事务锁外还增加Metadata Lock,其他alter(DDL)session将阻塞
lock_wait_timeout=3600
# 设置分组模式
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
init_connect='SET collation_connection = utf8mb4_general_ci'  # 设置全局聚合方式
init_connect='SET NAMES utf8mb4'
authentication_policy=mysql_native_password  # 设置密码验证规则
character-set-server=utf8mb4  # 服务端使用的字符集默认为UTF8
collation-server=utf8mb4_general_ci
default-time-zone='+08:00'  # 设置默认时区
activate_all_roles_on_login=ON  # 设置开启默认角色
# plugin-load-add=validate_password.so  # 配置密码复杂度策略
# validate-password=FORCE_PLUS_PERMANENT
# validate_password_length=8
# validate_password_policy=MEDIUM
# validate_password_check_user_name=ON
# default_password_lifetime=3  # 配置密码过期策略
# password_history=6
# password_reuse_interval=365
# plugin-load-add=connection_control.so  # 配置登录失败次数限制
# connection-control=FORCE_PLUS_PERMANENT
# connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT
# connection-control-failed-connections-threshold=5
# connection-control-min-connection-delay=60000
# require_secure_transport=ON  # 使用SSL加密连接

[mysqldump]
# user="root"
# password="123456"

6.4、Nginx 服务

version: "3.8"
services: 
  nginx:
    container_name: nginx
    image: nginx:latest
    restart: always
    privileged: true
    ports:
      - "80:80"
    volumes:
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/log:/var/log/nginx
      - ./nginx/html:/usr/share/nginx/html
      - ./files:/home/data/files  # 静态资源代理

完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 如何使用Timeline预览、播放特效

在使用unity制作和拟合动画时&#xff0c;我们常用到Timeline&#xff0c;前后拖动滑轨&#xff0c;预览动画正放倒放非常方便。如果我们想对特效也进行这个操作&#xff0c;可以使用下文的步骤。 至此&#xff0c;恭喜你又解锁了一个新的技巧。如果我的分享对你有帮助&#xf…

MySQL篇-其他面试题

MySQL事务 问题&#xff1a;事务是什么&#xff1f;ACID问题 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 1、事务…

iOS 蓝牙开发中的 BT 与 BLE

在 iOS 开发者的语境里&#xff0c;大家把 BT 和 BLE 当成两种不同的蓝牙技术在谈——它们来自同一个 Bluetooth 规范&#xff0c;但面向的场景、协议栈乃至 Apple 提供的 API 都截然不同。 缩写全称 / 技术名称规范层叫法iOS 支持现状典型用途BTBluetooth Classic&#xff08…

鸿蒙Flutter实战:21-混合开发详解-1-概述

引言 在前面的系列文章中&#xff0c;我们从搭建开发环境开始&#xff0c;讲到如何使用、集成第三方插件&#xff0c;如何将现有项目进行鸿蒙化改造&#xff0c;以及上架审核等内容&#xff1b;还以高德地图的 HarmonyOS SDK 的使用为例&#xff0c; 讲解了如何将高德地图集成…

[架构之美]从PDMan一键生成数据库设计文档:Word导出全流程详解(二十)

[架构之美]从PDMan一键生成数据库设计文档&#xff1a;Word导出全流程详解&#xff08;二十&#xff09; 一、痛点 你是否经历过这些场景&#xff1f; 数据库字段频繁变更&#xff0c;维护文档耗时费力用Excel维护表结构&#xff0c;版本混乱难以追溯手动编写Word文档&#…

大量程粗糙度轮廓仪适用于哪些材质和表面?

大量程粗糙度轮廓仪是一种能够在广泛的测量范围内对工件表面进行粗糙度分析的精密仪器。它通常采用接触式或非接触式传感器&#xff0c;通过对工件表面的扫描&#xff0c;捕捉表面微观的起伏和波动&#xff0c;从而获取粗糙度数据。该仪器不仅能测量微小的表面细节&#xff0c;…

Unity-编辑器扩展

之前我们关于Unity的讨论都是针对于Unity底层的内容或者是代码层面的东西&#xff0c;这一次我们来专门研究Unity可视化的编辑器&#xff0c;在已有的基础上做一些扩展。 基本功能 首先我们来认识三个文件夹&#xff1a; Editor&#xff0c;Gizmos&#xff0c;Editor Defaul…

Lucide:一款精美的开源矢量图标库,前端图标新选择

名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、前言&#xff1a;为何选择 Lucide&#xff1f;二、Lucide 是什么&#xff1f;1.…

Mac如何允许安装任何来源软件?

打开系统偏好设置-安全性与隐私&#xff0c;点击右下角的解锁按钮&#xff0c;选择允许从任何来源。 如果没有这一选项&#xff0c;请到打开终端&#xff0c;输入命令行&#xff1a;sudo spctl --master-disable, 输入命令后回车&#xff0c;输入电脑的开机密码后回车。 返回“…

2025最新版Visual Studio Code for Mac安装使用指南

2025最新版Visual Studio Code for Mac安装使用指南 Installation and Application Guide to The Latest Version of Visual Studio Code in 2025 By JacksonML 1. 什么是Visual Studio Code&#xff1f; Visual Studio Code&#xff0c;通常被称为 VS Code&#xff0c;是由…

【嵙大o】C++作业合集

​ 参考&#xff1a; C swap&#xff08;交换&#xff09;函数 指针/引用/C自带-CSDN博客 Problem IDTitleCPP指针CPP引用1107 Problem A编写函数&#xff1a;Swap (I) (Append Code)1158 Problem B整型数据的输出格式1163 Problem C时间&#xff1a;24小时制转12小时制1205…

C++23 范围迭代器作为非范围算法的输入 (P2408R5)

文章目录 一、引言二、C23及范围迭代器的背景知识2.1 C23概述2.2 范围迭代器的概念 三、P2408R5提案的内容3.1 提案背景3.2 提案内容 四、范围迭代器作为非范围算法输入的优势4.1 代码简洁性4.2 提高开发效率4.3 更好的兼容性 五、具体的代码示例5.1 使用范围迭代器进行并行计算…

2025.05.20【Treemap】树图数据可视化技巧

Multi-level treemap How to build a treemap with group and subgroups. Customization Customize treemap labels, borders, color palette and more 文章目录 Multi-level treemapCustomization Treemap 数据可视化技巧什么是 TreemapTreemap 的应用场景如何在 R 中绘制 T…

深入了解Springboot框架的启动流程

目录 1、介绍 2、执行流程 1、运行run方法 2、初始化SpringApplication对象 1、确定容器类型 3、加载所有的初始化器 4、加载Spring上下文监听器 5、设置程序运行的主类 3、进入run方法 1、开启计时器 2、Headless模式配置 3、获取并启用监听器 4、准备环境 1、设…

LLaMA-Factory微调LLM-Research/Llama-3.2-3B-Instruct模型

1、GPU环境 nvidia-smi 2、pyhton环境安装 git clone https://github.com/hiyouga/LLaMA-Factory.git conda create -n llama_factory python3.10 conda activate llama_factory cd LLaMA-Factory pip install -e .[torch,metrics] 3、微调模型下载&#xff08;LLM-Research/…

3.8.1 利用RDD实现词频统计

在本次实战中&#xff0c;我们通过Spark的RDD实现了词频统计功能。首先&#xff0c;准备了包含单词的文件并上传至HDFS。接着&#xff0c;采用交互式方式逐步完成词频统计&#xff0c;包括创建RDD、单词拆分、映射为二元组、按键归约以及排序等操作。此外&#xff0c;还通过创建…

Spring Ioc和Aop,Aop的原理和实现案例,JoinPoint,@Aspect,@Before,@AfterReturning

DAY25.2 Java核心基础 Spring两大核心&#xff1a;Ioc和Aop IOC Ioc容器&#xff1a;装载bean的容器&#xff0c;自动创建bean 三种方式&#xff1a; 1、基于xml配置&#xff1a;通过在xml里面配置bean&#xff0c;然后通过反射机制创建bean&#xff0c;存入进Ioc容器中 …

[解决conda创建新的虚拟环境没用python的问题]

问题复现 使用conda create -n env的时候&#xff0c;在对应的虚拟环境的文件里面找不到对应的python文件 为什么 首先&#xff0c;我们来看一下创建环境时的触发链路&#xff1a; 这表明当前环境中找不到Python可执行文件。 解决方法 所以很明显&#xff0c;我们需要指定…

【C++】控制台小游戏

移动&#xff1a;W向上&#xff0c;S上下&#xff0c;A向左&#xff0c;D向右 程序代码&#xff1a; #include <iostream> #include <conio.h> #include <windows.h> using namespace std;bool gameOver; const int width 20; const int height 17; int …

配合本专栏前端文章对应的后端文章——从模拟到展示:一步步搭建传感器数据交互系统

对应文章&#xff1a;进一步完善前端框架搭建及vue-konva依赖的使用&#xff08;Vscode&#xff09;-CSDN博客 目录 一、后端开发 1.模拟传感器数据 2.前端页面呈现数据后端互通 2.1更新模拟传感器数据程序&#xff08;多次请求&#xff09; 2.2&#x1f9e9; 功能目标 …