1.docker的安装

1.1 环境准备

  • 操作系统:CentOS Linux release 7.9.2009 (Core)

  • Docker版本

    • Docker-ce Docker社区版,主要用于个人开发者测试使用,免费版本

    • Docker-ee Docker企业版,主要用于为企业开发及应用部署使用,收费版本,免费试用一个月。

  • 这里主要安装Docker-ce社区版

1.2 系统更新依赖准备

  • 更新软件源

    sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    
  • 系统更新一下

    sudo yum update -y
    
  • 安装docker需要的依赖

    sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    
  • 使用阿里镜像源
    阿里巴巴镜像站:Docker CE镜像-Docker CE镜像下载安装-开源镜像站-阿里云

    # step 1: 安装必要的一些系统工具
    sudo yum install -y yum-utils
    
    # Step 2: 添加软件源信息
    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    # Step 3: 安装Docker
    sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    # Step 4: 开启Docker服务
    sudo service docker start
    
    # 注意:
    # 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
    # vim /etc/yum.repos.d/docker-ce.repo
    #   将[docker-ce-test]下方的enabled=0修改为enabled=1
    #
    # 安装指定版本的Docker-CE:
    # Step 1: 查找Docker-CE的版本:
    # yum list docker-ce.x86_64 --showduplicates | sort -r
    #   Loading mirror speeds from cached hostfile
    #   Loaded plugins: branch, fastestmirror, langpacks
    #   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
    #   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
    #   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
    #   Available Packages
    # Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
    # sudo yum -y install docker-ce-[VERSION]
    
    

1.3 安装Docker ce社区版本

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

1.3.1 启动Docker并设置开机自启

systemctl enable --now docker

查看状态

systemctl status docker

1.4 配置docker加速

由于无法pull到Docker官方的镜像文件 https://hub.docker.com/,

我这里使用的是

1.轩辕镜像 https://docker.xuanyuan.me/

使用教程 Docker 镜像访问与配置教程 | 登录方式配置指南 - 轩辕镜像 ,具体请自行查看,教程,这里不做太多介绍

  1. 毫秒镜像 https://1ms.run/ 具体教程查看毫秒镜像文档 https://mdoc.cc/mliev/1ms/v1.0.0/10

1.5 安装DPanel社区版来可视化管理及操作docker

  • lite 版
    docker run --privileged -d --name dpanel --restart=always \
     -p 8807:8080 -e APP_NAME=dpanel \
     -v /var/run/docker.sock:/var/run/docker.sock \
     -v /home/dpanel:/dpanel registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:lite
    
    
  • 标准版
    docker run -d --name dpanel --restart=always \
     -p 80:80 -p 443:443 -p 8807:8080 -e APP_NAME=dpanel \
     -v /var/run/docker.sock:/var/run/docker.sock \
     -v /home/dpanel:/dpanel registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:latest 
    
    

一般安装 lite 版 即可,安装成功即可通过ip:8807端口访问到管理页面 教程:https://github.com/donknap/dpanel

docker、DPanel一件安装脚本教程 使用安装脚本

2. docker 指令

2.1 镜像常用的指令

2.1.1 搜索镜像

docker search 轩辕域名/镜像名

docker search docker.xuanyuan.run/nginx

2.1.2 拉起镜像

docker pull docker.xuanyuan.run/镜像名:标签

docker pull docker.xuanyuan.run/library/nginx:latest

2.1.3 统计常用命令

  • 常用命令

    命令说明常用参数示例输出示例/说明
    docker images列出本地镜像-a 所有镜像
    -q 只显示ID
    --digests 显示摘要
    --format 自定义格式
    --no-trunc 不截断ID
    docker images
    docker images -a
    docker images ubuntu:20.04
    docker images --format "table {{.ID}}\t{{.Repository}}"
    REPOSITORY TAG IMAGE ID CREATED SIZE
    docker search搜索Docker Hub镜像--limit N 限制结果
    --filter is-official=true 官方镜像
    --filter stars=N 星数过滤
    --no-trunc 完整描述
    docker search nginx
    docker search --limit 5 redis
    docker search --filter is-official=true mysql
    NAME DESCRIPTION STARS OFFICIAL
    docker pull拉取镜像到本地-a 所有标签
    --platform 指定平台
    --quiet 安静模式
    docker pull ubuntu:20.04
    docker pull nginx:alpine
    docker pull --platform linux/arm64 mysql
    20.04: Pulling from library/ubuntu...
    docker build构建镜像-t 指定标签
    -f 指定Dockerfile
    --no-cache 禁用缓存
    --build-arg 构建参数
    --target 多阶段构建目标
    docker build -t myapp:v1 .
    docker build -f Dockerfile.prod .
    docker build --build-arg VERSION=1.0 .
    Successfully built abc123...
    Successfully tagged myapp:v1
    docker tag给镜像打标签(无主要参数)docker tag myapp:v1 myapp:latest
    docker tag abc123 registry.com/myapp:v1
    docker tag oldname:tag newname:tag
    无输出,标签已添加
    docker push推送镜像到仓库--disable-content-trust 跳过验证docker push myapp:v1
    docker push registry.com/myapp:v1
    docker push --disable-content-trust myapp
    The push refers to repository...
    docker rmi删除本地镜像-f 强制删除
    --no-prune 保留父层
    docker rmi myapp:v1
    docker rmi -f abc123
    docker rmi $(docker images -q)
    Untagged: myapp:v1
    Deleted: sha256:abc123...
    docker save保存镜像为tar文件-o 输出文件docker save -o myimage.tar ubuntu:20.04
    docker save ubuntu:20.04 > ubuntu.tar
    docker save -o all.tar img1 img2
    创建.tar文件,无控制台输出
    docker load从tar文件加载镜像-i 输入文件
    -q 安静模式
    docker load -i myimage.tar
    docker load < ubuntu.tar
    docker load -i all.tar
    Loaded image: ubuntu:20.04
    docker history查看镜像构建历史--no-trunc 不截断
    -H 可读格式
    -q 只显示层ID
    --format 自定义格式
    docker history ubuntu:20.04
    docker history --no-trunc nginx
    docker history --format "{{.ID}} {{.CreatedBy}}"
    IMAGE CREATED CREATED BY SIZE
    docker inspect查看镜像详细信息--format 格式化输出
    -f 同–format
    docker inspect ubuntu:20.04
    docker inspect --format='{{.Id}}' nginx
    docker inspect -f '{{json .Config}}' mysql
    JSON格式的详细配置信息
    docker image prune清理未使用的镜像-a 删除所有未使用
    -f 强制不确认
    --filter 过滤条件
    docker image prune
    docker image prune -a
    docker image prune -a -f
    docker image prune --filter "until=24h"
    Deleted Images: ...
    Total reclaimed space: 1.2GB
    docker commit从容器创建镜像-a 作者
    -m 提交信息
    -p 暂停容器
    docker commit mycontainer myimage:v1
    docker commit -a "john" -m "更新配置" container1
    docker commit -p running_container new_image
    sha256:abc123...
    docker import从归档创建镜像-c 应用Dockerfile指令
    -m 提交信息
    docker import ubuntu.tar myubuntu
    docker import -c "CMD /bin/bash" rootfs.tar
    cat ubuntu.tar | docker import - myimported
    sha256:def456...
    docker image lsimages命令的别名docker imagesdocker image ls
    docker image ls -a
    docker images
    docker image rmrmi命令的别名docker rmidocker image rm ubuntu:18.04
    docker image rm -f abc123
    docker rmi
    docker image tagtag命令的别名docker tagdocker image tag old newdocker tag
    docker image pushpush命令的别名docker pushdocker image push myrepo/myappdocker push
    docker image pullpull命令的别名docker pulldocker image pull nginxdocker pull
    docker image buildbuild命令的别名docker builddocker image build -t myapp .docker build
    docker image historyhistory命令的别名docker historydocker image history myappdocker history
    docker image inspectinspect命令的别名docker inspectdocker image inspect ubuntudocker inspect
  • 镜像管理常用组合命令

    用途组合命令示例说明
    批量删除镜像docker rmi $(docker images -q)删除所有本地镜像
    批量删除未标签镜像docker rmi $(docker images -f "dangling=true" -q)删除 标签镜像
    清理所有未使用docker system prune -a清理镜像、容器、网络等
    按时间过滤删除docker image prune --filter "until=24h"删除24小时前的未使用镜像
    查看镜像依赖docker image inspect --format='{{.RootFS.Layers}}' IMAGE查看镜像层依赖
    统计镜像大小docker system df查看Docker磁盘使用情况
    导出多个镜像docker save -o all.tar image1 image2 image3打包多个镜像到一个文件
    导入并重命名docker load -i my.tar && docker tag OLDID newname:tag加载后重新打标签
    查看镜像环境变量docker inspect --format='{{range .Config.Env}}{{.}}{{"\n"}}{{end}}' IMAGE查看镜像预设的环境变量
  • 镜像过滤和格式化示例

    过滤类型命令示例说明
    按仓库过滤docker images "ubuntu*"显示ubuntu开头的镜像
    按标签过滤docker images --filter "reference=*:latest"显示latest标签的镜像
    悬空镜像docker images --filter "dangling=true"显示未被任何容器引用的中间层镜像
    创建时间前docker images --filter "before=ubuntu:20.04"显示在ubuntu:20.04之前创建的镜像
    创建时间后docker images --filter "since=nginx:alpine"显示在nginx:alpine之后创建的镜像
    格式化输出docker images --format "{{.Repository}}:{{.Tag}} ({{.Size}})"自定义显示格式
    表格格式化docker images --format "table {{.ID}}\t{{.Repository}}\t{{.CreatedSince}}"表格形式显示
  • 高级镜像操作

    操作命令示例说明
    查看镜像层docker history --no-trunc IMAGE查看完整构建历史
    导出镜像文件系统docker export CONTAINER > fs.tar导出容器文件系统(非镜像格式)
    多架构镜像docker pull --platform linux/arm64 IMAGE拉取特定架构的镜像
    镜像签名验证docker trust inspect IMAGE查看镜像签名信息
    构建缓存管理docker builder prune清理构建缓存
    查看镜像元数据docker image inspect --format='{{json .Config}}' IMAGE查看镜像配置信息

