Dockerfile详解构建镜像

Dockerfile构建企业级镜像

在服务器上可以通过源码或rpm方式部署Nginx服务,但不利于大规模的部署。为提高效率,可以通过Dockerfile的方式将Nginx服务封装到镜像中,然后Docker基于镜像快速启动容器,实现服务的快速部署。

Dockerfile是一个用来构建镜像的文本文件,文本内容包含一条条构建镜像所需的指令和说明。

Dockerfile构建

Dockerfile用于定义Docker镜像构建过程的文件。是一个文本文件,包含一系列的指令和参数,用于自动化构建Docker镜像。Dockerfile中每个指令代表一个构建步骤,可以指定所使用的基础镜像、安装软件、配置环境变量、复制文件、运行命令等。

  • 构建镜像

在Dockerfile文件所在目录下执行命令

docker build -t image_name:tag .

# 例子
docker build -t myapp:1.0 .

-t指定镜像名称和标签 .表示是Dockerfile文件的所在目录

  • 运行容器
docker run -d -p 8080:80 myapp:1.0

Dockerfile文件内容语法

  • FROM:指定所用的基础镜像,如FROM centos:latest
FROM centos
RUN yum install -y httpd
COPY index.html /var/www/html/
EXPOSE 80
CMD ["httpd","-DFOREGROUND"]

该Dockerfile创建一个基于CentOS的镜像,安装httpd服务器,将index.html文件复制到/var/www/html/目录下,将容器的80端口暴露,最后容器启动时启动httpd服务器

  • MAINTAINER:指定镜像维护者的信息,MAINTAINER yourname <email>
  • RUN:在容器中执行的命令,如RUN apt-get update && apt-get install -y curl

RUN用于在镜像构建过程中的执行命令。在Dockerfile中,每一个RUN指令都会在一个新的镜像层上执行,最终形成一个新的镜像。

RUN命令中可以执行任何有效的Linux命令,如安装软件包、创建文件夹、运行脚本等。

RUN指令有两种模式:shell模式和exec模式。shell模式下,命令在容器默认的shell中运行,在exec模式下,命令以exec系统调用的方式运行。exec模式更加高效和安全

exec模式示例

FROM alpine
RUN apk add --no-cache git
RUN --mount=type=cache,target=/root/.cache \
	git clone https://github.com/example/example.git
WORKDIR /example
RUN --mount=type=cache,target=/root/.cache \
	apk add --no-cache python3 \
	&& pip3 install -r requirements.txt
CMD ["python3", "app.py"]

使用exec模式,第一个RUN命令,使用apk安装git,第二个和第三个RUN指令中,使用–mount选项指定缓存目录,安装Python3和Python依赖库。第二个RUN指令中,使用Git克隆了一个仓库目录。最后在CMD中执行了python的程序。

  • CMD:容器启动时执行的命令

CMD命令可以有多个,但是只有最后一个会被执行。

同样有shell模式和exec模式,exec模式更安全和高效。要注意的是:使用exec模式时,必须将CMD指令和参数放入JSON数组中。否则Docker会将整个字符串当成命令执行,可能导致错误。

  • ENTRYPOINT: 指令用于设置容器启动时默认命令或应用程序,与CMD指令类似,都是容器启动时执行的命令。但当ENTRYPOINTCMD同时出现时,CMD指令的作用就是为ENTRYPOINT命令指定的程序或命令提供默认参数。也就是说,CMD中定义的参数将会把ENTRYPOINT中的参数给覆盖。
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl
ENTRYPOINT ["curl","-s","-o","/dev/null"]
CMD ["https://www.google.com"]

最后的效果就是使用curl指令获取Google网站的内容…,达到了参数拼接的效果。

  • EXPOSE:声明容器运行监听的端口,EXPOSE 80

声明容器监听的网络端口。此指令不会在容器启动时自动将端口映射到宿主机上,而是提供给运行容器的人员一个提示,告诉他们应该监听的 端口。

FROM nginx
EXPOSE 80

启动容器时,使用-p参数指定宿主机和容器的端口映射配置。

docker run -d -p 8080:80 my-nginx-image

宿主机监听8080端口,转发到容器的80端口上。

  • ENV: 设置环境变量,ENV_MYSQL_ROOT_PASSWORD=123456
FROM ubuntu:latest
ENV MY_NAME="Docker"
CMD echo "Hello, ${MY_NAME}!"

输出Hello, Docker但是需要注意的:Docker中ENV的变量只能是容器内部使用,只有像CMD,ENTRYPOINT这样的命令来使用,像RUN等构建镜像时的命令是使用不了的,可以用ARG声明的环境变量。

  • ARG:设置环境变量或传递Docker镜像构建时参数,可以动态进行传值
# 定义一个构建参数,可以设置默认值,若无指定参数的值,采用默认值
ARG <name>[=<default value>]

# 实例
ARG BUILD_VERSION
ARG COMMIT_SHA

Dockerfile中使用

ARG VERSION=latest
FROM ubuntu:${VERSION}

构建镜像时可以动态传值,若无值则使用默认值

docker build --build-arg VERSION=1.0.0 -t myimage
  • ADD: 将本地文件或目录复制到容器中,若本地是一个压缩包,先把压缩包解压后放入容器ADD ./app /app
# 语法
ADD <源路径> <目标路径>

# 示例
ADD example.tar.gz /app/	# ADD命令自动解压
ADD https://example.com/file.tar.gz /app/ # 可以从URL下载文件到容器中

注意:ADD命令会修改文件的权限和属主信息,若不需要ADD高级功能尽量采用COPY

  • COPY: 复制本地文件或目录到容器中,是压缩包时不会解压

需要注意:源路径必须在构建上下文中存在(放到和Dockerfile文件统一目录),否则Docker构建过程会失败

# 语法
COPY <源路径> <目标路径>

# 示例:将宿主机本目录下的app目录,复制到容器中的app目录下
COPY ./app/ /app
  • WORKDIR: 设置工作目录 WORKDIR /app,类似于linux的cd命令
  • VOLUME: 设置持久化数据的挂载点 VOLUME /data

Docker中创建一个挂载点,实现数据持久化功能。使用VOLUME指令创建的挂载点会在容器启动时自动创建,且容器销毁时挂载点不会被删除,数据可以长久保存。

VOLUME指令不会在主机上创建一个新目录,而是将一个已经存在的目录挂载到容器中。因此在使用VOLUME指令时,需要在容器创建时通过-v--mount参数指定挂载目录。

VOLUME /data

启动容器时

docker run -v /path/to/data:/data <image>

将主机的/path/to/data目录和容器的/data目录进行挂载。若是未声明/path/to/data的主机目录,那么会在主机随机生成一个目录(匿名数据卷)和容器/data目录进行挂载。

匿名数据卷在docker的存储目录是/var/lib/docker/volumes中,匿名数据卷在容器被删除时,也会被清理掉,所以尽量采用命令数据卷方式,防止数据意外丢失。

案例:构建Nginx镜像

# 创建一个dockerfile的目录
mkdir nginxDockerfile

# 进入目录
cd nginxDockerfile

# 创建Dockerfile文件
vim Dockerfile

创建内容如下:

FROM centos											# 使用centos作为基础镜像
MAINTAINER xiaolu									# 作者

WORKDIR /etc/yum.repos.d/							# 进入yum配置目录
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \ && sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*							# 设置os8的yum源
\&& yum makecache									# 更新缓存

\&& yum -y install nginx							# 安装nginx
\&& yum -y install wget								# 安装wget
COPY index.html /usr/share/nginx/html/				# 将文件拷贝到镜像
EXPOSE 80											# 提示暴露端口
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]	# 容器启动执行的命令

若是centos8镜像,记得给配置上yum源,同时最好可以一条RUN将他们全都执行完毕,因为每执行一个RUN,镜像就会增加一层。daemon off;是nginx的全局配置参数,用于让Nginx在前台运行,不作为守护进程在后台运行。

Tips:Docker容器启动时,默认把容器内第一个进程,也就是pid=1的程序作为判断docker容器是否在运行的依据,若pid=1的程序崩溃,那么docker容器自动关闭。该例中,nginx若是后台运行,Docker未执行自定义的CMD前,Nginx的pid=1,运行完毕后Nginx变成后台进程,docker将判断nginx程序崩溃或结束,自动关闭docker容器。

