【Docker第三篇】彻底搞懂Dockerfile文件

网友投稿 1704 2022-10-06

【Docker第三篇】彻底搞懂Dockerfile文件

文章目录

​​一、前言​​​​二、Dockerfile基本命令​​

​​2.1 FROM (导入基础镜像,几乎是必须的,就像是java程序中的import导入)​​​​2.2 RUN (在镜像内部执行一些命令,类似java程序中的main函数)​​​​2.3 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习)​​​​2.4 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令)​​​​2.5 ENV (环境变量,类似springboot工程的中的环境变量)​​​​2.6 VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作)​​​​2.7 LABEL (给生成的镜像打上标签)​​​​2.8 CMD 和 ENTRYPOINT (类似,放在一起学习)​​​​2.9 Dockerfile常用命令小结​​

​​三、看懂一个Dockerfile​​

​​3.1 在Github上找到一个Dockerfile文件​​​​3.2 阅读一个官方的Dockerfile​​

​​四、实践:jar -> image -> container​​

​​4.1 jar -> image -> container​​​​4.2 jar -> image -> container​​

​​五、尾声​​

一、前言

​​本文资源地址​​

二、Dockerfile基本命令

2.1 FROM (导入基础镜像,几乎是必须的,就像是java程序中的import导入)

FROM ubuntu:14.04

指定基础镜像,比如FROM ubuntu:14.04

2.2 RUN (在镜像内部执行一些命令,类似java程序中的main函数)

RUN groupadd -r mysql && useradd

在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用""

2.3 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习)

COPY docker-entrypoint.sh /usr/local/bin/

将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和 解压,类似于 linux 上的 cp 命令,对文件或目录执行 复制 操作

ADD application.yml /etc/itcrazy2016/

更多的是将主机的文件复制到目录内,最后这个文件也被打到 image 镜像里面,用COPY也可以实现这个功能,但是ADD会对压缩文件提取和解压

2.4 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令)

指定镜像的工作目录,之后的命令都是基于此目录工作(若不存在则创建),类似于是 xshell 中的 mkdir && cd 命令

WORKDIR /usr/local # 表示从根目录出发 mkdir /usr/local && cd /usr/localWORKDIR tomcat # 表示从当前目录 (/usr/local) 出发,mkdir tomcat && cd tomcatRUN touch

会在/usr/local/tomcat下创建test.txt文件

WORKDIR /root ADD app.yml test/

会在/root/test下多出一个app.yml文件

2.5 ENV (环境变量,类似springboot工程的中的环境变量)

ENV MYSQL_MAJOR 5.7

设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使 用${MYSQL_MAJOR}

2.6 VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作)

VOLUME /var/lib/mysql

指定数据的挂在目录

EXPOSE 3306

指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机

2.7 LABEL (给生成的镜像打上标签)

LABEL email="itcrazy2016@163.com" LABEL name="itcrazy2016"

设置镜像标签

2.8 CMD 和 ENTRYPOINT (类似,放在一起学习)

好了,Dockerfile所有的准备工作都完成了,现在要启动这个Dockerfile,将 .jar 变成一个 image 镜像。Dockerfile中的ENTRYPOINT指令和CMD指令都可以设置容器启动时要执行的命令,但用途是有略微不同的。这两个类似于 xshell 对于可执行脚本(linux上白色是文件,绿色是可执行文件,蓝色是目录),./aa.sh 执行。

容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效

CMD ["mysqld"]

和CMD的使用类似

ENTRYPOINT ["docker-entrypoint.sh"]

和CMD的不同,docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会

ENTRYPOINT指令和CMD指令虽然是在Dockerfile中定义,但是在构建镜像的时候并不会被执行,只有在执行docker run命令启动容器时才会起作用。

1、在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准。 2、在Dockerfile中,只能有一个CMD指令,如果有多个CMD指令则以最后一个为准。 3、在Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一。

对于每个Dockerfile文件,存在三种情况: 情况1:Dockerfile中最后只有一条ENTRYPOINT指令; 情况2:Dockerfile中最后只有一条CMD指令; 情况2:Dockerfile中最后有一条ENTRYPOINT指令和CMD指令。

2.9 Dockerfile常用命令小结