2.1.4 查看镜像

docker images -a

2.1.5 删除镜像

docker rmi 镜像名称或者镜像ID

2.2 容器的常用指令

2.2.1 创建并运行一个容器

docker run 镜像ID 或者 镜像名称
  • 以后台的方式创建并运行 -d

    docker run -d 镜像ID 或者 镜像名称
    
  • 指定容器名称 --name

    docker run -d --name 别名(指定容器名称) 镜像ID 或者 镜像名称
    
  • 指定端口映射 -p

    docker run -d --name 别名(指定容器名称)-p 80:80 -p 443:443 镜像ID 或者 镜像名称
    
  • 重启策略 --restart

    # 1.no  默认策略 容器不会自动重启,无论退出状态如何
    docker run --restart=no 容器ID 或 容器名称
    
    # 2. always 容器退出时总是重启(无论退出码是什么)如果手动停止容器,重启策略会被忽略,直到docker守护进程重启或容器手动启动
    docker run --restart=always 容器ID 或 容器名称
    
    # 3. on-failure[:max-retries] 只有容器以非零退出码退出时才重启 容器正常退出(退出码0)或手动停止时不会重启
    # 可以指定最大重试次数
    # 失败时最多重启3次
    docker run --restart=on-failure:3 容器ID 或 容器名称p
    
  • 环境变量配置 -e

    # 启动 MySQL 并设置 root 密码
    docker run -d \
      --name mysql-container \
      -e MYSQL_ROOT_PASSWORD=root \
      mysql:8.0
    
    # 设置多个环境变量
    docker run -d \
      --name mysql-container \
      -e MYSQL_ROOT_PASSWORD=rootpass \
      -e MYSQL_DATABASE=mydb \
      -e MYSQL_USER=root \
      -e MYSQL_PASSWORD=root \
      mysql:8.0
    
    # 完整的 MySQL 环境变量示例
    docker run -d \
      --name mysql8 \
      -p 3306:3306 \
      -e MYSQL_ROOT_PASSWORD=SecurePass123! \
      -e MYSQL_DATABASE=app_db \
      -e MYSQL_USER=app_user \
      -e MYSQL_PASSWORD=UserPass456! \
      -e MYSQL_CHARSET=utf8mb4 \
      -e MYSQL_COLLATION=utf8mb4_unicode_ci \
      -e MYSQL_INITDB_SKIP_TZINFO=1 \
      -v mysql_data:/var/lib/mysql \
      mysql:8.0 \
      --character-set-server=utf8mb4 \
      --collation-server=utf8mb4_unicode_ci
    
  • 退出时删除 --rm

    docker run --rm --name 别名(指定容器名称) 镜像ID 或者 镜像名称
    
  • 限制容器资源 -m 限制内存 --cpus 限制cpu

    # 硬性内存限制(容器不能超过此值)
    docker run -d \
      --name memory-limited \
      -m 512m \  # 限制为 512MB
      redis:alpine
    
    # 设置内存和交换分区限制
    docker run -d \
      --name redis-prod \
      -m 1g \           # 内存限制 1GB
      --memory-swap 2g \ # 交换分区 2GB (内存+交换区)
      redis:6.2
    
    # 禁止使用交换分区
    docker run -d \
      --name no-swap \
      -m 256m \
      --memory-swap 256m \  # 与内存相同,表示禁用交换
      nginx:alpine
    
    # 限制容器最多使用 1.5 个 CPU 核心
    
    docker run -d  --name app  --cpus="1.5"  # 最多使用 1.5 个 CPU 核心 my-web-app
    
    # 限制使用 0.5 个 CPU 核心(半核)
    
    docker run -d  --name background-task  --cpus="0.5"  # 限制磁盘读取速度
    
    # 限制磁盘读写速度
    
    docker run -d  --name io-limited  --device-read-bps /dev/sda:10mb  # 读取限速 10MB/s --device-write-bps /dev/sda:5mb \ # 写入限速 5MB/s ubuntu dd if=/dev/zero of=test.img bs=1M count=1000
    
    # 限制 IOPS(每秒 I/O 操作次数)
    
    docker run -d  --name database  --device-read-iops /dev/sda:1000  # 1000 次读取/秒 --device-write-iops /dev/sda:500 \ # 500 次写入/秒 mysql:8.0 python:3.9 python data_processor.py
    
    
    
  • 容器启动时给与ROOT最高权限 --privileged

docker run -d  --name 别名(指定容器名称)--privileged 镜像ID 或者 镜像名称
  • 查看容器logs日志

    # 查看实时日志(持续输出)
    docker logs -f 容器名或ID
    
    # 示例
    docker logs -f 容器名或ID
    
    # 查看最近100行
    docker logs --tail 100 容器名
    
    # 查看最近30秒的日志
    docker logs --since 30s 容器名
    
    
    
  • 实时查看 nginx 日志

