安装Linux虚拟机
在虚拟机上去安装docker
参考文档:
https://b11et3un53m.feishu.cn/wiki/FJAnwOhpIihMkLkOKQocdWZ7nUc
"绿色免安装版"
镜像:
当我们利用Docker安装应用时, Docker会自动搜索并下载应用镜像(image) 。镜像不仅包含应用本身,还包含应用运行所需要的环境、配置、系统函数库。
镜像忽略操作系统,一个镜像多个系统兼容
镜像只需要下载一次,可以创建多个实例
容器:
Docker会在运行镜像时创建一个隔离环境,称为容器(container)。
独立的网络,内存,文件系统
镜像仓库:
镜像仓库:存储和管理镜像的平台, Docker官方维护了一个公共仓库: Docker Hub。
公共仓库访问地址:https://hub.docker.com/_/nginx

这个图还是有些问题哈,通过同一个镜像创建出来的应用是被放在不同的容器中单独隔离的,而不是图中的在同一个容器中。
d ocker run : 创建 并 运行 一个 容器
bash
# -d表示 detached mode分离模式,即后台运行
docker run: 创建并运行一个容器,-d 是让容器在后台运行
bash
docker run -d \
--name mysql \
-р 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
逐行参数解析:
--name mysql :给容器起个名字,必须唯一
docker run :创建并运行一个容器
-d是让容器在后台运行
-p 3306:3306 :设置端口映射(第一个是宿主机端口,第二个是容器内端口)
-e KEY=VALUE :是设置环境变量(根据该镜像的官方文档做不同的配置)
mysql:指定运行的镜像的名字
端口映射:
因为没法访问mysql容器内部 只能做端口映射
容器内端口不需要改动,取决于进程,比如mysql的端口就是3306
镜像名规范:
- 镜像名称一般分两部分组成: [repository]:[tag]。
- repository---镜像名
- tag---镜像的版本
- 在没有指定tag时,默认是latest,代表最新版本的镜像
docker pull: 拉取镜像
docker images:查看本地镜像列表
docker rmi:删除镜像
docker build:通过声明docker file来自定义打包docker镜像
docker save:将本地镜像保存为压缩文件
docker load:将压缩文件加载到本地镜像列表中
docker push:推送镜像到镜像仓库
docker run:运行docker镜像(注意,运行一次镜像就会创建一个容器哦,执行一次就好了)
bash
# 暴露指定的服务端口
docker run -d -p 8080:8080 -e HOST=0.0.0.0 your-image
# 启动临时容器(添加 --rm 自动清理)
# 不添加退出后会停止变成exit状态,自动清除条件:仅当手动执行删除或系统级清理时
docker run -it --rm alpine sh
# 重新进入已停止的容器
# -a 附加到容器的标准输出/错误流,实时显示容器启动时的日志和输出
# -i 以交互模式运行,允许您通过终端与容器内的进程交互(如输入命令)
docker start -ai
docker stop:停止容器内进程(容器还在)
bash
docker stop <旧容器> && docker rm <旧容器>
docker start:重新启动容器内进程
docker ps:查看正在容器运行状态(被停掉的看不见)
- docker ps --format "table {{.ID}}\t{{.Image}}{t{{.Ports}}\t{{.Status}}\t{{.Names}}"(选择性输出)
docker ps -a:查看所有本地容器(包括停掉的容器)
docker rm:删除容器
- 运行中的容器删不了
- 删除方法一:docker stop 然后rm
- 删除方法二: docker rm mysql -f (添加f参数强制删除)
docker logs:查看容器运行日志
- docker logs -f:实时查看容器的运行日志,一直卡在当前命令,当有人操作的时候就会继续输出日志,使用 ctrl + C停止(用于调试)
docker exec:进入容器内部
- -it :可交互的终端
- bash:指定交互工具为bash
bash
docker exec -it nginx sh
列出所有Docker镜像,并通过grep筛选出包含'xxx-frontend'的镜像
bash
docker images | grep xxx-frontend
附:全流程图:

