CreateArtTechnology
/ Blog
Login
最新文章
Java
语言相关
库相关
虚拟机相关
CreateArtTechnology
项目搭建
使用的工具
自研的工具
开源工具
ELK
ElasticSearch
Jenkins
Markdown
GraphQL
Arthas
生产工具
Linux
Nginx
VersionControl
Subversion
Git
Redis
Archiva
Maven
Zookeeper
Spring
SpringBoot
MySql
HBase
Cassandra
容器化
Docker
Kubernetes
服务容器化从零开始
未分类笔记
算法相关
概念相关
豆知识
机器学习
机器学习从零开始
使用Dockerfile构建Docker镜像
12
2019-02-15 17:18:23
容器化
Docker
## 构建前需要知道的相关知识 1. **DO NOT WRITE WHOLE DOCKERFILE YOURSELF UNLESS YOU KNOW WHAT YOU ARE DOING.** 参见文末 2. **Dockerfile中每一行命令都会产生一层,每一层内容都会保留到最终镜像** 需要尽量合并命令,每层只保留需要的内容,及时清理不必要的内容 > Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。 ## 指令 指令只需要知道是干什么用的即可,有可能你用不上。用到的时候再细学。 **FROM** 第一行从FROM开始,说明这个镜像以谁为基础 `FROM nginx` 以nginx镜像为基础 **RUN** 指明使用哪个命令,执行什么内容 `RUN echo '
Hello, Docker!
' > /usr/share/nginx/html/index.html` 修改nginx首页的内容 尽量像这样合并多条命令,在一个命令内完成下载、编译、安装、清理: ```shell RUN buildDeps='gcc libc6-dev make wget' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && mkdir -p /usr/src/redis \ && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ && make -C /usr/src/redis \ && make -C /usr/src/redis install \ && rm -rf /var/lib/apt/lists/* \ && rm redis.tar.gz \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDeps ``` **COPY** 可以复制文件,文件权限、时间信息等会保留,支持通配符,支持设置权限,详见下一节“构建镜像” ```shell # 支持--chown=
:
COPY --chown=55:mygroup files* /mydir/ ``` **ENV** 设置环境变量 ```shell # 两种格式 ENV
ENV
=
=
... ``` **WORKDIR** 设置工作目录,不存在的话会自动建立 ```shell WORKDIR <工作目录路径> ``` 注意,每层文件是相互独立的,工作目录也是相互独立的 ```shell # 这样是修改 world.txt,而不是 /app/world.txt RUN cd /app RUN echo "hello" > world.txt ``` **EXPOSE** 暴露容器端口,具体是否真正暴露还看宿主设置 ```shell # 格式 EXPOSE <端口1> [<端口2>...] EXPOSE 80 8080 ``` **CMD** 用于指定默认的容器主进程使用什么命令启动 ```shell # 多种格式 # shell格式:CMD <命令> # exec格式:格式:CMD ["可执行文件", "参数1", "参数2"...] # 参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。 # 这是一个tomcat镜像的Dockerfile指明启动tomcat的默认命令 CMD ["catalina.sh", "run"] ``` > 一些初学者将 CMD 写为: CMD service nginx start 然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。 对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。 而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为 CMD [ "sh", "-c", "service nginx start"],因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。 正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如: CMD ["nginx", "-g", "daemon off;"] ## 构建镜像 在Dockerfile所在目录,执行: ```shell # build并打上tag,并带上上下文目录'.' docker build -t nginx:v3 . ``` 其中,上下文目录下的所有内容会打包发送给Docker引擎,在构建镜像时可通过`COPY`指令复制相应内容,如: ```shell COPY ./package.json /app/ ``` 但是,一旦超出上下文范围(如`../path/to/file`),Docker引擎将无法访问。 ## 不要自己从头写Dockerfile! [Docker Hub](https://hub.docker.com/search/?q=&type=image&image_filter=official)上有非常多的高质量官方镜像,同时提供了对应的高质量的Dockerfile文件,大多数情况下直接`FROM`或拿来稍微改动一点就可以作为很好用的镜像,如 [tomcat](https://hub.docker.com/_/tomcat/)、[nginx](https://hub.docker.com/_/nginx/)、[redis](https://hub.docker.com/_/redis/) 等。 除非真正需要自己完全定制,否则尽量使用这些高质量的镜像(Dockerfile)。 **注:有些Dockerfile使用的keyserver不稳定,可能出现50x(如ha.pool.sks-keyservers.net),遇到这种情况可使用这个keyserver:`keyserver.ubuntu.com`** ## 参考资料 其他构建细节、指令及方法请参考: [Docker——从入门到实践](https://yeasy.gitbooks.io/docker_practice/ "Docker——从入门到实践")
发布文章 101
文章被阅读 1817
最近修改
什么是“丝滑”的曲线
2021-12-08 15:19:20
高效空间数据索引R树及其批量加载方法STR简介
2021-09-29 20:33:37
关于分库分表的一些事儿
2021-06-25 11:51:25
获得诺奖的稳定匹配理论之TTC算法与GS算法
2021-03-14 23:04:48
算法小白的机器学习入门实践,从零到上线
2021-01-13 14:28:27
分站宗旨
一站式资料平台,减少重复检索,减少重复采坑。