记得Dockerfile文件中把中文注释删了哦,小心报错!!,完整版贴这里

FROM centos
MAINTAINER xiaolu
WORKDIR /etc/yum.repos.d/
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \
 && sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* \
 && yum makecache \
 && yum -y install wget \
 && yum -y install nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
  • 创建页面vim index.html
<html>
    <head>
        <title>page added to Dockerfile</title>
    </head>
    <body>
        <h1>
            Hello,My Name is Xiaolu,Welcome to my nginx page!
        </h1>
    </body>
</html>
  • 构建镜像
docker build -t xiaolu/nginx:v1 .
  • 查看镜像是否构建完毕
docker images |grep nginx

在这里插入图片描述

  • 镜像构建完毕了,创建启动容器
docker run -d -p 80:80 --name html2 xiaolu/nginx:v1

访问我们的宿主机的80端口将会映射到容器的80端口,获取到我们需要的资源。

这里说个小知识点,当80:80写成80时,意思是随机分配宿主机的端口和容器80端口进行映射。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/520719.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

统一网关 Gateway(黑马程序员)

网关的技术实现 在 SpringCloud 中网关的实现包括两种&#xff1a; gatewayzuul Zuul 是基于 Servlet 的实现&#xff0c;属于阻塞式编程。而 SpringCloudGateway 则是基于 Spring5 中提供的 WebFlux &#xff0c; 属于响应式编程的实现&#xff0c;具备更好的性能。 网关的作…

火柴排队(c++实现)

题目 涵涵有两盒火柴&#xff0c;每盒装有 n 根火柴&#xff0c;每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列&#xff0c;同一列火柴的高度互不相同&#xff0c;两列火柴之间的距离定义为&#xff1a; 其中 ai 表示第一列火柴中第 i 个火柴的高度&#xf…

【OneAPI】贴纸生成API

OneAPI新接口发布&#xff1a;贴纸生成 生成一个10241024像素的贴纸。 API地址&#xff1a;POST https://oneapi.coderbox.cn/openapi/api/stickers 请求参数&#xff08;body&#xff09; 参数名类型必填含义说明prompt提示词是提示词示例&#xff1a;一只可爱的小狗 响应…

网络网络层之(1)IPv4地址

网络网络层之(1)IPv4地址 Author: Once Day Date: 2024年4月1日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…

嵌入式系统初学者指南

什么是嵌入式系统&#xff1f; 嵌入式系统是一种独立的、基于微处理器的计算机系统。您可以将其视为大型系统的一部分的微型计算机。如今&#xff0c;从洗碗机到波音 747&#xff0c;几乎所有“电子”产品内部都有嵌入式系统。但是&#xff0c;嵌入式系统与笔记本电脑或手机不…

mysql dublewrite 双写缓存机制

mysql dublewrite 双写缓存机制&#xff0c;像不像主板双bois系统&#xff0c; 在MySQL的InnoDB存储引擎中&#xff0c;当进行数据写操作时&#xff0c;会先将数据写入到内存中的缓冲池&#xff08;Buffer Pool&#xff09;&#xff0c;然后异步刷新到磁盘上的数据文件。为了提…

基于巴法云物联网云平台构建可视化控制网页(以控制LED为例)

0 前言 如今大大小小的物联网云平台非常多&#xff0c;但大部分要收取费用&#xff0c;免费的物联网云平台功能则有很多限制使用起来非常不方便。以百度云物联网云平台为例&#xff0c;它的物可视不支持发布主题&#xff0c;等于可视化界面只能作为数据监控而不具备双向通信的…

打造个人高效图床系统:威联通NAS+兰空+PicGo全方位整合教程

1.图床选择 最近因为家里人有使用图床的需求&#xff0c;又担心第三方图床跑路导致数据丢失&#xff0c;恰好家里有个威联通NAS&#xff0c;还有公网IP和域名&#xff0c;既然如此&#xff0c;那就动手自建一个图床吧&#xff0c;毕竟开源的图床应用还是有很多的。 一上来就在…

掌握数据相关性新利器:基于R、Python的Copula变量相关性分析及AI大模型应用探索