docker logs -f nginx-container
  • 查看最近错误日志
docker logs --tail 50 my-app | grep -i error
  • 查看今天的日志
docker logs --since="$(date +'%Y-%m-%d')" 容器名或ID
  • 进入容器内部
# 进入MySQL容器

docker exec -it mysql_db bash

# 进入Nginx容器查看配置

docker exec -it nginx sh

# 进入Redis容器执行命令

docker exec -it redis redis-cli
  • 挂载文件同步

    # 将宿主机目录挂载到容器
    docker run -v /宿主机目录:/容器目录 镜像名
    
    # 示例:挂载当前目录到容器/app
    docker run -v $(pwd):/app nginx
    挂载单个文件
    
    docker run -v /宿主机文件:/容器文件 镜像名
    
    # 示例:挂载配置文件
    
    docker run -v ./config.conf:/etc/nginx/nginx.conf nginx
    
    # 查看容器挂载情况
    
    docker inspect 容器名 | grep Mounts -A 10
    
    # 开发时挂载代码目录
    
    docker run -v ./src:/app/src my-app
    
    # 挂载配置文件
    
    docker run -v ./mysql.conf:/etc/mysql/my.cnf mysql
    
    # 挂载数据目录(数据持久化)
    
    docker run -v mysql_data:/var/lib/mysql m# 1. 挂载网站文件到Nginxdocker run -v ./html:/usr/share/nginx/html nginx
    
    # 2. 挂载Python代码
    
    docker run -v ./app.py:/app/app.py python:3.9 python /app/app.py
    
    
    
    
    • 记住要点:
    • -v 宿主机路径:容器路径 格式

    • 路径可以是绝对路径或相对路径

    • 修改宿主机文件,容器内自动同步

    • 容器内修改也会同步到宿主机

2.2.2 查看容器

# 查看运行的容器
docker ps

#查看全部容器(包含运行的和没有运行的)
docker ps -a

2.2.3 删除容器

docker rm -f 容器ID 或者 容器名称

2.2.4 停止容器

docker stop 容器ID 或者 容器名称

2.2.5 启动容器

docker start 容器ID 或者 容器名称

2.2.6 进入容器内部

docker exec -it 容器ID 或者 容器名称 bash

2.2.7 查看容器日志

# -f 实时跟踪
docker logs -f --tail 10 容器ID 或者 容器名称

2.2.8 复制文件到容器里面

# 把宿主机的当前目录下的test.txt文件 复制到 702容器 下 test123目录里面;702开源时容器ID或者容器名称
docker cp test.txt 702:/test123/

2.2.9 将容器的当前状态保存为新镜像

docker commit 702 702:v1.0

2.2.10 查看容器的详细配置和状态(JSON格式)

docker inspect 容器ID 或者 容器名称

2.2.11 实时显示所有容器的资源占用(CPU、内存)

docker stats

2.2.12 显示容器内运行的进程列表

docker top 容器ID 或者 容器名称

2.2.13 暂停/恢复容器内所有进程

# 恢复暂停的容器
docker pause 容器名称 | 容器ID


# 暂停容器
docker unpause 容器ID 或者 容器名称 

2.2.14 数据卷挂载

  • 查看容器挂载的数据卷

    docekr volume ls
    
  • 启动容器映射数据卷,把宿主机文件夹映射到容器文件夹 -v

    #  /nginx-html 代表宿主机目录 /usr/share/nginx/html 代表容器里面的目录
    docker run -d --name nginx01 -p 81:80 -v /nginx-html:/usr/share/nginx/html nginx的容器名称或者容器ID
    
  • 删除数据卷

    docker volume rm 数据卷名称
    

3. docker网络network

3.1 Docker 网络基础

3.1.1 Docker 网络类型

Docker 提供5种原生网络驱动:

网络类型说明适用场景
bridge默认网络,容器通过虚拟网桥连接单主机上的容器通信
host容器直接使用宿主机网络高性能网络需求
none无网络连接安全隔离场景
overlay多主机网络,用于Swarm集群跨主机容器通信
macvlan为容器分配MAC地址,使其像物理设备需要独立MAC地址的场景

3.1.2 查看网络信息

# 列出所有网络
docker network ls

# 查看网络详细信息
docker network inspect bridge

# 查看容器网络信息
docker inspect 容器名 | grep -A 20 "Networks"

3.2 网络使用详解

3.2.1 Bridge 网络(默认)

创建和使用

# 创建自定义bridge网络
docker network create my-bridge-network

# 运行容器并连接到网络
docker run -d --name web1 --network my-bridge-network nginx
docker run -d --name web2 --network my-bridge-network nginx

# 容器间可以通过容器名互相访问
docker exec web1 ping web2

# 将运行中的容器连接到网络
docker network connect my-bridge-network existing-container

# 从网络断开容器
docker network disconnect my-bridge-network container-name

配置自定义bridge

# 创建带自定义配置的bridge网络
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \
  --ip-range=172.20.240.0/20 \
  --gateway=172.20.240.1 \
  --label env=production \
  production-net

# 运行容器并指定IP
docker run -d \
  --name db \
  --network production-net \
  --ip 172.20.240.10 \
  mysql:8.0

3.2.2 Host 网络

# 使用宿主机网络
docker run -d \
  --name nginx-host \
  --network host \
  nginx

# 容器将直接使用宿主机的IP和端口
# 容器内监听80端口 = 宿主机80端口

3.2.3 None 网络

# 容器无网络连接
docker run -it \
  --name isolated \
  --network none \
  alpine sh

# 容器内无法访问网络
# ifconfig 只能看到lo接口

3.2.4 Macvlan 网络

# 创建macvlan网络
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  macvlan-net

# 运行容器
docker run -d \
  --name macvlan-container \
  --network macvlan-net \
  --ip=192.168.1.100 \
  nginx

# 容器将获得独立MAC地址,像物理设备一样存在于网络中

3.2.5 Overlay 网络(Swarm集群)

# 初始化Swarm集群
docker swarm init

# 创建overlay网络
docker network create \
  --driver overlay \
  --attachable \
  overlay-net

# 在Swarm服务中使用
docker service create \
  --name web \
  --network overlay-net \
  --replicas 3 \
  nginx

3.2.6 自定义模式(推荐)

  • 创建自定义网络

    # --driver bridge  驱动模式 桥接  --subnet 192.168.138.0/24 指定子网ip段     --geteway 192.168.138.1 指定网关   my_network 自网络名称
    docker network create --driver bridge --subnet 192.168.138.0/24 --gteway 192.168.138.1 my_network
    
  • 查看所有网络

    docker network ls
    
  • 指定容器运行时绑定自定义的网络

     #   --net my_network 指定自定义的网络名称
     docker run --rm -d --net my_network --name c2 centos ping 127.0.0.1
    
  • 容器时间网络链接

      docker exec -it ub1 ping ub2
    

3.3 容器网络连接与通信

3.3.1 容器间通信

# 通过容器名通信(需要同一网络)
docker run -d --name app --network my-net node-app
docker run -d --name db --network my-net mysql

# 在app容器中可以ping db
docker exec app ping db

# 通过别名通信
docker run -d \
  --name app \
  --network my-net \
  --network-alias myapp \
  node-app

3.3.2 端口映射

# 映射单个端口
docker run -d -p 8080:80 nginx

# 映射多个端口
docker run -d \
  -p 8080:80 \
  -p 8443:443 \
  nginx

# 指定主机IP
docker run -d -p 127.0.0.1:8080:80 nginx

