目录
ToggleIaas Paas Saas (了解)
- Iaas:基础设施即服务 Infrastructure-as-a-Service
- Paas:平台即服务 Platform-as-a-Service
- Saas:软件即服务 Software-as-a-Service
- Caas:容器即服务 介于IAAS和PAAS
IAAS,PAAS,SAAS这些服务,用于帮助人们更快实现目标(搭建环境,使用产品)
从左到右,人们需要管理与维护的地方越来越少,人们可以把重点关注在使用/应用上.
IAAS平台:基础设施,IDC机房的服务器出租,阿里云,云厂商.云服务器
PAAS平台:服务/运行环境搭好了,部署(托管)用户写的代码,公有云SLB(负载均衡),RDS(数据库)
SAAS平台:服务(软件)已经准备好,您直接用,具体产品,processon,wps,亿图.

容器概念
容器是 隔离 的环境中运行的一个 进程 ,如果进程结束,容器就会停止.
容器的隔离环境,拥有自己的ip地址,系统文件,主机名,进程管理,相当于一个mini的系统
容器 vs 虚拟机(化) 


vmware esxi:裸机安装的操作系统,适用于物理服务器

虚拟机:安装多个操作系统,每个系统都有完整的启动流程
容器:服务软件,依赖,需要用到的命令等等放在一起(常见的为alpine系统)
Docker部署与使用–官方下载地址
容器管理工具:docker、podman、containerd (k8s)
要求Linux内核: 3.10以上. 如果旧的内核需要升级内核才能使用.
uname -r
安装docker环境,docker-ce(开源) docker-ee(企业版)
从1.13版本开始改成年-月版本命名方式.
17.03 18 19.03 20.10 年-月方式命名.
从23.0之后改为 传统版本命名方式(新版加1)
23.0 和24.0 和 25.0
docker 麒麟sp3的yum安装版本为 18.09
机器清单:
- sp3–10.0.0.81-docker01
- sp3–10.0.0.82-docker02
1) 配置docker源:用于安装docker(适用非麒麟系统)
通用的安装脚本
curl -fsSL https://get.docker.com/ -o install-docker.sh
curl -fsSL https://get.docker.com -o get-docker.sh
#sudo sh get-docker.sh
sh get-docker.sh –mirror Aliyun
安装完成后执行
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
下载到本地后直接bash执行脚本即可
配置docker yum源安装docker :安装最新版docker
#1.安装相关依赖. sudo yum install -y yum-utils #2.下载官方的docker yum源文件 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #3.替换yum源地址 sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo 或者直接使用国内地址:yum-config-manager --add-repo http://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo #4.安装docker-ce yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin #5.启动 systemctl enable --now docker #6.检查 docker version 检查
docker下载镜像加速的配置
我们使用docker的时候需要下载很多docker的镜像,为了加速下载,需要配置docker加速
docker下载镜像加速可以自己在阿里云,腾讯云申请加速用的地址.
阿里云为例,说明如何获取加速用的地址:搜索容器镜像服务
- 登录 容器镜像服务控制台。
- 在左侧导航栏选择 镜像工具 > 镜像加速器。
- 在 镜像加速器 页面获取您的加速器地址。

sudo mkdir -p /etc/docker#/etc/docker/daemon.json docker服务端的配置文件. #配置docker下载镜像的加速地址.sudo tee /etc/docker/daemon.json <<'EOF'{ "registry-mirrors":["https://bjjtv7cs.mirror.aliyuncs.com"] } EOFsudo systemctl daemon-reloadsudo systemctl restart docker
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.1panel.live",
"https://docker.m.ixdev.cn",
"https://hub.rat.dev",
"https://docker.xuanyuan.me",
"https://dockerproxy.net",
"https://docker-registry.nmqu.com",
"https://hub.amingg.com",
"https://docker.amingg.com",
"https://docker.hlmirror.com",
"https://hub1.nat.tf",
"https://hub2.nat.tf",
"https://hub3.nat.tf",
"https://docker.m.daocloud.io",
"https://docker.kejilion.pro",
"https://docker.367231.xyz",
"https://hub.1panel.dev",
"https://dockerproxy.cool",
"https://docker.apiba.cn",
"https://proxy.vvvv.ee"
]
}运行第1个docker
docker run -d -p 80:80 --name nginx_1st_1 nginx docker run xxxxx 选项/参数 镜像名字:版本 -d 守护进行,后台运行. -p 端口映射 宿主机端口:容器中的端口 --name nginx_1st 容器名字,不能冲突docker架构

Docker C/S架构
docker典型的cs结构,基于go语言,
go语言写的软件特点:大部分二进制安装
cs client/server 客户端/服务端
Docker 服务端:docker daemon 叫dockerd
Docker 客户端:docker命令(下载镜像,运行容器 )
镜像 image: 存放各种的环境或服务 容器 container: 进程,运行起来的镜像. 仓库(存放镜像): 远程仓库,本地仓库
docker pull nginx 下载nginx镜像到本地仓库.
如果本地仓库有则提示镜像已经下载.
如果本地出仓库没有,则docker服务端访问远程仓库,下载镜像.
docker run -d -p 80:80 nginx:1.24-alpine 启动容器
-d容器后台运行
-p端口映射
nginx镜像名字
命令执行后的过程:
docker客户端找dockerd服务端,问是否有nginx镜像
如果有,则启动这个镜像,后台运行,访问容器端口是80端口.
如果没有,则从远程仓库下载镜像,启动这个镜像,后台运行,访问容器
端口是80端口.
1. 提示你本地没有nginx镜像 nginx:latest最新版
Unable to find image ‘nginx:latest’ locally
2. 找远程仓库下载
3. 运行镜像,成为docker容器.
4.查看镜像docker images
5.查看容器docker ps
6. 访问10.0.81:80容器的80端口(出现nginx界面)
注意事项: 此处使用到了docker -p端口映射公共,需要使用iptables的nat功能,需要在sysct.conf中加上一行开启系统的内核转发功能
# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf net.ipv4.ip_forward = 1
# sysctl -p
net.ipv4.ip_forward = 1
Docker的镜像管理(相关命令)
镜像管理核心指令: 查看系统中的镜像
docker images == docker image ls
docker search 搜索镜像, 优先选官方,stars数量多 docker pull 拉取镜像(下载镜像),注意版本 docker push 推送镜像(上传镜像) docker load 导入镜像 #例子: docker load -i docker_nginx.tar.gz docker save 导出镜像 #例子:docker save centos:7 -o docker_centos7.tar.gz docker images 查看镜像列表 docker rmi 删除镜像 #如果有容器用着镜像,那么镜像删不掉 docker tag 给镜像打标签 #tag标签相当于软链接,新增后不占空间
案例01: 下载nginx:alpine镜像并查看
#1. docker pull 下载镜像
docker pull nginx:1.22-alpine
#2. docker image ls 简写为docker images查看镜像
docker images -a 查看所有镜像包含隐藏镜像.
查找镜像:
docker search 或者 访问hub.docker.com
镜像命名:
#指定版本: 只写服务名字一般下载服务的最新版本.
docker pull nginx 相当于 docker pull nginx:latest 下载最新版
下载ngx最新稳定的版本 nginx:stable
下载指定的版本 nginx:1.20.2
#指定系统: nginx镜像默认的系统是Debian系统
docker pull nginx:1.20-alpine 使用alpine系统更加节约空间(约比debian的小100M)
温馨提示:容器中常用的镜像

