作者:手机用户2502891267 | 来源:互联网 | 2023-07-27 16:18
本篇将介绍Docker的重要角色Dockerfile及用法。
关于Docker的安装,网络上有非常多的教程,所以这里不额外介绍。Dockerfile构建镜像简介前文已经介绍过,Dockerfile是用来构建镜像的,他实际上就是把在linux下的命令操作写到了Dockerfile中,通过Dockerfile去执行设置好的操作命令,保证通过Dockerfile的构建镜像是一致的。因为Docker镜像是分层构建的,在通过命令执行的时候,理解可能不太直观,所以这里借鉴一篇文章中的两张动图来直观展示一下:
镜像编辑1镜像编辑2图片来源:https://itnext.io/3-simple-tric
$graph TD;
A-->B;
B-->C;$
ks-for-smaller-docker-images-f0d2bda17d1e
如果看不太明白没关系,先看个大概,在构建命令的时候会逐步说明。
Dockerfile构建命令编写Dockerfile,需要提前了解一些编写命令与格式,如下:
FROM 指定镜像源
FROM命令是用来指定你需要用哪个镜像作为基础镜像进行构建,一般来说Dockerfile的第一行都会先指定一个镜像,官方仓库中有很多镜像,可以通过http://hub.docker.com进行搜索,建议尽量使用官方镜像作为基础镜像,因为官方镜像都是精简过的稳定版。
写法如下&#xff1a;FROM ubuntuFROM也可以指定多个镜像源进行构建&#xff08;最终还是构建为单个镜像&#xff09;&#xff0c;下面就是一个指定一个基础镜像&#xff0c;然后设置别名后&#xff0c;进行二次构建的例子&#xff1a;FROM ubuntu as image1······# 其他构建命令FROM image1······# 二次构建命令延申——为什么会有二次构建&#xff1f;上篇文章也讲过&#xff0c;Dockerfile构建镜像是一层一层的镜像构建的&#xff0c;如果底层的镜像没有变动&#xff0c;就不会重新构建&#xff0c;这样就节省了构建时间。如上面举例中&#xff0c;image1作为基础环境镜像&#xff0c;如果基础环境不变且没有改动&#xff0c;那么在构建镜像时&#xff0c;会直接跳过&#xff0c;从FROM image1开始构建。RUN 执行linux命令RUN是用来执行linux命令的指令&#xff0c;例如ubuntu系统下&#xff0c;需要更新软件包list&#xff0c;就需要执行apt-get update&#xff0c;之后会跟着执行apt-get install&#xff0c;那么在Dockerfile中&#xff0c;就需要进行如下写法&#xff1a;RUN apt-get update -yRUN apt-get install -y vim但是实际工作中&#xff0c;写法并不是上面这种&#xff0c;因为在Dockerfile中&#xff0c;每写一个RUN就会在基础镜像上增加一层镜像&#xff0c;Docker对镜像的层数有限制&#xff0c;所以一般情况下&#xff0c;多个连续执行的linux命令&#xff0c;都会用“\”做换行分割&#xff0c;再用“&&”将命令串联起来。所以更多的时候我们会如下写入多个命令&#xff1a;RUN apt-get update -y \ && apt-get install -y vim如果文字描述看不太明白&#xff0c;可以结合之前的镜像编辑1这张动图来理解&#xff0c;这样就能直观的明白多个RUN命令和单个RUN命令的区别了&#xff1a;多个RUN与单个RUN的区别延申——精简镜像大小有时候构建好的镜像会很大&#xff0c;就需要对镜像进行精简&#xff0c;一般会在基础环境的软件安装时&#xff0c;删除安装文件信息&#xff0c;所以通常我们会在install后面加上–no-install-recommends&#xff0c;如下&#xff1a;RUN apt-get update -y \ && apt-get install -y --no-install-recommends vimUSER 指定当前用户这个指令是用来切换当前用户和用户组的&#xff0c;比如我先用root账户执行了命令&#xff0c;后续命令需要用www指令来执行&#xff0c;就需要使用user来切换用户&#xff0c;前提是这个用户或用户组必须是已存在的&#xff0c;举例如下&#xff1a;USER root······USER www······COPY 复制文件到镜像中将对应文件复制到docker镜像中进行打包。注意这个COPY后面的指令分两段&#xff0c;前面是宿主机的路径&#xff0c;后面的是docker镜像中的路径&#xff0c;中间用空格分开&#xff0c;可以复制文件&#xff0c;也可以复制目录&#xff0c;可以是相对路径&#xff0c;也可以是绝对路径&#xff0c;docker路径中尽量使用绝对路劲&#xff0c;举例如下&#xff1a;COPY ./.env /var/www/html/.env······COPY f:/docker/ ./······ADD 增加文件到镜像中ADD和COPY的功能及用法类似&#xff0c;不同的是在执行 <源文件> 为 tar 压缩文件的话&#xff0c;压缩格式为 gzip, bzip2 以及 xz 的情况下&#xff0c;会自动复制并解压到 <目标路径>。在不解压的前提下&#xff0c;无法复制 tar 压缩文件。会令镜像构建缓存失效&#xff0c;从而可能会令镜像构建变得比较缓慢。具体是否使用&#xff0c;可以根据是否需要自动解压来决定。我个人而言更喜欢用COPY。ENV 环境变量设置设置环境变量&#xff0c;定义了环境变量&#xff0c;在后续的指令中&#xff0c;通过符号就可以使用这个环境变量。ENVBASEURLwww.songpangpang.comRUNcurl−SLO"https://符号就可以使用这个环境变量。ENV BASE_URL www.songpangpang.comRUN curl -SLO "https://符号就可以使用这个环境变量。ENVBASEURLwww.songpangpang.comRUNcurl−SLO"https://BASE_URL/“WORKDIR 工作目录指定工作目录。用 WORKDIR 指定的工作目录&#xff0c;会在构建镜像的每一层中都存在。&#xff08;WORKDIR 指定的工作目录&#xff0c;必须是提前创建好的&#xff09;。docker build 构建镜像过程中&#xff0c;每一个RUN命令都是新建的一层。只有通过WORKDIR创建的目录才会一直存在。WORKDIR <工作目录路径>一般来说&#xff0c;在指定了镜像后&#xff0c;可以通过as来将镜像作为一个别名&#xff0c;然后在后续的镜像构建中&#xff0c;可以直接FROM这个别名&#xff0c;来在镜像的基础上继续构建。可以通过前面的镜像编辑2来理解&#xff1a;镜像合并VOLUME 定义卷定义匿名数据卷。在启动容器时忘记挂载数据卷&#xff0c;会自动挂载到匿名卷。一般来说会在docker run或者docker-compose中使用&#xff0c;用于将容器内的数据挂载出来&#xff0c;持久化保存在宿主机上&#xff0c;避免容器重启后数据丢失。典型的就是将mysql的数据地址挂载出来&#xff0c;下次重启镜像容器的时候就可以直接使用数据。docker run中&#xff0c;通过-v来进行挂载VOLUME [”<宿主机路径>","<镜像路径>"]docker-compose中用法如下&#xff1a;volumes: - f:/code_path/:/var/www/htmlEXPOSE 暴露端口声明端口&#xff0c;作用是帮助镜像使用者理解这个镜像服务的守护端口&#xff0c;以方便配置映射。在运行时使用随机端口映射时&#xff0c;也就是 docker run -P时&#xff0c;会自动随机映射EXPOSE的端口。EXPOSE <端口1> [<端口2>…]通常在docker-compose中&#xff0c;会通过ports来映射并暴露端口&#xff0c;docker-compose用法如下&#xff1a;ports: - “8001:80"其中8001为宿主机端口&#xff0c;映射到镜像中的80端口&#xff0c;这样外部访问时&#xff0c;可通过8001端口访问。CMD 启动命令类似于RUN指令&#xff0c;用于运行程序&#xff0c;但二者运行的时间点不同&#xff0c;CMD在docker run时运行&#xff0c;RUN是在 docker build时运行。注意&#xff1a;CMD命令用于启动容器时&#xff0c;需要执行的命令&#xff0c;多个CMD命令&#xff0c;仅最后一个生效&#xff0c;同时CMD指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。CMD命令有多种写法&#xff0c;个人觉得好用的写法如下&#xff1a;CMD [”<可执行命令>","","",…] 执行Dockerfile知道了基本的Dockerfile命令&#xff0c;那么如何执行呢&#xff1f;首先当然是编写一个Dockerfile文件&#xff0c;一般默认用Dockerfile命名&#xff0c;虽然可以用其他名字&#xff0c;然后在build时指定一下即可&#xff0c;不过为了方便还是用Dockerfile。举例内容如下&#xff1a;FROM php:7.1-apacheRUN apt-get update -y \ && apt-get install -y --no-install-recommends git \ && docker-php-ext-install intl \ && pecl install redis \ && docker-php-ext-enable redis \ && curl -sS https://getcomposer.org/installer | php – --install-dir&#61;/usr/bin --filename&#61;composerWORKDIR /var/www/htmlCOPY . ./ENV APACHE_DOCUMENT_ROOT&#61;/var/www/html/publicRUN echo “ServerName localhost” >> /etc/apache2/apache2.conf \ && composer install这里解释一下&#xff1a;用php7.1带apache的镜像为基础&#xff0c;通过apt-get安装了git&#xff0c;通过docker镜像内的命令安装了intl扩展&#xff0c;然后通过pecl命令安装了redis扩展&#xff0c;单独安装了pecl扩展需要用enable打开&#xff0c;然后安装了composer。基础安装完成后&#xff0c;指定了工作目录&#xff0c;并把当前目录放入镜像内&#xff08;一般是代码目录&#xff0c;将项目文件放入镜像中&#xff09;&#xff0c;设定了APACHE的环境变量参数&#xff0c;最后执行了composer安装。编写好Dockerfile后&#xff0c;在同级目录下&#xff0c;执行build命令&#xff1a;docker build -t test:1.0a .其中-t参数用来指定打包的镜像名称&#xff0c;冒号后面的1.0a用来标识tag&#xff0c;不过千万要注意&#xff0c;最后还有一个点“.”&#xff0c;用来指定上下文。执行后&#xff0c;就等待docker慢慢打包镜像吧&#xff0c;过程可能会很慢&#xff0c;也可能报错&#xff0c;所以这里推荐一个方法&#xff0c;就是先将基础镜像下载下来&#xff0c;然后用docker run跑起来之后&#xff0c;通过docker exec进入镜像&#xff0c;然后一条一条的执行命令&#xff0c;将命令执行成功后&#xff0c;再来写入到Dockerfile中&#xff0c;这样就非常稳当了。Dockerfile就暂时介绍到这里&#xff0c;这里仅仅是构建了一个镜像&#xff0c;还需要启动镜像容器&#xff0c;才能真正将docker跑起来。因为docker-compose和docker run很多内容相通&#xff0c;所以将把docker-compose和docker run放在下一期一起介绍。感谢各位看到这里&#xff01;来自专栏跨界程序员狗儿飞 · 6 篇内容白话Docker—docker run及docker-compose文章 · 1 赞同 · 0 评论编辑于 10-05著作权归作者所有 · 申请转载「真诚赞赏&#xff0c;手留余香」赞赏还没有人赞赏&#xff0c;快来当第一个赞赏的人吧&#xff01;分享到容器云容器虚拟化Docker评论添加评论…推荐阅读面试官&#xff1a;你说你精通 Docker&#xff0c;那你来详细说说 Dockerfile 吧小知的文章 · 35 赞同dockerfile 与 docker-compose的区别先简单理解 docker 的使用过程&#xff0c;它分为镜像构建与容器启动。 镜像构建&#xff1a;即创建一个镜像&#xff0c;它包含安装运行所需的环境、程序代码等。这个创建过程就是使用 dockerfile 来完成的。 容器启动&#xff1a;容…龙神之飞…的文章 · 19 赞同两小时入门 Docker1、引言2、Docker安装3、Docker