# 随机端口映射
docker run -d -p 80 nginx
docker port 容器名  # 查看实际映射的端口

# 映射UDP端口
docker run -d -p 53:53/udp dns-server

3.3.3 DNS与域名解析

# 自定义DNS服务器
docker run -d \
  --dns 8.8.8.8 \
  --dns 114.114.114.114 \
  --dns-search example.com \
  nginx

# 查看容器DNS配置
docker exec 容器名 cat /etc/resolv.conf

3.4 跨容器之间网络通讯connect

1. 基本用法

# 先创建网络
docker network create my-network

# 运行容器(不指定网络)
docker run -d --name container1 nginx
docker run -d --name container2 redis

# 将容器连接到网络
docker network connect my-network container1
docker network connect my-network container2

# 验证连接
docker exec container1 ping container2
连接时指定 IP 地址
# 为容器指定静态 IP
docker network connect --ip 172.20.0.100 my-network container1
docker network connect --ip 172.20.0.101 my-network container2

2. 多个网络连接

容器可以同时连接到多个网络:

# 创建多个网络
docker network create frontend
docker network create backend

# 运行容器
docker run -d --name web nginx
docker run -d --name db redis

# 连接不同网络
docker network connect frontend web
docker network connect backend db

# 将 web 也连接到后端网络(跨网络访问)
docker network connect backend web

# 现在 web 可以访问 db
docker exec web ping db

3. 网络别名(Service Discovery)

为容器添加别名

# 连接时添加别名
docker network connect --alias api --alias service1 my-network container1
docker network connect --alias db --alias database my-network container2

# 现在可以通过多个别名访问
docker exec container1 ping api     # 访问 container1 自己
docker exec container1 ping db      # 访问 container2
docker exec container1 ping database # 同样访问 container2

4. Dockerfile

docker为我们提供一个可以构建自定义镜像的配置文件

4.1 基于一个现有的容器去构建一个新的镜像 commit

docker commit -a "作者" -m "新镜像的描述信息"  容器名称或者容器ID 镜像名称:tag

4.2 Dockerfile的常用指令

  • 指令不区分大小写,但惯例是全部大写以增加可读性。

  • 指令按从上到下的顺序执行

  • 每条指令都会在镜像中创建一个新的层

  • # 开头的行被视为注释。

4.2.1 指令详解(按常用度与功能分类)

1. 构建基础与上下文

FROM

  • 作用:指定基础镜像。所有 Dockerfile 都必须以 FROM 指令开始(除了 ARG 可能在其之前)。

  • 语法FROM <image>[:<tag>] [AS <name>]

  • 示例

    FROM ubuntu:22.04
    FROM node:18-alpine AS builder
    FROM nginx:latest
    
  • 说明:可以使用官方镜像、私有仓库镜像或之前构建的镜像。AS <name> 用于多阶段构建。

ARG

  • 作用:定义构建时的变量。仅在构建过程中有效,不会存在于最终镜像中。

  • 语法ARG <name>[=<default value>]

  • 示例

    ARG VERSION=latest
    FROM ubuntu:$VERSION
    ARG USERNAME=docker_user
    RUN echo "Building for $USERNAME"
    
  • 说明:可以在 docker build 命令中用 --build-arg <varname>=<value> 覆盖默认值。ARG 定义的变量在其定义后的阶段有效。

2. 镜像元数据与配置

LABEL

  • 作用:为镜像添加元数据标签,通常是键值对。

  • 语法LABEL <key>=<value> <key>=<value> ...

  • 示例

    LABEL version="1.0"
    LABEL description="This is a custom web app"
    LABEL maintainer="dev@example.com"
    # 或合并
    LABEL version="1.0" \
          description="My App" \
          maintainer="dev@example.com"
    
  • 说明:使用 docker inspect 可以查看镜像的标签信息。推荐将所有标签合并到一个指令中以减少镜像层数

EXPOSE

  • 作用声明容器在运行时监听的端口。这只是一个文档和提示,并不会自动打开端口

  • 语法EXPOSE <port> [<port>/<protocol>...]

  • 示例

    EXPOSE 80
    EXPOSE 443/tcp
    EXPOSE 3000 5000
    
  • 说明:实际端口映射需要在 docker run 时使用 -p-P 参数。

3. 构建过程与环境

ENV

  • 作用:设置环境变量,该变量在构建过程和最终容器运行时都有效。

  • 语法ENV <key>=<value> ...

  • 示例

    ENV NODE_ENV=production
    ENV APP_HOME=/usr/src/app \
        USER=appuser
    
  • 说明:在容器中可以通过 echo $NODE_ENV 访问。一个指令可以设置多个变量,但建议使用 \ 换行提高可读性。

WORKDIR

  • 作用:设置工作目录。如果目录不存在,会自动创建。相当于 cd 到这个目录。

  • 语法WORKDIR /path/to/workdir

  • 示例

    WORKDIR /app
    RUN pwd # 输出 /app
    WORKDIR src
    RUN pwd # 输出 /app/src
    
  • 说明推荐使用绝对路径。后续的 RUN, CMD, ENTRYPOINT, COPY, ADD 指令都会在此目录下执行。

RUN

  • 作用在构建过程中执行命令,并提交结果到新镜像层。常用于安装软件包、编译代码等。

  • 语法

    • Shell 格式RUN <command> (默认在 /bin/sh -c 下执行)

    • Exec 格式RUN ["executable", "param1", "param2"]

  • 示例

    # Shell 格式
    RUN apt-get update && apt-get install -y nginx
    RUN echo "Hello" > /tmp/hello.txt
    
    # Exec 格式
    RUN ["/bin/bash", "-c", "echo 'Hello'"]
    RUN ["apt-get", "install", "-y", "python3"]
    
  • 说明:为了减少镜像层数和大小,建议将多个命令用 && 连接放在一个 RUN 指令中,并记得清理 apt 缓存。

4. 文件操作

COPY

  • 作用:将构建上下文中的文件或目录复制到镜像内的指定路径。

  • 语法

    • COPY [--chown=<user>:<group>] <src>... <dest>

    • COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (路径包含空格时使用)

  • 示例

    COPY package.json /app/
    COPY ./src /app/src
    COPY --chown=node:node . /home/node/app
    COPY hom* /mydir/ # 通配符复制
    
  • 说明<src> 路径是相对于构建上下文的。<dest> 可以是绝对路径,也可以是相对于 WORKDIR 的相对路径。

ADD

  • 作用:与 COPY 类似,但功能更多。除了复制,<src> 可以是 URL,或者本地的 tar 压缩文件(会自动解压到目标路径)。

  • 语法ADD [--chown=<user>:<group>] <src>... <dest>

  • 示例

    ADD https://example.com/file.tar.gz /tmp/ # 从URL下载
    ADD app.tar.gz /app/ # 自动解压
    
  • 说明除非确实需要自动解压或从 URL 下载,否则官方推荐优先使用 COPY,因为 COPY 行为更明确、简单。

5. 容器启动与执行

CMD

  • 作用:为容器提供默认的启动命令。一个 Dockerfile 中只能有一个 CMD,如果多个则只有最后一个生效。

  • 语法

    • Exec 格式(推荐)CMD ["executable","param1","param2"]

    • Shell 格式CMD command param1 param2

    • 作为 ENTRYPOINT 的参数CMD ["param1","param2"]

  • 示例

    # Exec 格式
    CMD ["nginx", "-g", "daemon off;"]
    
    # Shell 格式
    CMD nginx -g 'daemon off;'
    
    # 配合 ENTRYPOINT
    ENTRYPOINT ["echo"]
    CMD ["Hello, Docker!"]
    
  • 说明docker run 时如果指定了命令,会覆盖 CMDCMD 的主要目的是定义容器启动时的默认行为。