案例02: sl大法
保存docker镜像(save),其他节点上导入(load).
未来也可以搭建本地私有镜像仓库
docker image save #(docker save)
docker image load #(docker load)
保存docker 镜像 -o输出到指定的文件(这里的tar没有进行真正的压缩,大小体积没变)
docker save nginx:alpine -o nginx_alpine.tar
#2. 导入load
docker load -i nginx_alpine.tar
批量导入docker镜像
tar xf oldboyedu_useful_docker_images.tar.gz unzip openjdk-docker-镜像.zip -d openjdk cd oldboyedu_useful_docker_images for name in `ls ` do docker load -i $name done cd ../openjdk for name in `ls ` do docker load -i $name done
#清理压缩包和解压后的目录
批量导出镜像
- 一行命令实现导出,利用awk根据docker images的输出拼接成导出命令即docker save ****,但是只适用于镜像名里没有/,不支持目录结构的镜像
docker images | awk 'NR>1{print "docker save",$1":"$2 " -o "$1"_"$2".tar"}' > save.sh && bash save.sh

- 脚本实现导出:
- 思路还是使用awk取出docker save命令需要的第1,2列即镜像名:版本
- 处理上面没有解决的输出tar文件名里面带/的问题
cat save_scripts.sh #批量导出docker镜像的脚本. #!/bin/bash #author: lidao996 #desc: 批量导出docker镜像 docker images |awk 'NR>1{print $1":"$2}' >/root/images.txt for name in `cat /root/images.txt` do name_new=`echo $name |sed -r 's#:|/#_#g' ` docker save ${name} -o ${name_new}.tar done案例03:删除镜像
条件:镜像不能在使用中.(没有基于这个镜像的容器).
docker image rm == docker rmi
案例04:镜像清理用的命令
用于清理一些临时镜像,自定义镜像的时候
这些镜像一般来自于自定义镜像,生成临时镜像.没有名字和tag标签
docker image prune
docker images -a #可以查看系统中所有镜像,包含隐藏镜像
案例05:给镜像设置标签(类似ansible)
给镜像设置一个新的名字;tag标签相当于软链接,新增后不占空间
应用场景:
- 自定义镜像.
- 搭建与使用内部镜像仓库.registry
docker tag nginx:1.24 testngx:1.24 [root@sp3-docker01-10.0.0.81 ~]# docker images nginx 1.24 b6c621311b44 2 years ago 142MB testngx 1.24 b6c621311b44 2 years ago 142MB
案例06:查看镜像详细信息
docker 家目录在 /var/lib/docker/
docker inspect查看镜像容器,网络等各种信息
做镜像巡检的时候使用.
docker image inspect nginx:1.24 查看json数据配合jq使用
yum install -y jq
#jq用于专门过滤json形式的数据:
使用步骤:逐级进入,
结果中最外面是: [] 所以先用 jq .[]进入到 []中.
结果中{} 可以用jq .Id 形式取出,对于缩进的需要先访问上级然后继续访问.
docker inspect mysql:8.0-debian | jq .[]

docker inspect mysql:8.0-debian | jq .[].ContainerConfig
docker inspect mysql:8.0-debian | jq .[].ContainerConfig.ExposedPorts

多层[]时候使用多次.[]无效,需要加个管道再来一次.[]进入[]

案例07:自定义镜像
docker image build == docker build
docker image prune自定义镜像后进行清理无用的临时镜像
Docker的容器管理
docker container xxx
docker ps 查看容器列表 -a 查看所有容器 docker run 创建并运行容器 #例子:docker run -d -it -p 80:80 nginx:latest docker create --name创建容器 docker start 启动容器 docker stop 停止容器 docker restart 重启容器 docker kill 强制停止容器 docker rm 删除容器 批量删除所有容器 docker rm -f `docker ps -a -q` docker exec 进入正在运行的容器(分配一个新终端) #例子: docker exec -it 容器id/容器名字 /bin/bash(/bin/sh) docker attach 进入正在运行的容器(使用相同的终端), 偷偷离开的快捷键ctrl +p,ctrl +q 如果使用ctrlc会退出并关闭容器 docker inspect #查看详细信息 docker stats #查看容器运行状态,占用内存,cpu,io等信息 docker top #查看容器内当前进程
案例08:run 运行容器与查看容器信息
docker container run == docker run
- docker container run过程
run包含了pull,create,start
查找本地是否有这个镜像,如果没有则先下载镜像. docker image pull
下载完成,创建容器 docker container create ,没有启动.
启动容器docker container start
容器启动,进行访问
docker container run -d -p 80:80 nginx
-d 后台运行; -p指定端口

docker端口映射过程

