docker主要解决了最初软件开发环境配置的困难,完善了虚拟机部署的资源占用多,启动慢等缺点,保证了一致的运行环境,可以更轻松的维护和扩展。docker在linux容器的基础上进行了进一步的封装,提供更简单易用的接口。
把自己的应用放入容器,应用在docker的虚拟容器里运行,就像在真实的物理机上运行一样,容器还可以进行版本管理、复制、分享、修改等,像管理普通的代码一样简单。
镜像(Image)
docker镜像一个特殊的文件系统。主要作用是提供容器运行时需要的程序、库、资源、配置参数等。
docker镜像的最大特征是分层存储(即它并不是由一个文件组成,而是由多层文件联合组成)
镜像分为基础镜像(各大厂商提供的,例如ubuntu、node镜像等)和个人镜像(由个人开发者构建上传)。
容器(Container)
容器是基于镜像创建的,镜像和容器类似于js中的类和对象(镜像是静态定义,容器是镜像运行时的实体)。
容器既然是基于镜像创建的,那么容器也是分层存储的。每一个容器都是以一个镜像为基础层,在其上创建一个当前容器的存储层,即容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失,因此容器不应该向其存储层内写入任何数据
容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository)
docker仓库是集中存放镜像的地址。类似于npm包和npm仓库的关系。可以将本地的容器发布到一个镜像仓库中,给其他服务器使用。
每个镜像仓库可以包含多个不同版本的标签(Tag);每个标签对应一个镜像。
我们从镜像仓库中获取镜像是通过<仓库名>:<标签>?来指定版本的镜像(eg:ubuntu18.04)
? ? ? ? 描述:从dockerHub搜索镜像(?在docker Hub上有大量的镜像可以使用,类似于npm仓库)
? ? ? ? 描述:从dockerHub上拉取镜像使用
? ? ? ? 示例:docker pull ubuntu:18.04
? ? ? ? ? ? ? ? ? ?docker pull docker.io/library/node:18-alpine
? ? ? ? 描述:列出本机所有镜像
? ? ? ? 描述:可以通过镜像的ID、长ID、名称等进行定位并删除镜像,也可以批量删除镜像
理解:我们除了可以使用官方镜像,还构建自己的镜像,通常都是在其他的镜像基础上进行构建,例如node、nginx等。
可以到官网理解镜像的构成原理,然后发现构建镜像其实是通过一条条指令构建出来的。因此构建镜像可以新建一个Dockerfile文件来编写指令完成。
构建流程:
1,创建Dockerfile文件:
mkdir mynginx #创建一个目录
cd mynginx/ #进入新建的目录跟文件夹
touch Dockerfile #创建文件
2,Dockerfile文件内容:
FROM nginx
RUN echo '<h1>Hello, This is My Nginx</h1>' > /usr/share/nginx/html/index.html
??指令说明:
??FROM:基于哪个基础镜像进行定制
??RUN:执行命令行的命令(注意:每一个RUN都会新建一层然后执行命令,因此一个Dockerfile文件尽量使用一次RUN指令)
3,构建镜像:
docker build [选项] <上下文路径/URL/->
docker build -t mynginx:v3 .
? 描述:最后的点.?即为上下文路径。
? 注意:这个上下文路径并不是Dockerfile所在的路径,而是Dockerfile中指令工作的目录。(例如Dockerfile文件中经常能见到拷贝代码到镜像中“COPY ./package.json /app/”这种命令,他复制的是上下文路径下的package.json文件)
?源路径是URL,ADD会自动下载文件到目标目录;如果源路径是压缩文件,则复制并解压缩
?区别是,当一个文件指定了ENTRYPOINT,则CMD的含义就会发生变化,不再是直接的运行其命令,而是将
CMD
的内容作为参数传给ENTRYPOINT
指令?应用场景:例如在启动前需要启动一些其他文件
["/bin/sh", "-c"]
)示例:
#基础镜像
FROM alpine:3.4
#复制目录
COPY --chown=55:mygroup files* /mydir/
#复制压缩包并解压
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /mydir/
#运行指定的文件命令
ENTRYPOINT ["docker-entrypoint.sh"]
#定义匿名卷到/data目录
VOLUME /data
#声明端口6379
EXPOSE 6379
#切换用户root
USER root
#切换工作目录/app
WORKDIR /app
#设置环境变量
ENV NODE_VERSION 7.2.0
ENV VERSION=1.0 DEBUG=on
#下一级镜像构建时复制package.json到app目录,同事执行npm install
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
#添加元数据
LABEL APP_CON app-config
#指定shell命令并运行shell一行指令
SHELL ["/bin/sh", "-c"]
RUN lll; ls
#启动命令
CMD [ "npm", "start" ]
CMD [ "redis-server" ]
docker run [选项] 镜像名称 [命令] [参数...]
选项列表:
- -d:容器守护态运行(即容器在后台运行)
- -t:为容器分配一个伪输入终端,通常与-i同时使用(退出终端使用
exit
命令或者ctrl+d
)- -i:以交互模式运行容器(就是允许用户交互),通常与-t同时使用
- --name:为容器指定一个名称(默认是随机名称)
- -P:随机端口映射
- -p:指定端口映射
- -e:设置环境变量
- --rm:退出容器后删除该容器
- ... ...
命令常用:
- /bin/bash:启动容器后立即执行的命令
示例:
#启动ubuntu容器,并立即关闭
docker run ubuntu:18.04 /bin/bash
#启动ubuntu容器,并输出Hello world,然后终止容器
docker run ubuntu:18.04 /bin/echo 'Hello world'
#启动ubuntu容器,并允许用户进行交互
docker run -it ubuntu:18.04
#启动ubuntu容器,并且在后台一直运行
docker run -d ubuntu
docker [?container ]?start?容器ID/名称
docker [ container ]? restart?容器ID/名称
docker [ container ]? stop 容器ID/名称
对于不会终止的容器,需要使用:docker [ container ]??kill 容器ID/名称
Tips(终止容器后的确定操作):
(1)运行docker ps,确定该容器不在查询结果列表中
(2)运行docker ps a,确定该容器可以查询到,并且STATUS值为Exited
示例:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
af3e13b5d2r3 ubuntu:18.04 "/bin/bash" 1 hours ago Exited (0) 2 minutes ago
说明:由于在使用 -d
参数时,容器启动后会进入后台,因此某些时候需要进入容器进行操作。
方式:
(1)docker exec [选项]?容器ID/名称?[命令]?-?建议使用。因为从这个容器退出,容器不会停止
(2)docker attach - 不建议使用。因为从这个容器中退出,会导致容器停止
说明:
示例:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
af3e13b5d2r3 ubuntu:18.04 "/bin/bash" 18 hours ago Up 17 seconds
#进入容器,只使用参数-i
$ docker exec -i af3e13b5d2r3 bash
ls
bin
boot
dev
etc
home
lib
pwd
/
#进入容器,同时使用参数-i和-t
$ docker exec -it af3e13b5d2r3 bash
root@af3e13b5d2r3:/# exit
docker logs [选项] 容器ID/名称
选项列表:
- -f :?实时跟踪日志输出
- -t :?给日志加上时间戳显示
- --tail :仅列出最新N条容器日志
- --since :显示某个开始时间的所有日志
示例:
# 查看后台运行的日志
docker logs af3e13b5d2r
# 实时监控(类似tail -f)
docker logs -f af3e13b5d2r
# 获取最后10行
docker logs --tail 10 af3e13b5d2r
# 实时查看最近的日志
docker logs --tail 0 -f af3e13b5d2r
# 加上时间戳
docker logs -t af3e13b5d2r
删除一个终止状态的容器:docker [ container ]? rm 容器ID/名称
删除一个运行状态的容器(加一个-f参数):docker [ container ]? rm -f 容器ID/名称
因容器中是随用随删,并不会保存数据记录。因此对于容器中使用mysql这种需要数据持久化的,则需要容器的数据管理。有数据卷、挂载主机目录两种方式。
数据卷:是一个可以提供一个或者多个容器使用的特殊目录,他提供了很多有用的特性。
创建数据卷:docker volumn create
列出所有数据卷:docker volumn ls
挂载主机目录:挂载到本地的一个绝对路径下,需要注意的是挂载的目录下有程序运行需要的文件,例如nginx容器在本地目录/home/nginx下要有index.html文件。
示例:$ docker run -d -P --name web --mount source=/home/nginx,target=/usr/share/nginx/html nginx
访问docker官方维护的公共仓库,可以先在https://hub.docker.com免费注册一个 Docker 账号,然后通过docker login登录命令,docker logout退出命令,并通过docker?search来查找镜像。
更详细的API与教程可参考:
前言 - Docker — 从入门到实践https://yeasy.gitbook.io/docker_practice/
通过docker完整的部署一个vue工程,可参考: