Docker入门之Dockerfile命令相关总结与基于centos镜像构建tomcat镜像
程序员文章站
2022-04-30 12:48:46
...
前言
- 上篇博客: Docker入门之安装docker即初步使用介绍了docker的相关命令以及如何运行一些基础镜像,但是运行的都是别人构建的镜像,要是能构建一些自己的镜像就爽了。于是,现在我们来学习了构建镜像的Dockerfile的相关知识点以及构建一个属于自己的tomcat镜像。
一、Dockerfile指令汇总
指令(不区分大小写,最好用大写,能更好的区别参数) | 规则 | 描述 | 示例 | 注意事项 |
---|---|---|---|---|
FROM | FROM 镜像名 | 指定基础镜像 | FROM <镜像>:[TAG] | 首先从本地找,若本地没有再从docker hub中找(可配置自己的docker registry) |
MAINTAINER | MAINTAINER 维护者信息 | 镜像的维护者 | MAINTAINER ‘avengerEug’ | 在高版本的docker中可能会被抛弃,取而代之的LABEL指令 |
COPY | COPY … COPY ["",…""] |
将宿主机的文件复制到镜像中去 | COPY 源文件(夹) 目标文件(夹) | 1. 必须是build上下文中的路径,不能是父目录中的文件 2. 如果是目录,其内部文件或子目录会被递归复制,但目录自身不会被复制 3. 如果指定了多个,或在中使用了通配符,则必须是一个目录,则必须以/结尾 4. 如果不存在,将会被自动创建 |
ADD | ADD … ADD ["",…""] |
将宿主机的文件添加到镜像中去 | ADD 源文件(夹) 目标文件(夹) | 1. 和COPY指令基本相同 2. 支持tar文件和url路径 3. 若是一个URL则执行的文件将被下载,但不会被解压 4. 如果是一个本地系统上压缩格式的tar文件,它会展开成一个目录; 但是通过URL获取的tar文件不会自动展开 5. 如果有多个,直接或间接使用了通配符指定多个资源,则必须是目录并且以/结尾 |
WORKDIR | WORKDIR | 指定工作目录, 在该命令下执行的文件操作 | WORKDIR /usr/local/src | 若在此命令后面执行了ADD或COPY命令,那么目标文件(夹)都会添加/usr/local/src前缀 同时我们进入容器后的工作目录也为/usr/local/src(这就是我们进入容器后发现有些容器是/目录, 有些是其他的目录) |
ENV | ENV ENV =… |
指定环境变量, ENV = 或 ENV key value | ENV JAVA_HOME /usr/local/jdk ENV PATH JAVA_HOME/bin/ |
调用格式:{variableName} |
RUN | RUN RUN ["","",""] |
后面接shell脚本的命令, 会按照shell脚本的格式解析. 用来指定docker build过程中运行指定的命令 |
RUN echo ‘Hello docker’ | 无 |
CMD | CMD CMD ["<可执行的命令>","",""] CMD ["",""] |
后面接shell脚本命令, 与RUN不同的是, 该CMD后面接的命令是在镜像启动后被执行的 | 无 | CMD命令可以写多个,但是只有最后一个CMD命令会生效, 所以我们在拉取其他人制作镜像的时候,若他人的镜像在启动时使用CMD命令来启动程序的, 那么我们在使用docker run命令添加shell命令时,会将里面的CMD命令覆盖。eg: 使用docker run --name tomcat -it -d -p 8080:8080 tomcat:latest ls命令启动 tomcat镜像时,容器不会被启动,容器启动时执行的命令为ls。 CMD ["",""] 此种方式是为ENTRYPOINT指令添加参数的 |
ENTRYPOINT | ENTRYPOINT ENTRYPOINT["","",""] |
容器启动时需要执行的命令 | ENTRYPOINT [“java”, “-jar”, “/root/test.jat”] | 与CMD类似,但它不会被docker run中的命令给覆盖。 它和CMD指令,谁在最后面,谁就生效 |
VOLUME | VOLUME VOLUME [""] |
挂载卷,可以将容器中的某个目录挂在到宿主机的随机目录下,eg: mysql中的数据存储就可以使用此命令将mysql存放的持久化数据挂载到宿主机的随机目录下, 保证容器重启后也能正常访问数据 |
VOLUME 中的mountpoint为容器中的一个目录,而挂在到宿主机的目录是随机产生的。 可以使用docker inspact 容器id命令来查看数据, 找到key为MOUNTS的信息就可以找到挂载到宿主机的详细目录了 |
|
ARG | ARG userName = defaultValue | 与ENV命令类似,定义环境变量的,但它支持我们在build镜像的时候使用–build-arg =格式来为变量填充值 | docker build -t test:latest --build-arg userName = eugene . |
二、构建自定义镜像实例之tomcat镜像
2.1 创建构建tomcat镜像文件夹
-
mkdir /root/tomcat-docker
2.2 构建dockerfile文件
- 进入构建tomcat镜像文件夹
cd /root/tomcat-docker
- 构建
# 基于centos镜像 FROM centos # 添加build镜像时的参数 ARG author=default # 添加标签, 值由ARG中的参数获取 LABEL maintainer=$author # 使用ADD命令从远程下载tomcat包 ADD https://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.100/bin/apache-tomcat-7.0.100.tar.gz / # 因为ADD下载远程资源的方式不会被解压,所以我们解压下, 加压后的tomcat包名为: apache-tomcat-7.0.100 RUN tar -zxvf apache-tomcat-7.0.100.tar.gz -C /usr/local/ # 采用ADD添加本地tar包, 解压后的包名为: jdk1.8.0_221 ADD jdk-8u221-linux-x64.tar.gz /usr/local/ # 定义环境变量参数, 添加tomcat和jdk的环境变量 ENV JAVA_HOME=/usr/local/jdk1.8.0_221 ENV TOMCAT_HOME=/usr/local/apache-tomcat-7.0.100 # 将tomcat和java环境变量添加到系统环境变量中 ENV PATH=$PATH:$JAVA_HOME/bin:$TOMCAT_HOME/bin # 挂载tomcat生成日志的目录至宿主机的随机目录,可在宿主机中查看日志 VOLUME "/usr/local/apache-tomcat-7.0.100/logs" # 暴露8080端口 EXPOSE 8080 # 添加CMD指令 -> 将会被ENTRYPOINT替换,CMD和ENTRYPOINT两个指令谁在后面,谁就会被执行 CMD echo $JAVA_HOME # 添加容器上下文, 当进入容器时,会默认进入此文件夹 WORKDIR /usr/local/apache-tomcat-7.0.100 # 启动tomcat ENTRYPOINT ["catalina.sh", "run"]
2.3 将jdk1.8 tar包放置与Dockerfile同目录下
- 如图所示
2.4 构建tomcat镜像
- 运行如下脚本build镜像
docker build -t mytomcat:v1 --build-arg author=eugene .
2.5 启动镜像
-
docker run --name mytomcat -it -d -p 8081:8080 mytomcat:v1
2.6 查看镜像运行log
- 运行如下命令
docker logs mytomcat
- 运行结果如下图
可以看到容器运行成功了
2.7 查看容器元信息
- 运行如下命令
docker inspect mytomcat
- 运行结果如下:
[ { "Id": "a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb", "Created": "2020-03-15T11:24:35.374661463Z", "Path": "catalina.sh", "Args": [ "run", "/bin/sh", "-c", "echo $JAVA_HOME" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 3700, "ExitCode": 0, "Error": "", "StartedAt": "2020-03-15T11:24:36.388929347Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:b3668180dbfb595f08d6e8457ce1f54f05e3aa128bf97cd707246cfb48b2eec7", "ResolvConfPath": "/var/lib/docker/containers/a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb/resolv.conf", "HostnamePath": "/var/lib/docker/containers/a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb/hostname", "HostsPath": "/var/lib/docker/containers/a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb/hosts", "LogPath": "/var/lib/docker/containers/a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb/a68f7f0efde04b248e0bdb279f051d2f4dd4520ee5d43b0858ddb5ecc9b14dbb-json.log", "Name": "/mytomcat", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": { "8080/tcp": [ { "HostIp": "", "HostPort": "8081" } ] }, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Capabilities": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "private", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "KernelMemory": 0, "KernelMemoryTCP": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": [ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi", "/sys/firmware" ], "ReadonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/a0867cbc4ae00a5de11fbfcb5e1d3547a63c284de32556ecaf98bd21c91b5b5c-init/diff:/var/lib/docker/overlay2/bc4f600a2ed70eee7b5da2e7ec190dfd5531c8d4e7cd80f8cce0ccc7cd929247/diff:/var/lib/docker/overlay2/9f84cb4e4ef1d2c30ff0809786d2065577576d2bdfb467131c199e86c2ac00ea/diff:/var/lib/docker/overlay2/811a02af3d6518642276925f82c98deab538e745a1a5bab64d23088c816945a6/diff:/var/lib/docker/overlay2/9d22f9d8c3d9d31a374834e3f4f5ff3d246e0c5f2148f46d696e8d8d548305fd/diff", "MergedDir": "/var/lib/docker/overlay2/a0867cbc4ae00a5de11fbfcb5e1d3547a63c284de32556ecaf98bd21c91b5b5c/merged", "UpperDir": "/var/lib/docker/overlay2/a0867cbc4ae00a5de11fbfcb5e1d3547a63c284de32556ecaf98bd21c91b5b5c/diff", "WorkDir": "/var/lib/docker/overlay2/a0867cbc4ae00a5de11fbfcb5e1d3547a63c284de32556ecaf98bd21c91b5b5c/work" }, "Name": "overlay2" }, "Mounts": [ { "Type": "volume", "Name": "a62dade48437f200874a5ba18b60681b91fc3968d14982d82eeea30e59a8699c", "Source": "/var/lib/docker/volumes/a62dade48437f200874a5ba18b60681b91fc3968d14982d82eeea30e59a8699c/_data", "Destination": "/usr/local/apache-tomcat-7.0.100/logs", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], "Config": { "Hostname": "a68f7f0efde0", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "8080/tcp": {} }, "Tty": true, "OpenStdin": true, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk1.8.0_221/bin:/usr/local/apache-tomcat-7.0.100/bin", "JAVA_HOME=/usr/local/jdk1.8.0_221", "TOMCAT_HOME=/usr/local/apache-tomcat-7.0.100" ], "Cmd": [ "/bin/sh", "-c", "echo $JAVA_HOME" ], "Image": "mytomcat:v1", "Volumes": { "/usr/local/apache-tomcat-7.0.100/logs": {} }, "WorkingDir": "/usr/local/apache-tomcat-7.0.100", "Entrypoint": [ "catalina.sh", "run" ], "OnBuild": null, "Labels": { "maintainer": "eugene", "org.label-schema.build-date": "20200114", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS", "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00", "org.opencontainers.image.licenses": "GPL-2.0-only", "org.opencontainers.image.title": "CentOS Base Image", "org.opencontainers.image.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "e27935f70ffebb9a888d7e5e6f3f965d18792e5856f65ae0c6ddb15341dce805", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "8080/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "8081" } ] }, "SandboxKey": "/var/run/docker/netns/e27935f70ffe", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "c077b34f7b89df2e6a591009d031c258626890e80ea17c9fdb7328d29981067f", "Gateway": "172.18.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.18.0.6", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:12:00:06", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "c39de0a86ef7d1e6d1e5f69a5e45fdbcc035aa47aa442f360d96ba807590e086", "EndpointID": "c077b34f7b89df2e6a591009d031c258626890e80ea17c9fdb7328d29981067f", "Gateway": "172.18.0.1", "IPAddress": "172.18.0.6", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:06", "DriverOpts": null } } } } ]
- 可以看到Mounts节点下的挂载信息,发现tomcat的
/usr/local/apache-tomcat-7.0.100/logs
目录挂载到了宿主机的/var/lib/docker/volumes/a62dade48437f200874a5ba18b60681b91fc3968d14982d82eeea30e59a8699c/_data
目录下,于是我们在宿主机中查看此目录,发现日志文件果真存在,如图:
至此,VOLUME
指令也是生效的
2.8 访问tomcat首页
-
http://49.235.135.230:8081
-> ip地址为我的云服务器,可根据自己的服务器ip进行修改 - 熟悉的tomcat首页
- 至此,tomcat镜像构建成功并运行成功了
三、总结
- 主要是总结下Dockerfile中的各种指令的用法,以及添加了一个实例来实践
- I am a slow walker, but I never walk backwards.