Docker——Dockerfile介绍和使用

1、Dockerfile 介绍

什么是 Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

查看官方Dockerfile制作的镜像

1、在DockerHub上随便搜索一个镜像,以mysql为例

2、然后找一个版本点进去,就能跳转到镜像在github的地址

在这里插入图片描述

3、查看mysql镜像的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 added
RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN 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
# 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 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

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-get update && apt-get install -y --no-install-recommends \
# for MYSQL_RANDOM_ROOT_PASSWORD
		pwgen \
# for mysql_ssl_rsa_setup
		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 \
# install "xz-utils" for .sql.xz docker-entrypoint-initdb.d files
		xz-utils \
	&& rm -rf /var/lib/apt/lists/*

RUN set -ex; \
# gpg: key 5072E1F5: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
	key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
	export GNUPGHOME="$(mktemp -d)"; \
	gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
	gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
	gpgconf --kill all; \
	rm -rf "$GNUPGHOME"; \
	apt-key list > /dev/null

ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.36-1debian10

RUN echo 'deb http://repo.mysql.com/apt/debian/ 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 quieter
RUN { \
		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/mysql

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060
CMD ["mysqld"]

Dockerfile 基本结构

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。

Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..

#基础镜像信息
FROM ubuntu

#维护者信息
MAINTAINER docker_user docker_user@email.com

#镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

#容器启动时执行指令
CMD /usr/sbin/nginx

镜像操作指令,例如 RUN指令,RUN 指令将对镜像执行跟随的命令。每运行一条 RUN指令,镜像添加新的一层,并提交。

CMD 指令,来指定运行容器时的操作命令。

2、Dockerfile 指令说明

Dockerfile 常用命令

img

补充:

MAINTAINER:镜像的维护者信息,格式:姓名+邮箱

VOLUME:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

格式:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

ONBUILD:配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令,这是一个触发指令。

LABEL:指令用来给镜像添加一些元数据(metadata),以键值对的形式,

比如我们可以添加镜像的作者:

LABEL myimage.authors="cheng"

CMD 和 ENTRYPOINT 的区别

CMD:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

ENTRYPOINT :类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

3、构建自定义的centos 镜像

官方提供的centos镜像是个压缩版的,有些命令不支持使用,如clear,ll,ifconfig,vim:

在这里插入图片描述

1、编写dockerfile文件mydockerfile-centos:

[root@CHENG ceshi]# vim mydockerfile-centos

FROM centos  #定制的镜像都是基于FROM 的镜像,这里的 centos 就是定制需要的基础镜像。后续的操作都是基于 centos。

MAINTAINER wanli<3194525857@qq.com>  #镜像的维护者信息

ENV MYPATH /usr/local #容器运行时的环境变量,在后续的指令中,就可以使用这个环境变量

WORKDIR $MYPATH  #指定工作目录。WORKDIR指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

RUN yum -y install vim  #执行后面跟着的命令行命令
RUN yum -y install net-tools

EXPOSE 80 #声明端口

CMD echo $MYPATH 
CMD echo "----end----"
CMD /bin/bash

2、通过dockerfile文件构建镜像,镜像名 mycentos

docker build -f mydockerfile-centos -t mycentos:1.0 .

3、查看自定义的centos镜像

在这里插入图片描述

4、查看指定镜像的创建历史 docker history

语法

docker history [OPTIONS] IMAGE

OPTIONS说明:

  • -H :以可读的格式打印镜像大小和日期,默认为true;
  • –no-trunc :显示完整的提交记录;
  • -q :仅列出提交记录ID。

实例:查看自定义centos镜像的创建历史

在这里插入图片描述

5、创建并运行容器,进行命令测试

测试ifconfig命令:ifconfig 可以执行

在这里插入图片描述

4、构建 tomcat 镜像并部署项目

1、准备tomcat镜像,jdk压缩包和tomcat压缩包

tomcat镜像最新版:

在这里插入图片描述

jdk压缩包和tomcat压缩包:

在这里插入图片描述

在容器外创建一个文件:

touch readme.txt

2、编写dockerfile文件

如果dockerfile文件命名为Dockerfile,docker build 的时候就不需要使用 -f ,会自动查找Dockerfile这个文件:

[root@CHENG tomcat]# vim Dockerfile

FROM centos
MAINTAINER wanli<3194525857@qq.com>

COPY readme.txt usr/local/readme.txt

ADD jdk-8u202-linux-x64.tar.gz /usr/local/jdk
ADD apache-tomcat-8.5.30.tar.gz /usr/local/tomcat

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk/jdk1.8.0_202
ENV CATALINA_HOME /usr/local/tomcat/apache-tomcat-8.5.30
ENV CATALINA_BASE /usr/local/tomcat/apache-tomcat-8.5.30
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin


EXPOSE 8080

CMD /usr/local/tomcat/apache-tomcat-8.5.30/bin/startup.sh && tail -f /usr/local/tomcat/apache-tomcat-8.5.30/logs/catalina.out

3、使用Dockerfile文件构建镜像

#因为我们dockerfile文件ming使用的是官方的名字Dockerfile,所以不用写 -f 指定文件路径
docker build -t diytomcat .

构建完成后查看镜像:

在这里插入图片描述

4、启动镜像

#-p 9001:8080 端口映射,服务器打开端口
#--name wanlitomcat 容器名
# -v /usr/local/tomcat/test:/usr/local/apache-tomcat-9.0.52/webapps/test 挂载项目发布
# -v /usr/local/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.52/logs 挂载日志目录
docker run -d -p 9001:8080 --name wanlitomcat 
-v /usr/local/dockertomcat/test:/usr/local/tomcat/apache-tomcat-8.5.30/webapps/test
-v /usr/local/dockertomcat/tomcatlogs:/usr/local/tomcat/apache-tomcat-8.5.30/logs 
diytomcat

容器运行成功:

在这里插入图片描述

5、进入容器内部

docker exec -it wanlitomcat /bin/bash

在这里插入图片描述

进入tomcat目录

在这里插入图片描述

6、浏览器访问tomcat ,ip+9001端口访问测试

在这里插入图片描述

7、发布项目,tomcat的webpapps目录已经和test目录挂载上,项目只需发布在test目录中就行

在test目录下创建一个WEB-INF目录,在WEB-INF目录下编写web.xml文件

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

  </web-app>

在test目下编写index.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>diytomcat</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("----diytomcat test-project----")
%>
</body>
</html>

浏览器访问项目:项目部署成功还可以访问。

在这里插入图片描述

进入挂载日志的目录tomcatlogs,查看日志输出:

在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