记录学习Docker容器技术笔记
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 镜像访问与配置教程 | 登录方式配置指南 - 轩辕镜像 ,具体请自行查看,教程,这里不做太多介绍
- 毫秒镜像 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不截断IDdocker imagesdocker images -adocker images ubuntu:20.04docker images --format "table {{.ID}}\t{{.Repository}}"REPOSITORY TAG IMAGE ID CREATED SIZEdocker search 搜索Docker Hub镜像 --limit N限制结果--filter is-official=true官方镜像--filter stars=N星数过滤--no-trunc完整描述docker search nginxdocker search --limit 5 redisdocker search --filter is-official=true mysqlNAME DESCRIPTION STARS OFFICIALdocker pull 拉取镜像到本地 -a所有标签--platform指定平台--quiet安静模式docker pull ubuntu:20.04docker pull nginx:alpinedocker pull --platform linux/arm64 mysql20.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:v1docker tag 给镜像打标签 (无主要参数) docker tag myapp:v1 myapp:latestdocker tag abc123 registry.com/myapp:v1docker tag oldname:tag newname:tag无输出,标签已添加 docker push 推送镜像到仓库 --disable-content-trust跳过验证docker push myapp:v1docker push registry.com/myapp:v1docker push --disable-content-trust myappThe push refers to repository...docker rmi 删除本地镜像 -f强制删除--no-prune保留父层docker rmi myapp:v1docker rmi -f abc123docker rmi $(docker images -q)Untagged: myapp:v1Deleted: sha256:abc123...docker save 保存镜像为tar文件 -o输出文件docker save -o myimage.tar ubuntu:20.04docker save ubuntu:20.04 > ubuntu.tardocker save -o all.tar img1 img2创建.tar文件,无控制台输出 docker load 从tar文件加载镜像 -i输入文件-q安静模式docker load -i myimage.tardocker load < ubuntu.tardocker load -i all.tarLoaded image: ubuntu:20.04docker history 查看镜像构建历史 --no-trunc不截断-H可读格式-q只显示层ID--format自定义格式docker history ubuntu:20.04docker history --no-trunc nginxdocker history --format "{{.ID}} {{.CreatedBy}}"IMAGE CREATED CREATED BY SIZEdocker inspect 查看镜像详细信息 --format格式化输出-f同–formatdocker inspect ubuntu:20.04docker inspect --format='{{.Id}}' nginxdocker inspect -f '{{json .Config}}' mysqlJSON格式的详细配置信息 docker image prune 清理未使用的镜像 -a删除所有未使用-f强制不确认--filter过滤条件docker image prunedocker image prune -adocker image prune -a -fdocker image prune --filter "until=24h"Deleted Images: ...Total reclaimed space: 1.2GBdocker commit 从容器创建镜像 -a作者-m提交信息-p暂停容器docker commit mycontainer myimage:v1docker commit -a "john" -m "更新配置" container1docker commit -p running_container new_imagesha256:abc123...docker import 从归档创建镜像 -c应用Dockerfile指令-m提交信息docker import ubuntu.tar myubuntudocker import -c "CMD /bin/bash" rootfs.tarcat ubuntu.tar | docker import - myimportedsha256:def456...docker image ls images命令的别名 同 docker imagesdocker image lsdocker image ls -a同 docker imagesdocker image rm rmi命令的别名 同 docker rmidocker image rm ubuntu:18.04docker image rm -f abc123同 docker rmidocker image tag tag命令的别名 同 docker tagdocker image tag old new同 docker tagdocker image push push命令的别名 同 docker pushdocker image push myrepo/myapp同 docker pushdocker image pull pull命令的别名 同 docker pulldocker image pull nginx同 docker pulldocker image build build命令的别名 同 docker builddocker image build -t myapp .同 docker builddocker image history history命令的别名 同 docker historydocker image history myapp同 docker historydocker image inspect inspect命令的别名 同 docker inspectdocker image inspect ubuntu同 docker 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时如果指定了命令,会覆盖CMD。CMD的主要目的是定义容器启动时的默认行为。
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.容器编排
容器编排 是自动化管理容器化应用程序的部署、扩展、网络连接和生命周期的过程。当你有成百上千个容器需要协同工作时,手动管理几乎不可能,编排工具就是为此而生。
类比理解:如果把单个容器比作“货船上的集装箱”,那么容器编排就是“整个港口的调度系统”,它决定:
-
哪些集装箱放哪里
-
如何连接它们
-
如何确保足够的资源
-
故障时如何自动恢复
-
主流编排工具:
-
Kubernetes(最流行,占主导地位)
-
Docker Swarm(Docker原生,简单易用)
-
Apache Mesos(更通用,支持多种工作负载)
-
6.1 容器编排是如何运行的?
┌─────────────────────────────────────────┐
│ 控制平面(Control Plane) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ API │ │调度器 │ │控制器 │ │
│ │ Server │ │Scheduler│ │Controller│ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────┬─────────────────────────┘
│
┌─────────────────▼─────────────────────────┐
│ 工作节点(Worker Nodes) │
│ ┌─────────────────────────────────────┐ │
│ │ 节点1:Kubelet + 容器运行时 + Pod │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ 节点2:Kubelet + 容器运行时 + Pod │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
6.2 运行流程
-
声明式配置:你提交一个YAML文件,描述应用的期望状态
-
控制平面监控:编排系统持续比较当前状态与期望状态
-
调度决策:调度器选择最合适的节点运行容器
-
执行部署:在对应节点拉取镜像、创建容器
-
持续保障:如果容器故障,自动重新调度
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 配置指令详解
| 分类 | 指令 | 说明 | 示例 | 用途/重要性 |
|---|---|---|---|---|
| 基本配置 | version | Compose文件格式版本 | 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网络 | |
| ipam | IP地址管理 | 配置子网、网关等 | 精细控制容器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 总结
-
版本控制:始终指定
version,并使用最新稳定版 -
环境分离:使用多个文件管理不同环境
docker-compose.yml # 基础配置 docker-compose.override.yml # 开发环境覆盖 docker-compose.prod.yml # 生产环境配置 -
安全性:
-
使用 secrets 管理敏感信息
-
避免在代码中硬编码密码
-
以非root用户运行容器
-
-
资源管理:
-
设置合理的资源限制
-
配置健康检查
-
选择合适的重启策略
-
-
数据持久化:
-
重要数据使用命名卷
-
定期备份卷数据
-
测试恢复流程
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
更多推荐
所有评论(0)