ENTRYPOINT

  • 作用:配置容器启动时执行的核心命令,让容器以固定应用或工具的方式运行。

  • 语法

    • Exec 格式(推荐)ENTRYPOINT ["executable", "param1", "param2"]

    • Shell 格式ENTRYPOINT command param1 param2

  • 示例

    ENTRYPOINT ["top", "-b"]
    # 运行容器时: docker run myimage -c 5 (这里的 -c 5 会作为参数传给 top)
    
  • 说明

    • docker run 的命令行参数会追加ENTRYPOINT (Exec 格式) 之后。

    • docker run --entrypoint 可以覆盖 ENTRYPOINT

    • ENTRYPOINT + CMD 模式ENTRYPOINT 定义固定命令,CMD 定义默认参数。运行时参数会覆盖 CMD

USER

  • 作用:指定后续指令 (RUN, CMD, ENTRYPOINT) 以哪个用户身份执行。

  • 语法USER <user>[:<group>]USER <UID>[:<GID>]

  • 示例

    RUN groupadd -r appuser && useradd -r -g appuser appuser
    USER appuser
    CMD ["node", "app.js"]
    
  • 说明:为了安全,避免使用 root 用户运行应用。应该先创建用户/组,然后用 USER 切换。

6. 其他指令

VOLUME

  • 作用:创建一个挂载点,用于持久化数据和与宿主机共享。即使容器被删除,该卷中的数据也会保留

  • 语法VOLUME ["/data"]VOLUME /data /config

  • 示例

    VOLUME /var/lib/mysql
    VOLUME ["/app/data", "/app/config"]
    
  • 说明:在 docker run 时,如果没有指定 -v 绑定挂载,Docker 会自动创建一个匿名卷。

HEALTHCHECK

  • 作用:告诉 Docker 如何测试容器是否仍在正常工作。

  • 语法

    • HEALTHCHECK [OPTIONS] CMD command (在容器内运行命令检查健康)

    • HEALTHCHECK NONE (禁用任何基础镜像的健康检查)

  • 示例

    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
      CMD curl -f http://localhost/ || exit 1
    
  • 说明:选项包括 --interval, --timeout, --start-period, --retries。命令退出码为 0 表示健康,1 表示不健康。

ONBUILD

  • 作用:设置一个“触发器”指令,当当前镜像被用作其他镜像的基础镜像时,这些指令会在下游镜像的构建过程中执行。

  • 语法ONBUILD <其他指令>

  • 示例

    # 基础镜像的 Dockerfile
    ONBUILD COPY . /app/src
    ONBUILD RUN make /app/src
    
    # 子镜像的构建会自动执行上述 ONBUILD 指令
    
  • 说明:常用于创建“构建器”镜像或模板化镜像。

指令一句话核心作用关键注意点
FROM指定基础镜像必须是第一条(除 ARG 外)。
ARG定义构建变量仅构建期有效,可被 --build-arg 覆盖。
LABEL添加元数据建议合并以减少层数。
ENV设置环境变量构建期和运行期都有效。
WORKDIR设置工作目录推荐绝对路径,自动创建。
RUN构建时执行命令合并命令,清理缓存以减少镜像大小。
COPY复制文件(推荐)从构建上下文复制到镜像。
ADD复制+解压+下载功能多但行为复杂,无特殊需求用 COPY
USER切换用户提升安全性,避免 root 运行。
EXPOSE声明端口仅是文档,实际映射需 docker run -p
VOLUME定义匿名数据卷数据持久化。
CMD容器默认启动命令可被 docker run 的命令覆盖。
ENTRYPOINT容器核心启动命令定义容器的“身份”,与 CMD 配合使用。

构建命令

# 在 Dockerfile 所在目录执行
docker build -t my-image:tag .

# 指定 Dockerfile 路径
docker build -f /path/to/Dockerfile .

# 使用构建参数
docker build --build-arg VERSION=2.0 -t my-image .

示例文件

# 1. 先指定当前镜像的基础镜像是什么
FROM openjdk:8

# 2. 描述这个镜像的作者以及联系方式(可选)
MAINTAINER progincc<progincc@gmail.com>

# 3.镜像的标签信息(可选)
LABEL version="1.0"
LABEL description="这是一个描述信息"

# 4. 环境变量配置
# 方式一
ENV JAVA_ENV dev

#方式二
ENV JAVA_ENV=dev APP_NAME=test-dockerfile 

# 5.在构建镜像的时候,需要执行shell命令
RUN ls -al
RUN mkdir /www/test

# 6.将主机中的指定文件复制到容器的目标位置,可简单的理解为 cp 命令
# ADD /www/dockerfile/index.html /www/server
ADD ["/www/dockerfile/index.html","/www/server"]

# 7. 设置容器中的工作目录,如果改目录不存在,那么会自行创建
WORKDIR /app
# 在设置玩工作目录后,执行pwd 命令,打印的目录就是 /app
RUN pwd

# 8.镜像数据卷绑定,将主机中的指定目录挂载到容器中
VOLUME /var/lib/mysql
VOLUME ["/app/data", "/app/config"]
VOLUME ["/www/dockerfile","/app"]

# 9. 设置容器启动后要暴露的端口
EXPOSE 8080/tcp
EXPOSE 8181/udp

# 10. CMD和ENTRYPOINT 选择其一即可,作用是描述镜像构建完成后,启动容器时默认执行的脚本
# CMD ping 127.0.0.1
CMD ["sh","-c","ping 127.0.0.1"]

# 11.ENTRYPOINT 
#ENTRYPOINT ping 127.0.0.1
ENTRYPOINT ["sh","-c","ping 127.0.0.1"]

5. 仓库Registry

5.1 搭建私有的仓库Registry

安装使用Harbor
# 下载离线安装包(推荐离线安装)
wget https://github.com/goharbor/harbor/releases/download/v2.8.0/harbor-offline-installer-v2.8.0.tgz

# 解压
tar xzvf harbor-offline-installer-v2.8.0.tgz
cd harbor

# 复制配置文件并修改
cp harbor.yml.tmpl harbor.yml

# 修改配置(最少需要修改 hostname 和端口)
vi harbor.yml
# hostname: reg.yourdomain.com  # 改为您的域名或IP
# http:
#   port: 80  # HTTP 端口
# https:
#   port: 443  # HTTPS 端口
#   certificate: /your/cert/path
#   private_key: /your/key/path

# 安装
sudo ./install.sh --with-trivy --with-chartmuseum

# 访问地址:http://your-ip
# 默认账号:admin / Harbor12345

6.容器编排

容器编排 是自动化管理容器化应用程序的部署、扩展、网络连接和生命周期的过程。当你有成百上千个容器需要协同工作时,手动管理几乎不可能,编排工具就是为此而生。

类比理解:如果把单个容器比作“货船上的集装箱”,那么容器编排就是“整个港口的调度系统”,它决定:

  • 哪些集装箱放哪里

  • 如何连接它们

  • 如何确保足够的资源

  • 故障时如何自动恢复

  • 主流编排工具

    1. Kubernetes(最流行,占主导地位)

    2. Docker Swarm(Docker原生,简单易用)

    3. Apache Mesos(更通用,支持多种工作负载)

6.1 容器编排是如何运行的?

