1.dockerfile是什么

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。可以理解为docker自己的语言编写的脚本。

2.Dockerfile内容基础知识

1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数

2:指令按照从上到下,顺序执行

3:#表示注释

4:每条指令都会创建一个新的镜像层,并对镜像进行提交

3.redis的dockerfile实例

https://hub.docker.com/_/redis/

FROM debian:buster-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r -g 999 redis && useradd -r -g redis -u 999 redis # grab gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.12
RUN set -eux; \
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates dirmngr gnupg wget; \
rm -rf /var/lib/apt/lists/*; \
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
chmod +x /usr/local/bin/gosu; \
gosu --version; \
gosu nobody true ENV REDIS_VERSION 6.0.15
ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-6.0.15.tar.gz
ENV REDIS_DOWNLOAD_SHA 4bc295264a95bc94423c162a9eee66135a24a51eefe5f53f18fc9bde5c3a9f74 RUN set -eux; \
\
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends \
ca-certificates \
wget \
\
dpkg-dev \
gcc \
libc6-dev \
libssl-dev \
make \
; \
rm -rf /var/lib/apt/lists/*; \
\
wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; \
echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; \
mkdir -p /usr/src/redis; \
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; \
rm redis.tar.gz; \
\
# disable Redis protected mode [1] as it is unnecessary in context of Docker
# (ports are not automatically exposed when running inside Docker, but rather explicitly by specifying -p / -P)
# [1]: https://github.com/redis/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' /usr/src/redis/src/config.c; \
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' /usr/src/redis/src/config.c; \
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' /usr/src/redis/src/config.c; \
# for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
# see also https://github.com/docker-library/redis/issues/4#issuecomment-50780840
# (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
\
# https://github.com/jemalloc/jemalloc/issues/467 -- we need to patch the "./configure" for the bundled jemalloc to match how Debian compiles, for compatibility
# (also, we do cross-builds, so we need to embed the appropriate "--build=xxx" values to that "./configure" invocation)
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
extraJemallocConfigureFlags="--build=$gnuArch"; \
# https://salsa.debian.org/debian/jemalloc/-/blob/c0a88c37a551be7d12e4863435365c9a6a51525f/debian/rules#L8-23
dpkgArch="$(dpkg --print-architecture)"; \
case "${dpkgArch##*-}" in \
amd64 | i386 | x32) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=12" ;; \
*) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=16" ;; \
esac; \
extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-hugepage=21"; \
grep -F 'cd jemalloc && ./configure ' /usr/src/redis/deps/Makefile; \
sed -ri 's!cd jemalloc && ./configure !&'"$extraJemallocConfigureFlags"' !' /usr/src/redis/deps/Makefile; \
grep -F "cd jemalloc && ./configure $extraJemallocConfigureFlags " /usr/src/redis/deps/Makefile; \
\
export BUILD_TLS=yes; \
make -C /usr/src/redis -j "$(nproc)" all; \
make -C /usr/src/redis install; \
\
# TODO https://github.com/redis/redis/pull/3494 (deduplicate "redis-server" copies)
serverMd5="$(md5sum /usr/local/bin/redis-server | cut -d' ' -f1)"; export serverMd5; \
find /usr/local/bin/redis* -maxdepth 0 \
-type f -not -name redis-server \
-exec sh -eux -c ' \
md5="$(md5sum "$1" | cut -d" " -f1)"; \
test "$md5" = "$serverMd5"; \
' -- '{}' ';' \
-exec ln -svfT 'redis-server' '{}' ';' \
; \
\
rm -r /usr/src/redis; \
\
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
find /usr/local -type f -executable -exec ldd '{}' ';' \
| awk '/=>/ { print $(NF-1) }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -r apt-mark manual \
; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
\
redis-cli --version; \
redis-server --version RUN mkdir /data && chown redis:redis /data
VOLUME /data
WORKDIR /data COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 6379
CMD ["redis-server"]

4.dockerfile执行流程

(1)docker从基础镜像运行一个容器

(2)执行一条指令并对容器作出修改

(3)执行类似docker commit的操作提交一个新的镜像层

(4)docker再基于刚提交的镜像运行一个新容器

(5)执行dockerfile中的下一条指令直到所有指令都执行完成

5.dockerfile内容

1)FROM:基础镜像,当前新镜像是基于哪个镜像的

2)MAINTAINER:镜像维护者的姓名和邮箱地址

3)RUN:镜像构建容器时会运行此条命令

4)EXPOSE:当前容器对外暴露出的端口

5)WORKDIR:指定在创建容器后,终端登陆的进来默认工作目录,就像进入centos默认容器是在根目录/这里

6)ENV:用来在构建镜像过程中设置环境变量,这个环境变量可以在后续的任何RUN指令中使用,也可以在其它指令中直接使用这些环境变量
7)ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

8)COPY:类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

9)VOLUME:容器数据卷,用于数据保存和持久化工作

10)CMD:指定一个容器启动时要运行的命令,Dockerfile 中可以有多个 CMD 指令,最终只有最后一个生效,CMD 会被 docker run 之后的参数替换

11)ENTRYPOINT :指定一个容器启动时要运行的命令,docker run -it id /bin/bash,这里后面接了命令/bin/bash,对于/bin/bash命令不会覆盖ENTRYPOINT 的目录而是追加,但是会覆盖CMD的命令

12)ONBUILD:当构建一个被继承的Dockerfile时会运行此条命令

6.示例

6.1示例1

1)编辑dockerfile文件

FROM centos:6.8
MAINTAINER zzyy<zzyy167@126.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN ls -la
EXPOSE 80
CMD echo $MYPATHCMD echo "success--------------ok"
CMD /bin/bash

命令说明

FROM centos:6.8                  继承自centos:6.8
MAINTAINER zzyy<zzyy167@126.com>    作者和邮箱
ENV MYPATH /usr/local           定义环境变量MYPATH = /usr/local 
WORKDIR $MYPATH              进入容器后的默认目录/usr/local 
RUN ls -la                 运行RUN命令创建容器时,会执行命令 ls -la
EXPOSE 80                  对外暴露端口80
CMD echo $MYPATHCMD echo "success--------------ok" 执行命令 打印字符串
CMD /bin/bash

2)build生成新的镜像

可以看到 la -la执行了  打印字符串也执行了

最终成功生成新的镜像

3)使用新生成的镜像创建运行容器

进入容器,运行命令pwd查看当前目录,发现当前目录是/usr/local,说明配置生效了

4)小结

上面已涉及到了命令:FROM 、MAINTAINER 、ENV 、WORKDIR 、RUN 、EXPOSE 、CMD

6.2示例2-CMD和ENTRYPOINT的不同

6.2.1CMD

1)创建dockerfle

里面就一个ls命令

FROM centos:6.8
CMD ls

2)build创建新的镜像

3)使用镜像创建运行容器

ls命令执行了

4)使用镜像创建运行容器并追加命令

这样子执行相当于dockerfile是下面这样

FROM centos:6.8
CMD ls
CMD -la

加了一条命令 -la

由于-la不是命令,所以执行出错了

6.2.2ENTRYPOINT

1)dockerfile

FROM centos:6.8
ENTRYPOINT ls

2)build创建新镜像

3)创建和启动容器

执行了命令 ls

4)使用镜像创建运行容器并追加命令

这样子执行相当于dockerfile是这样子

FROM centos:6.8
ENTRYPOINT ls -la

ls和-la命令拼接起来了

这就是CMD和ENTRYPOINT 的区别

6.2示例3-ONBUILD

6.2.1父镜像

1)dockerfile

FROM centos:6.8
ONBUILD RUN echo "bei ji chengle 666666"

ONBUILD:当这个dockerfile生成的镜像被继承的时候,会打印这段文字

2)build

6.3.2子镜像

1)dockerfile

FROM zzyy/mycentos:4.2
RUN echo "run---qidong"

继承自上面生成的镜像:zzyy/mycentos:4.2

2)build

由于它继承自zzyy/mycentos:4.2,所以build的时候打印了父镜像zzyy/mycentos:4.2的dockerfile里面ONBUILD要打印的字符串

6.3带有JAVA、TOMCAT环境的centos

1)dockerfile

FROM  centos
MAINTAINER    zzyy<zzyybs@126.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中 从宿主机复制jdk和tomcat到容器的usr/local目录下
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE  8080
#启动时运行tomcat并且打印日志
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

2)build

  dodker build -f /usr/local/docker/Dockerfile -t zzyytomcat9 .

3)run

docker run -d -p 9080:8080 --name myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs --privileged=true zzyytomcat9

在tomcat的webapp目录下创建了两个容器数据卷,相当于两个项目,这样子可以在宿主机下直接对项目进行修改,容器下项目会同步

最新文章

  1. ArcSDE解除图层锁定
  2. 前端见微知著AngularJS备忘篇:温故而知新,可以为师矣
  3. phpcms v9无法连接数据库服务器,请检查配置
  4. Go Mobile 例子 basic 源码分析
  5. python安装(windows)
  6. JSON对象、JSON字符串的相互转换
  7. Mybatis mapper文件中的转义方法
  8. ElasticSearch 学习记录之集群分片内部原理
  9. netty深入学习之一: 入门篇
  10. 杭电ACM2014--青年歌手大奖赛_评委会打分
  11. linux添加超级管理员用户,修改,删除用户
  12. Java集合实现
  13. python-json函数
  14. [Linux][Mac]如何使用SSH登陆远程Linux服务器&amp;使用SCP下载远程终端文件
  15. 一. Redis 常用命令
  16. &lt;Spark&gt;&lt;Spark Streaming&gt;
  17. 今天折腾phantomjs+selenium的笔记
  18. 《mysql必知必会》学习_第五章_20180730_欢
  19. 【比赛游记】NOIP2017游记
  20. YARN结构分析与工作流程

热门文章

  1. mysql如何备份
  2. PGL图学习之图神经网络GraphSAGE、GIN图采样算法[系列七]
  3. [排序算法] 树形选择排序 (C++)
  4. &lt;七&gt;深入理解new和delete的原理
  5. Map的遍历方式,常用的key-value遍历方式
  6. Boolean.getBoolean() 与 Boolean.parseBoolean()
  7. 浅谈 Java 和 Python 的反射
  8. jQuery类库
  9. SQLMap入门——获取数据库用户的密码
  10. LoadRunner11录制脚本