当前位置: 首页 > news >正文

Dockerfile详解:构建简单高效的容器镜像

引言

  在容器化技术日益普及的今天,Dockerfile 成为了构建 Docker 镜像的核心工具。通过编写 Dockerfile,开发者可以将应用程序及其依赖打包成一个可移植、可复用的镜像,从而简化部署和运维工作。本文将详细介绍 Dockerfile 的基本概念、常用指令、制作镜像实例以及优化技巧,帮助读者掌握如何构建简单高效的容器镜像。

Dockerfile 简介

Dockerfile 是一个包含了一系列命令的文本文件,这些命令用于自动化地创建一个 Docker 镜像。通过编写 Dockerfile,开发者可以将环境配置、应用程序代码、依赖关系等打包成一个镜像,从而快速创建容器。用户可以将自己的应用打包成镜像,让应用在容器中运行,也可以对官方镜像进行扩展,打包成适合生产环境的应用镜像。

Dockerfile 常用指令

2.1 FROM:指定基础镜像

# 格式
FROM <image:[版本标签]>
# 示例
FROM centos
FROM ubuntu:20.04

FROM 指令用于指定构建新镜像时使用的基础镜像,通常是 Dockerfile 的第一个有效指令。如果不指定版本标签,默认使用 latest

2.2 LABEL:添加镜像的元数据

# 格式
LABEL <key>=<value> <key>=<value>....
# 示例
LABEL version="2.0" description="业务系统第二个版本"

LABEL 指令使用键值对方式为镜像添加元数据。一条 LABEL 可以指定多条元数据,尽量不要写多个 LABEL。

2.3 RUN:构建镜像时执行的命令

RUN 指令有两种执行方式:shell 执行和 exec 执行。

# 格式
RUN <command>
# 示例
RUN yum update -y

RUN 指令创建的中间镜像会被缓存,并在下次构建中使用。可以在构建时使用 --no-cache 取消缓存。

Exec 执行
# 格式
RUN ["executable", "参数1", "参数2"]
# 示例
RUN ["/bin/bash", "-c", "echo hello"]

2.4 ENV:在容器内部设置环境变量

# 格式
ENV <key> <value>
# 示例
ENV MYPATH /usr/local

ENV 指令用于在容器内部设置环境变量。

2.5 ADD:将本地文件添加到镜像中

# 语法
ADD <src> <dest>
ADD ["src", "dest"]
# 示例
ADD nginx.tar /opt

ADD 指令类似于 scp,但不需要用户名和密码权限验证。tar 类型文件会自动解压,可以访问网络资源,类似 wget。建议使用绝对路径,尽量不要把 <src> 写成一个文件夹。

2.6 COPY:将文件或目录复制到镜像中

# 语法
COPY <src> <dest>
COPY ["<src>", "<dest>"]
# 示例
COPY myapp.jar /app/

COPY 指令的功能类似 ADD,但不会自动解压文件,也不能访问网络资源。COPY 的只能是本地文件,其他用法一致。

2.7 VOLUME:指定持久化目录

# 格式
VOLUME ["/path/to/dir"]
# 示例
VOLUME ["/data"]
VOLUME ["/data/log", "/data/config"]

VOLUME 指令用于指定持久化目录。卷可以在容器间共享和重用,修改卷后会立即生效,对卷的修改不会对镜像产生影响。

2.8 CMD:容器启动时运行的命令(不常用)

# 语法
CMD ["executable", "param1", "param2"]
CMD command param1 param2
# 示例
CMD echo $LANG

CMD 指令用于指定容器启动时运行的命令。如果写了多条 CMD 指令,只有最后一条生效。

2.9 ENTRYPOINT:容器启动时运行的命令(常用)

# 语法
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
# 示例
ENTRYPOINT java -jar /data/config.jar

ENTRYPOINT 指令也用于指定容器启动时运行的命令。与 CMD 不同,ENTRYPOINT 不会被运行的 command 覆盖,而 CMD 则会被覆盖。如果同时写了 ENTRYPOINT 和 CMD,CMD 指定的内容将作为 ENTRYPOINT 的参数。

2.10 EXPOSE:暴露容器运行时的监听端口给外部

# 格式
EXPOSE <port> [<port>...]
# 示例
EXPOSE 8080
EXPOSE 443/tcp 80/tcp

EXPOSE 指令用于暴露容器运行时的监听端口给外部。但需要注意的是,EXPOSE 并不会让容器的端口访问到主机。在运行时使用随机端口映射时,会自动随机映射 EXPOSE 的端口。

2.11 WORKDIR:工作目录

WORKDIR 指令用于设置工作目录,后续指令将在该目录中执行。

2.12 其他指令

  • MAINTAINER:指定作者。
  • USER:设置启动容器的用户。
  • ONBUILD:用于设置镜像触发器。
  • HEALTHCHECK:用于检查容器健康状况。

制作镜像实例(重点)

3.1 制作镜像语法

docker build -t 镜像名:标签名 Dockerfile路径

3.2 实例1:构建 Nginx 镜像

(1)编写 Dockerfile
# 使用官方 Nginx 镜像
FROM nginx:1.25
# 复制自定义配置文件
COPY nginx.conf /etc/nginx/nginx.conf
# 复制网站文件
COPY html /usr/share/nginx/html
# 暴露 Nginx 端口
EXPOSE 80
(2)编写配置文件和网站文件

将 nginx.conf 和 html 目录放在 Dockerfile 同级目录下。

(3)构建镜像

由于 Docker Hub 镜像拉取可能不稳定,可以使用公开的镜像加速服务,如 docker.m.daocloud.io

# 拉取 nginx 镜像(需要跟 Dockerfile 中同版本)
docker pull docker.m.daocloud.io/nginx:1.25
# 修改标签
docker tag docker.m.daocloud.io/nginx:1.25 nginx:1.25
# 构建镜像
docker build -t mynginx .
(4)运行容器
docker run -d -p 80:80 --name mynginx mynginx

3.3 实例2:构建 Java 应用镜像

(1)准备工作

确保 Java 应用已经打包成 JAR 文件,并放在 Dockerfile 同级目录下。

(2)编写 Dockerfile
# 使用官方 OpenJDK 镜像
FROM openjdk:8
# 指定作者
MAINTAINER liyb <liyb@gdhmail.com>
# 设置时区并创建工作目录
RUN cp -a -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
mkdir /work
# 复制 JAR 文件到工作目录
COPY *.jar /work/app.jar
# 暴露应用端口
EXPOSE 9999
# 设置容器启动时运行的命令
ENTRYPOINT java -jar /work/app.jar
(3)构建镜像
# 构建镜像
docker build -t myapp .
(4)运行容器
docker run -d -p 8080:9999 myapp

Dockerfile 优化技巧

在编写高效的 Dockerfile 时,可以遵循以下最佳实践,以便优化镜像的构建和运行性能:

4.1 使用轻量基础镜像

选择小巧的基础镜像,如 Alpine,以减少最终镜像的体积。

4.2 合并命令

每个指令(如 RUN、COPY 等)都会生成一个新的镜像层。使用 && 将多个 RUN 命令合并,减少镜像层数,从而提高构建速度和效率。

RUN wget http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz && \
tar -zxvf nginx-$NGINX_VERSION.tar.gz && \
cd nginx-$NGINX_VERSION && \
./configure --prefix=/usr/local/nginx --with-http_ssl_module && \
make && \
make install

4.3 缓存优化

合理地安排指令顺序,将不常变化的指令放在 Dockerfile 前面,常变化的放在后面,以利用缓存,加快构建速度。

4.4 使用 .dockerignore

排除不必要的文件,减小上下文大小,提升构建速度。

4.5 多阶段构建

利用多阶段构建,仅将最终运行所需的文件复制到最终镜像,降低镜像大小。

4.6 优化入口

Dockerfile是一个文本文件,其中包含了用于创建Docker镜像的一系列指令和参数。这些指令定义了镜像的构建步骤,从基础镜像开始,逐层添加软件、配置文件、依赖项等,直到构建出最终的应用镜像。

相关文章:

Dockerfile详解:构建简单高效的容器镜像

引言 在容器化技术日益普及的今天&#xff0c;Dockerfile 成为了构建 Docker 镜像的核心工具。通过编写 Dockerfile&#xff0c;开发者可以将应用程序及其依赖打包成一个可移植、可复用的镜像&#xff0c;从而简化部署和运维工作。本文将详细介绍 Dockerfile 的基本概念、常用指…...

RHCD-----shell

要求&#xff1a; 通过shell脚本分析部署nginx网络服务 1.接收用户部署的服务名称 2.判断服务是否安装 ​ 已安装&#xff1b;自定义网站配置路径为/www&#xff1b;并创建共享目录和网页文件&#xff1b;重启服务 ​ 没有安装&#xff1b;安装对应的软件包 3.测试 判断服务是…...

<硬件有关> 内存攒机认知入门,内存的选择 配置 laptop PC 服务器

原因 这不是黑五吗&#xff0c;给我儿子买了台最便宜 ($300) DELL laptop&#xff0c;CPU 是 i5-1235U&#xff0c;但只有 8GB 内存。升级内存吧。 如何选择内存&#xff1a;家用范围 这里不考虑品牌&#xff0c;在我眼里&#xff0c;区别就是价格&#xff0c;还有所谓的物理…...

基于springboot的来访管理系统的设计与实现

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的来访管理系统的设计与实…...

window11编译pycdc.exe

一、代码库和参考链接 在对python打包的exe文件进行反编译时&#xff0c;会使用到uncompyle6工具&#xff0c;但是这个工具只支持python3.8及以下&#xff0c;针对更高的版本的python则不能反编译。 关于反编译参考几个文章&#xff1a; Python3.9及以上Pyinstaller 反编译教…...

11.22.2024 面试后记

Watching those fucking ap’s paper is bullshit and wasting your time. you’d mother fucker directly say I’m not qualified. if I’m qualified, how could I see u at this place. your dad is alread being rich and enjoy the world. 抽了一周时间去看那些教授的文章…...

Bug Fix 20241122:缺少lib文件错误

今天有朋友提醒才突然发现 gitee 上传的代码存在两个很严重&#xff0c;同时也很低级的错误。 因为gitee的默认设置不允许二进制文件的提交&#xff0c; 所以PH47框架下的库文件&#xff08;各逻辑层的库文件&#xff09;&#xff0c;以及Stm32Cube驱动的库文件都没上传到Gi…...

Pinia 实战教程:构建高效的 Vue 3 状态管理系统

前言 在前端开发中&#xff0c;状态管理已成为必不可少的一部分&#xff0c;Vue.js 生态系统中提供了多种状态管理解决方案。Pinia 是 Vue 3 推出的一种全新的状态管理库&#xff0c;旨在取代 Vuex&#xff0c;提供更简洁的 API、更优雅的 TypeScript 支持以及更高效的性能表现…...

springboot3如何集成knife4j 4.x版本及如何进行API注解

1. 什么是Knife4j knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案, 取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!knife4j的前身是swagger-bootstrap-ui,swagger-bootstrap-ui自1.9.6版本后,正式更名为knife4j为了契合微服务的架构发展,由于原来…...

区块链讲解

区块链技术是一种分布式账本技术&#xff0c;其应用场景和优势可以总结如下&#xff1a; 金融服务&#xff1a;区块链可以用于支付、跨境汇款、证券交易、贷款等金融服务领域&#xff0c;通过去中心化的方式实现快速、低成本、安全的交易。 物联网&#xff1a;区块链可以用于物…...

使用eclipse构建SpringBoot项目

我这里用eclipse2018版本做演示&#xff0c;大家有需要的可以下载Eclipse Downloads | The Eclipse Foundation 1.打开eclipse&#xff0c;选择存放代码的位置 2.选择 file >> new >> project >> 选择springboot文件下的 spring starter project 2.这里选择N…...

uniapp input限制输入负数,以及保留小数点两位.

简单处理的方式 限制输入负数,以及保留小数点两位.: <input type"number" placeholder"请输入" v-model"num"input"numnum.toString().replace(/\-/g,).match(/^\d(?:\.\d{0,2})?/)" /> 可以输入负数,保留两位小数点,把rep…...

《FreeRTOS任务删除篇》

任务删除函数 源码1. 进入临界区1.1 第一步1.2 第二步1.3 第三步1.4 第四步 2. 获取待删除任务的任务控制块TCB3. 从就绪/延迟列表中删除任务4. 从事件列表中删除任务5. 如果待删除任务是当前运行的任务6. 如果待删除任务是其它任务7. 退出临界区7.1 第一步7.2 第二步7.3 第三步…...

递归算法专题一>Pow(x, n)

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …...

数据结构第一讲

数据结构定义 算法的定义 什么是好算法&#xff1f; 空间复杂度 时间复杂度 例子1 打印1到N之间的正整数 有递归和循环两种方法实现。 但是在数字变大后&#xff0c;递归的方法会导致内存占用过多而崩溃。 而循环则不会 例子2 写程序给定多项式在X处的值 从里往外算的算…...

SHELL笔记(循环)

在 Shell 编程中&#xff0c;循环结构是极为重要的一部分&#xff0c;它能够让我们轻松地重复执行特定的代码块&#xff0c;从而高效地处理各种重复性任务。本文将详细介绍 Shell 中常见的循环结构&#xff0c;包括 for 循环、while 循环和 until 循环&#xff0c;并通过具体的…...

SpringBoot多文件上传

多文件上传是在单文件上传的基础上修改而来&#xff0c;不了解单文件上传可以参考上一篇。以下在将修改部分展示如下&#xff1a; 一、修改upload.html文件&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title&g…...

MyBatis-数据库连接池、属性文件config.properties、类名简化、MyBatis的整体架构

一、数据库连接池 1、概述 存储实现创建好的连接对象的容器 2、优点 避免了频繁创建和销毁连接对象 3、使用 在使用到连接对象时可在数据库连接池中直接获取 4、实现 不需要我们去实现,框架和一些第三方有现成的组件&#xff08;C3P0、ADCP、德鲁伊(阿里巴巴)&#xff…...

Flink-Source的使用

Data Sources 是什么呢&#xff1f;就字面意思其实就可以知道&#xff1a;数据来源。 Flink 做为一款流式计算框架&#xff0c;它可用来做批处理&#xff0c;也可以用来做流处理&#xff0c;这个 Data Sources 就是数据的来源地。 flink在批/流处理中常见的source主要有两大类…...

C0031.在Clion中使用mingw编译器来编译opencv的配置方法

mingw编译器编译opencv库的配置方法...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...