Dockerfile实现
1)Dockerfile 概述
- 我们目前都是手动拉取镜像,手动进行配置,手动安装依赖,手动编译安装,创建用户……这个过程类似于命令行使用ansible模块(繁琐,不方便重复执行)
- 书写Dockerfile把之前手动创建自定义镜像的过程,通过Dockerfile里面的指令实现,类似于书写playbook
- Dockfile用于根据要求自动创建镜像
2)Dockerfile 构建过程
过程
- 编写Dockerfile 文件
- dockerbuild构建镜像
- docker run 运行容器
- docker push 上传镜像
须知
- 每个保留关键字指令都是大写字母
- 执行顺序是从上往下
- 表示注释
- 每一个指令都会提交一个新的镜像层

3) Dockerfile 的指令
| FROM |
| MAINTAINER |
| RUN |
| ADD |
| COPY |
| WORKDIR |
| VOLUME |
| EXPOSE |
| CMD |
| ENTRYPOINT |
| ONBUILD |
| ENV |

-
构建centos7–nginx:
-
:Dockerfile 使用
| FROM centos:centos7.9.2009 |
| MAINTAINER "This is quyi by Dockerfile" |
| |
| RUN yum install -y wget curl |
| RUN cd /etc/yum.repos.d/\ |
| && wget https://mirrors.aliyun.com/repo/Centos-7.repo\ |
| && wget http://mirrors.aliyun.com/repo/epel-7.repo |
| RUN yum install -y nginx |
| RUN rm -rf /usr/share/nginx/html/index.html\ |
| && echo 'qy.nbrhce.com' > /usr/share/nginx/html/index.html |
| CMD ["nginx","-g","daemon off;"] |
4) Dockerfile中的指令
Dockerfile指令 |
含义 |
应用 |
建议 |
Dockerfile开头部分 |
|
|
|
FROM |
指定基本镜像类似于docker pull 下载镜像 |
FROM ubuntu:20.04 |
尽量少写ubuntu或ubuntu:latest尽量指定具体的版本 |
LABEL |
用于指定容器的属性信息,作者个人联系方式(邮件) |
LABEL maintainer=”quyi996 _linux@qq.com” |
推荐使用LABEL,不推荐使用下面的MAINTAINER |
MAINTAINER |
不在使用,推荐使用LABEL 个人信息 |
|
|
ENV |
用于创建Dockerfile中使用的变量 |
ENV Tengine_Version空格2.3.3 |
软件版本可以创建使用变量 |
Dockerfile中间处理部分 |
|
|
|
RUN |
制作镜像过程中需要的执行命令,通常系统配置服务配置,部署但不能出现阻塞当前终端的命令 |
RUN系统命令即可 |
不建议使用连续多个RUN,合并连续多个RUN |
ADD |
可以把指定文件或目录拷贝到容器中(指定目录)压缩包解压,相当于当前目录 |
ADD restart.tar.gz 空格 /app/code/restart |
拷贝压缩包使用 |
COPY |
可以把指定文件或目录拷贝到容器中(指定目录),不支持自动解压,相对于当前目录 |
COPY nginx.conf 空格 /etc/nginx/nginx.conf |
拷贝文件或目录 |
WORKDIR |
指定容器的默认工作目录 |
WORKDIR /app/code/restart ADD restart.tar.gz 空 |
一般用于配合ADD,COPY需要书写容器中路径指令,Dockerfile中使用相对路径操作容器 |
VOLUME |
挂载数据卷 |
VOLUME /usr/share/nginx/html |
创建随机数据卷挂载容器的目录,未来推荐docker run 的时候指定 -v 即可 |
Dockerfile结尾部分书写的内容 |
|
|
|
EXPOSE |
指定镜像要对外暴露的端口 |
EXPOSE 80 |
用于指定一个或多个容器的端口,未来这个端口可以被IP识别 |
CMD |
用于指定容器的入口命令,入口命令可以在docker run的时候替换,运行后 |
CMD ["命令","参数 01","参数02"] CMD ["nginx","- g","daemon off;"] |
大部分都会使用CMD |
ENTRYPOINT |
用于指定容器的入口命令,无法被docker run 替换,docker run指定的时候仅仅作为entrypoint命令的参数而已 |
ENTRYPOINT ["executable", "param1", "param2"] |
使用不多 |
5)案例01 编译安装tengine变成Dockerfile
| FROM centos:centos7.9.2009 |
| LABEL maintainer="This is quyi by Dockerfile" |
| |
| |
| RUN yum install -y wget\ |
| && cd /etc/yum.repos.d/\ |
| && wget https://mirrors.aliyun.com/repo/Centos-7.repo\ |
| && wget http://mirrors.aliyun.com/repo/epel-7.repo |
| |
| RUN cd /tmp\ |
| && wget http://tengine.taobao.org/download/tengine-2.3.3.tar.gz\ |
| && tar xf tengine-2.3.3.tar.gz\ |
| && cd tengine-2.3.3\ |
| && yum install -y make gcc zlib-devel pcre-devel openssl-devel\ |
| && ./configure --prefix=/app/tools/\ |
| --user=nginx\ |
| --group=nginx\ |
| --with-http_ssl_module\ |
| --with-http_v2_module\ |
| --with-http_realip_module\ |
| --with-http_stub_status_module\ |
| --with-http_mp4_module\ |
| --with-stream \ |
| --with-stream_ssl_module\ |
| --with-stream_realip_module\ |
| --add-module=modules/ngx_http_upstream_check_module/\ |
| --add-module=modules/ngx_http_upstream_session_sticky_module\ |
| && make\ |
| && make install\ |
| && ln -s /app/tools/sbin/nginx /sbin\ |
| && groupadd nginx\ |
| && useradd -g nginx nginx\ |
| && echo 'qy.nbrhce.com' > /app/tools/html/index.html |
| EXPOSE 80 |
| CMD ["nginx","-g","daemon off;"] |
| |
| |
| Successfully built b7226374548a |
| Successfully tagged new-quyi-tengine:latest |
| |
| [root@docker02 /server/tools/file] |
06) CMD与ENTRYPOINT的区别
区别 |
CMD |
ENTRYPOINT |
共同点 |
用于设置容器入口命令,容器启动后默认运行什么指令什么参数 |
用于设置容器入口命令,容器启动后默认运行什么指令什么参数 |
共同点 |
CMD [“命令”,“参数”,“参数2”] |
ENTRYPOINT [“命令”,“参数1”,“参数2”] |
区别(不是同步使用) |
用户通过docker run /exec 启动进入容器的时候,指定了命令,这个命令会替代CMD命令和参数 |
用户通过docker run /exec 启动进入容器的时候,指定了命令,指定的命令,选项会成为ENTRYPOINT命令的选项 |
区别(同步使用) |
CMD写的入口命令和命令的选项(可以被替换) |
入口的指令不可替换,一般指定脚本,脚本用于判断用户docker run/exec 的时候是否输入了命令, 如果没加 docker run -d nginx:1.20.2 ,这种的就直接运行CMD如果加了,则运行对应的命令和选项 |
- 案例理解:CMD或ENTRYPONT的时候
- CMD
| |
| FROM ubuntu:20.04 |
| RUN touch oldboy.txt |
| CMD ["top","-b","-c"] |
| |
| [root@docker02 /docker-v2] |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 1f5df3a23cd3 test_cmd "top -b -c" 40 seconds ago Up 40 seconds try-1 |
| [root@docker02 /docker-v2] |
| [root@docker02 /docker-v2] |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 1ffca110063d test_cmd "sleep 90" 3 seconds ago Up 2 seconds try-2 |
| |
| |
| docker run -d --name "test_entrypoint" test:ubunt_entrypoint |
| docker run -d --name "test_entrypoint_sLeep9" test:ubunt_entrypoint sleep 9 |
| |
| FROM ubuntu:20.04 |
| RUN touch oldboy.txt |
| ENTRYPOINT ["top"] |
| CMD ["-b","-c"] |
| [root@docker02 /docker-v2] |
| |
| |
07)多阶段提交
- 在1个dockerfile中使用多个FROM,以减小最终镜像大小
- tengine+restart项目多阶段提交
- 1️⃣创建镜像的时候起个别名FROM xxx AS temp
- 2️⃣对中间镜像进行操作,下载依赖,下载软件包,编译
- 3️⃣创建镜像 FROM ubuntu:20.04
- 4️⃣把中间镜像的命令,配置文件/目录复制到最终镜像中,复制代码
- 5️⃣EXPOSE 80 , 设置入口指令CMD
| FROM ubuntu:20.04 AS demo |
| LABEL auther=quyi sys_version=ubuntu_20.04 |
| |
| RUN sed -ri 's#archive.ubuntu.com|security.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list\ |
| && apt update\ |
| && apt install -y wget libssl-dev make gcc pcre2-utils libpcre3-dev zlib1g-dev |
| RUN cd /tmp/\ |
| && wget http://tengine.taobao.org/download/tengine-2.3.3.tar.gz\ |
| && tar xf tengine-2.3.3.tar.gz\ |
| && cd tengine-2.3.3\ |
| && ./configure --prefix=/app/tools/tengine-2.3.3\ |
| --user=nginx\ |
| --group=nginx\ |
| --with-http_ssl_module\ |
| --with-http_v2_module\ |
| --with-http_realip_module\ |
| --with-http_stub_status_module\ |
| --with-http_mp4_module\ |
| --with-stream\ |
| --with-stream_ssl_module\ |
| --with-stream_realip_module\ |
| --add-module=modules/ngx_http_upstream_check_module/\ |
| --add-module=modules/ngx_http_upstream_session_sticky_module\ |
| && make\ |
| && make install |
| |
| |
| FROM ubuntu:20.04 |
| COPY --from=demo /app/ /app/ |
| RUN sed -ri 's#archive.ubuntu.com|security.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list\ |
| && apt update\ |
| && apt install -y libssl-dev pcre2-utils libpcre3-dev zlib1g-dev\ |
| && ln -s /app/tools/tengine-2.3.3/sbin/nginx /sbin/ \ |
| && groupadd nginx\ |
| && useradd -g nginx nginx\ |
| && rm -rf /app/tools/tengine-2.3.3/html/*\ |
| && rm -rf /tmp/*\ |
| && rm -rf /var/cache/* |
| ADD restart.tar.gz /app/tools/tengine-2.3.3/html/ |
| EXPOSE 80 443 |
| CMD ["nginx","-g","daemon off;"] |
| [root@docker01 /docker] |
| REPOSITORY TAG IMAGE ID CREATED SIZE |
| ubuntu-tengine seo 267c26d252c2 About a minute ago 194MB |
| nginx latest 605c77e624dd 4 months ago 141MB |
| ubuntu 20.04 ba6acccedd29 7 months ago 72.8MB |
| centos centos7.9.2009 eeb6ee3f44bd 8 months ago 204MB |
| |
| [root@docker01 /docker] |
| ubuntn-tengine |
| [root@docker01 /docker] |
- 适用于构建场合,先通过中间镜像进行编译,编程结果存放到新的镜像中
- FROM ubuntu:20.04 AS demo
- FROM ubuntu:20.04
- ADD –from
- COPY –from=demo …
08)Dockfile--php自定义镜像插件
主要是针对php连接web服务时候,缺少插件连接不上导致,
以下是自定义插件--用户是nginx带ID
| FROM php:7.4.29-fpm-alpine |
| LABEL Description='Extension gd mysqli pdo-mysql redis' Author='quyi' |
| |
| ENV URL https://pecl.php.net/get/redis-5.3.7.tgz |
| ENV DIR /usr/src/php/ext/ |
| |
| RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \ |
| && apk add zlib-dev libpng-dev libwebp-dev libjpeg-turbo-dev freetype-dev \ |
| && docker-php-source extract \ |
| && wget -P /tmp ${URL} \ |
| && tar xf /tmp/redis-5.3.7.tgz -C ${DIR}/ \ |
| && mv ${DIR}/redis-5.3.7 ${DIR}/redis \ |
| && cd ${DIR}/gd \ |
| && docker-php-ext-configure gd \ |
| --enable-gd \ |
| --with-webp \ |
| --with-jpeg \ |
| --with-freetype \ |
| && docker-php-ext-install gd \ |
| && cd ${DIR} \ |
| && docker-php-ext-install mysqli \ |
| && docker-php-ext-install pdo_mysql \ |
| && docker-php-ext-install redis \ |
| && addgroup -g 101 nginx \ |
| && adduser -s /sbin/nologin -D -S -H -u 101 -G nginx nginx \ |
| && sed -i 's#www-data#nginx#g' /usr/local/etc/php-fpm.d/www.conf \ |
| && rm -fr /var/cache/* /tmp/* /usr/src/php |
| |
| EXPOSE 9000 |
| |
| CMD ["php-fpm"] |
17)docker-file图解