在工程、水文和金融等各学科的研究中&#xff0c;总是会遇到很多变量&#xff0c;研究这些相互纠缠的变量间的相关关系是各学科的研究的重点。虽然皮尔逊相关、秩相关等相关系数提供了变量间相关关系的粗略结果&#xff0c;但这些系数都存在着无法克服的困难。例如&#xff0c;…

写JDBC遇到的问题

执行会出现以下错误信息 java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ? and loginPwd ? at line 1 at com.mysql.cj.jdbc.exceptions…

spark3.x新特性

Adaptive Query Execution自适应查询(SparkSQL) 由于缺乏或者不准确的数据统计信息&#xff08;元数据&#xff09;和对成本的错误估算&#xff08;执行计划调度&#xff09;导致生成的初始执行计划不理想 在Spark3.x版本提供Adaptive Query Execution自适应查询技术 通过在”…

数据结构顺序表的初始化,头插,尾插,头删,尾删,指定位置删除,指定位置插入,查找,销毁(详解)

目录 前言顺序表的介绍静态顺序表动态顺序表一.顺序表的初始化二.销毁扩容顺序表打印顺序表三.头插四.尾插五.头删六.尾删七.指定位置之前&#xff08;包括指定位置&#xff09;的插入八.指定位置数据的删除九.查找全部的代码实现总结 前言 数据结构是什么&#xff1f; 数据结…

碘浊度法与红外相机联用测定食品中维生素C

&#x1f31e;欢迎来到看论文的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年4月6日&…

1.微服务

一、微服务是什么 微服务是一种架构风格&#xff0c;即&#xff0c;一个应用应该是一组小型服务&#xff0c;每个服务器只负责一种服务&#xff0c;服务之间可以通过 HTTP 的方式进行互通。每一个功能元素最终都是一个可独立替换和独立升级的软件单元。 可以说&#xff0c;微…

网络编程套接字应用分享【Linux C/C++ 】【UDP应用 | TCP应用 | TCP线程池小项目】

目录 前提知识 1. 理解源ip&#xff0c;目的ip和Macip 2. 端口号 3. 初识TCP&#xff0c;UDP协议 4. 网络字节序 5. socket 编程 sockaddr类型 一&#xff0c;基于udp协议编程 1. socket——创建套接字 2. bind——将套接字强绑定 3. recvfrom——接受数据 4. s…

c++11的重要特性2

可变参数模板在3中。 目录 ​编辑 1、统一的列表初始化&#xff1a; std::initializer_list&#xff1a; std::initializer_list是什么类型&#xff1a; std::initializer_list使用场景&#xff1a; 让模拟实现的vector也支持{}初始化和赋值 2、声明 auto decltype nul…

「每日跟读」英语常用句型公式 第4篇

「每日跟读」英语常用句型公式 第4篇 1. I’ve decided to ____ 我决定要____了 I’ve decided to take a vacation (我决定要去度假) I’ve decided to change my lifestyle (我决定要改变我的生活方式) I’ve decided to adopt a dog (我决定要收养一条狗了) I’ve dec…

【深度学习环境配置】一文弄懂cuda,cudnn,NVIDIA Driver version,cudatoolkit的关系

【深度学习环境配置】一文弄懂cuda&#xff0c;cuDNN&#xff0c;NVIDIA Driver version&#xff0c;cudatoolkit的关系 NVIDIA Driver version&#xff08;NVIDIA驱动程序&#xff09;CUDAcuDNNcudatoolkit深度学习环境配置顺序 今天突然发现配置的环境有些问题&#xff0c;意…

使用阿里云试用Elasticsearch学习:2.6 深入搜索——控制相关度

处理结构化数据&#xff08;比如&#xff1a;时间、数字、字符串、枚举&#xff09;的数据库&#xff0c;只需检查文档&#xff08;或关系数据库里的行&#xff09;是否与查询匹配。 布尔的是/非匹配是全文搜索的基础&#xff0c;但不止如此&#xff0c;我们还要知道每个文档与…

java日志框架简介

文章目录 概要常用日志框架常见框架有以下&#xff1a;slf4j StaticLoggerBinder绑定过程&#xff08;slf4j-api-1.7.32 &#xff09;JCL 运行时动态查找过程&#xff1a;&#xff08;commons-logging-1.2&#xff09;使用桥接修改具体日志实现 一行日志的打印过程开源框架日志…