Docker概述
Docker思想来自于集装箱,打包装箱,每个箱子都是相互隔离的;通过隔离机制,可以将服务器利用到极致
Docker中的名次概念
镜像(image)
docker镜像好比一个模板,可以通过这个模板来创建容器服务,centos镜像->run->centos01容器;通过这个镜像可以创建多个容器(最终使用的就是镜像创建出的容器)
容器(container)
Docker利用容器技术,独立运行一个或者一个组的应用,容器是通过镜像来创建的。
启动、停止、删除 基本命令
可以将一个容器理解为一个简易的linux系统,可以在这个简易的linux系统里安装我们需要的软件,运行我们的项目等等
仓库(repository)
仓库就是存放镜像(image)的地方
仓库分为私有仓库和公有仓库(默认Docker Hub)
在最初使用时候,我们可以将仓库设置为国内仓库提升下载速度
Docker安装
本次实例使用机器为阿里云的服务器,操作系统为centos 7.6
Docker的安装步骤:
#1.安装前,我们将旧版本的docker进行卸载
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2.需要的安装包
yum install -y yum-utils
#3.设置镜像仓库(阿里云)
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4.在安装前我们更新一下yum软件版索引
yum makecache fast
#5.下载安装docker相关 docker-ce为社区版,docker-ee为企业版
yum install docker-ce docker-ce-cli containerd.io
#6.启动docker
systemctl start docker
#7.检查安装是否成功
docker version
#8.配置阿里云镜像加速(个人专属)
#阿里云->容器镜像服务->控制台->镜像工具->镜像加速器->选择自己对应的操作系统进行复制
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://fyshm8qx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker卸载:
#1.卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2.删除资源
rm -rf /var/lib/docker
docker run的运行流程
底层原理
Docker是怎么工作的?
Docker是一个Client - Server 结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问;当DockerServer接收到Docker - Client 的指令,就会执行这个命令
Docker为什么比VM快?
Docker有着比虚拟机更少的抽象层,Docker利用的是宿主机的内核,而VM需要是Guest OS
Docker基本命令
帮助命令
docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help
镜像命令
docker images -aq #查看所有本地主机上的镜像,q只查看id
docker search #搜索镜像,可通过--filter进行过滤
docker pull #下载镜像,在pull后加:版本号可指定版本下载
docker rmi -f #删除镜像,在后面加$(docker images -aq)删除所有镜像
创建容器
docker run [可选参数] image #运行镜像
#参数说明
# --name="Name" 容器名字 centos01 centos02 ,用来区分容器
# -d 后台方式运行
# -it 使用交互方式运行,进入容器查看内容
# -p 容器指定端口, -p 8080:8080
# -p 主机端口:容器端口
# -p 容器端口
# -p 主机ip:主机端口:容器端口
# -P 随机指定端口
docker run -d 镜像名
#问题:在运行之后,使用docker ps命令查看发现运行的镜像停止了
#原因:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
容器命令
#创建一个centos容器并进入
docer run -it centos /bin/bash
#从容器中退回主机,退出后容器会停止
exit
#从容器中退回主机,退出后容器不停止
control + P + Q
#查看所有运行的容器
docker ps
# -a 列出当前运行+历史运行过的容器
# -n=? 显示最近?条创建的容器
# -q 只查询容器id
docker rm 容器id #删除指定容器,不能删除正在运行的容器,如要删除使用 rm -f 强制删除
docker rm -f $(docker ps -aq) #删除所有容器
docker ps -a -q|xargs docker rm #删除所有容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行容器
docker kill 容器id #强制停止当前容器
其他常用命令
#查看日志
docker logs
#查看容器中的进程信息
docker top 容器id
#查看容器内部元数据
docker inspect 容器id
#进入当前正在运行的容器(进入容器并打开一个新的终端)
docker exec it 容器id bash/shell
#进入当前正在运行的容器(进入容器正在执行的终端,不会启动新的进程)
docker attach 容器id
#从容器拷贝文件到本地
docker cp 容器id:容器内路径 目的主机的路径
Docker命令小结
attach Attach to a running container #当前shell下attach连接指定运行镜像
build Build an image from a Dockerfile #通过Dockerfile定制镜像
commit Create a new image from a container’s changes #提交当前容器为新的镜像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同run 但不启动容器
diff Inspect changes on a container‘s filesystem #查看docker容器变化
events Get real time events from the server #从docker服务获取容器实时事件
exec Run a command in a running container #在已存在的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
history Show the history of an image #展示一个镜像形成历史
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
info Display system-wide information #显示系统相关信息
inspect Return low-level information on a container or image #查看容器详细信息
kill Kill a running container #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Register or log in to a Docker registry #注册或者登陆一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within a container #暂停容器
port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
rename Rename a container #重命名容器
restart Restart a running container #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image(s) to a tar archive #保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在dockerhub中搜索镜像
start Start one or more stopped containers #启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop a running container #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within a container #取消暂停容器
version Show the Docker version information #查看容器版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
常用Docker容器部署
Nginx
#1.搜索nginx镜像,默认下载最新版
docker search nginx
#2.拉取/下载镜像
docker pull nginx
#3.查看是否下载成功
docker images
#4.创建nginx容器并且启动,对应本机端口3344
docker run -d --name nginx01 -p 3344:80 nginx
#5.查看nginx容器是否创建并启动成功(查看本机3344端口是否有nginx部署成功)
curl localhost:3344
#6.进入刚刚创建的nginx容器
docker exec -it nginx01 /bin/bash
#7.查找nginx配置文件,可以通过修改配置文件进行容器配置修改
whereis nginx
#问题:每次改动nginx配置文件都需要进入到容器内部,是否可以在容器外部提供个一个映射路径,达到在容器外部修改配置文件,容器内部就可以自动修改?
#解决:-v数据卷实现
Tomcat
#1.搜索tomcat镜像,默认下载最新版
docker search tomcat
#2.拉取/下载镜像
docker pull tomcat
#3.查看是否下载成功
docker images
#4.创建一个tomcat容器并运行,命名tomcat01,对应本机端口3304
docker run -d -p 3304:8080 --name tomcat01 tomcat
#5.访问测试
curl localhost:3304
#问题:访问发现404报错,进入容器内部linux命令缺失,没有webapps
#原因:镜像原因:默认下载最小镜像,把不必要的全部剔除,保证最小可运行环境
#解决:将webapps.dist内的文件复制到webapps内
cp -r webapps.dist/* webapps
#问题:如果每次部署项目都要进入容器进行部署会十分麻烦,是否可以在容器外部提供一个映射路径对应webapps,我们在外部放置项目,自动同步到内部webapps目录内?
可视化
portainer
portainer是一个Docker图形化界面管理工具,提供一个后台面板供我们操作
docker run -d -p 3304:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
在创建完并启动容器之后,我们通过公网IP+端口号去访问这个portainer容器
首先我们创建出个人用户,然后在下一步选择本地
进来后,通过该面板我们就可以可视化的操控我们的docker了
Docker镜像详解
镜像是什么?
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。
所有的应用直接打包成docker镜像,就可以直接运行,不需要再去部署环境。
如何得到镜像:
- 远程仓库下载
- 拷贝已有的镜像
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker的镜像实际上是由一层一层的文件系统(UnionFS联合文件系统)组成。
bootfs(boot file system) 主要包含BootLoader和kernel;BootLoader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在bootfs之上。包含的就是典型的Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOs等等。
相比虚拟机安装CentOS,Docker安装CentOS只需要200M,因为对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。
分层理解
下载完我们可以看看镜像的详细内容,可以查看redis镜像内的layer
docker image inspect redis
理解:
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上创建新的镜像层。
举个例子:假如基于Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。以此类推…
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合。举个简单的例子,下面这张图有两个镜像层,每层各3个文件,整个镜像包含了两个镜像层共6个文件。
但是如果对于上图的镜像有了新需求,就会再添加一个镜像层,在外部看来新的镜像虽然也只有6个文件,实际上是因为上层文件的文件7是文件5的一个更新版。这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windows filter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]
下图展示了与系统显示相同的三层镜像。所有的镜像层堆叠并合并,对外提供的统一视图
Docker的镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们通常说的容器层,容器之下都叫镜像层
Docker的所有镜像包(Image)都包含一个叫Dockerfile的文件,我们可以理解Docker镜像和千层蛋糕一样,有一层一层的分层,绝大部分还夹了不同的馅,这些不同层级就是Docker layer——具体表现为,Docker file有特定书写规则,这个文件的每一行都会成为镜像build时的一层。所以我们在pull或者build时,屏幕上显示的,每一行都是不同12位的字母数字组成的,这是Docker随机生成的Docker Layer的名字。所有Layer层ok了,那么这个千层蛋糕–容器就制作好了。
Docker Layer最上面一层,是我们可以进行改写操作的一层,称之为可写层。除此之外,所有下层的Layer,都是只读层,是不允许我们用户直接进行修改的。所以我们exec进去进行操作的,都是最上面一层可写层。如果我们修改了一个下面只读层的一个文件(只要有权限,在可写层允许任意修改),那么这个只读层文件就会是我们可写层修改的内容。但是呢,原来未修改版本的这个只读层文件还是存在的,只是被隐藏起来了,这即是Docker的“写时复制”的机制。我们设源文件为A,这个修改过的文件为A’,在当前这个容器里,退出再进去我们看见的就会是A’,但是删除容器,重新用镜像构建,我们看到的就是A。当我们把这个A’删掉以后,源文件A就会出现了。
Commit镜像
#提交容器成为一个新的副本
docker commit
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
下面我们以tomcat做一个演示
#1.首先我们拉取官方最新的tomcat
docer pull tomcat
#2.拉取镜像之后我们运行出一个tomcat容器
docker run -it -p 8080:8080 tomca
#3.容器启动后我们通过bash进入容器内部
docker exec -it 容器id /bin/bash
#4.我们可以看到官方的webapps里面是空的,我们将webapps.dist内的文件拷贝到webapps下
cp -r webapps.dist/* webapps/
#5.拷贝成功后,我们退出容器,进行commit提交
docker commit -a="作者名" -m="add webapps" c4dc43df1384 tomcat1.0:v1.0
#提交成功后,我们就可以在images里看到我们提交的镜像了,之后我们就可以直接使用我们commit的镜像去创建容器了
容器数据卷
什么是容器数据卷?
如果容器删除,数据就会丢失;如何做到数据持久化?容器之间是否可以有一个数据共享技术?Docker容器中产生的数据是否可以同步到本地?
解决:卷技术,目录的挂载,将容器内的目录挂载到外部Linux上
容器的持久化和同步操作,容器间也可以数据共享
使用数据卷
方式一
#直接使用命令挂载,两边的目录都为绝对路径
docker run -it -v 主机目录:容器目录 image
演示:
#创建一个tomcat容器使用-v来挂载卷
docker run -it -p 8080:8080 -v /home/tomcat:/home tomcat
#创建成功之后,可以通过查看容器详情
docker inspect 容器id
可以看到,tomcat内部已经和外部卷挂载了,无论在容器内部还是外部的挂载目录进行文件操作两边都会同步。
mysql挂载演示:
#将mysql的conf目录和data目录挂载到本地,对应端口3306
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
即使将该mysql容器删除,同步到本地的文件也不会消失
具名挂载和匿名挂载
匿名挂载
# -v 后直接加容器内路径,随机端口
docker run -d -P -v /etc/nginx nginx
#创建并挂载完成之后,查看所有卷详情
[root@iZbp1bf94i2chxlvqq1ipiZ ~]# docker volume ls
DRIVER VOLUME NAME
local 2effdb41f9221f022ed4d24ad15c71f62cced27d9add3fe960de4a06d8060227
local 52a813c4f930ee04484ecb2a4cd52532529215d63a7d89374161bd5ddb85f09b
local 636b0fc8acee33aff3fa32eea146def7c9bce1496ba84f75bfc17304cc985c8e
local f644a28bf7a7593f8c7812decb7f09c02a9f0cc303a07611a6b2cf08792b40ce
#我们会发现,有一串串字符,这种就是匿名挂载
#挂载时没有对外部的数据文件命名,称之为匿名挂载(内外部是对docker来说的)
具名挂载
# -v 卷名:内部路径
docker run -d -P -v juming-nginx:/etc/nginx nginx
#创建并挂载完成之后,查看所有卷详情
[root@iZbp1bf94i2chxlvqq1ipiZ ~]# docker volume ls
DRIVER VOLUME NAME
local 2effdb41f9221f022ed4d24ad15c71f62cced27d9add3fe960de4a06d8060227
local 52a813c4f930ee04484ecb2a4cd52532529215d63a7d89374161bd5ddb85f09b
local 636b0fc8acee33aff3fa32eea146def7c9bce1496ba84f75bfc17304cc985c8e
local f644a28bf7a7593f8c7812decb7f09c02a9f0cc303a07611a6b2cf08792b40ce
local juming-nginx
#这里我们可以看到,我们刚刚创建容器挂载的卷是有VOLUME NAME的,这种就是具名挂载
#我们可以查看刚刚具名挂载的卷的详细信息
[root@iZbp1bf94i2chxlvqq1ipiZ ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-01-07T20:08:59+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
#可以看到,我们刚刚具名挂载的卷实在一个指定的位置
所有的docker容器内的卷,在没有指定目录的情况下都是在
/var/lib/docker/volumes/卷名/_data
下
挂载类型总结
总结
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v 宿主机路径:容器内路径 #指定路径挂载
拓展
#通过 -v 在挂载路径最后加: ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
docker run -d -P -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P -v juming-nginx:/etc/nginx:rw nginx
一旦设置了容器权限,容器对我们挂载出的卷就有限定
1. 不指定权限
文件:宿主机修改该文件后容器里面看不到变化;容器里面修改该文件,宿主机也看不到变化
文件夹:不管是宿主机还是容器内修改、新增、删除文件,都会相互同步
2.ro
文件:容器内不能修改,会提示read-only
文件夹:容器内不能修改、新增、删除文件夹中的文件,会提示read-only
3.rw
文件:不管是宿主机还是容器内修改,都会相互同步,但容器内不允许删除,会提示Device or resource busy;宿主机删除文件,容器内的不会被同步
文件夹:不管是宿主机还是容器内修改、新增、删除文件,都会相互同步
数据卷之初识Dockerfile
方式二
Dockerfile就是用来构建docker镜像的构建文件,命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层。
#演示
#创建一个dockerfile
vim dockerfile01
#开始编写内容,基于centos,并且挂载两个目录
#注意大小写
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#对dockerfile文件进行build成image
docker build -f /home/docker-test-volume/dockerfile01 -t w/centos:1.0 .
# -f后指定dockerfile文件,-t指定tag标签
#之后我们在去创建并且运行我们自己构建出来的镜像
docker run -it run -it w/centos:1.0 /bin/bash
#进来后我们可以看见我们之前挂载的卷volume01和volume02
#退出容器后我们再看看镜像详细信息
可以看到,我们之前挂载的卷都在默认的卷路径里了,这种也是另一种的挂载卷的方式,为匿名挂载。
数据卷容器
命名的容器挂载数据卷,其他容器通过挂载这个父容器实现数据共享,挂载数据卷的容器称为数据卷荣容器。
#通过--volumes-from实现多个容器之间的数据共享
#docker run -it --name 当前容器命名 --volumes-from 需要实现同步的容器名 镜像 /bin/bash
docker run -it --name centos04 --volumes-from centos02 w/centos:1.0 /bin/bash
当然,通过这种方式,我们可以实现多个容器中间的数据共享,当我们删除其中任意的容器,其共享的目录其实也不会消失,因为所有容器都是挂载到宿主机的同一个目录下的,但如果删掉宿主机下的这个目录的文件,容器的数据都会消失。
Dockerfile
Dockerfile介绍
dockerfile是用来构建docker镜像的文件-命令参数脚本 编写步骤:
- 编写一个dockerfile文件
- docker build将dockerfile文件构建成一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub,阿里云镜像仓库)
很多官方的镜像包都是基础包,缺失很多功能,通常我们可以自己搭建自己的镜像并且打包发布。
Dockerfile构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 执行从上到下顺序执行
- #号表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务
DockerFile指令
-
FROM
格式为FROM image或FROM image:tag,并且Dockerfile中第一条指令必须是FROM指令,且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令。 -
MAINTAINER
格式为MAINTAINER user_name user_email,指定维护者信息 -
RUN
格式为RUN command或 RUN [“EXECUTABLE”,“PARAM1”,“PARAM2”…],前者在shell终端中运行命令,/bin/sh -c command,例如:/bin/sh -c “echo hello”;后者使用exec执行,指定其他运行终端使用RUN["/bin/bash","-c",“echo hello”]。
每条RUN指令将当前的镜像基础上执行指令,并提交为新的镜像,命令较长的时候可以使用\来换行。 -
CMD
支持三种格式:
CMD [“executable”,“param1”,“param2”],使用exec执行,这是推荐的方式。
CMD command param1 param2 在/bin/sh中执行。
CMD [“param1”,“param2”] 提供给ENTERYPOINT的默认参数。
CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。 -
EXPOSE
格式为 EXPOSE port [port2,port3,…],例如EXPOSE 80这条指令告诉Docker服务器暴露80端口,供容器外部连接使用。
在启动容器的使用使用-P,Docker会自动分配一个端口和转发指定的端口,使用-p可以具体指定使用哪个本地的端口来映射对外开放的端口。 -
ENV
格式为:EVN key value 。
用于指定环境变量,这些环境变量,后续可以被RUN指令使用,容器运行起来之后,也可以在容器中获取这些环境变量。 -
ADD
格式:ADD src dest。
该命令将复制指定本地目录中的文件到容器中的dest中,src可以是是一个绝对路径,也可以是一个URL或一个tar文件,tar文件会自动解压为目录。 -
COPY
格式为:COPY src desc
复制本地主机src目录或文件到容器的desc目录,desc不存在时会自动创建。 -
ENTRYPOINT
格式有两种:
ENTRYPOINT [“executable”,“param1”,“param2”]
ENTRYPOINT command param1,param2 会在shell中执行。
用于配置容器启动后执行的命令,这些命令不能被docker run提供的参数覆盖。和CMD一样,每个Dockerfile中只能有一个ENTRYPOINT,当有多个时最后一个生效。 -
VOLUME
格式为 VOLUME ["/data"]
作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。 -
USER
格式为:USER username
指定容器运行时的用户名或UID,后续的RUN也会使用指定的用户。要临时使用管理员权限可以使用sudo。在USER命令之前可以使用RUN命令创建需要的用户。
例如:RUN groupadd -r docker && useradd -r -g docker docker -
WORKDIR
格式: WORKDIR /path
为后续的RUN CMD ENTRYPOINT指定配置工作目录,可以使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于之前的命令指定路径。 -
ONBUILD
格式ONBUILD [INSTRUCTION]
该配置指定当所创建的镜像作为其他新建镜像的基础镜像时所执行的指令。
例如下面的Dockerfile创建了镜像A:
ONBUILD ADD . /app
ONBUILD RUN python app.py
则基于镜像A创建新的镜像时,新的Dockerfile中使用from A 指定基镜像时,会自动执行ONBBUILD指令内容,等价于在新的要构建镜像的Dockerfile中增加了两条指令:
FROM A
ADD ./app
RUN python app.py -
docker build
创建好Dockerfile之后,通过docker build命令来创建镜像,该命令首先会上传Dockerfile文件给Docker服务器端,服务器端将逐行执行Dockerfile中定义的指令。
通常建议放置Dockerfile的目录为空目录。另外可以在目录下创建.dockerignore文件,让Docker忽略路径下的文件和目录,这一点与Git中的配置很相似。
通过 -t 指定镜像的标签信息,例如:docker build -t regenzm/first_image . ##"."指定的是Dockerfile所在的路径
演示创建
创建一个自己的centos,先编写dockerfile
# 首先以centos为基础
FROM centos
# 添加作者
MAINTAINER WANG<1605653045@qq.com>
# 配置环境变量目录
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 下载vim等工具
RUN yum -y install vim
RUN yum -y install net-tools
# 暴露端口80
EXPOSE 80
# 创建容器时启动的命令
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
编写完成,将dockerfile build成镜像,注意最后的 点
docker build -f dockerfile文件路径 -t 镜像名:版本信息(可为空) .
docker history 镜像id # 查看镜像构建步骤
如果需要可将自己构建的镜像发布到DockerHub
#首先需要登录自己的账号
docker login -u -p
#登录过后就可以push了
docker push 镜像名:版本号
也可以发布到阿里云镜像仓库,具体可以参考阿里云官方平台操作步骤