–name 创建容器并指定名称
查看容器运行状态docker run -d -p 81:80 --name nginx-test nginx:1.24docker ps -a #显示所有状态容器.docker ps #只显示运行中的容器.不会显示其他状态容器
使用-p选项需要配置端口映射: vim /etc/sysctl.conf# tail -1 /etc/sysctl.conf #写入到文件最后即可
net.ipv4.ip_forward = 1# sysctl -p
net.ipv4.ip_forward = 1
查看各种镜像需要映射哪些端口
#查看redis镜像需要映射端口
docker inspect redis:5.0-alpine | jq .[].Config.ExposedPorts
{
"6379/tcp": {}
}
#查看tomcat镜像需要映射端口
docker inspect tomcat:9.0-jdk8 | jq .[].Config.ExposedPorts
{
"8080/tcp": {}
}
#查看nginx镜像需要映射端口
docker inspect nginx:1.24| jq .[].Config.ExposedPorts
{
"80/tcp": {}
}
#查看mysql镜像需要映射端口
docker inspect mysql:8.0-debian| jq .[].Config.ExposedPorts
{
"3306/tcp": {},
"33060/tcp": {}
}案例09:删除容器
删除1个容器docker container rm === docker rmdocker rm 容器名字或iddocker rm -f 容器名字或id #强制删除(运行中的容器无法强制删除,只能删除名字)
删除所有容器(极其危险)
- #显示所有容器(-a)并只显示容器id (-q)
docker ps -a -q- #删除容器
- docker rm -f `docker ps -a -q`
案例10: 启动centos7容器运行系统镜像(用于临时测试)
docker run -it --name centos_7 centos:7 /bin/bashdocker run -it --name alpine_v2 alpine:latest /bin/sh
使用-it场景,用于测试或启动某个镜像并进入容器.
缺点:终端退出,容器退出
原因:运行中的容器需要在容器中持续运行某个命令或服务,(前台).
如服务软件有守护进程,所以容器可以一直运行
运行系统镜像时要在容器中有个命令/服务,把这个容器阻塞/卡住:运行sleep 9
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]docker container run -d -p 80:80 nginxdocker container run -d --name "centos7.9_v1" centos:7 sleep 9
温馨提示:
容器想要放在后台(-d)一直运行的话,那么容器的初始命令必须夯住(阻塞/前台运行),否则容器就会退出.
常见的前台运行方式:
nginx -g ‘daemon off;’ nginx前台运行.
/usr/sbin/php-fpm –nodaemonize php前台运行.
/usr/sbin/sshd -D ssh前台运行.
java -jar xxx.jar java前台运行.
#启动服务容器docker run -d --name ngx_v1.24 -p 80:80 nginx:1.24
#启动系统容器(使用/bin/bash将系统阻塞住)docker run -itd --name centos7_v4 centos:7 /bin/bash
案例11: 进入到已经运行的容器中.
如果容器已经运行了,无法使用docker run -it方式进入到容器中.
docker container exec === docker exec
#运行容器docker run -itd --name "centos7_v1" centos:7 /bin/bash
#检查容器运行情况docker ps
#连接到运行中的容器中docker exec -it centos7_v1 /bin/bash
#对于其他系统可以用/bin/bash
案例12: exec与attach区别

docker attach 的特点
附加到运行中的进程:连接到容器的主进程(通常是前台进程),这时两个终端同时连接会显示出对方的输入和输出信息
docker attach centos7_v1
退出会停止容器:如果使用 Ctrl+C 或 Ctrl+P Ctrl+Q 退出可能会影响容器运行
如果 attach 后无法输入:可能是容器没有配置交互式终端,建议使用docker exec

容器已经运行,如果重启docker服务端会怎么样?
#发现问题
重启linux或docker服务后,容器处于关闭状态.类似于Linux的服务没有设置开机自启动一样.
#解决方法
1. docker start 启动
2. docker run的时候设置容器重启策略docker run -d -p 80:80 --name ngx_1.24_alpine --restart=always nginx:1.24-alpine-new
docker重启策略说明:

案例14: 查看容器日志
docker logs 查看容器日志
-f 类似于tail -f显示实时更新
-n或–tail最近多少行日志
–since 从指定的时间开始到现在的日志
–until 指定结束的日志的时间(一般与since一起用,表示时间段)docker logs --tail 10 nginx_v1.24docker logs -f --since "2025-09-26T00:00:00Z" nginx_v1.24
注意:日期和时间都需要使用两位数
年月日十分秒中间需要加T
相对时间参数(推荐使用)相对时间更简单,不容易出错:
–since “1h” 最近1小时
–since “30m” 最近30分钟
–since “2d” 最近2天
–since “1h30m” 最近1小时30分钟
案例15: docker run 背后的指令
docker run -d -p 81:80 --name ngx_v1.24 --restart=always nginx:1.24
#1. 拉取镜像docker pull nginx:1.24
#2. 创建容器docker create -p 81:80 --name ngx_v1.24 --restart=always nginx:1.24
#3. 启动容器docker start ngx_v1.24
#4. 检查结果
docker ps

docker pause,挂起相当于vm虚拟机的挂起,暂停运行
案例16: 宿主机文件传输到容器中
docker cp传输1个代码文件.
#1.问题:容器中默认没有远程连接服务,又要把宿主机文件传输到容器中.
#2.解决: cp
[root@docker01.linuxjk.cn ~]# cat index.html
docker cp docker.linuxjk.cn
docker cp index.html nginx_v1.24:/usr/share/nginx/html/
docker cp 传输配置文件
#1. 准备nginx配置文件:default.conf
[root@docker01.linuxjk.cn ~]# cat default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* \.(html|css|js|jpg|jpeg|png)$ {
root /usr/share/nginx/html;
expires max;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
#2. 传输配置文件docker cp default.conf nginx_v1.24:/etc/nginx/conf.d/
#3. 重启容器docker restart nginx_v1.24
#4. 检查结果

