@[toc]
1. 镜像和容器
- 镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
- 容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。
2. Docker和DockerHub
- DockerHub:DockerHub是一个Docker镜像的托管平台。这样的平台称为Docker Registry。
- 国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库等。
3. docker架构
-
Docker是一个CS架构的程序,由两部分组成:
1、服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等
2、客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。
- 镜像:
将应用程序及其依赖、环境、配置打包在一起 - 容器:
镜像运行起来就是容器,一个镜像可以运行多个容器 - Docker结构:
服务端:接收命令或远程请求,操作镜像或容器
客户端:发送命令或者请求到Docker服务端 - DockerHub:
一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry
4. 镜像相关命令
- 镜像名称一般分两部分组成:[repository]:[tag]。
- 在没有指定tag时,默认是latest,代表最新版本的镜像

5. 镜像操作命令

- 从DockerHub中拉取一个nginx镜像并查看
1、首先去镜像仓库搜索nginx镜像,比如DockerHub
2、根据查看到的镜像名称,拉取自己需要的镜像,通过命令:docker pull nginx
3、通过命令:docker images 查看拉取到的镜像
- 利用
docker save将nginx镜像导出磁盘,然后再通过load加载回来
1、利用docker xx --help命令查看docker save和docker load的语法
2、使用docker save导出镜像到磁盘 
3、使用docker load加载镜像
删除 nginx 镜像


6. 容器相关命令

6.1 创建运行一个Nginx容器
步骤一:去docker hub查看Nginx的容器运行命令
docker run --name containerName -p 80:80 -d nginx
命令解读:
1、docker run :创建并运行一个容器
2、--name : 给容器起一个名字,比如叫做nx
3、-p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器
4、nginx:镜像名称,例如nginx,不写版本默认最新版
-
运行后:

-
查看 ip的 8080 端口


-
查看访问容器的日志信息:
docker logs 容器名称
-
跟踪日志持续输出:

- docker run命令的常见参数有哪些
--name:指定容器名称-p:指定端口映射-d:让容器后台运行 - 查看容器日志的命令:
docker logs 容器名或id - 添加
-f参数可以持续查看日志:docker logs -f 容器名或id - 查看容器状态:
docker ps
6.2 进入Nginx容器,修改HTML文件内容
- 步骤一:进入容器。进入我们刚刚创建的nginx容器的命令为:
docker exec -it nx bash
-
命令解读:
docker exec:进入容器内部,执行一个命令-it: 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互nx:要进入的容器的名称,如:nginx 别名 nxbash:进入容器后执行的命令,bash是一个linux终端交互命令 - 步骤二:进入nginx的HTML所在目录
/usr/share/nginx/html
cd /usr/share/nginx/html
- 步骤三:修改index.html的内容
sed -i 's#Welcome to nginx#兮动人#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html

- 查看容器状态:
docker ps - 添加
-a参数查看所有状态的容器 - 删除容器:
docker rm - 不能删除运行中的容器,除非添加
-f参数 - 进入容器:
命令docker exec -it [容器名] [要执行的命令]
exec命令可以进入容器修改文件,但是在容器内修改文件是不推荐的
7. 数据卷
-
数据卷(
volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
- 操作数据卷
- 数据卷操作的基本语法如下:
docker volume [COMMAND]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
1、create创建一个volume
2、inspect显示一个或多个volume的信息
3、ls列出所有的volume
4、prune删除未使用的volume
5、rm删除一个或多个指定的volume
7.1 创建一个数据卷,并查看数据卷在宿主机的目录位置
1、创建数据卷
docker volume create html
2、查看所有数据
docker volume ls
3、查看数据卷详细信息卷
docker volume inspect html

4、删除未使用的volume
docker volume prune

5、删除一个或多个指定的volume
docker volume rm html

- 数据卷的作用:
将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全 - 数据卷操作:
docker volume create
docker volume ls
docker volume inspect
docker volume rm
docker volume prune
8. 挂载数据卷
在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器目录
- 创建一个nginx容器,修改容器内的html目录内的index.html内容
- 需求说明:nginx的html目录所在位置/usr/share/nginx/html ,需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。
- 提示:运行容器时使用 -v 参数挂载数据卷
- 步骤:
1、创建容器并挂载数据卷到容器内的HTML目录
docker run --name nginx1 -v html:/usr/share/nginx/html -p 8080:80 -d nginx

2、进入html数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vim index.html

- 数据卷挂载方式:
-v volumeName: /targetContainerPath
- 如果容器运行时volume不存在,会自动被创建出来
9. Dockerfile自定义镜像
-
常见的镜像在DockerHub就能找到,但是如果自己写的项目就必须自己构建镜像了。
-
而要自定义镜像,就必须先了解镜像的结构。
-
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
-
以MySQL为例,来看看镜像的组成结构:

- 镜像是分层结构,每一层称为一个Layer
- BaseImage层:包含基本的系统函数库、环境变量、文件系统
- Entrypoint:入口,是镜像中应用启动的命令
-
其它:在BaseImage基础上添加依赖、安装程序、完成整个应用的安装和配置
- 简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。
- 要构建镜像,其实就是实现上述打包的过程。
10. DockerFile
- Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

- 更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder
1、基于Ubuntu镜像构建一个新镜像,运行一个java项目
步骤1:新建一个空文件夹docker-demo
步骤2:上传docker-demo.jar文件到docker-demo目录
步骤3:上传jdk8.tar.gz文件到docker-demo目录
步骤4:上传Dockerfile到docker-demo目录,dockerfile 文件如下:
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
步骤5:进入docker-demo目录下
步骤6:运行命令:
docker build -t javaweb:1.0 .
-t:表示 tag,镜像的名称由两部分组成:repository:tag,如:javaweb:1.0.:表示 dockerfile 所在的目录


- 启动项目:
docker run --name web -p 8090:8090 -d javaweb:1.0

如果要运行多个 jar 包,上述构建项目的命令好多都是重复的,大部分名称都是在安装jdk的环境等
虽然可以基于Ubuntu基础镜像,添加任意自己需要的安装包,构建镜像,但是却比较麻烦。所以大多数情况下,都可以在一些安装了部分软件的基础镜像上做改造。
例如,构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。
下面就介绍下直接在搭建好的java环境镜像中进行操作
2、基于java:8-alpine镜像,将一个Java项目构建为镜像
- 新建一个空的目录,然后在目录中新建一个文件,命名为
Dockerfile - 上传所需的 docker-demo.jar 到目录中
- 编写Dockerfile文件:
- 基于java:8-alpine作为基础镜像
- 将app.jar拷贝到镜像中
- 暴露端口
- 编写入口ENTRYPOINT,内容如下:
# 指定基础镜像
FROM java:8-alpine
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
- 使用docker build命令构建镜像
docker build -t javaweb:2.0 .

- 使用docker run创建容器并运行
docker run --name web1 -p 8091:8091 -d javaweb:2.0
- 小结:
- Dockerfile的本质是一个文件,通过指令描述镜像的构建过程
- Dockerfile的第一行必须是
FROM,从一个基础镜像来构建 - 基础镜像可以是基本操作系统,如:Ubuntu。也可以是其他人制作好的镜像,例如:
java:8-alpine
11. Docker-Component
- Docker Compose可以基于Compose文件快速的部署分布式应用,而无需手动一个个创建和运行容器。
- Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。
version: "3.8"
services:
mysql:
image: mysql:5.7.25
environment:
MYSQL_ROOT_PASSWORD: 123
volumes:
- "/tmp/mysql/data:/var/lib/mysql"
- "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
web:
build: .
ports:
- "8090:8090"
-
上面的Compose文件就描述一个项目,其中包含两个容器:
1、mysql:一个基于mysql:5.7.25镜像构建的容器,并且挂载了两个目录
2、 web:一个基于docker build临时构建的镜像容器,映射端口时8090 - DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/
-
其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,只是语法稍有差异。
- DockerCompose的作用:
快速部署分布式应用,无需一个个微服务去构建镜像和部署。