bash
curl -v http://localhost:8080
举例:拉取nginx镜像到本地
bash
# 从官网上拉取镜像到名称,后面不跟版本号默认拉取latest
docker pull nginx
# 查看本地镜像列表
docker images
补充:不理解的命令可以通过help命令来查看
bash
docker save --help
Linux中 ll命令的作用是 以详细列表形式显示当前目录下的文件和子目录信息 。
ll
针对于容器信息过多的情况,也可以加格式化方式访问,格式会更加清爽
bash
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
命令别名:
通过修改系统文件来简化docker命令的输入

docker权限:
临时会话权限
bash
# 检查当前会话是否加载了 docker 组
id -nG
# 或
groups
# 查看当前用户组
groups | grep docker
# 如果未显示 docker 组,重新添加
sudo usermod -aG docker $USER
# 立即激活当前用户对 docker用户组的组成员权限
# 强制刷新当前会话的组权限,使 docker组权限立即可用
newgrp docker
- newgrp仅对当前 Shell 会话有效, 新开的终端仍需重新登录或再次执行 newgrp 。
- 执行后会启动一个子 Shell(可通过 exit返回原 Shell),原环境变量可能被重置。
建议:
- 长期解决方案仍是 退出并重新登录 。
- 脚本中建议使用 sg docker "command"替代。
长期权限:
将用户加入 docker组
bash
# 添加当前用户到 docker 组
sudo usermod -aG docker $USER
# 验证是否添加成功
grep docker /etc/group
如何退出/登录服务器
bash
# 1. 关闭当前终端或输入
exit
# 2. 重新登录服务器
ssh tenfeifang@your-server-ip
数据卷挂载 ( 宿主机 与 容器 内 目录 的 双向 映射 )
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
创建了数据卷,就会在当前宿主机上创建对应真实的目录,也就是在容器外,当前宿主机上做映射了
好处:因为镜像是一个最小单位,只包括当前镜像运行的配置,当我们需要对镜像做其他修改操作,为了引入其他操作配置,就需要做数据卷的挂载
声明数据卷,每个数据卷都和宿主机上的一个目录进行一一对应了

卷是逻辑的,虚拟的,但是对应的目录是真实的
这样做之后就会双向绑定双向映射(一个地方修改了,另一个地方也会一起修改)

- 在执行docker run命令时,使用**-v数据卷:容器内目录** 可以完成数据卷挂载
- 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷
bash
# 数据卷目录随便写,只要在宿主机上不和别的目录冲突就行
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
# 查看映射的html数据卷的详细信息
docker valume inspect html

本地目录挂载
bash
# 查看当前容器详情
docker inspect <容器名称>
数据卷挂载是由docker自动生成的宿主机的挂载位置,我们可以自定义挂载位置和挂载名称
针对于类似mysql这种自带数据卷的容器,我们最好是对数据卷进行本地自定义目录的挂载,防止因mysql版本升级导致每次生成的匿名数据卷(mysql自带带存储数据的数据卷,防止数据过多不好做迁移,所以自己生成的数据卷)名字都不一样导致的数据丢失(版本升级会导致mysql重新生成匿名数据卷)
- 在执行docker run命令时,使用 -v 本地目录:容器内目录 可以完成本地目录挂载
- 本地目录必须以"/"或"./"开头,如果直接以名称开头,会被识别为数据卷而非本地目录
- -v mysql : /var/lib/mysql 会被识别为一个数据卷叫mysql
- -v./mysql : /var/lib/mysd会被识别为当前目录下的mysql目录
注意哈,因为数据卷的映射是在宿主机的,所以一旦我们完成了改造,无论删多少次myslq,都是同步的我们宿主机的目录,数据是一直在的
原因:
- 宿主机中的目录一直在,容器内存储的位置一直不变,就能一直映射
- 之前是会一直生成匿名存储卷,是因为没有真正我们自定义的本地目录挂载导致(mysql检测不到对当前容器内目录的挂载就会自动生成匿名数据卷)
- 当然我们也可以去自己做存储卷的挂载(挂载volume目录下)也是不会生成匿名数据卷
总之:在创建容器的时候如果不指定数据卷,就会生成匿名数据卷就会导致随机。。。