Docker之使用Dockerfile创建定制化镜像(四)
Dockerfile简介
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么哪些无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,
因此每一条指令的内容,就是描述该层应当如何构建
Dockerfile编写注意项
- # 备注
- 指令参数,指令的大小写不敏感
- 第一个非注释行必须是FROM指令
- 编写Dockerfile必须在一个目录下进行,这个目录称之为 工作目录(WORKSPACE)
- Dockerfile文件命令的首字母必须大写
- 制作镜像所要用的文件必须放在工作目录或者工作目录的子目录之下,不能放在父目录
- 可以通过隐藏文件 .dockeringnore 来指定不要放入到镜像中的文件,一行是一个文件,可以用通配符
- 基于dockerfile做镜像,本质上还是基于一个现有的镜像做新镜像
Dockerfile指令详解
1. FROM
作用:FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令
格式:
FROM <registry>:[tag]
FROM <registry>@<digest>
FROM 示例:
第一步:创建工作目录及dockerfile
- [root@ken ~]# mkdir /ken
- [root@ken ~]# cd /ken
- [root@ken ken]# touch Dockerfile
第二步:写入from指令
docker.io:注册表
nginx:仓库
latest:版本号
- [root@ken ken]# cat Dockerfile
- FROM docker.io/nginx:latest
2. LABEL
作用:设定一些元数据
格式:
LABEL 信息
LABEL示例:
- LABEL author "ken"
3. COPY
作用:将工作目录下的文件复制到所做得镜像中的文件系统中
格式:
复制单个文件:COPY <src> <dest>
复制多个文件:COPY [<src> <src> <src>… <dest>]
COPY示例:
- COPY passwd /data/
注意:
- 源文件路径用相对路径,目标一般用绝对路径
- 也可以通配符
- 源文件必须在工作目录或者工作目录的子目录中
- 目标路径可以不存在,会自动创建
- 如果源文件是一个目录,会自动递归复制目录下的文件到目标位置,但是目录自身不会复制
- 如果复制多个文件,或者源文件中用了通配符,那么目标路径必须以 / 为结尾
4. ADD
作用:和COPY类似,可以实现将文件和目录加载镜像中,但是区别是可以实现将tar包解压,也可以实现从网络下载文件到镜像
注意:下载的tar无法解压
格式
ADD <src> <dest>
ADD [“<src>” “<src>” “<src>” “<dest>”]
ADD示例:
- ADD nginx-1.14.0.tar.gz /data/
5. WORKDIR
作用:相当于执行cd命令。切换目录,为后续的RUN、CMD、ENTRYPOINT 指令配置工作目录。
格式:
WORKDIR 容器目录
WORKDIR示例:
- WORKDIR /pack/nginx/
6. VOLUME
作用:指定数据卷的挂载点
格式:
VOLUME 容器目录
VOLUME示例:
- VOLUME /data/mysql/mysql3306/data
7. EXPOSE
作用:设置Docker容器内部暴露的端口号,如果需要外部访问,还需要启动容器时增加-p或者-P参数进行分配。
格式:
EXPOSE PORT/[PROTOCOL]
EXPOSE示例:
- EXPOSE 80/tcp
9. ENV
作用:设置环境变量
格式:
ENV var value
ENV var1=value1 var2=value2 …
注意:
通过ENV所定义的变量是可以传递到容器之中,但是,在创建容器的时候,如果手动指定了变量的值,那么这个值会覆盖掉镜像中原有的值
ENV示例:
- ENV pkgname=nginx-1.14.0.tar.gz root=/data/mysql/mysql3306/data
10. RUN
作用:基于镜像构建容器时候要执行命令
阶段:第一阶段,也就是构建镜像的时候执行
格式:
RUN 命令
RUN示例:
- RUN tar xf $root$pkgname
11. CMD
作用:定义容器启动以后要默认运行的程序,pid为1的程序
阶段:第二阶段,也就是将镜像构成成容器的时候执行
注意:可以在启动容器的时候用指定的命令替换掉镜像所要执行的命令
CMD指定容器启动是执行的命令,每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行。如果你在启动容器的时候也指定的命令,那么会覆盖Dockerfile构建的镜像里面的CMD命令
格式:
CMD <命令> 相当于执行的是/bin/sh -c 命令,也相当于执行exec来运行命令
CMD [“<命令>”, “<参数>”, “<参数>”]
CMD [“<参数>”, “<参数>”] <<< 需要借助于ENTRYPOINT指令
CMD示例:
- CMD mkdir /ken
12. ENTRYPOINT
作用:定义容器启动以后要默认运行的程序,pid为1的程序
注意:
在运行RUN的时候所执行的命令无法覆盖ENTRYPOINT中的命令
RUN 后面的命令会被以参数的方式追加到原本要执行的命令的末尾,而不是替换
基于一个镜像,在创建容器的时候,通过传递不同的参数实现创建不同的容器
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效
格式:
ENTRYPOINT [“执行命令”,”参数1″,”参数2″…]
ENTRYPOINT示例:
- ENTRYPOINT [ "curl", "-s", "http://10.220.5.138" ]
例如如下CMD和ENTRYPOINT的结合
FROM nginx
label auther=ken
ARG name=ken
ENV path=/ken/
COPY test /data/
ADD https://mirrors.aliyun.com/centos/7/os/x86_64/Packages/audiocd-kio-devel-4.10.5-3.el7.i686.rpm $path
WORKDIR $path
RUN mkdir $name
VOLUME $path
EXPOSE 80
RUN mkdir /test1
CMD ["-g","daemon off;"]
ENTRYPOINT ["nginx"]
13. ARG
作用:定义变量,这个变量是用在第一阶段(构建镜像——build)
格式:
ARG 变量名=变量值
ARG示例:
- ARG name=ken
补充:Dockerfile中ENV 和 ARG的区别
在指定docker build 过程中传参数,要用ARG
在执行docker run的过程中传参数,要用ENV
ARG构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的
环境变量,在将来容器运行时是不会存在这些环境变量的
14. USER
作用:指定运行容器时的用户名和UID,后续的RUN指令也会使用这里指定的用户
该用户必须存在于容器的用户空间中(容器的文件系统的中的/etc/passwd中)
格式:
USER <UID>|<USERNAME>
USER示例:
- user ken
15. HEALTHCHECK
作用:docker daemon检查docker容器是否正常,如果异常会将该容器stop
将容器stop的条件
1)主进程停止了
2)主进程工作在了后台
格式:
HEALTHCHECK [options] CMD
options
–interval=#s|m 指定健康检查的时间间隔(例如:30s,30m)
–timeout=#s|m 指定等待响应的超时时间
–start-period=#s|m 指定容器启动多久以后才可以做监控检查
–retries=# 指定重试次数
返回值
0:success
1:unhealth
HEALTHCHECK示例:
- HEALTHCHECK --interval=5m --timeout=1s --retries=3 CMD curl http://10.220.5.138/ken.html || exit 1
16. SHELL
可以用来指定系统中默认的shell类型
格式:
SHELL [“/bin/sh”, “-c”] (linux系统中)
SHELL示例:
- SHELL ["/bin/sh","-c"]
17. STOPSIGNAL
向容器中pid为1的进程发送一个信号,通过这个信号来关闭这个主进程
默认是15信号
格式:
STOPSIGNAL 数值
STOPSIGNAL示例:
- STOPSIGNAL 9
18. ONBULID
作用:定义一个触发器,指定的命令在构建镜像时并不执行,用来实现当基于这个这个镜像做新镜像的时候要执行的命令
格式:
ONBUILD 其他指令
ONBUILD示例:
- ONBUILD COPY ken /app/
Dokcerfile完整演示创建nginx镜像
根据上面各个指令的介绍,我就直接用上面写的dockerfile进行演示。整个dockerifle内容如下。
- [root@ken ~]# vim /ken/Dockerfile
- FROM docker.io/nginx:latest
- LABEL author "ken"
- COPY ./passwd /data/
- WORKDIR /pack/nginx/
- ENV pkgname=nginx-1.14.0.tar.gz root=/data/mysql/mysql3306/data/
- COPY nginx-1.14.0.tar.gz $root
- VOLUME $root
- EXPOSE 80/tcp
- RUN tar xf $root$pkgname
- CMD nginx -g "daemon off;"
第一步:构建镜像
build:是指根据dockerfile制作镜像
-t:指定一个tag标签
.:表示上下文。你也可以理解为dockfile所在的目录,但是并不是准确的
如果下方出现successfully就表示镜像已经构建成功了
- [root@ken ken]# docker build -t ken:v1-0 .
- Sending build context to Docker daemon 1.021 MB
- Step 1/10 : FROM docker.io/nginx:latest
- ---> 568c4670fa80
- Step 2/10 : LABEL author "ken"
- ---> Using cache
- ---> 80e4e5846fd9
- Step 3/10 : COPY ./passwd /data/
- ---> Using cache
- ---> 685a7ceb74b3
- Step 4/10 : WORKDIR /pack/nginx/
- ---> Using cache
- ---> 0fc65f8c36df
- Step 5/10 : ENV pkgname nginx-1.14.0.tar.gz root /data/mysql/mysql3306/data/
- ---> Using cache
- ---> 3f6038473472
- Step 6/10 : COPY nginx-1.14.0.tar.gz $root
- ---> Using cache
- ---> 0cbff6223d5b
- Step 7/10 : VOLUME $root
- ---> Using cache
- ---> b74ac1c36c31
- Step 8/10 : EXPOSE 80/tcp
- ---> Using cache
- ---> 6863a87a61a2
- Step 9/10 : RUN tar xf $root$pkgname
- ---> Using cache
- ---> b32ac636a389
- Step 10/10 : CMD nginx -g "daemon off;"
- ---> Running in 02308825301d
- ---> 4a91d70a57eb
- Removing intermediate container 02308825301d
- Successfully built 4a91d70a57eb
第二步:查看镜像
可以发现构建的名为ken标签为v1-0的镜像已经存在了
- [root@ken ken]# docker image ls
- REPOSITORY TAG IMAGE ID CREATED SIZE
- ken v1-0 4a91d70a57eb 21 minutes ago 116 MB
第三步:启动容器
可以发现基于我们刚才的创建的镜像的容器已经顺利跑起来了。
- [root@ken ken]# docker run -d --name ken3 -d ken:v1-0
- 11f492a28b943e619b0ed5d6b19f212f1c9cc47f9bdbe132845e7a7129e5b419
- [root@ken ken]# docker container ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 11f492a28b94 ken:v1-0 "/bin/sh -c 'nginx..." 16 seconds ago Up 11 seconds 80/tcp ken3
第四步:登录容器
可以发现我们这个启动的容器里面已经有我们指定的工作目录
复制过来的passwd文件
已经下载并传送到/data下了
- [root@ken ken]# docker exec -it ken3 bash
- root@11f492a28b94:/pack/nginx# ls /data/
- mysql/ passwd
- root@11f492a28b94:/pack/nginx# ls /data/
- mysql/ passwd
- oot@11f492a28b94:/pack/nginx# ls /data/mysql/mysql3306/data/nginx-1.14.0.tar.gz
- /data/mysql/mysql3306/data/nginx-1.14.0.tar.gz
这样基于dockerfile自主创建镜像的过程就演示完了,快去自己制作一个属于自己的镜像吧。
基于centos部署LAMP镜像
第一步:拉取centos7镜像
并按照如下的dockerfile初始化镜像
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
第二步:编写制作LAMP架构的dockerfile
FROM local/c7-systemd
COPY local.repo /etc/yum.repos.d/
COPY wordpress /var/www/html/
RUN yum -y install httpd mariadb-server php php-mysql; yum clean all; systemctl restart mariadb httpd;systemctl enable mariadb httpd.service
EXPOSE 80 3306
CMD ["/usr/sbin/init"]
1.使用第一步创建出来的镜像
2.把local.repo文件发送到镜像中,因为镜像文件没有mariad数据库
local.repo文件内容
[local]
name=local
enabled=1
gpgcheck=0
baseurl=https://mirrors.aliyun.com/centos/7/os/x86_64/
3.把配置好的wordpress安装包复制到网站根目录下
4.下载LAMP架构
5.暴露80 和3306 端口
6.启动
第三步:运行容器
[root@ken-node3 centos]# docker run -d -v /sys/fs/cgroup/:/sys/fs/cgroup/ -p 888:80 --privileged centos-wordpress:v1
–privileged 让容器能够获得更多特权,否则在容器内部不能使用systemctl,会报如下的错
Failed to get D-Bus connection: Operation not permitted
第四步:进入容器创建数据库
[root@ken-node3 centos]# docker exec -it f80ed6fb67b3 bash
[root@f80ed6fb67b3 /]# ls /var/www/html/
index.php wp-activate.php wp-config-sample.php wp-links-opml.php wp-register.php
license.txt wp-admin wp-config.php wp-load.php wp-settings.php
readme.html wp-app.php wp-content wp-login.php wp-signup.php
wordpress wp-blog-header.php wp-cron.php wp-mail.php wp-trackback.php
wordpress-3.3.1-zh_CN.zip wp-comments-post.php wp-includes wp-pass.php xmlrpc.php
[root@f80ed6fb67b3 /]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.60-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database ken;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> grant all on *.* to ken@'localhost' identified by '123';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
第五步:浏览器访问
Docker之使用Dockerfile创建定制化镜像(四)的更多相关文章
- Docker之使用Dockerfile创建定制化镜像(四)--技术流ken
前言 在之前的博客<Docker端口映射及创建镜像演示(二)--技术流ken>,演示了如何使用一个现有容器创建一个镜像,以及镜像在阿里云的上传和下载. 但是这样的镜像有很大的局限性,不能根 ...
- [转]Docker基础-使用Dockerfile创建镜像
本文转自:https://www.cnblogs.com/jie-fang/p/7927643.html 1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # T ...
- Docker基础-使用Dockerfile创建镜像
1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # This dockerfile uses the ubuntu image # VERSION 2 - ED ...
- docker学习系列(二):使用Dockerfile创建自己的镜像
dockerfile可以允许我们自己创建镜像,通过编写里面的下载软件命令,执行docker build 即可生成镜像文件. 初尝dockerfile 新建一个目录test,然后进入这个目录,创建一个名 ...
- 使用Dockerfile创建一个tomcat镜像,并运行一个简单war包
docker已经看了有一段时间了,对镜像和容器也有了一个大致了解,参考书上的例子制作一个tomcat镜像,并简单运行一个HelloWorld.war 1.首先下载linux环境的tomcat和jdk, ...
- 基于alpine用dockerfile创建的tomcat镜像
1.下载alpine镜像 [root@docker43 ~]# docker pull alpine Using default tag: latest Trying to pull reposito ...
- 基于alpine用dockerfile创建的ssh镜像
1.下载alpine镜像 [root@docker43 ~]# docker pull alpine Using default tag: latest Trying to pull reposito ...
- docker定制化镜像的构建及基于该定制的镜像创建容器
1.在项目里创建Dockerfile(注意大小写)文件,执行构建命令:docker build -t tiny-node-1 /root/tiny-node-docker 其中tiny-node ...
- 使用odoo官方dockerfile 创建最新版镜像
以odoo11.0为例 1.检出odoo/docker仓:git clone https://github.com/odoo/docker.git 2.打开目录 http://nightly.odoo ...
随机推荐
- start-stop-daemon: matching on world-writable pidfile /var/run/redis/redis-server.pid is insecurefailed
Microsoft Store上 看到最新的Ubuntu 20.04 LTS 已经适配到WSL上了, 于是卸载了老版本 18.04 LTS,安装上了最新版本的. 第一次启动会比较慢,需耐心等待 Ins ...
- Debug很重要
之前做一个小功能,就是用php发送邮件,项目中已经使用了wordpress的wp_mail,所以同事建议我继续用wp_mail函数. 然而遇到了一个奇怪的情况,邮件没有发出去,也没有任何报错日志. 照 ...
- Python钉钉报警及Zabbix集成钉钉报警
钉钉报警设置 创建群机器人 11111 接口地址 发送短消息 发送普通消息 import requests import json url = 'https://oapi.dingtalk.com/r ...
- JavaScript学习系列博客_16_JavaScript中的函数(Function)简介
函数(Function) - 函数也是一个对象,也具有普通对象的功能 - 函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码:当调用函数时,函数中封装的代码会按照顺序执行. - 使用ty ...
- JavaScript学习系列博客_38_JavaScript 事件
事件(Event) - 事件指的是用户和浏览器之间的交互行为.比如:点击按钮.关闭窗口.鼠标移动.... - 我们可以为事件来绑定回调函数来响应事件. - 绑定事件的方式: 1.可以在标签的事件属性中 ...
- 关于ACID,BASE和CAP定理的探究
前言 当我看到"根据CAP理论,由于分布式系统必须保证分区容错性,所以只能选择AP原则或者CP原则"这种结论时,我感到很疑惑: 什么是分区容错性? 为什么分布式系统必须保证分区容错 ...
- SPSSAU数据分析思维培养系列2:分析方法
大家好!在上篇文章中,我们一起学习了如何掌握正确的数据处理思维(文章链接:https://www.cnblogs.com/spssau/p/12523530.html).在完成数据准备和清理工作后,就 ...
- Shell编程—结构化命令(2)
1for命令 for命令的基本格式: for var in list do commands done 在list参数中,你需要提供迭代中要用到的一系列值. 1.1读取列表中的值 例子: $ vim ...
- 用 Python 写个七夕表白神器
今天是七夕节,相比于现代人自创的 502,不对是 520,七夕才是中国传统意义上的情人节,本文分享几个 Python 表白程序,情侣可以现学现用,单身的话也可以先收藏一下,说不定下次就用上了. 爱心树 ...
- 新手学习java路线
关于新手学习java的路线 笔者也是根据这个路线学习的,希望对你们有所帮助. 首先你要确定你是学习java 并且能够踏踏实实的走下去.一定要多学习,我也可以一直陪你走下去的. 笔者一年工作经验,科班毕 ...