案例17: 保存容器
生成镜像
通过镜像启动的容器,往往无法完全符合我们使用要求.
每次都是修改配置.上传代码后使用
如何把修改保留下来:把被修改的容器保存成镜像.
启动基础镜像docker run -d --name ngx_bunengsi_v1 -p 8848:80 --restart=always nginx:1.24
准备好bunengsi.tar代码,解压后传输到容器的/tmp/目录tar xf bunengsi.tardocker cp bunengsi ngx_bunengsi_v1:/tmp/
进入容器进行操作,把bunengsi/目录下面代码移动到站点目录docker exec -it ngx_bunengsi_v1 /bin/bashmv /tmp/bunengsi/* /usr/share/nginx/html/
访问当前容器并测试是否可以访问 http://10.0.0.82:8848
测试完成保存容器为镜像docker commit ngx_bunengsi_v1 web:ngx_bunengsi_v1
通过新镜像创建容器并测试docker run -d --name ngx_bunengsi_v2 -p 12306:80 --restart=always web:ngx_bunengsi_v1
测试通过,删除之前用于测试的临时容器docker stop ngx_bunengsi_v1docker rm ngx_bunengsi_v1
通过docker commit可以实现初步自定义镜像.
手动自定义镜像流程:
选择合适的基础镜像 . 启动容器, 连接容器,部署,配置,调试 . commit生成镜像 通过镜像创建容器并调试
案例18:其他容器指令
docker kill 用于结束指定的容器. stop无法关闭,可以使用kill.
docker top 查看容器中进程信息.
docker stats 查看所有容器的cpu,内存,磁盘,网络,进程信息.
docker update 更新容器配置,增加cpu,内存限制,修改restart重启规则
不能添加规则,只能修改,比如没做数据卷挂载,端口映射只能重新创建容器
资源限制: -m 限制内存 –cpus显示cpu核数
通过docker run的时候加上资源限制的选项
-e:创建或修改容器中的环境变量(全局变量)
案例19:export和import导入导出
docker export(导出容器)
# 导出容器到.tar文件docker export nginx_v1.24 > nginx_container.tar
# 或者使用 -o 参数指定输出文件nginx_container.tar,默认不会压缩docker export -o nginx_container.tar nginx_v1.24
# 导出并压缩docker export nginx_v1.24 | gzip > nginx_container.tar.gz
docker import(导入为镜像)
# 从tar文件导入为镜像docker import nginx_container.tar mynginx:latest
# 从标准输入导入cat nginx_container.tar | docker import - mynginx:latest
# 从压缩文件导入docker import nginx_container.tar.gz mynginx:v1
# 指定更多信息(docker inspect 查看)docker import --message "Imported from backup" nginx_container.tar mynginx:backup
docker commit 保存容器为镜像(手动自定义镜像)
与 docker save/load 的区别
| 特性 | export/import | save/load |
|---|---|---|
| 操作对象 | 容器 → 镜像 | 镜像 → 镜像 |
| 保存内容 | 仅文件系统 | 文件系统+历史+元数据 |
| 层级结构 | 扁平化(单层) | 保留所有层 |
| 使用场景 | 创建基础镜像、备份容器 | 迁移完整镜像 |
容器管理命令小结:

端口映射
docker run -d -p 选项.
使用docker的时候 外界访问docker容器中的服务或端口,需要使用端口映射.本质类似于iptables防火墙的端口映射.
应用场景: 未来容器需要被外界访问(80端口).需要暴漏在外界一个端口.
用户通过端口访问容器中的某个端口.
实现方法:docker run通过-p选项实现.
本质是通过iptables nat规则实现的.nat表中创建了docker自定义的链.
比如说
docker run -d --name "oldboy_nginx_1.20.2-apline" -p 8888:80 nginx:1.20.2-apline
1) 背后做了什么?
添加了对应防火墙规则iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.17.0.10:80
开启内核转发功能(需要我们自己开启)# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf net.ipv4.ip_forward = 1
用户访问的时候经历了什么?

#输出所有运行中容器的ip地址.
for cid in `docker ps -q`
do
docker inspect $cid |jq .[].NetworkSettings.IPAddress
done
端口映射案例

案例20: 1对1端口映射 

映射80端口和443端口

docker run -d -p 80:80 -p 443:443 --name ngx_ports nginx:1.24-alpine-new
案例21: 映射多个端口
映射 容器中8080,8081,8082
一个一个写docker run -d -p 8080:8080 -p 8081:8081 -p 8082:8082 -p 86:80 nginx:1.24-alpine

指定范围,宿主机8084-8086端口对应容器中的8080-8082
docker run -d -p 8084-8086:8080-8082 -p 88:80 nginx:1.24-alpine

docker port hopeful_northcutt(容器名字或id) 表示连续
案例22:把容器的端口随机映射到宿主机
docker run -d -P --name ngx_ports_v3 nginx:1.24-alpine
随机映射本质:根据镜像中的配置 EXPOSE配置映射端口.docker inspect nginx:1.24-alpine |grep -i -A1 expose
可以看到nginx的镜像配置里面写的是80端口:
[root@sp3-docker02-10.0.0.82 ~]# docker inspect nginx:1.24-alpine |grep -i -A1 expose
"ExposedPorts": {
"80/tcp": {}
--
"ExposedPorts": {
"80/tcp": {}案例23:ip绑定端口 
docker run -d -p 172.16.1.82:8080:80 --name secure_nginx nginx:1.24-alpine 3012118e5fb4878dc07344b5fd47dc0bbe5ef8e0846fc81260734de1e54607c2 [root@sp3-docker02-10.0.0.82 ~]# docker ps -a CONTAINER ID IMAGE PORTS NAMES 3012118e5fb4 nginx:1.24-alpine 172.16.1.82:8080->80/tcp secure_nginx
数据卷挂载
1) 概述
如果容器崩了,容器被误删除了,容器中的数据将会丢失,接下来解决数据不丢.
如何解决数据持久化问题? 数据卷(挂载),让数据永久保存在宿主机中
不做数据卷挂载,数据库被删除数据不会保留

2) 使用
不使用数据卷,数据会丢失;在上方的mysql容器运行指令中加上
-v /app/data/db80/:/var/lib/mysql/
注意目录后需要加/表示为目录
数据卷使用 -v选项:指定要挂载的目录/文件
格式:
-v 宿主机的路径:容器内部路径
案例24: 部署mysql容器并指定数据卷挂载
docker run -p 3306:3306 --name db_8.0_v2 \ --restart always \ -v /app/mysql/log/:/var/log/mysql/ \ -v /app/mysql/data/:/var/lib/mysql/ \ -v /app/mysql/conf/:/etc/mysql/ \ -e MYSQL_ROOT_PASSWORD=1 \ -d mysql:8.0-debian

案例25: 挂载到数据卷空间(不指定存放位置,docker处理)
查看所有docker数据卷docker volume ls
1.在宿主机上创建一个数据卷给容器mysql使用,实际位置在docker的目录/var/lib/dockerdocker volume create mysql_data
运行mysql 容器中的/var/lib/mysql挂载到宿主机中.-v mysql_data:/var/lib/mysql
2.使用(如果没执行下一步这里会自动创建数据卷)
docker run -p 3307:3306 -d --name mysql \ --restart always \ -v mysql_data:/var/lib/mysql/ \ -e MYSQL_ROOT_PASSWORD=1 \ mysql:8.0-debian
3.连接与创建用户,创建库
4.查看数据卷空间的信息(实际数据存放地址)docker inspect mysql_data
查看一部分镜像的dockerfile:
docker history 镜像名/ID (加上–no-trunc更全)
容器架构自动化部分

手动实现(commit指令),对于复杂的服务不建议用
1.创建容器
docker run -d -p 8080:80 --name ngx_bunengsi nginx:1.24-alpinemkdir -p /app/dk/bunengsicp -a ~/bunengsi.tar /app/dk/bunengsivim bunengsi.confdocker exec -it ngx_bunengsi /bin/sh
容器内部:mkdir -p /app/code/bunengsi
这里在容器内部创建目录时自动750,不给用户组权限会出现错误
解决方案:umask 查看输出,正常是0022,这个数字越大限制越多
修改方法:umask 0022
2.导入代码及配置文件
docker cp bunengsi.conf ngx_bunengsi:/etc/nginx/conf.ddocker cp bunengsi.tar ngx_bunengsi:/app/code/bunengsi
容器内部:tar xf bunengsi.tar
容器内部:nginx -tdocker restart ngx_bunengsidocker logs -f ngx_bunengsi
3.测试,成功访问
4.将容器保存为镜像
docker commit ngx_bunengsi web:ngx_1.24_bunengsi_v1
检查docker images | grep web
5.根据镜像生成容器
docker run -d -p 80:80 --name web_bunengsi_v1 web:ngx_1.24_bunengsi_v1docker ps -a 查看刚生成的容器:web_bunengsi_v1
检查页面成功访问,手动将容器保存为镜像结束
自动实现Dockerfile实现
Dockerfile概述
应用场景: 通过1个文件Dockerfile,生成自定义镜像
为何使用Dockerfile:
我们目前都是手动拉取镜像,手动进行配置,手动安装依赖,手动编译安装,创建用户….
这个过程类似于命令行使用ansible模块(繁琐,不方便重复执行).
书写Dockerfile把之前手动创建自定义镜像的过程,通过Dockerfile里面的指令实现.类似于书写playbook.
Dockerfile用于根据要求自动创建镜像 .
Dockerfile格式
需要在容器中执行的指令可以写多行RUN,也可以写在一行RUN里面
书写dockerfile
ADD可以用于传配置文件(docker cp),或者传输代码后直接解压(保证压缩包里目录结构正确)
ADD和COPY都可以用于修改传输过去文件的所有者,
COPY –chown=root:root *****.tar.gz /app/code/test
COPY –chmod=755 *.sh /*.sh
FROM nginx:1.24-alpine LABEL author="linuxjk.cn" ADD bunengsi.conf /etc/nginx/conf.d/ RUN umask 0022 && \ mkdir -p /app/code/bunengsi/ ADD bunengsi.tar.gz /app/code/bunengsi/ EXPOSE 80 443 CMD ["nginx","-g","daemon off;"]
nginx -g "daemon off" (容器环境nginx专用)
# Nginx 在前台运行,保持容器活跃
# 主进程不会退出,一直保持运行
进入dockerfile所在目录,根据dockerfile创建镜像
docker build -t web:ngx_bunengsi_v2_dockerfile .
docker imagesweb ngx_bunengsi_v2_dockerfile 553b048b46b4 4 seconds ago 41.2MB
根据镜像运行容器
docker run -d -p 80:80 --name bunengsi_dockerfile web:ngx_bunengsi_v2_dockerfile
容器启动后检查,访问宿主机80端口
docker ps21f039e3e9ea web:ngx_bunengsi_v2_dockerfile "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 443/tcp bunengsi_dockerfile
注意:每个项目的所需配置文件,代码等等和dockerfile都单独放在指定的目录中,否则会把目录中的所有文件交给docker服务端处理,像卡住
Dockerfile中的指令(都是大写)

FROM指定基础镜像
LABEL注释,镜像属性信息
RUN 在镜像中执行命令,尽可能把多个RUN合并,减少build的步骤
ADD传输文件,目录,压缩包等等,可以解压.tar.gz
COPY不能解压,只能传输(作用同上)
EXPOSE 服务需要的端口
CMD[“命令”,”参数”,”参数”]:容器的入口命令,运行容器后自动运行这个命令
最多三个””,最少两个,参数中可以写多个参数
ENV,WORKDIR,VOLUME
ENV
- 定义全局环境变量,dockerfile中可用,dockerfile中涉及的脚本也可以用,用法和shell类似
定义:ENV CODE_NAME=bird.tar.gz
位置:FROM,LABEL下方,RUN上方
使用格式:ADD ${CODE_NAME} /app/code/code/
#将bird.tar.gz中的内容发到容器中的/app/code/bird目录
WORKDIR
- 指定工作目录,进入容器所在的目录,一般web服务器指定代码的站点目录,不指定也可以
位置:都可以,放在ENV与EXPOSE之间
使用格式:WORKDIR /app/code/bird/
相当于执行了cd /app/code/bird/ ;下面的操作可以使用相对路径,比如ADD ${CODE_NAME} . 将代码直接发到站点目录
注意:和ENV一样可以在dockerfile中用多次
VOLUME
- 指定容器中哪些目录或文件需要做数据卷挂载(-v),需要时加上
位置:一般写在下面,COMPOSE之前
使用格式:
VOLUME /app/code/bird/VOLUME /etc/nginx/nginx.conf
案例26 CMD, ENTRYPOINT区别
共同点:都与入口有关,运行容器的时候默认运行CMD或ENTRYPOINT后面的命令,使用格式相同

区别01:二选一时,在dockerfile中选择其一使用
CMD:使用较多(替换)
docker run的时候,如果镜像名字后面指定了命令,则cmd内容就会被替换
ENTRYPOINT:(追加)
run的时候,如果指定了命令内容,在entrypoint命令后面追加
区别02:一起使用
FROM nginx:1.24 LABEL author=linuxjk.cn desc="测试 cmd和entrypoint" ENTRYPOINT ["nginx"] CMD ["-g","daemon off;"]
CMD的内容会作为entrypoint的选项参数,运行容器时可以修改参数,但是命令不变
查看官方dockerfile格式:hub.docker.com👉github存放dockerfile
set -e: shell严格模式,前面命令执行报错自动退出脚本,不进行下一步操作,和手动加exit效果类似
所以用了-e选项后,在剧本中就可以将&&替换为; 效果相同
set -x显示脚本详细输出
set -u 如果用到了没定义的变量,就报错
在脚本中可以写set -eux,严格模式+显示过程+引用未定义变量报错,实现的效果:引用未定义的变量直接退出脚本
案例27 极速搭建个人不限速的网盘,再也不用办理xx会员了.
案例说明:
代码kodbox可道云.云盘和云桌面.

项目步骤:ngx+php镜像
基础镜像: debian:bullseye
启动debian容器映射端口80端口docker run -itd --name ngx_php_kodbox_v1 -p 80:80 debian:bullseye /bin/bash
进入容器配置各种apt源:系统源,配置ngx源cp /etc/apt/sources.list /tmp/
cat >/etc/apt/sources.list<<'EOF'deb https://mirrors.tencent.com/debian/ bullseye main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye main non-free contrib deb https://mirrors.tencent.com/debian-security/ bullseye-security main deb-src https://mirrors.tencent.com/debian-security/ bullseye-security main deb https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib deb https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib EOF
临时禁用证书验证
# 临时解决方案(仅测试用)apt update -o Acquire::https::Verify-Peer=false
#临时切换为http源安装ca-certificatessed -i 's/https/http/g' /etc/apt/sources.listapt install -y ca-certificatessed -i 's/http/https/g' /etc/apt/sources.listapt updateapt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring unzip
时间同步ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#配置ngx源-gpgcheck认证密钥curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \| tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
#配置ngx源echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| tee /etc/apt/sources.list.d/nginx.listapt update
#安装nginxapt install -y nginx
#安装php
apt install -y php7.4-bcmath php7.4-bz2 php7.4-cgi \ php7.4-cli php7.4-common php7.4-curl php7.4-dba \ php7.4-dev php7.4-enchant php7.4-fpm php7.4-gd \ php7.4-gmp php7.4-imap php7.4-interbase php7.4-intl \ php7.4-json php7.4-ldap php7.4-mbstring php7.4-mysql \ php7.4-odbc php7.4-opcache php7.4-pgsql php7.4-phpdbg php7.4-pspell php7.4-readline php7.4-snmp \ php7.4-soap php7.4-sybase php7.4-tidy php7.4-xml \ php7.4-xmlrpc php7.4-xsl php7.4-zip php7.4-redis
#检查安装结果dpkg -l |grep nginxdpkg -l |grep php7.4 |wc -l
此处应输出33
安装后配置php
#默认为www-data 用户
#sed -i 's#^user =.*$#user =www-data#g' /etc/php/7.4/fpm/pool.d/www.conf#sed -i 's#^group = www-data#group = nginx#g'/etc/php/7.4/fpm/pool.d/www.confcp /etc/php/7.4/fpm/pool.d/www.conf /tmp/
#开启php-fpm 9000端口sed -i 's#/run/php/php7.4-fpm.sock#127.0.0.1:9000#g'/etc/php/7.4/fpm/pool.d/www.conf
#修改php7.4的pid文件的路径sed -i 's#/run/php/php7.4-fpm.pid#/run/php7.4-fpm.pid#g' /etc/php/7.4/fpm/php-fpm.conf
#检查语法php-fpm7.4 -t
#启动phpphp-fpm7.4
#检查进程ps -ef
安装后配置ngx
#修改ngx用户为www-datased -i '/^user/s#nginx#www-data#g' /etc/nginx/nginx.conf
#准备子配置文件
server {
listen 80;
server_name kodbox.linuxjk.cn;
root /app/code/kodbox;
access_log /var/log/nginx/kodbox.access.log main;
error_log /var/log/nginx/kodbox.error.log notice;
location / {
index index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}#检查语法nginx -t
#启动ngxnginx -g "daemon off;"
日志软连接(dockerfile中创建软连接即可) 暂时略过
想使用docker logs查看日志而不是进入容器看日志,需要日志文件软连接到
/dev/stdout 普通访问日志
/dev/stderr 错误日志
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stdout -> /proc/self/fd/1
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stdin -> /proc/self/fd/0
rm -f /var/log/nginx/*rm -f /var/log/php7.4-fpm.log
ln -sf /dev/stdout /var/log/nginx/kodbox.access.logln -sf /dev/stderr /var/log/nginx/kodbox.error.logln -sf /dev/stderr /var/log/php7.4-fpm.log
部署代码
上传代码到/tmp/unzip /tmp/kodbox.zipmkdir -p /app/code/kodboxmv /tmp/* /app/code/kodbox
#修改权限chown -R www-data.www-data /app/code/kodbox/chmod 755 /app/ /app/code/ /app/code/kodbox/
#报错没有读写权限可以执行chmod -R 777 /app/code/kodbox/
hosts解析并浏览器访问
常见故障
nginx命令启动ngx服务,重启nginx -s reload
重启php-fpm pkill php-fpm然后启动php-fpm7.4 即可.
项目步骤:启动mysql和redis镜像
启动mysqldocker volume create mysql57_kodboxdocker volume lsdocker run -d --name mysql57_kodbox --restart=always -v mysql57_kodbox:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=666 \ -e MYSQL_DATABASE=kodbox \ -e MYSQL_USER=kodbox \ -e MYSQL_PASSWORD=1 \ -p 3306:3306 \ -p 33060:33060 \ mysql:5.7-debian
链接数据库容器docker exec -it mysql57_kodbox mysql -ukodbox -p666
-e指定容器所需变量-e MYSQL_ROOT_PASSWORD=666 mysql的root密码-e MYSQL_DATABASE=kodbox 创建1个数据库-e MYSQL_USER=kodbox 指定用户(高权限用户)-e MYSQL_PASSWORD=1 新建用户的密码
启动redis容器docker volume create redis5.0_datadocker run -d --name "redis5.0" --restart=always -v redis5.0_data:/data/ -p 172.16.1.81:6379:6379 redis:5.0-alpine
限制本地ip
项目步骤:部署redis
用于缓存通用数据及会话session,加快系统访问

书写webdockerfile: 官方dockerfile
将宿主机的entry.sh发到容器中,放在根目录下
脚本中只写两条指令,一条后台运行php,一条前台运行nginx用于阻塞容器,只要跑多个服务就写脚本
CMD [“/entry.sh”]
#!/bin/bash #desc:docker容器的入口脚本
php-fpm7.4
nginx -g “daemon off;”
根据dockerfile生成的镜像运行可道云容器并连接mysql,redis
进入Dockerfile所在目录生成镜像
chmod +x entry.sh
docker build -t web:kodbox_v1 .
docker run -d --restart=always --name kodbox_v1 -p 8888:80 web:kodbox_v1 /entry.sh
启动mysqldocker volume create mysql57_kodboxdocker volume ls
docker run -d –name mysql57_kodbox –restart=always -v mysql57_kodbox:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=666 \
-e MYSQL_DATABASE=kodbox \
-e MYSQL_USER=kodbox \
-e MYSQL_PASSWORD=1 \
-p 3306:3306 \
-p 33060:33060 \
mysql:5.7-debian
链接数据库容器docker exec -it mysql57_kodbox mysql -ukodbox -p1
启动redis容器docker volume create redis5.0_datadocker run -d --name "redis5.0" --restart=always -v redis5.0_data:/data/ -p 172.18.244.60:6379:6379 redis:5.0-alpine
进入安装页面,mysql;redis的地址都写私网IP即可,成功配置后设置账号密码
admin 123456Ok.
dockerfile优化
清除镜像中缓存,避免镜像文件过大
可以删:/var/cache 缓存文件/usr/share/doc 软件的帮助
删前注意:/usr/lib 软件安装位置,dockerfile中指定安装了很多php的依赖可以适当删除/usr/bin 命令位置,系统内置到解释器中的命令删不掉(如cd)/usr/share/locale 字符集语言,可以留几个常用的,zh,en开头留着
脚本优化方向
在容器运行后启动的脚本中加入语法检查的判断,如果检查失败则退出脚本输出报错
在根据dockerfile生成镜像的过程中,docker会把完成的每一步生成缓存,如果某一步报错了,修改dockerfile重新运行docker build会自动检查前面的步骤是否有变化,如果有变化则重新加载那一步,没变化不进行处理,从报错的步骤往下继续运行
kodbox两个模式
模拟桌面和类似网盘的文件管理系统
开源版本:用户10个以内,更多需要付费版支持

kodbox接入负载
多运行几个容器
docker run -d -p 8889:80 –name kodbox_final_8889 –restart=always web:kodbox_v1
docker run -d -p 8890:80 –name kodbox_final_8890 –restart=always web:kodbox_v1
docker run -d -p 8891:80 –name kodbox_final_8891 –restart=always web:kodbox_v1
负载机配置文件/etc/nginx/conf.d/kodbox.linuxjk.cn.conf
upstream kodbox_pools {
ip_hash;
#hash $remote_addr consistent;
server 10.0.0.81:80;
server 10.0.0.81:8889;
server 10.0.0.81:8890;
server 10.0.0.81:8891;
}
server {
listen 80;
server_name localkodbox.linuxjk.cn;
location / {
proxy_pass http://kodbox_pools;
include proxy.conf;
}
}
统一proxy配置/etc/nginx/proxy.conf
#Host头保留
proxy_set_header Host $http_host;
#XFF头
#XFF追加
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Ip $remote_addr;
#proxy_cache oldboy_lidao;
#proxy_cache_valid 200 302 1h;
#proxy_cache_valid 301 1d;
#proxy_cache_valid any 1m;
#ngx buffer
proxy_buffering on;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;
proxy_buffers 32 128k;
多阶段提交:编译安装tingene的dockerfile
一般在需要编译安装软件包或者代码时使用,一个Dockerfile中有多个FROM
解决镜像大小问题,第一次编译完361M,最终结果160M
ADD/COPY –from调用中间镜像,最终把加工出的结果复制出来在最终镜像中使用

Dockerfile内容:
创建好临时镜像后使用COPY 或ADD –from=temp ,将编译安装后的结果都复制到新镜像中
安装命令需要的依赖
创建用户组,用户
配置日志
构建与运行docker build -t web:bunengsi_tengine_v1 .docker run -d --name "bunengsi_tengine_v1" --restart=always -p 90:80 web:bunengsi_tengine_v1
浏览器访问

案例29 : war包容器tomcat
案例30: 制作jar包容器-ngx-webtui
案例:31前后端分离镜像
dockerfile小结
目标:自定义镜像
终极目标:根据企业需求创建各种各样的镜像(服务,配置,代码)
项目目标:
1.网站架构容器化.
2.一般web服务器即可
熟练掌握dockerfile格式及书写,dockerfile常用的指令,尽量多阅读官方或gitee/github上面的代码中的dockerfile.

.dockerignore 和dockerfile同一层级的隐藏文件
如果当前的dockerfile所在目录中正好有dockerfile所需的代码文件,用不到这个文件
如果dockerfile所在目录有很多和dockerfile不相关的文件,为了避免创建出来的文件过大,可以使用创建.dockerignore文件告诉docker服务端需要忽略的文件,不会被传输到镜像内(docker老版本有这个问题)
docker镜像层次架构
未来应用的时候,镜像做好后存放在镜像仓库中

服务镜像:最好一个服务一个镜像
应用镜像:服务镜像+代码形成
这些镜像放在公司内部,做一个镜像仓库(私有云)
容器互联 —link
–link是用于容器连接其他容器的选项,其他容器要运行中才行.
案例 分离式 nginx+php

问题:nginx和php如何互联
方案:1.使用ip链接,使用nginx的配置文件修改ip(繁琐)php的ip不固定
2. docker run 通过–link 连接两个容器(单向)类似于软链接
流程:
机器清单:nginx:1.24-alpine;php:7-fpm
准备好ngx,php配置文件, docker run -v 挂载配置文件,代码目录
修改配置,挂载配置,(nginx依赖php,先启动php,再启动nginx)
启动php容器 挂载www.conf到php容器中/usr/local/etc/php-fpm.d/www.conf
docker run -d –name test_php74 –restart=always \
-v `pwd`/conf/www.conf:/usr/local/etc/php-fpm.d/www.conf \
-v `pwd`/code/:/app/code/kodexp/ \
php:7-fpm
两个容器之间连接,所以php不需要设置端口映射
docker run -d –name kodexp_ngx –restart=always –link test_php74:php \
-p 12307:80 \
-v `pwd`/conf/nginx.conf:/etc/nginx/nginx.conf \
-v `pwd`/conf/kodexp.conf:/etc/nginx/conf.d/kodexp.conf \
-v `pwd`/code:/app/code/kodexp \
nginx:1.24
test_php74:php给test_php74容器起一个别名为php,nginx解析时会自动找到php容器的ip
在nginx配置文件中写–link右面的名字指代php容器的ip
location ~ \.php$ {
fastcgi_pass php:9000;
nginx与php,代码目录必须一致.因为php解析代码的时候也要找这个代码目录,如果不指定,php工作目录默认为/var/www/html/目录

小结
–link用于容器之间连接nginx ʖ php ,
–link本质是在对应的机器上添加了1个hosts解析 容器名字与容器的ip
给官方的php镜像安装php依赖:可以使用
docker-php-ext-install命令,我们自定义的镜像是不能使用的
通过自定义镜像或手动进入容器.
apt install -y zlib1g-dev libpng-dev
docker-php-ext-install gd
docker-php-ext-configure gd
php -m |grep gd
检查
<?php
phpinfo();
?>
里面有gd即可
docker -f过滤指令(docker自带过滤工具)
官方文档:
也可以用于过滤特定状态的容器:
根据镜像名字进行过滤reference,过滤.
docker images -f "reference=web"(默认按照时间排序)
docker images -f "reference=web:exam*"
docker images -f "reference=web:exam_back*"
对比镜像时间过滤出更加老的镜像
docker images -f "before=web:exam_back_v2"
对比镜像时间过滤出更加新的镜像
docker images -f "since=web:exam_back_v2"
过滤出指定镜像,同类中更老的镜像
docker images -f "reference=web:exam_back*" -f "before=web:exam_back_v2"
根据容器运行状态/是否health过滤:
docker ps -f "status=exited"(running)
docker ps -f 'health=unhealthy'
过滤后删除
docker images -f “reference=web” | awk ‘NR>=2{print $3}’ (以后镜像名字可以写细致一点)
dd4eecedb141
087139b2256d
553b048b46b4
e4fc4a61b303
awk取出id后交给docker rmi或者加上-q就可以只显示镜像id,最后通过docker rmi删除
容器名字要有规范与标准化.
工具类镜像
好多镜像没有内置这些镜像,准备好一个有各种工具的镜像,需要运行的时候使用–link连接上需要调试的容器,
可以写dockerfile用于不同环境复用,也可以下载系统镜像进行安装
ping /telnet/nmap/nc/其他排查工具/ab/mysql客户端(测试mysql -h 指定ip -P指定端口 -u 用户 -p 密码能不能连通)
docker run -itd –link 调试容器 /bin/bash
Docker Compose—官网二进制版本(最新)
目前面临的问题:
- docker run指令越来越长.
- docker build后需要手动运行docker run.
解决:通过docker compose实现.
compose带来的新问题:docker compose单机编排工具,遇到网站群里的管理较为费劲.
容器集群管理解决方案:
- ansible+docker compose
- docker swarm docker官方提供集群管理工具.
- k8s(kubernetes) 容器集群编排与管理工具.
- mesos
- rancher web页面
通过Dockerfile一键创建镜像.
目前问题:⚠docker容器的管理(启动,关闭,重启),需要手动执行,如何管理多个容器.
部署与使用:
yum install -y docker-compose
环境准备
mkdir -p /server/compose/01-run-nginx
docker-compose格式
配置文件和ansible类似,但是比ansible简单

默认支持的compose文件名:docker-compose.yaml/docker-compose.yml

[root@docker01 /app/docker/compose/01-ngx]# cat index.html
docker-compose-ngx1.24
[root@docker01 /app/docker/compose/01-ngx]# cat docker-compose.yml
version: “3.3”
services:
ngx:
image: “nginx:1.24”
ports:
– 18888:80
restart: always
volumes:
– “./index.html:/usr/share/nginx/html/index.html”
1. 文件格式
cat docker-compose.yml
version: “3.3”
services:
web_ngx:
image: “nginx:1.20.2-alpine”
links:
– web_php
ports:
– “8000:80”
web_php:
image: “php:7-fpm”
2. 启动命令
docker-compose up -d
-d 后台运行
案例kodexp案例:nginx/php两个容器之间通信

注意这里使用的links连接方式,在Docker Compose中,links 参数应该使用服务名(service name)而不是容器名(container name)。
- 服务名(service name):
kodexp_php_dc– 在Docker Compose网络内部使用的标识 - 容器名(container name):
kodexp_php_v2_dc– 在宿主机Docker环境中使用的标识
为什么使用服务名
Docker Compose网络机制:
- Compose会为项目创建一个专用网络
- 在网络内部,服务之间通过服务名进行通信
links参数实际上是在配置网络内的DNS解析
#在较新版本的docker-compose中 不需要显式声明links,Compose会自动创建网络
为什么可以省略links?
- 自动网络创建: Compose会自动创建网络并将所有服务加入
- DNS自动解析: 在网络内可以通过服务名直接访问其他服务
- 更简洁的配置: 减少冗余配置
depends_on指定依赖容器,需要先运行php
修改docker-compose与生效
如果docker-compose简单修改端口,数据卷.docker-compose up -d 会自动识别,重新创建容器.
如果容器的名字也改了,会造成新旧容器的端口冲突,会失败. 可以 up -d –remove-orphans 删除之前容器或失效容器
案例包含数据库kodbox案例:
部署kodbox,ngx,php,db
流程:
- docker run 数据库容器,数据卷挂载(数据卷空间)
- ngx+php 1个镜像(dockerfile) docker build 然后run
改为docker-compose:
- 读取dockerfile构建,并且指定镜像名字

cat docker-compose.yml
version: "3.3" services: kodbox_ngx_php: image: "web:kodbox_dc_v1" build:#根据Dockerfile构建上面名字的镜像 context: . ports: - 12306:80 links:#新版本的可以不加,会自动创建网络 - kodbox_db:db depends_on:#此kodbox容器依赖db容器 - kodbox_db restart: always kodbox_db: image: "mysql:5.7-debian" volumes:#数据卷挂载 - kodbox_db_5.7:/var/lib/mysql environment:#环境变量,同docker run 的-e - MYSQL_ROOT_PASSWORD=666 - MYSQL_DATABASE=kodbox - MYSQL_USER=kodbox - MYSQL_PASSWORD=1 volumes:#与services同级,用于自动在宿主机上创建目录 kodbox_db_5.7:
compose文件的常用指令
volumes: 挂载数据卷
depends_on容器之间的依赖,先后顺序
docker-compose启动多个dockerfile的容器
前后端分离
nginx镜像包含前端代码+ngx配置文件
后端镜像jdk+jar包+配置文件
数据库独立.
后端内容[root@docker01 /app/docker/compose/04_all_in_one_exam]# tree -F
.
└── exam_back/
├── application-prod.yml
├── Dockerfile
├── entry.sh*
└── xzs-3.9.0.jar
1 directory, 4 files
前端内容
exam_front
├── admin.tar.gz
├── Dockerfile
├── exam.conf
└── student.tar.gz
2 directories, 8 files

书写docker-compose version: "3.3"
services:
exam_db:
image: "web:exam_db_dc_v1"
container_name: exam_db_v1#指定容器名
build:#根据/db/路径下的Dockerfile进行构建镜像
context: ./db/
dockerfile: Dockerfile
volumes:
- exam_db_80_dc:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=1
- MYSQL_DATABASE=exam
- MYSQL_USER=1
- MYSQL_PASSWORD=1
exam_back:
image: "exam:backend_v1"
build:
context: ./exam_back/
dockerfile: Dockerfile
ports:
- 8000:8000
links:
#连接exam_db,简写db
#(在compose网络中exam_db就相当于exam_db_v1这个容器)
- exam_db:db
depends_on:
- exam_db
restart: always
exam_front:
image: "exam:front_v1"
build:
context: ./front/
dockerfile: Dockerfile
ports:
- 80:80
links:
- exam_back:back
depends_on:#前端依赖后端服务
- exam_back
restart: always
volumes:
exam_db_80_dc: