Dockerfile极简入门与实践

前文中,罗列了docker使用中用到的基本命令
此文,将会对怎样使用Dockerfile去创建一个镜像做简单的介绍

Dockerfile命令

要开始编写Dockerfile,首先要对相关的命令有个清晰的认识
下面列出了部分Dockerfile命令的功能以及使用方法,供参考:

1. FROM

Dockerfile的第一条指定必须是FROM,用于指定基础镜像。
用法:
FROM [image]:[tag]

2. MAINTAINER

用于指定此Dockerfile维护者信息。
用法:
MAINTAINER <name> <email>

3. ADD

复制指定内容到镜像中,指定内容可以是一个相对或绝对路径,也可以是一个url(此时相当于wget),如果添加的文件是个tar压缩文件,文件在复制的时候会自动解压。
用法:
ADD <src> <dest>

4. COPY

与ADD命令用法相同,区别是COPY只能复制本地文件
用法:
COPY <src> <dest>

5. RUN

构建镜像时运行指定命令,建议多个命令尽量写在同一个RUN中,用&&分割或使用\换行。
用法:
RUN <command>
RUN ["executable", "param1", "param2"]
前者在shell终端上运行,后者使用exec运行。

6. CMD

容器启动时运行指定命令,每个容器只能执行一条CMD命令,多个CMD命令时,只最后一条被执行。
用法:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD <command> <param1> <param2>

7. ENV

指定一个环境变量,可以被RUN,WORKDIR命令使用,并在容器运行时保持。
用法:
ENV <key> <value>
ENV <key1>=<value1> <k2>=<v2> <k3>=<v3> ...

8. ENTRYPOINT

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,每个Dockerfile中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。
用法:
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT <command> <param1> <param2>

9. WORKDIR

设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建。
用法:
WORKDIR <path>

10. EXPOSE

功能为暴漏容器运行时的监听端口给外部
用法:
EXPOSE <port>

Dockerfile实践

通读过上面的Dockerfile命令,相信对编写一个Dockerfile有了一个初步的认识
接着,我们来通过一个具体的需求,来看一个完整的镜像是怎么通过Dockerfile生成的

1. 需求

使用32位的jre环境运行一个dubbo服务的jar包

2. 编写Dockerfile

首先,我们需要一个32位的jre环境,你可以从镜像仓库找一个,但此处,我们选择通过Dockerfile自己创建

# 指定基础镜像
FROM i386/centos:6
# 作者信息
MAINTAINER trainoo "[email protected]"
# 添加jre环境,add会自动解压
ADD jre-8u211-linux-i586.tar.gz /opt/docker/java/jre8
# 设置java环境变量
ENV JAVA_HOME=/opt/docker/java/jre8/jre1.8.0_211     CLASSPATH=$JAVA_HOME/bin     PATH=.:$JAVA_HOME/bin:$PATH
# 容器启动后执行,显示java版本号,可以查看环境是否安装成功
CMD ["java","-version"]

问:为什么使用 i386/centos:6 作为基础镜像?
答:因为32位的jre当然是使用32位的环境运行比较方便
如果使用64位的环境运行32位jre也是可以的,但是需要安装如下依赖:
RUN yum update && yum -y install glibc.i686 zlib.i686 libstdc++.i686
如果打包的是64位的jre,那么基础镜像可以换成:frolvlad/alpine-glibc

问:jre-8u211-linux-i586.tar.gz 这个包从哪下载?
答:你可以从官网下载,当然,你看到此文章时,可能网址已经变化。

3. 构建

如上,我们写好了一个Dockerfile,只需把jre包跟Dockerfile放在同一路径
即可开始构建,命令如下:docker build -t jre8-64:second .
ps: 此处应该贴32位的运行过程的,但是64位的跟32位没太大区别,所以就这样吧

[[email protected] jre8-x32]# ll
total 89060
-rw-r--r--. 1 root root      369 Jun 27 18:38 Dockerfile
-rw-r--r--. 1 root root 91192891 Jun 26 14:52 jre-8u211-linux-i586.tar.gz

