
官网安装教程地址
如果已经安装过旧版本的docker需要先通过以下命令删除
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
然后通过以下命令确认CentOS的版本在7及以上(这里使用的是7.6.1810版本)
cat /etc/centos-release
然后通过以下命令安装gcc环境
sudo yum -y install gcc
sudo yum -y install gcc-c++
然后通过以下命令安装yum-utils
sudo yum install -y yum-utils
然后设置stable镜像仓库(用于下载docker远程仓库中的镜像,因为在大陆所以建议采用阿里或腾讯等的源)
这里采用阿里云的源
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
然后最好更新以下yum软件包索引
注意:CentOS8要去掉fast
sudo yum makecache fast
然后要安装Docker引擎
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
安装完以上环境后就可以启动Docker了
sudo systemctl start docker
启动后通过以下命令测试是否启动完成
sudo docker version
如果出现以下信息则说明安装成功
注意:Client端和Server端的版本号要一致

可以再使用以下命令进行验证
sudo docker run hello-world
如果出现以下内容说明docker运行正常

# 停止服务
sudo systemctl stop docker
# 移除docker依赖
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 移除本地配置文件和各种第三方依赖
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

docker images
如下图所示:

各个表格项说明:
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签(相当于版本号)
IMAGE ID:镜像唯一ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个TAG版本,代表这个仓库源的不同个版本,我们使用REPOSITORY:TAG来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用ubuntu,docker将默认使用ubuntu:latest镜像
常用参数:
-a:列出本地所有的镜像(含历史映像层)
-q:只显示镜像ID
docker search 镜像名称
比如查找redis镜像:

各个表格项说明:
NAME:镜像名称
DESCRIPTION:镜像说明
STARS:点赞数量
OFFICIAL:是否是官方的
AUTOMATED:是否是自动构建的
常用参数:
--limit :只列出N个镜像,默认25个
比如:docker search --limit 5 redis
docker pull 镜像名称[:TAG]
没有TAG就是最新版
等价于
docker pull 镜像名字:latest
docker system df
如下:

docker rmi 某个镜像名字或ID
当被删除的镜像已经创建了实例容器后,需要用以下参数强制删除:
-f
比如:docker rmi -f redis
强制删除多个:
docker rmi -f 镜像名1[:TAG] 镜像名2[:TAG] ...
仓库名、标签都是的镜像,俗称虚悬镜像dangling image
docker run [options] image [command] [arg...]
run执行流程图

常用选项(options,重点):
--name="容器新名字" 为容器指定一个名称;
-d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
-i:以交互模式运行容器,通常与t同时使用;
-t:为容器重新分配一个伪输入终端,通常与-i同时使用;
也即启动交互式容器(前台有伪终端,等待交互);
-P:随机端口映射,大写P
-p:指定端口映射,小写p
释义:
1.启动一个交互式容器,比如一个centos系统

如果使用的不是镜像的latest版本则需要在后面加上版本号
启动完成后注意观察终端的用户名称,会变为新终端的名称。此时可以进行交互

2.端口映射的作用

docker ps [options]

常用选项:
-a:列出当前所有正在运行的容器+历史上运行过的
-l:显示最近创建的容器
-n:显示最近n个创建的容器
-q:静默模式,只显示容器编号
1、使用exit命令退出
run进去容器,exit退出,容器停止
2、ctrl+p+q
run进去容器,ctrl+p+q退出,容器不停止
docker start 容器ID或者容器名
#重启
docker restart 容器ID或者容器名
#停止
docker stop 容器ID或者容器名
#强制停止
docker kill 容器ID或者容器名
一定要先停止容器才能删除
docker rm 容器ID
常用选项
-f:强制删除某个容器,即使正在运行
一次性删除多个容器实例
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
在大部分的场景下,我们希望docker的服务是在后台运行的,我们可以过 -d 指定容器的后台运行模式。
很重要的一点: Docker容器后台运行,就必须有一个前台进程
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
例子:以守护容器的方式启动redis

docker logs 容器ID

docker top 容器ID

docker inspect 容器ID

docker exec [options] 容器ID 命令行环境(bash或者/bin/bash或者/bin/sh)
常用选项
-d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
-i:以交互模式运行容器,通常与t同时使用;
-t:为容器重新分配一个伪输入终端,通常与-i同时使用;
也即启动交互式容器(前台有伪终端,等待交互);
docker attach 容器ID
attach直接进入容器启动命令的终端,不会启动新的进程用exit退出,会导致容器的停止。
exec是在容器中打开新的终端,并且可以启动新的进程用exit退出,不会导致容器的停止。
推荐使用exec

docker cp 容器ID:容器内路径 目的主机路径
注意:导入的容器会作为一个镜像!!!
#导出
docker export 容器ID > 文件名.tar(或者一个新文件的绝对路径,只有文件名即导入到当前目录下)
# 导入
cat 文件名.tar(或者一个新文件的绝对路径) | docker import - 镜像用户/镜像名:镜像版本号
镜像用户、镜像名、镜像版本号均可自定义,注意:横杠和后面的内容直接有空格
export导出容器的内容流作为一个tar归档文件[对应import命令]
import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export命令]

通过该命令将一个容器处理成一个镜像
docker commit -m="提交的信息" -a="作者" 容器ID 要创建的目标镜像名[:版本号]
方式一相当于先把一个容器打包成压缩包然后导入成一个镜像其本质是一个压缩包,每次都是一个整体。方式二相当于在Base镜像的基础上扩展,如下图:

主要作用:
1.将容器内的数据备份到宿主机对应目录中,防止数据丢失
2.在读写权限允许的情况下,可以在宿主机目录中对映射的容器内对应文件进行修改而不必进入容器修改。简化操作

语法:
1.使用命令
使用多个-v命令可以挂载多个文件或目录
如果要设置读写权限则在后面加上即可,如下 (默认为rw):
这里的权限限制的是容器内的目录或文件而不是宿主机
2.使用docker-compose编排服务

个人理解: 比如在宿主机A中有个xxx.txt文件,在容器B中有个yyy.txt文件。
此时通过 -v命令 将宿主机A中的xxx.txt文件与容器B中的yyy.txt文件进行映射(即将容器B中的yyy.txt文件挂载到宿主机A中的xxx.txt文件)。这种映射可以是文件,也可以是目录。
此时如果容器中对应文件是可读写的,那么当在容器B内修改yyy.txt文件的内容时宿主机A中的xxx.txt文件的内容也会相应更改,反之亦然。
如果映射的是目录也是同理,比如在宿主机A的XXX目录中新建了一个xxx.txt文件则在容器内对应的YYY目录中也会新增一个xxx.txt文件,反之亦然。
上述操作,即使容器已经停止了,只要再启动回来也依旧能进行同步。
通过以下命令查看:
docker inspect 容器ID

语法:
1.使用命令
个人理解: 现在有两个容器B1和B2,其中容器B1已经与宿主机建立了某种映射关系。现在通过以上命令将容器B2继承容器B1的映射关系。此时容器B2与宿主机的映射关系就相同了。此时哪怕容器B1停止甚至销毁了,容器B2与宿主机之间的映射关系都不会消失。

如果使用命令则加上--privileged=true即可:

如果使用的是docker-compose编排服务的方式则通过以下配置开启权限:

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
相当于一个清单,里面包含构建当前镜像所需要的所有构建命令。
在Dockerfile中:
1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2:指令按照从上到下,顺序执行
3:#表示注释
4:每条指令都会创建一个新的镜像层并对镜像进行提交
(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4) docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成

FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from
MAINTAINER(已弃用)
镜像维护者的姓名和邮箱地址
RUN
指定容器构建时需要运行的命令
两种格式:
1.shell格式:RUN <命令行命令>
<命令行命令>等同于,在终端操作的shell命令。
2.exec格式
RUN [“可执行文件”,“参数1”,“参数2”]
例如:
RUN [ “./test.php”, “dev”, “offline”]等价于RUN ./test.php dev offline
EXPOSE
当前容器对外暴露出的端口
WORKDIR
指定在创建容器后,终端默认登录进来的工作目录,一个落脚点。即运行该容器后所在的容器内部目录
USER
指定该镜像以什么样的用户去执行,如果都不指定,默认是root
ENV
用来在构建镜像过程中设置环境变量
VOLUME
容器数据卷,用于数据保存和持久化工作
ADD与COPY
ADD:将宿主机目录下的文件拷贝进镜像里的目录且会自动处理URL和解压tar压缩包
COPY:拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
CMD与ENTRYPOINT
都是指定容器启动后(run之后) 要干的事情
CMD:
ENTRYPOINT:

docker在启动后会产生一个名为docker0的虚拟网桥:

1.用于进行docker的网络管理和容器调用之间的规划
2.容器ip变动时候可以通过服务名直接网络通信而不受到影响。docker容器的ip会因为容器的重启、重新创建等产生变动所以推荐用服务名来进行网络通信,避免写死ip
针对第二个作用例子如下:
我们在容器编排时,编排了两个服务mysql和redis:

同时将它们划归到了同一个名为darkforest_net的自定义docker网络下

此时在springboot项目的配置文件中就可以直接采用服务名来连接服务了,而无需写死ip地址:

采用这种方式后,无论mysql和redis两个服务的ip地址如何变化,docker都能自动映射。无需手动变更ip






例子:
通过ip addr命令查看宿主机中的ip分配情况:

以同样的方式查看容器中的ip分配情况:

可以注意到是存在对应关系的,这里描述的就是上面图中bridge上的情况。






要注意:诸如tomcat等容器会默认使用8080端口,此时如果有个tomcat容器采用这种方式共用另一个tomcat容器的网络模式则会造成端口冲突(因为ip和端口都一样)。此时可以选择更改其中一个tomcat容器的默认端口(8080)。
作用:将一个或一组容器划归到同一个自定义网络中(即处在同一网段),以便通过服务名实现容器间的数据互通和进行网络管理。通过创建多个自定义网络来管理多组容器
自定义网络默认使用bridge模式
创建自定义网络命令:
docker network create 自定义网络名称
docker-compose配置文件中:

加入自定义网络选项:
--network 自定义的网络名称
docker-compose配置文件中:

1.采用docker-compose配置文件的方式创建自定义网络时,网络名称会带上所在目录的前缀
在lighthouse目录下执行该docker-compose.yml文件后查看当前所有的docker网络
可以发现多了一个所在目录的前缀
2.docker-compose配置文件中为容器服务配置的网络,一定要在docker-compose配置文件中创建。不能先创建再执行会报找不到网络的错,即便加上目录前缀也没用。(docker版本:20.10.21;docker-compose版本:2.12.2)
命令:
docker network ls

命令:
docker network inspect 网络ID






实际生产场景中一般使用一下命令来将容器实例运行为后台服务:
docker-compose up -d
模板文件是使用 Docker Compose 的核心,涉及到的指令关键字也比较多。默认的模板文件名称为 docker-compose.yml ,格式为YAML 格式。一个 docker-compose.yml 文件可以分为三层:
#第一层 版本号
version: "3.8" #代表使用docker-compose项目的版本号
#第二层:services 服务配置
services:
web:
build: .
ports: #宿主机和容器的端口映射
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
# 第三层 其他配置 网络、卷、全局规划
...
build 指令
指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
version: "3.8"
services:
web:
build: . #指定Dockerfile的上下文目录为当前目录
如上例子:要求构建web镜像的Dockerfile与 docker-compose.yml 文件在同一目录下。
你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。
使用 dockerfile 指令指定 Dockerfile 文件名。
使用 arg 指令指定构建镜像时的变量。
如下例子:
version: '3'
services:
webapp:
build:
context: ./dir #指定Dockerfile的上下文目录为当前目录的dir目录下
dockerfile: Dockerfile-alternate #指定要运行的Dockerfile文件名为Dockerfile-alternate
args:
buildno: 1
command 指令
覆盖容器启动后默认执行的命令,类似于docker run image 命令
以下面的Dockerfile文件为例,容器启动后执行的是 java -jar apps.jar
FROM openjdk:8-jre
EXPOSE 8081
ENV APP_PATH=/apps
WORKDIR $APP_PATH
COPY apps.jar $APP_PATH
ENTRYPOINT ["java","-jar"]
CMD ["apps.jar"]
如果我们想要容器启动后执行的是 java -jar test.jar,
在docker-compose.yml文件中使用指令 command: [“test.jar”]
version: '3'
services:
webapp:
build:
context: ./dir #定Dockerfile的上下文目录为当前目录的dir目录下
dockerfile: Dockerfile-alternate
args:
buildno: 1
command: ["test.jar"]
container_name 指令(不推荐使用)
指定容器名称。默认将会使用 所在目录名_服务名称_序号 这样的格式。
container_name: docker-web-container
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
depends_on 指令
解决容器的依赖、启动先后的问题。以下例子中会先启动 redis 、db 再启动 web:
version: '3'
services:
web:
build: .
depends_on: # web服务依赖于db和web服务
- db
- redis
redis:
image: redis
db:
image: postgres
注意:在启动web服务时,并不会等待 redis 、db 服务进入ready状态,而只是等到它们被启动状态(running状态)。
environment 指令
设置环境变量,相当于 docker run -e。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 的宿主机上对应变量的值,可以用来防止泄露不必要的数据。
version: '3'
services:
mysql:
image: mysql:5.7
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root #字典格式
#====================================================
environment:
- "MYSQL_ROOT_PASSWORD=root" #数组格式
- "SESSION_SECRET"
env_file 指令
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则按照惯例,以 environment 为准。
env_file: .env
env_file: #指定多个环境变量文件
- ./common.env
- ./.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持 # 开头的注释行。
环境变量文件 .env:推荐使用这种命名,因为在Linux下,这种方式命名的文件属于隐藏文件,一定程度上防止泄露不必要的数据。
expose 指令
用来指定镜像构建过程中容器暴露的端口号,但不映射到宿主机,只被连接的服务访问。
该指令compose配置文件中一般不用,都在Dockerfile文件中使用EXPOSE指定。
image 指令
指定创建容器实例服务所依赖的镜像,一般为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像,相当于 docker run image(镜像名)。
networks 指令
指定启动容器时使用的网络,相当于 docker run --network
详情见Docker network章节
version: "3"
services:
some-service:
networks:
- some-network #指定使用的网络
- other-network
networks: #创建网络
some-network:
other-network:
ports 指令
指定宿主机和容器端口映射,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

注意:当使用 HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为YAML会自动解析xx:yy这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
volumes 指令
用来指定宿主机目录(或文件)和容器目录(或文件)映射。目录(或文件)不存在时会自动创建
详情见容器数据卷章节
version: "3"
services:
my_src:
image: mysql:8.0
volumes: #数据卷名称挂载
- mysql_data:/var/lib/mysql
volumes: #定义数据卷名称
mysql_data:
restart 指令
指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效。
restart: always