开始,写一个Dockerfile文件的时候: 第一,先一个 FORM 命令,表示导入基础镜像,几乎是必须的,就像是java程序中的import导入; 第二,开始在 Dockerfile 中执行 RUN (在镜像内部执行一些命令,类似xshell程序中的main函数),执行 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习),执行 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令); 第三,需要的环境环境 ENV (环境变量,类似springboot工程的中的环境变量) 第四,VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作) 第五,LABEL 给需要生成的image镜像打好标签 最后,镜像完成之后,执行 CMD 和 ENTRYPOINT。

三、看懂一个Dockerfile

3.1 在Github上找到一个Dockerfile文件

3.2 阅读一个官方的Dockerfile

​​NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"## PLEASE DO NOT EDIT IT DIRECTLY.#FROM debian:buster-slim# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get addedRUN groupadd -r mysql && useradd -r -g mysql mysqlRUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*# add gosu for easy step-down from root# GOSU_VERSION 1.14RUN set -eux; \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends ca-certificates wget; \ rm -rf /var/lib/apt/lists/*; \ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ wget -O /usr/local/bin/gosu "\ wget -O /usr/local/bin/gosu.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 trueRUN mkdir /docker-entrypoint-initdb.dRUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ bzip2 \ openssl \# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:# File::Basename# File::Copy# Sys::Hostname# Data::Dumper perl \ xz-utils \ zstd \ ; \ rm -rf /var/lib/apt/lists/*RUN set -eux; \ key='859BE8D7C586F538430B19C2467B942D3A79BD29'; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ mkdir -p /etc/apt/keyrings; \ gpg --batch --export "$key" > /etc/apt/keyrings/mysql.gpg; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME"ENV MYSQL_MAJOR 5.7ENV MYSQL_VERSION 5.7.39-1debian10RUN echo 'deb [ signed-by=/etc/apt/keyrings/mysql.gpg ] buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)# also, we set debconf keys to make APT a little quieterRUN { \ echo mysql-community-server mysql-community-server/data-dir select ''; \ echo mysql-community-server mysql-community-server/root-pass password ''; \ echo mysql-community-server mysql-community-server/re-root-pass password ''; \ echo mysql-community-server mysql-community-server/remove-test-db select false; \ } | debconf-set-selections \ && apt-get update \ && apt-get install -y \ mysql-server="${MYSQL_VERSION}" \# comment out a few problematic configuration values && find /etc/mysql/ -name '*.cnf' -print0 \ | xargs -0 grep -lZE '^(bind-address|log)' \ | xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \# don't reverse lookup hostnames, they are usually another container && echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \ && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime && chmod 1777 /var/run/mysqld /var/lib/mysqlVOLUME /var/lib/mysqlCOPY docker-entrypoint.sh /usr/local/bin/RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compatENTRYPOINT ["docker-entrypoint.sh"]EXPOSE 3306 33060CMD ["mysqld"]

四、实践:jar -> image -> container

4.1 jar -> image -> container

(1)创建一个Spring Boot项目 (2)写一个controller

@RestControllerpublic class DockerController { @GetMapping("/dockerfile") @ResponseBody String dockerfile() { return "hello docker"; }}

(3)mvn clean package打成一个jar包 在target下找到"dockerfiledemo-0.0.1-SNAPSHOT.jar"

(4)在docker环境中新建一个目录"first-dockerfile"

(5)上传"dockerfiledemo-0.0.1-SNAPSHOT.jar"到该目录下,并且在此目录创建Dockerfile

(6)创建Dockerfile文件,编写内容

FROM openjdk:8 MAINTAINER maoLABEL name="dockerfile-demo" version="1.0" author="mao" COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar CMD ["java","-jar","dockerfile-image.jar"]

(7)基于Dockerfile构建镜像

docker build -t test-docker-image .

(8)基于image创建container

docker run -d --name user01 -p 6666:8080 test-docker-image

(9)查看启动日志

docker

(10)宿主机上访问

curl localhost:6666/dockerfile hello docker

(11)还可以再次启动一个

docker run -d --name user02 -p 8081:8080 test-docker-image

注意1:mvn clean package 将 jar变为package 注意2:宿主机都是当前的centos机器

4.2 jar -> image -> container

五、尾声

彻底搞懂Dockerfile文件,完成了。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SAP ABAP OData 服务如何支持修改(Update)操作试读版
下一篇:微信小程序实现根据字母选择城市的功能(微信小程序城市选择列表)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~