Docker-制作镜像的两种方式=》基于容器制作基于Dockerfile制作

本文主要是基于Docker如何制作一个Java镜像,而一个Java镜像想要运行需要系统环境,JDK。所以我们要先有一个系统环境,本文使用的是centos7,JDK选择版本是8,而我使用的Java程序是一个简易的springBoot项目,你可以选择使用本地的Java程序。我了解docker制作镜像有两种方式,一种是Docker Commit基于容器构建镜像;一种是Docker Build基于Dockerfile构建镜像。我接下来都会讲一下这两种方式的使用

文章目录

  • Docker Commit基于容器构建镜像
    • 1.拉取centos7镜像
    • 2.拷贝Java jar程序到容器
    • 3.安装jdk和验证Java程序是否正常运行
    • 4.构建镜像
    • 5.启动容器
  • Dockerfile
    • Dockerfile介绍常用指令
      • FROM
      • MAINTAINER
      • LABEL
      • RUN
      • ADD
      • COPY
      • EXPOSE
      • ENV
      • CMD
      • ENTRYPOINT
      • WORKDIR
      • VOLUME
  • Docker Build基于Dockerfile构建镜像
    • 1.根据指令编写Dockerfile文件
    • 2.构建镜像
    • 3.启动容器
  • 总结

Docker Commit基于容器构建镜像

1.拉取centos7镜像

# 拉取镜像
sudo docker pull centos:7
# 创建容器
sudo docker -di --name centos7 centos:7

2.拷贝Java jar程序到容器

项目源码:简易springboot项目

# 拷贝Java jar包到容器
sudo docker cp demo-0.0.1-SNAPSHOT.jar centos7:/usr/local/data

3.安装jdk和验证Java程序是否正常运行

# 进入容器
sudo docker exec -it  centos7 /bin/bash
# 安装jdk
yum -y install java-1.8.0-openjdk.x86_64
# 验证Java是否成功安装
java -version
# 运行Java 程序
nohup java -jar /usr/local/data/demo-0.0.1-SNAPSHOT.jar > nohup.out 2>&1 &
# 验证程序是否正常运行,输出hello java即成功
curl localhost:9080/index
# 验证成功后退出该容器
exit

4.构建镜像

# 执行下面命令会生成镜像
docker commit -a="cyl" -m="simple springboot" centos7 mycentos:7

docker commit构建镜像指令格式

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

-a:提交的镜像作者;
-c:使用 Dockerfile 指令来创建镜像;
-m:提交时的说明文字;
-p:在 commit 时,将容器暂停。

# 查看景象是否生成
sudo docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 7 2ae82069a24b 51 minutes ago 726MB
centos 7 eeb6ee3f44bd 2 years ago 204MB

我们构建的景象mycentos比centos大,因为里面有jdk和Java程序

5.启动容器

# 启动容器
sudo docker run -di --name mycentos7 -p 9080:9080 mycentos:7
# 进入容器
sudo docker exec -it  mycentos7 /bin/bash
# 运行Java 程序
nohup java -jar /usr/local/data/demo-0.0.1-SNAPSHOT.jar > nohup.out 2>&1 &
# 退出容器
exit
# 主机直接调用Java程序接口,输出hello java即成功
curl ip:9080/index

这种镜像制作的方式就介绍完了,但是执行过程中发现它有些复杂,制作镜像启动后还需要再次进入容器,手动启动Java程序。是否有更简便的方式,启动容器时直接就运行Java程序了呢。接下来我就要讲这种更优的方式,是构建镜像中最常用的方式就是Dockerfile。

Dockerfile

Dockerfile它是一种构建镜像的文本文件,文本内容中包含了一条条镜像所需的指令和说明。可以参考Dockerfile官方文档

Dockerfile介绍常用指令

FROM

语法:FROM <image>:<tag>
指明构建的新镜像是来自于哪个基础镜像,如果没有选择 tag,那么默认值为 latest。
FROM centos:7

MAINTAINER

语法:MAINTAINER <name>
指明镜像维护者及其联系方式(一般是邮箱地址)。官方说明已过时,推荐使用 LABEL。

MAINTAINER cyl <cyl@cyl.com>

LABEL

语法:LABEL <key>=<value> <key>=<value> <key>=<value> ...
功能是为镜像指定标签。也可以使用 LABEL 来指定镜像作者。

LABEL maintainer="cyl.com"

RUN

语法:RUN <command>
构建镜像时运行的 Shell 命令,比如构建的新镜像中我们想在 /usr/local 目录下创建一个 java 目录。

RUN mkdir -p /usr/local/java

ADD

语法:ADD <src>... <dest>
拷贝文件或目录到镜像中。src 可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压。还可以是一个 url,如果把 src 写成一个 url,那么 ADD 就类似于 wget 命令,然后自动下载和解压。

ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java

COPY

语法: COPY <src>... <dest>
拷贝文件或目录到镜像中。用法同 ADD,只是不支持自动下载和解压。

COPY jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java

EXPOSE

语法:EXPOSE <port> [<port>/<protocol>...]
暴露容器运行时的监听端口给外部,可以指定端口是监听 TCP 还是 UDP,如果未指定协议,则默认为 TCP。

EXPOSE 80 443 8080/tcp

如果想使得容器与宿主机的端口有映射关系,必须在容器启动的时候加上 -p 参数。

ENV

语法:ENV <key> <value> 添加单个,ENV <key>=<value> ... 添加多个。
设置容器内环境变量。

ENV JAVA_HOME /usr/local/java/jdk-11.0.6/

CMD

语法:

  • CMD ["executable","param1","param2"],比如:CMD ["/usr/local/tomcat/bin/catalina.sh", "start"]
  • CMD ["param1","param2"],比如:CMD [ "echo", "$JAVA_HOME" ]
  • CMD command param1 param2,比如:CMD echo $JAVA_HOME
    启动容器时执行的 Shell 命令。在 Dockerfile 中只能有一条 CMD 指令。如果设置了多条 CMD,只有最后一条 CMD 会生效。
CMD echo $JAVA_HOME

如果创建容器的时候指定了命令,则 CMD 命令会被替代。假如镜像叫 centos:7,创建容器时命令是:docker run -it --name centos7 centos:7 echo “helloworld” 或者 docker run -it --name centos7 centos:7 /bin/bash,就不会输出 $JAVA_HOME 的环境变量信息了,因为 CMD 命令被 echo “helloworld”、/bin/bash 覆盖了。

ENTRYPOINT

语法:

  • ENTRYPOINT ["executable", "param1", "param2"],比如:ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh", "start"]
  • ENTRYPOINT command param1 param2,比如:ENTRYPOINT ehco $JAVA_HOME

启动容器时执行的 Shell 命令,同 CMD 类似,不会被 docker run 命令行指定的参数所覆盖。在 Dockerfile 中只能有一条 ENTRYPOINT 指令。如果设置了多条 ENTRYPOINT,只有最后一条 ENTRYPOINT 会生效。

ENTRYPOINT echo $JAVA_HOME

如果在 Dockerfile 中同时写了 ENTRYPOINT 和 CMD,并且 CMD 指令不是一个完整的可执行命令,那么 CMD 指定的内容将会作为 ENTRYPOINT 的参数;
如果在 Dockerfile 中同时写了 ENTRYPOINT 和 CMD,并且 CMD 是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效

WORKDIR

语法:WORKDIR /path/to/workdir
RUNCMDENTRYPOINT 以及 COPY AND 设置工作目录。

WORKDIR /usr/local

指定容器挂载点到宿主机自动生成的目录或其他容器。一般的使用场景为需要持久化存储数据时。

VOLUME

语法:VOLUME ["/var/lib/mysql"]

容器的 /var/lib/mysql 目录会在运行时自动挂载为匿名卷,匿名卷在宿主机的 /var/lib/docker/volumes 目录下

一般不会在 Dockerfile 中用到,更常见的还是在 docker run 的时候通过 -v 指定数据卷。

Docker Build基于Dockerfile构建镜像

1.根据指令编写Dockerfile文件

# 创建宿主机文件目录
sudo mkdir -p /docker/dockerfile
# 到目录下
cd /docker/dockerfile
# 编写Dockerfile文件
vim Dockerfile

Dockerfile文件内容如下:

# 指明构建的新镜像是来自于 centos:7 基础镜像
FROM centos:7
# 通过镜像标签声明了作者信息
LABEL maintainer="cyl.com"
# 设置工作目录
WORKDIR /usr/local
# 新镜像构建成功以后创建指定目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/soft
# 拷贝文件到镜像中并解压
ADD  jdk-8u411-linux-x64.tar.gz /usr/local/java
ADD  demo-0.0.1-SNAPSHOT.jar /usr/local/soft
# 暴露容器运行时的 8080 监听端口给外部
EXPOSE 9080
# 设置容器内 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.8/
ENV PATH $PATH:$JAVA_HOME/bin
# 指定容器启动时运行Java程序
CMD ["java","-jar","/usr/local/soft/demo-0.0.1-SNAPSHOT.jar"]

其中jdk-8u411-linux-x64.tar.gz和demo-0.0.1-SNAPSHOT.jar我都放在了/docker/dockerfile目录下,和Dockerfile同一个目录

2.构建镜像

Dockerfile 文件编写好以后,真正构建镜像时需要通过 docker build 命令。

# 使用当前目录的 Dockerfile 创建镜像
sudo docker build -t mycentos-01:7 .

在这里插入图片描述
执行sudo docker images可以查看制作的镜像,mycentos-01是我刚刚使用Dockerfile制作的
在这里插入图片描述
还可以通过执行以下命令构建镜像

# 通过 -f Dockerfile 文件的位置创建镜像
docker build -f /docker/dockerfile/Dockerfile -t mycentos:7 .

-f:指定要使用的 Dockerfile 路径;
–tag, -t:镜像的名字及标签,可以在一次构建中为一个镜像设置多个标签。

最后的 . 号含义是什么?

若是.号则意味着宿主机中的Dockerfile文件和Dockerfile其它文件是同在一个目录下,比如jdk-8u411-linux-x64.tar.gz和demo-0.0.1-SNAPSHOT.jar,由于它们都在一个目录下,所以最后加一个.
若是不在一个目录,比如我的宿主机 jdk 文件在 /root 目录下,Dockerfile 文件在 /usr/local/dockerfile 目录下,文件内容如下:

ADD jdk-8u411-linux-x64.tar.gz /usr/local/java

那么构建镜像时的命令就该这样写:

docker build -f /usr/local/dockerfile/Dockerfile -t mycentos:7 /root

3.启动容器

# 启动容器
sudo docker run -di --name mycentos1 -p 9080:9080  mycentos-01:7
# 主机直接调用Java程序接口,输出hello java即成功
curl ip:9080/index

总结

本文主要讲解了Docker Commit基于容器构建镜像和Docker Build基于Dockerfile构建镜像的两种方式,同时也介绍了Dockerfile的常用指令操作,一般推荐Dockerfile这种方式构建镜像,只需要在Dockerfile中写好构建所需的指令,非常灵活和方便!

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

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

相关文章

时空扭曲:重温相对论的终极挑战,探寻真理的脚步

大家都知道&#xff0c;相对论是爱因斯坦提出的划时代理论&#xff0c;为人类认知时空和引力做出了革命性贡献。但这个理论真的万无一失吗&#xff1f;近日&#xff0c;一项新研究提出了测试时间扭曲的新方法&#xff0c;或许能让我们重新审视相对论在宇宙大尺度上的适用性。 时…

【数据结构】快速排序(详解)

目录 快速排序 历史&#xff1a; 基本思想&#xff1a; 主框架&#xff1a; 下面解释实现单次排序的几种版本&#xff1a; 1.Hoare版本 2. 挖坑法 3. 前后指针法 快速排序的实现包括递归与非递归&#xff1a; 1. 递归实现&#xff1a;&#xff08;即开头的基本框架&am…

正在直播:Microsoft Copilot Studio 新增支持Copilot代理、Copilot扩展等多项功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

现代C++ 如何使用 Lambda 使代码更具表现力、更容易理解?

使用 Lambda 使代码更具表现力 一、Lambda VS. 仿函数二、总结 一、Lambda VS. 仿函数 Lambda 是 C11 中最引人注目的语言特性之一。它是一个强大的工具&#xff0c;但必须正确使用才能使代码更具表现力&#xff0c;而不是更难理解。 首先&#xff0c;要明确的是&#xff0c;…

上位机图像处理和嵌入式模块部署(mcu之串口控制gpio)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们陆续学习了gpio输入、输出&#xff0c;串口输入、输出。其实有了这两个接口&#xff0c;就可以做产品了。因为我们可以通过发送串口命令&a…

【智能算法应用】北方苍鹰算法求解二维栅格路径规划问题

目录 1.算法原理2.二维路径规划数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】北方苍鹰优化算法&#xff08;NGO)原理及实现 2.二维路径规划数学模型 栅格法模型最早由 W.E. Howden 于 1968 年提出&#xff0c;障碍物的栅格用黑色表示&#xff0c;可通过的…

element-plus表格的表单校验如何实现,重点在model和prop

文章目录 vue&#xff1a;3.x element-plus&#xff1a;2.7.3 重点&#xff1a; 1) tableData放到form对象里 2) form-item的prop要写成tableData.序号.属性 <!--table-表单校验--> <template><el-form ref"forms" :model"form"><e…

百度墨斗鱼文库创作中心上传验证码分析

之前发表过一篇&#xff0c;百度墨斗鱼后台上传文章分析的文章。时隔几个月&#xff0c;文件预览接口加了asc- token 和 验证码&#xff08;百度v2&#xff09;。闲来没事分析一下。所有的分析都基于协议&#xff0c;不基于web自动化。 验证码目前有四种&#xff0c;验证码刷…

【Flutter】线性布局弹性布局层叠布局

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Flutter学习 &#x1f320; 首发时间&#xff1a;2024年5月25日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 目…

第十五届“北斗杯”全国青少年空天科技体验与创新大赛安徽赛区阜阳市解读会议

5月19日&#xff0c;第十五届“北斗杯”全国青少年空天科技体验与创新大赛安徽赛区阜阳解读活动在阜阳市图书馆隆重举行。共青团阜阳市委员会学少部副部长丁晓龙、阜阳市师范大学物理系副主任黄银生教授、安徽科技报阜阳站站长李伟、市人工智能学会秘书长郭广泽、“北斗杯”安徽…

牛客NC236 最大差值【simple 动态规划 Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/a01abbdc52ba4d5f8777fb5dae91b204 思路 不难看出该题可以使用动态规划的方式解题。 在循环数组的过程中&#xff0c;记录截止到当前位置-1的最小值&#xff0c; 然后用当前的值去计算最大的差值。Java代码 im…

AI时代下对于bloger的影响

前言 AI已经不是一个新词儿了&#xff0c;相信能看到这篇文章的同学都使用AI工具。AI工具已经渗透各行各业了。今天简谈一下AI对我们技术bloger的影响。 文章的访问量变少了 文章的访问量主要是两个渠道&#xff0c;博客平台内部推送&#xff0c;搜索引擎推送。AI的兴起肯定会…

每日练习之深度优先搜索——最大的湖

最大的湖 题目描述 运行代码 #include<iostream> using namespace std; bool mp[102][102]; int sum,num; int N,M,K; int dfs(int x,int y ) {if( mp[x][y] ){mp[x][y]0;sum;dfs(x1,y);dfs(x-1,y);dfs(x,y1);dfs(x,y-1);}return 0; } int main() {cin>>N>>…

【B站 heima】小兔鲜Vue3 项目学习笔记Day02

文章目录 Pinia1.使用2. pinia-计数器案例3. getters实现4. 异步action5. storeToRefsx 数据解构保持响应式6. pinia 调试 项目起步1.项目初始化和git管理2. 使用ElementPlus3. ElementPlus 主题色定制4. axios 基础配置5. 路由设计6. 静态资源初始化和 Error lens安装7.scss自…

无人机+飞行服务:无人机飞防服务(打药+施肥+播种)技术详解

无人机飞防服务&#xff0c;结合了先进的无人机技术与农业实践&#xff0c;为现代农业提供了高效、精准的打药、施肥和播种解决方案。以下是对这些技术的详细解析&#xff1a; 一、无人机打药技术 无人机打药技术利用无人机搭载喷雾设备&#xff0c;对农田进行精准施药。通过…

【Numpy】深入解析numpy.mgrid()函数

numpy.mgrid()&#xff1a;多维网格生成与数值计算的利器 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393…

vuejs路由和组件系统

前端路由原理 createRouter * hash* window.addEventListener(hashChange)* 两种实现路由切换的模式&#xff1a;UI组件&#xff08;router-link&#xff0c;router-view&#xff09;&#xff0c;Api&#xff08;push()方法&#xff09; * history * HTML5新增的API &#xff0…

Qt下使用QImage和OpenCV实现图像的拼接与融合

文章目录 前言一、使用QImage进行水平拼接二、使用OpenCV进行水平拼接三、使用OpenCV进行图像融合四、示例完整代码总结 前言 本文主要讲述了在Qt下使用QImage和OpenCV实现图像的拼接与融合&#xff0c;并结合相应的示例进行讲解&#xff0c;以便大家学习&#xff0c;如有错误…

分割文本文件

分割一个.txt文件&#xff0c;可以选择在命令行中使用split指令&#xff0c;或者编写一段脚本进行操作。以下是一个简单的Python脚本来分割文本文件&#xff1a; def split_file(file, lines):# Open source filewith open(file, r) as source:count 0atEOF Falsewhile not …

齐护K210系列教程(三十四)_视觉PID巡线小车

视觉PID巡线小车 1.前言2.简介3.代码讲解3.1初始化3.2.色块查找3.3色块分析3.3.1 区域13.3.2 区域2 3.4 侦测关键点部分3.4.1正常巡线3.4.2 右转路口 3.4.3十字路口3.4. PID计算 4.完整代码5.小车端程序6.参考程序联系我们 1.前言 本课程主要讲述如何使用AIstart_k210主板完成…