[[email protected] jre8-x64]# docker build -t jre8-64:second .
Sending build context to Docker daemon  87.86MB
Step 1/5 : FROM frolvlad/alpine-glibc:alpine-3.10
 ---> 74b43ef19206
Step 2/5 : MAINTAINER trainoo "[email protected]"
 ---> Using cache
 ---> 1257f5f17f2a
Step 3/5 : ADD jre-8u211-linux-x64.tar.gz /opt/docker/java/jre8
 ---> Using cache
 ---> 10692b79be49
Step 4/5 : ENV JAVA_HOME=/opt/docker/java/jre8/jre1.8.0_211 CLASSPATH=$JAVA_HOME/bin PATH=.:$JAVA_HOME/bin:$PATH
 ---> Running in 1710cc8fd3aa
Removing intermediate container 1710cc8fd3aa
 ---> 5dd2f0ae922c
Step 5/5 : CMD ["java","-version"]
 ---> Running in 368238c0940b
Removing intermediate container 368238c0940b
 ---> e6e9cf729e37
Successfully built e6e9cf729e37
Successfully tagged jre8-64:second

[[email protected] jre8-x64]# docker images -f reference=jre8*
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jre8-64             second              e6e9cf729e37        53 seconds ago      251MB
jre8-32             base                9035f0dcd0ed        20 hours ago        433MB
jre8-64             base                ce0823b7fdc3        47 hours ago        251MB

由上面的构建步骤可以看出,每运行一个命令,都会产生一个临时镜像,所以为了避免产生多余的临时镜像,我们要尽量的把多个相同指令的的构建步骤,写在同一行里。

4. 运行项目

假设我们把项目打包好了,打包好的jar包为:my-service-1.0.jar。

FROM jre8-32:base
MAINTAINER trainoo "[email protected]"
COPY ./jar/ /opt/dubbo-server/
RUN cd /opt/dubbo-server/ && mv $(ls | grep jar) app.jar
WORKDIR /opt/dubbo-server/
CMD ["java","-Xms512M","-Xmx512M","-jar","app.jar"]

// 为了通用性,这里把jar文件(如果不是springboot项目,还有lib等依赖包)放在jar目录下,COPY时一起复制过去
// 同样目的,使用 mv $(ls | grep jar) app.jar 将需要被执行的jar文件统一命名成 app.jar
# 构建镜像
[[email protected] jre8-x64]# docker build -t myservice:v1 .
.....此处省略部分.....
# 启动容器
[[email protected] jre8-x64]# docker run -d --name myservice myservice:v1
# 查看容器
[[email protected] jre8-x64]# docker ps 

后续总结

事情总是不会这么顺利,中途总是会有一些小插曲,所以下面是可能遇到的问题的解决方案

docker 批量删除产生的缓存镜像
# 第一种风格
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop
docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm
docker images | grep none | awk '{print $3}' | xargs docker rmi

# 第二种风格
docker rm $(docker ps -aq -f status=exited)
docker rmi $(docker images -qa -f reference=*:v1)
container 时区跟 host 不一致
# Dockerfile中添加
RUN echo "Asia/Shanghai" > /etc/timezone

# 启动时添加:-v /etc/localtime:/etc/localtime:ro
docker run -d -v /etc/localtime:/etc/localtime:ro --net mynet --name myservice myservice:v1
docker运行项目,日志中文显示???
# Dockerfile中添加,指定语言环境
RUN localedef -i en_US -f UTF-8 en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

原文地址:https://www.cnblogs.com/Trainoo/p/11108389.html

时间: 2025-01-07 07:44:16

Dockerfile极简入门与实践的相关文章

反向传播神经网络极简入门

反向传播神经网络极简入门 我一直在找一份简明的神经网络入门,然而在中文圈里并没有找到.直到我看到了这份162行的Python实现,以及对应的油管视频之后,我才觉得这就是我需要的极简入门资料.这份极简入门笔记不需要突触的图片做装饰,也不需要赘述神经网络的发展历史:要推导有推导,要代码有代码,关键是,它们还对得上.对于欠缺的背景知识,利用斯坦福大学的神经网络wiki进行了补全. 单个神经元 神经网络是多个“神经元”(感知机)的带权级联,神经网络算法可以提供非线性的复杂模型,它有两个参数:权值矩阵{W

Nginx 极简入门教程!

上篇文章和大家聊了 Spring Session 实现 Session 共享的问题,有的小伙伴看了后表示对 Nginx 还是很懵,因此有了这篇文章,算是一个 Nginx 扫盲入门吧! 基本介绍 Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务. Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日. Nginx 特点是占有内存少,

【Java杂货铺】用Security做权限极简入门

原来大多数单体项目都是用的shiro,随着分布式的逐渐普及以及与Spring的天生自然的结合.Spring Security安全框架越受大家的青睐.本文会教你用SpringSecurity设计单项目的权限,关于如何做分布式的权限,后续会跟进. 为什么选择SpringSecurity? 现如今,在JavaWeb的世界里Spring可以说是一统江湖,随着微服务的到来,SpringCloud可以说是Java程序员必须熟悉的框架,就连阿里都为SpringCloud写开源呢.(比如大名鼎鼎的Nacos)作

ActiveMQ + NodeJS + Stomp 极简入门

前提 安装ActiveMQ和Nodejs 测试步骤 1.执行bin\win32\activemq.bat启动MQ服务 2. 打开http://localhost:8161/admin/topics.jsp 用户名和密码都是 admin 3. 下载Stomp npm install stomp-client 4. js的测试代码 var Stomp = require('stomp-client'); var destination = '/topic/myTopic'; var client =

Express4+Mongodb极简入门实例

一.准备工作: 1.启动mongodb:bin目录下运行 2.在test数据库里插入一条数据: 二.正式开始: 1.通过应用生成器工具 express 快速创建一个应用的骨架,参考Express中文网http://www.expressjs.com.cn/starter/generator.html: 2.这里我创建了一个名叫firstapp的应用: 通过Express生成器就快速生成了如下的应用骨架: 3.express4默认以jade为模板,这里我改用ejs,在package.json文件中

Node.js 极简入门Helloworld版服务器例子

粗浅得很,纯属备忘. // 内置http模块,提供了http服务器和客户端功能(path模块也是内置模块,而mime是附加模块) var http=require("http"); // 创建服务器,创建HTTP服务器要调用http.createServer()函数,它只有一个参数,是个回调函数,服务器每次收到http请求后都会调用这个回调函数.服务器每收到一条http请求,都会用新的request和response对象触发请求函数. var server=http.createSer

如何实践极简主义生活方式

极简主义生活方式,是对自身的再认识,对自由的再定义. 深入分析自己,首先了解什么对自己最重要,然后用有限的时间和精力,专注地追求,从而获得最大幸福. 放弃不能带来效用的物品,控制徒增烦恼的精神活动,简单生活,从而获得最大的精神自由. 欲望极简 了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风. 把自己的精力全部用在自己最迫切的欲望上,如提升专业素养.照顾家庭.关心朋友.追求美食等. 精神极简 了解.选择.专注于1-3项自己真正想从事的精神活动,充分学习.提高. 不盲目浪费自己的时间与精力.

Flask入门小项目 - 搭建极简博客(7)

目录: Flask入门小项目 - 搭建极简博客(1)介绍与项目结构 Flask入门小项目 - 搭建极简博客(2)添加主页 Flask入门小项目 - 搭建极简博客(3)添加登录.登出功能 Flask入门小项目 - 搭建极简博客(4)添加注册功能 Flask入门小项目 - 搭建极简博客(5)添加写文章功能 Flask入门小项目 - 搭建极简博客(6)添加删除文章功能 Flask入门小项目 - 搭建极简博客(7)部署到服务器,实现外网访问 完整程序点这 零.效果 域名的话要等它备案完才能访问... 一

React Native的极简手册

安装入门可以参考:React Native官方文档(http://reactnative.cn/docs/0.31/tutorial.html#content). NodeJS知识储备:参考<NodeJS入门>(https://leanpub.com/nodebeginner-chinese).(尊重知识,请购买原版). 书籍:<React Native入门与实战> 代码示例:30天学习React Native教程(https://github.com/fangwei716/30-