┌─────────────────────────────────────────┐
│           控制平面(Control Plane)       │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐    │
│  │  API    │ │调度器   │ │控制器   │    │
│  │ Server  │ │Scheduler│ │Controller│   │
│  └─────────┘ └─────────┘ └─────────┘    │
└─────────────────┬─────────────────────────┘
                  │
┌─────────────────▼─────────────────────────┐
│           工作节点(Worker Nodes)         │
│  ┌─────────────────────────────────────┐  │
│  │ 节点1:Kubelet + 容器运行时 + Pod    │  │
│  └─────────────────────────────────────┘  │
│  ┌─────────────────────────────────────┐  │
│  │ 节点2:Kubelet + 容器运行时 + Pod    │  │
│  └─────────────────────────────────────┘  │
└─────────────────────────────────────────┘

6.2 运行流程

  1. 声明式配置:你提交一个YAML文件,描述应用的期望状态

  2. 控制平面监控:编排系统持续比较当前状态与期望状态

  3. 调度决策:调度器选择最合适的节点运行容器

  4. 执行部署:在对应节点拉取镜像、创建容器

  5. 持续保障:如果容器故障,自动重新调度

6.3 docker comopose(单机)容器编排

6.3 安装docker compose

使用官方脚本(推荐)

# 下载最新版本(兼容 x86_64/arm64)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 或者指定版本(如 2.20.0)
sudo curl -L "https://github.com/docker/compose/releases/download/v5.0.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 赋予执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 验证安装
docker-compose --version

6.4 docker-compose配置文件介绍

Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。它允许您使用 YAML (docker-compose.yml)文件来配置应用程序的服务、网络和存储卷,然后通过一个简单的命令创建和启动所有服务。

6.4.1 简单的配置docker-compose.yml

# docker-compose.yml
version: "2.2"           # 指定 Compose 文件格式版本,确保兼容性
services:                # 定义服务的根节点,所有服务都在此定义
  web:                   # 服务名称,用户自定义(此处命名为 web)
    image: nginx:alpine  # 指定使用的 Docker 镜像(nginx:alpine)

作用

  • 启动一个名为 web 的服务

  • 使用官方的 nginx:alpine 镜像

  • 最简单的配置,没有端口映射、没有数据持久化

6.4.2 添加端口映射

version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:               # 端口映射配置
      - "8080:80"        # 格式:"主机端口:容器端口"
                         # 作用:将主机的8080端口映射到容器的80端口

为什么需要端口映射?

  • 容器默认是隔离的,外部无法访问容器内的服务

  • 通过端口映射,可以让外部通过网络访问容器中的应用

6.4.3 添加数据持久化

version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:             # 数据卷配置
      - ./html:/usr/share/nginx/html  
      # 格式:"宿主机路径:容器路径"
      # 作用:将当前目录下的html文件夹挂载到容器的nginx默认网页目录
      # 效果:修改主机上的html文件会立即反映在容器中

6.4.4 添加环境变量

version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    environment:          # 环境变量配置
      - NGINX_HOST=localhost   # 设置nginx主机名
      - NGINX_PORT=80          # 设置nginx端口
    # 作用:配置应用程序的行为,无需修改代码或配置文件

6.4.5 添加多个服务(Web + 数据库)

version: "3.8"
services:
  # Web 应用服务
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    depends_on:          # 依赖关系配置
      - db               # 作用:确保db服务在web服务之前启动
      # 重要:这仅控制启动顺序,不保证db已准备好接受连接

  # 数据库服务
  db:
    image: postgres:13
    environment:
      - POSTGRES_PASSWORD=secretpassword
      # 作用:设置PostgreSQL数据库的root密码
    volumes:
      - postgres_data:/var/lib/postgresql/data
      # 使用命名卷,确保数据库数据持久化

volumes:
  postgres_data:        # 声明一个命名卷
    # 作用:数据存储在Docker管理的位置,不依赖于主机特定路径
    # 优势:便于备份、迁移,适合生产环境

6.4.6 添加健康检查和重启策略

version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    healthcheck:         # 健康检查配置
      test: ["CMD", "curl", "-f", "http://localhost"]
      # 检查命令:使用curl访问本地,如果返回非0则检查失败
      interval: 30s      # 每30秒检查一次
      timeout: 10s       # 每次检查超时时间为10秒
      retries: 3         # 连续失败3次则标记为不健康
      start_period: 40s  # 容器启动后40秒开始检查
    restart: unless-stopped
    # 重启策略选项:
    # - "no":不自动重启(默认)
    # - "always":总是重启
    # - "on-failure":非正常退出时重启
    # - "unless-stopped":除非手动停止,否则总是重启

6.4.7 部署WordPress 网站 示例

version: "3.8"

# 1. 定义所有服务
services:
  # WordPress 前端服务
  wordpress:
    image: wordpress:latest
    container_name: wp_site  # 自定义容器名称,便于识别
    ports:
      - "80:80"              # 将主机的80端口映射到容器的80端口
    environment:
      - WORDPRESS_DB_HOST=db:3306
      # WordPress连接数据库的地址,使用服务名"db"作为主机名
      # 这是Docker Compose网络特性:服务名自动解析为容器IP
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress123
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress_data:/var/www/html
      # WordPress核心文件、主题、插件等存储在这里
    depends_on:
      - db
    networks:
      - wp_network
    restart: always          # 确保服务始终运行,适合生产环境

  # MySQL 数据库服务
  db:
    image: mysql:8.0
    container_name: wp_db
    environment:
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress123
      - MYSQL_ROOT_PASSWORD=rootpassword
      # 设置root密码,虽然应用不使用,但MySQL镜像要求设置
    volumes:
      - db_data:/var/lib/mysql
      # 数据库数据存储,确保数据持久化
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
      # 初始化SQL脚本,容器启动时自动执行
    networks:
      - wp_network
    restart: always
    command: --default-authentication-plugin=mysql_native_password
    # MySQL 8.0需要这个选项以兼容旧客户端

  # phpMyAdmin 数据库管理工具
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: wp_admin
    ports:
      - "8081:80"            # 通过8081端口访问phpMyAdmin
    environment:
      - PMA_HOST=db          # 连接上面定义的db服务
      - PMA_PORT=3306
    depends_on:
      - db
    networks:
      - wp_network
    restart: always

# 2. 定义网络
networks:
  wp_network:
    driver: bridge
    # 网络驱动类型:
    # - bridge:默认,容器间通信,主机可访问
    # - host:共享主机网络命名空间
    # - none:无网络
    ipam:
      config:
        - subnet: "172.20.0.0/16"  # 自定义IP地址范围

# 3. 定义存储卷
volumes:
  wordpress_data:
    # 命名卷,Docker自动管理位置
    # 特点:独立于容器生命周期,删除容器不会删除卷
  db_data:
    driver: local
    # 使用本地驱动,数据存储在主机上
    # 生产环境可能需要更专业的驱动(如NFS、AWS EBS等)

6.4.8 Docker Compose 配置指令详解

分类指令说明示例用途/重要性
基本配置versionCompose文件格式版本version: "3.8"必须,决定可用功能
services定义所有服务的根节点services:必须,所有服务在此定义
服务配置image指定使用的镜像image: nginx:alpine基础,指定容器基础镜像
build从Dockerfile构建镜像build: ./app使用自定义镜像而非现有镜像
container_name自定义容器名称container_name: myapp便于识别和管理容器
网络配置ports端口映射ports: ["80:80", "443:443"]允许外部访问容器服务
expose暴露端口(仅容器间)expose: ["3000"]内部服务通信,不暴露给主机
networks加入网络networks: - frontend容器网络隔离和通信
存储配置volumes数据卷挂载volumes: ["./data:/app/data"]数据持久化和共享
volumes(命名卷)使用命名卷volumes: - db_data:/data生产环境推荐的数据管理方式
环境配置environment设置环境变量environment: [KEY=value]配置应用行为,敏感信息
env_file从文件加载环境变量env_file: .env分离配置和代码,便于管理
依赖与控制depends_on服务依赖关系depends_on: [db, redis]控制服务启动顺序
restart重启策略restart: unless-stopped确保服务高可用性
healthcheck健康检查见上方详细示例监控服务状态,自动恢复
资源管理deploy部署配置(Swarm模式)deploy: replicas: 3生产环境负载均衡和高可用
resources资源限制resources: limits: cpus: '0.5'防止单个容器耗尽主机资源
运行时配置command覆盖默认启动命令command: npm start自定义容器启动行为
entrypoint覆盖入口点entrypoint: /app/start.sh更深层次的启动控制
working_dir工作目录working_dir: /app指定命令执行的目录
user运行用户user: "node"安全考虑,避免root运行
网络定义driver网络驱动类型driver: bridge决定网络行为特性
external使用外部网络external: true连接已存在的Docker网络
ipamIP地址管理配置子网、网关等精细控制容器IP分配
卷定义driver卷驱动driver: local决定数据存储位置和方式
driver_opts驱动选项driver_opts: type: "nfs"配置特定驱动的参数
external使用外部卷external: true连接已存在的Docker卷

6.4.9 带监控的微服务应用 示例

version: "3.8"

services:
  # 主应用服务
  app:
    build: ./app
    environment:
      - NODE_ENV=production
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - postgres
    networks:
      - app-network
    deploy:
      replicas: 2        # 运行2个实例(需Swarm模式)
      resources:
        limits:
          memory: 512M   # 内存限制
          cpus: '0.5'    # CPU限制(0.5核)
        reservations:
          memory: 256M   # 预留资源
          cpus: '0.25'
    healthcheck:
      test: ["CMD", "node", "healthcheck.js"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 缓存服务
  redis:
    image: redis:alpine
    command: redis-server --requirepass $${REDIS_PASSWORD}
    # 注意:$$用于转义$,实际变量名为$REDIS_PASSWORD
    volumes:
      - redis-data:/data
    networks:
      - app-network

  # 数据库服务
  postgres:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network
    secrets:
      - db_password

  # 监控服务
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - app-network

  # 可视化监控
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana
    networks:
      - app-network

# 网络配置
networks:
  app-network:
    driver: overlay      # Swarm模式需要的网络类型
    attachable: true     # 允许非Swarm服务连接

# 存储卷配置
volumes:
  redis-data:
    driver: local
  postgres-data:
    driver: local
  prometheus-data:
    driver: local
  grafana-data:
    driver: local

# 密钥配置(安全)
secrets:
  db_password:
    file: ./secrets/db_password.txt

6.4.10 总结

  1. 版本控制:始终指定 version,并使用最新稳定版

  2. 环境分离:使用多个文件管理不同环境

    docker-compose.yml           # 基础配置
    docker-compose.override.yml  # 开发环境覆盖
    docker-compose.prod.yml      # 生产环境配置
    
  3. 安全性

    • 使用 secrets 管理敏感信息

    • 避免在代码中硬编码密码

    • 以非root用户运行容器

  4. 资源管理

    • 设置合理的资源限制

    • 配置健康检查

    • 选择合适的重启策略

  5. 数据持久化

  • 重要数据使用命名卷

  • 定期备份卷数据

  • 测试恢复流程

6.5 docker conpose 常用命令

6.5.1 Docker Compose 命令核心结构

docker-compose [选项] 命令 [命令选项] [服务名...]

6.5.2 生命周期管理命令

1. 启动服务
# 1. 基本启动(前台运行,显示日志)
docker-compose up

# 2. 后台启动(最常用)
docker-compose up -d
# -d:detach,后台运行
# 作用:启动所有在 docker-compose.yml 中定义的服务

# 3. 启动指定服务
docker-compose up web db
# 只启动名为 web 和 db 的服务,忽略其他服务

# 4. 启动时重建镜像(强制重新构建)
docker-compose up --build
# --build:重新构建镜像后再启动
# 适用场景:Dockerfile 有更新时

# 5. 启动时移除冲突的容器
docker-compose up --force-recreate
# 如果存在同名的旧容器,强制删除并创建新容器

# 6. 完整示例
docker-compose up -d --build --force-recreate web
# 后台启动web服务,重新构建镜像,强制重新创建容器
2. 停止服务
# 1. 停止并移除所有容器(最常用)
docker-compose down

# 2. 停止但保留网络和卷
docker-compose stop
# 仅停止容器,不删除容器、网络、卷

# 3. 停止并移除所有资源
docker-compose down --volumes --rmi all
# --volumes:同时删除所有命名卷
# --rmi all:删除所有使用的镜像
# --rmi local:只删除未标记的自定义镜像

# 4. 停止指定服务
docker-compose stop web
# 只停止名为 web 的服务

# 5. 强制停止(立即终止)
docker-compose kill
# 发送 SIGKILL 信号强制终止
docker-compose kill -s SIGINT
# 发送特定信号,如 SIGINT(Ctrl+C)

# 6. 完整示例
docker-compose down -v --remove-orphans
# -v:删除卷
# --remove-orphans:删除未在配置文件中定义的容器
3. 重启服务
# 1. 重启所有服务
docker-compose restart

# 2. 重启指定服务
docker-compose restart web db

# 3. 重启并设置超时时间
docker-compose restart -t 30 web
# -t 30:设置停止容器的超时时间为30秒

# 4. 重新创建容器(配置文件变更时使用)
docker-compose up -d --no-deps --build web
# --no-deps:不重新启动依赖的服务

6.5.3 查看与监控命令

1 查看服务状态
# 1. 查看运行状态(最常用)
docker-compose ps
# 输出示例:
#   Name                Command               State    Ports
#   web_app   docker-entrypoint.sh ngin ...   Up       0.0.0.0:80->80/tcp
#   db        docker-entrypoint.sh postgres   Up       5432/tcp

# 2. 查看所有容器(包括停止的)
docker-compose ps -a

# 3. 显示容器ID
docker-compose ps -q
# 只输出容器ID,用于脚本处理
# 输出:容器ID1 容器ID2

# 4. 查看指定服务
docker-compose ps web redis
2 查看日志
# 1. 查看所有服务的日志(实时)
docker-compose logs -f
# -f:follow,实时跟踪日志输出
# 按 Ctrl+C 退出

# 2. 查看指定服务的日志
docker-compose logs -f web

# 3. 查看最近N行日志
docker-compose logs --tail=100 web
# 查看web服务最近100行日志

# 4. 查看指定时间后的日志
docker-compose logs --since="2023-01-01" web

# 5. 查看指定时间范围内的日志
docker-compose logs --since="10m" --until="5m" web
# 查看10分钟前到5分钟前的日志

# 6. 时间戳显示
docker-compose logs -t
# -t:显示时间戳

# 7. 完整示例
docker-compose logs -f --tail=50 --timestamps web db
3 查看服务配置
# 1. 查看配置文件内容
docker-compose config
# 显示解析后的配置,验证配置是否正确

# 2. 验证配置文件语法
docker-compose config --quiet
# 只检查配置,不显示内容

# 3. 查看解析后的服务配置
docker-compose config --services
# 输出所有服务名称:web db redis

# 4. 查看所有镜像
docker-compose images
# 显示服务使用的镜像信息

# 5. 查看端口映射
docker-compose port web 80
# 查看web服务的80端口映射到主机的哪个端口
# 输出:0.0.0.0:8080

6.5.4 构建与镜像管理

1 构建镜像
# 1. 构建所有服务的镜像
docker-compose build
# 根据 docker-compose.yml 中的 build 配置构建镜像

# 2. 强制重新构建(不使用缓存)
docker-compose build --no-cache
# 完全重新构建,不使用任何缓存

# 3. 并行构建多个镜像
docker-compose build --parallel
# 加快构建速度

# 4. 构建指定服务的镜像
docker-compose build web
# 只构建web服务的镜像

# 5. 拉取依赖镜像
docker-compose pull
# 下载服务所需的所有镜像
docker-compose pull --ignore-pull-failures
# 忽略失败的拉取,继续其他

# 6. 推送镜像到仓库
docker-compose push
# 推送所有服务的镜像到仓库

6.5.5 服务管理命令

1 执行命令
# 1. 在容器中执行命令(最常用)
docker-compose exec web ls /app
# 在web服务的容器中执行 ls /app

# 2. 交互式执行
docker-compose exec -it web sh
# -i:交互模式
# -t:分配伪终端
# 进入web容器的shell

# 3. 以特定用户执行
docker-compose exec --user=root web whoami
# 以root用户执行命令

# 4. 在工作目录执行
docker-compose exec -w /app web npm install
# -w:指定工作目录

# 5. 非交互执行
docker-compose exec -T web echo "Hello"
# -T:禁用伪终端分配

# 6. 完整示例
docker-compose exec -it --user=node -w /app/src web bash
2 运行一次性命令
# 1. 运行一次性容器执行命令
docker-compose run --rm web npm init
# --rm:命令执行完后自动删除容器
# 用途:运行管理命令(如数据库迁移)

# 2. 指定服务端口映射
docker-compose run --service-ports web
# 为一次性容器分配端口映射

# 3. 使用特定环境变量
docker-compose run -e NODE_ENV=test web npm test

# 4. 挂载额外卷
docker-compose run -v /host/path:/container/path web bash

# 5. 完整示例
docker-compose run --rm --entrypoint bash web -c "ls -la && pwd"
3 暂停与恢复
# 1. 暂停所有服务
docker-compose pause

# 2. 暂停指定服务
docker-compose pause web

# 3. 恢复暂停的服务
docker-compose unpause web

6.5.6 扩展与多文件管理

1 多配置文件管理
# 1. 使用多个配置文件(开发环境)
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# 配置合并顺序:后面的文件覆盖前面的配置

# 2. 生产环境配置
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 3. 常用配置文件组织
# docker-compose.yml              # 基础配置
# docker-compose.override.yml     # 开发配置(自动加载)
# docker-compose.prod.yml         # 生产配置
# docker-compose.test.yml         # 测试配置

# 4. 查看合并后的配置
docker-compose -f docker-compose.yml -f docker-compose.prod.yml config
2 扩展服务
# 1. 扩展服务实例数(Swarm模式)
docker-compose up --scale web=3 --scale worker=2
# 启动3个web实例,2个worker实例

# 2. 只能用于无状态服务
# 注意:有状态服务(如数据库)不能scale

6.5.7 网络与卷管理

1 网络管理
# 1. 查看网络
docker-compose network ls

# 2. 查看网络详情
docker network inspect <project_name>_default

# 3. 连接容器到外部网络
docker network connect my-network <container_name>
2 卷管理
# 1. 查看所有卷
docker volume ls

# 2. 查看卷详情
docker volume inspect <volume_name>

# 3. 清理未使用的卷
docker volume prune

6.5.8 完整的项目生命周期管理示例

1 开发环境工作流
# 第一天:开始新项目
mkdir myproject && cd myproject

# 1. 创建基础配置文件
vim docker-compose.yml
# 内容:
version: "3.8"
services:
  web:
    build: ./app
    ports:
      - "3000:3000"
    volumes:
      - ./app:/app

  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: secret

# 2. 创建开发环境覆盖配置
vim docker-compose.override.yml
# 内容:
version: "3.8"
services:
  web:
    environment:
      NODE_ENV: development
      DEBUG: "true"
    command: npm run dev
    ports:
      - "9229:9229"  # 调试端口

# 3. 启动开发环境
docker-compose up -d --build

# 4. 查看实时日志
docker-compose logs -f web

# 5. 进入容器调试
docker-compose exec -it web bash

# 6. 运行测试
docker-compose run --rm web npm test

# 下班时暂停服务
docker-compose stop

# 第二天继续开发
docker-compose start

# 代码有重大更新时
docker-compose up -d --build --force-recreate
2 生产环境部署工作流
# 1. 创建生产配置
vim docker-compose.prod.yml
# 内容:
version: "3.8"
services:
  web:
    environment:
      NODE_ENV: production
    restart: always
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s

# 2. 部署生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 3. 验证部署
docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps
docker-compose -f docker-compose.yml -f docker-compose.prod.yml logs --tail=100 web

# 4. 零停机更新
# 首先更新配置文件
vim docker-compose.yml
# 然后执行滚动更新
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build --force-recreate web

# 5. 回滚到上一个版本
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --no-deps web

# 6. 监控服务
watch -n 5 'docker-compose ps'
# 每5秒刷新一次状态

6.5.9 Docker Compose 命令速查表

命令选项说明常用场景
up-d启动所有服务(后台)常规启动
up--build重新构建镜像后启动Dockerfile更新后
up--force-recreate强制重新创建容器配置变更后
up--no-deps不启动依赖服务单独重启某服务
down停止并移除所有容器清理环境
down-v同时删除所有卷完全清理数据
down--rmi all删除所有镜像彻底清理
ps查看容器状态检查运行状态
ps-a查看所有容器包括停止的容器
ps-q只显示容器ID脚本处理
logs-f实时查看日志调试问题
logs--tail=N查看最后N行日志快速查看最新日志
logs-t显示时间戳分析日志时间
exec-it进入容器交互模式容器内调试
exec--user=name指定执行用户权限管理
run--rm运行一次性命令数据库迁移
run-e VAR=value设置环境变量测试不同配置
restart重启服务应用配置更新
restart-t N设置停止超时时间优雅重启
stop停止服务暂停应用
start启动已停止的服务恢复应用
build构建镜像开发环境
build--no-cache不使用缓存构建确保全新构建
pull拉取最新镜像更新基础镜像
config验证配置文件调试配置
config--services列出所有服务查看服务列表
images列出所有镜像查看镜像信息
pause暂停容器临时冻结状态
unpause恢复容器解除冻结
kill强制停止容器处理卡死服务
kill-s SIGNAL发送特定信号优雅终止

6.5.10 实用技巧

1 查看容器资源使用
# 查看容器资源使用情况
docker-compose stats

# 持续监控
docker-compose stats --no-stream
2 清理未使用的资源
# 清理所有未使用的资源
docker-compose down --rmi all -v --remove-orphans

# 仅清理特定项目的资源
docker-compose down --rmi local
3 端口冲突解决
# 检查端口占用
netstat -tulpn | grep :80

# 修改端口映射
# 在 docker-compose.yml 中:
ports:
  - "8080:80"  # 改为其他端口
4 环境变量管理
# 使用 .env 文件
echo "COMPOSE_PROJECT_NAME=myapp" > .env

# 覆盖环境变量
docker-compose up -e DATABASE_URL=mysql://newhost

更多推荐