首页 > 其他分享 >Dockerfile完全指南

Dockerfile完全指南

时间:2025-01-05 22:56:21浏览次数:1  
标签:指南 ago ipinfo tar 完全 && linux docker Dockerfile

Dockerfile完全指南

基础镜像的选择

基础原则

  • 官方镜像优于非官方的镜像,如果没有官方镜像,则尽量选择Dockerfile开源的。
  • 固定版本Tag而不是每次都使用lastest
  • 尽力选择体积小的镜像<-alpine 精简版>
[root@node01 ~]# docker images

REPOSITORY           TAG             IMAGE ID       CREATED         SIZE
nginx                latest          f876bfc1cc63   5 weeks ago     192MB
mysql                5.7             5107333e08a8   12 months ago   501MB
nginx                1.21.0          4f380adfc10f   3 years ago     133MB
nginx                1.21.0-alpine   a6eb2a334a9f   3 years ago     22.6MB

可以看到,nginx:1.21.0大小为133MB,而nginx:1.21.0-alpine大小仅22.6MB

通过RUN执行命令

RUN主要用于在Image里执行命令,比如安装软件、下载等。

$ apt-get update
$ apt-get install wget
$ wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz
$ tar zxf ipinfo_2.0.1_linux_amd64.tar.gz
$ mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo
$ rm -rf ipinfo_2.0.1_linux_amd64.tar.gz

Dockerfile

  • Dockerfile-bad
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y wget
RUN wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz
RUN tar zxf ipinfo_2.0.1_linux_amd64.tar.gz
RUN mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo
RUN rm -rf ipinfo_2.0.1_linux_amd64.tar.gz

image-20250104120324098

docker image build -f dockerfile.bad -t ipinfo-bad .

镜像的大小和分层

[root@node01 dockerfile]# docker image ls
REPOSITORY           TAG             IMAGE ID       CREATED          SIZE
ipinfo-bad           latest          e5260983907f   15 minutes ago   159MB
zhangshao3/mynginx   1.0             4c17ff0fc31c   5 days ago       192MB
tomcat               latest          f62f518e5c5c   3 weeks ago      467MB
nginx                latest          f876bfc1cc63   5 weeks ago      192MB
mysql                5.7             5107333e08a8   12 months ago    501MB
nginx                1.21.0          4f380adfc10f   3 years ago      133MB
nginx                1.21.0-alpine   a6eb2a334a9f   3 years ago      22.6MB
[root@node01 dockerfile]# docker image history  e526
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
e5260983907f   15 minutes ago   RUN /bin/sh -c rm -rf ipinfo_2.0.1_linux_amd…   0B        buildkit.dockerfile.v0
<missing>      15 minutes ago   RUN /bin/sh -c mv ipinfo_2.0.1_linux_amd64 /…   9.36MB    buildkit.dockerfile.v0
<missing>      15 minutes ago   RUN /bin/sh -c tar zxf ipinfo_2.0.1_linux_am…   9.36MB    buildkit.dockerfile.v0
<missing>      15 minutes ago   RUN /bin/sh -c wget https://github.com/ipinf…   4.85MB    buildkit.dockerfile.v0
<missing>      16 minutes ago   RUN /bin/sh -c apt-get install -y wget # bui…   7.65MB    buildkit.dockerfile.v0
<missing>      16 minutes ago   RUN /bin/sh -c apt-get update # buildkit        55.4MB    buildkit.dockerfile.v0
<missing>      2 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      2 months ago     /bin/sh -c #(nop) ADD file:7486147a645d8835a…   72.8MB
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG RELEASE                  0B

每一行的RUN命令都会产生一层image layer,导致镜像的臃肿

image-20250104122327384

改进后Dockerfile

FROM ubuntu:20.04
RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz && \
    tar zxf ipinfo_2.0.1_linux_amd64.tar.gz && \
    mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_2.0.1_linux_amd64.tar.gz

构建

 docker image build -f dockerfile.good -t ipinfo-good .
[root@node01 dockerfile]# docker images
REPOSITORY           TAG             IMAGE ID       CREATED          SIZE
ipinfo-good          latest          3ec094c48160   30 seconds ago   145MB
ipinfo-bad           latest          e5260983907f   33 minutes ago   159MB
zhangshao3/mynginx   1.0             4c17ff0fc31c   5 days ago       192MB
tomcat               latest          f62f518e5c5c   3 weeks ago      467MB
nginx                latest          f876bfc1cc63   5 weeks ago      192MB
mysql                5.7             5107333e08a8   12 months ago    501MB
nginx                1.21.0          4f380adfc10f   3 years ago      133MB
nginx                1.21.0-alpine   a6eb2a334a9f   3 years ago      22.6MB
[root@node01 dockerfile]# docker image history 3ec094c48160
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
3ec094c48160   48 seconds ago   RUN /bin/sh -c apt-get update &&     apt-get…   72.5MB    buildkit.dockerfile.v0
<missing>      2 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      2 months ago     /bin/sh -c #(nop) ADD file:7486147a645d8835a…   72.8MB
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B
<missing>      2 months ago     /bin/sh -c #(nop)  ARG RELEASE                  0B

可以观察到,一条命令,只占用72.8MB

image-20250104122353503

文件复制和目录操作

往镜像里复制文件有两种方式,COPYADD

复制普通文件

COPYADD都可以把local的一个文件复制到镜像里,如果目标目录不存在,则会自动创建。

FROM python:3.9.5-alpine3.13
COPY hello.py /app/hello.py

复制压缩文件

ADDCOPY高级一点的地方就是,如果复制的是一个gzip等压缩文件时,ADD会帮助我们自动去解压缩文件。

FROM python:3.9.5-alpine3.13
ADD hello.tar.gz /app/

如何选择

因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。

# 切换目录,类似于cd, 如果目录不存在,自动创建
WORKDIR /app

构建参数和环境变量

ARGENV是经常易被混淆的两个Dockerfile的语法,都可以用来设置一个“变量”,但实际上两个有很多不同的地方。

FROM ubuntu:20.04
RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-2.0.1/ipinfo_2.0.1_linux_amd64.tar.gz && \
    tar zxf ipinfo_2.0.1_linux_amd64.tar.gz && \
    mv ipinfo_2.0.1_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_2.0.1_linux_amd64.tar.gz

ENV

FROM ubuntu:20.04
ENV VERSION=2.0.1
RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz

ARG

FROM ubuntu:20.04
ARG VERSION=2.0.1
RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz

区别

ARG 可以在镜像build的时候动态修改value, 通过 --build-arg

$ docker image build -f .\Dockerfile-arg -t ipinfo-arg-2.0.0 --build-arg VERSION=2.0.0 .
$ docker image ls
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
ipinfo-arg-2.0.0   latest    0d9c964947e2   6 seconds ago    124MB
$ docker container run -it ipinfo-arg-2.0.0
root@b64285579756:/#
root@b64285579756:/# ipinfo version
2.0.0
root@b64285579756:/#

ENV 设置的变量可以在Image中保持,并在容器中的环境变量里。

CMD容器启动命令

CMD可以用来设置容器启动时默认会执行的命令。

  • 容器启动时默认执行的命令
  • 如果docker container run启动容器时制定了其他命令,则CMD命令会被忽略
  • 如果定义了多个CMD,只有最后一个会被执行

快速删除已退出的镜像

[root@node01 dockerfile]# docker system prune -f
Deleted Containers:
19775fd1fe8c40d07394eebee075f586a485a3192c03492d72b510ba2515e763
519f513648cdc281a995c69e1f2ecb4f2cc033240ff3dbfba0c3caf078eadc9b
e07a6f8a70f7266a5502bc0c477f831a274f81397ac6e432579a10b433588dd3

Deleted build cache objects:
hez2u8fzodf8afths4nwvtve8
wf9env47fjy7l1h48j6kxhvgz
xh4h2kju1k40362q46k54c1ud

Total reclaimed space: 167.2kB

快速删除所有的镜像

docker image prune -a

创建一个带cmd的dockerfile

FROM ubuntu:20.04
ENV VERSION=2.0.1
# 如果网络情况不佳,可制定阿里源
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz

docker build -f dockerfile.cmd -t ipinfo .

image-20250104162121567

 docker container run -it ipinfo

随后启动容器,发现已经进入ubuntu shell中,这是因为ubuntu的基础镜像中有自定义的CMD

docker image history ipinfo

image-20250104162311365

如果启动容器时指定了其他命令,cmd会被忽略。

# 追加ipinfo命令
docker container run -it ipinfo ipinfo

image-20250104162728387

如果容器中包含多个CMD命令

FROM ubuntu:20.04
ENV VERSION=2.0.1
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

RUN apt-get update && \
    apt-get install -y wget && \
    wget https://github.com/ipinfo/cli/releases/download/ipinfo-${VERSION}/ipinfo_${VERSION}_linux_amd64.tar.gz && \
    tar zxf ipinfo_${VERSION}_linux_amd64.tar.gz && \
    mv ipinfo_${VERSION}_linux_amd64 /usr/bin/ipinfo && \
    rm -rf ipinfo_${VERSION}_linux_amd64.tar.gz
CMD ["ipinfo"]

此时,既有ubuntu默认的cmd也有制定的cmd。

docker build -f dockerfile.cmd -t ipinfo-new .

image-20250104163252970

docker container run -it ipinfo-new

进入容器,发现执行的CMD为ipinfo,即如果dockerfile中指定了CMD,优先执行。

针对一次性执行的容器,可以在创建时带上-rm命令,创建运行完成后即删除。

docker container run --rm -it ipinfo ipinfo 8.8.8.8

容器启动命令ENTRYPOINT

ENTRYPOINT也可以设置启动时要执行的命令,但是和CMD是有区别的。

  • CMD设置的命令,可以在docker container run时传入其他命令,覆盖掉CMD的命令,但是ENTRYPOINT所设置的命令是一定会被执行的。
  • ENTRYPOINTCMD可以联合使用,ENTRYPOINT设置执行的命令,CMD传递参数。

使用CMD命令

FROM ubuntu:20.04
CMD ["echo", "hello docker"]

使用ENTRYPOINT命令

FROM ubuntu:20.04
ENTRYPOINT ["echo", "hello docker"]

Both

FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD []
# 构件cmd镜像
docker build -f dockerfile-cmd -t demo-cmd .

运行demo-cmd镜像

docker container run --rm -it demo-cmd

结果输出“hello docker”

使用命令追加在container命令后,执行追加的命令,会覆盖dockerfile中的cmd。

docker container run --rm -it demo-cmd echo "hello world"

结果输出“hello world”

image-20250104170732323

# 构件entrypoint
docker container run --rm -it demo-entrypoint

结果输出“hello docker”

docker container run --rm -it demo-entrypoint echo "hello world"

结果输出“hello docker echo hello world”,原因是在ENTRYPOINT中设置的echo命令是一定会被执行的。

# 构建both
docker container run --rm -it demo-both

结果打印为空

# 追加cmd
docker container run --rm -it demo-both hello world

image-20250104171507337

Shell格式和Exec格式

CMD和ENTRYPOINT同时支持shell和exec格式。

注意shell脚本问题

FROM ubuntu:20.04
ENV NAME=docker
CMD echo "hello $NAME"

假如我们要把上面的CMD改成Exec格式,下面这样改是不行的。

FROM ubuntu:20.04
ENV NAME=docker
CMD ["echo", "hello $NAME"]

它会打印出 hello $NAME , 而不是 hello docker ,需要以shell脚本的方式去执行。

FROM ubuntu:20.04
ENV NAME=docker
CMD ["sh", "-c", "echo hello $NAME"]

练习

编写Tomcat DockerFile

FROM centos
MAINTAINER zhang<xxxxx@qq.com>

ADD jdk-8u11-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.98.tar.gz /usr/local

RUN yum -y install vim 

ENV MYPATH=/usr/local

WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:${JAVA_HOME}/lib/tools.jar

ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.98
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.98
ENV PATH $PATH:$JAVA_HOME/bin:${CATALINA_HOME}/bin:${CATALINA_HOME}/lib

EXPOSE 8080


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

构件镜像

docker build -t diy_tomcat .

启动镜像

docker run -d -p 9090:8080 --name diy_tomcat -v /root/tomcat/test:/usr/local/apache-tomcat-9.0.98/webapps/test -v /root/tomcat/logs/:/usr/local/apache-tomcat-9.0.98/logs diytomcat

查看运行状态

docker ps -a

浏览器可正常访问tomcat首页

image-20250104200214506

随后在/root/tomcat/test下编辑index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>我的复杂网页</title>
  <link rel="stylesheet" href="styles.css">
</head>

<body>
  <!-- 这里将是网页内容的主要部分 -->
  <h3>hello docker</h3>

</body>

查看/test路径

image-20250104200422513

全貌

标签:指南,ago,ipinfo,tar,完全,&&,linux,docker,Dockerfile
From: https://www.cnblogs.com/shine-rainbow/p/18654104

相关文章

  • 高效撰写文献综述的指南:利用ChatGPT提升研究能力
    进行文献综述是一项颇具挑战性的任务。作为学术研究的重要组成部分,它要求我们对以往在特定主题上发表的研究成果进行全面而深入的分析。这一过程不仅帮助我们理解该领域的现状,还能识别出研究中的空白,为未来的探索奠定基础。在本文中,我将从8个方面详细介绍如何利用ChatGPT强大......
  • 转型传统行业避坑指南!
    0前言大环境不好,很多程序员被优化,被逼转型传统行业,但:不同级别的人,咋融入传统行业?转型传统行业的同学会经历哪3个经典阶段?入局后的“坑”1不同阶层,咋转型传统行业?1.1高层总监及总监以上的VP、C*O等。最重要的是想尽一切办法找到价值,同时带领团队做出有价值的事:找......
  • SQLite 调试与性能优化指南
    在前几篇文章中,我们深入了解了SQLite的基础和高级功能,以及如何利用其扩展能力。本篇文章将重点讲解SQLite的调试工具和性能优化技巧,以帮助您解决常见问题并进一步提升数据库性能。常见问题及解决方法SQLite的轻量级特性使其非常易用,但在某些场景下可能会遇到以下常......
  • 「Java 数据结构全面解读」:从基础到进阶的实战指南
    「Java数据结构全面解读」:从基础到进阶的实战指南数据结构是程序设计中的核心部分,用于组织和管理数据。Java提供了丰富的集合框架和工具类,涵盖了常见的数据结构如数组、链表、栈、队列和树等。本文将系统性地介绍这些数据结构的概念、特点以及在Java中的实现,并通过代码......
  • GitHub 基础使用指南
        GitHub是一个流行的代码托管平台,主要用于版本控制和协作开发项目。它为开发者提供了强大的工具来管理项目、追踪问题、以及进行代码审查。    本文将介绍GitHub的一些基础功能,包括镜像站点、导航栏的使用、贡献设置、以及如何寻找特定代码或仓库。1.Gi......
  • Linux 基础应用指南:从入门到实践
    一、引言 Linux作为开源操作系统,凭借其稳定性、安全性及高度可定制性,在服务器领域广泛应用,也深受开发者与技术爱好者青睐。对于初学者,掌握Linux基本使用方法是开启高效技术之旅的关键一步。 二、Linux系统安装与环境搭建 (一)选择合适的Linux发行版 常见发行......
  • 动态规划<八> 完全背包问题及其余背包问题
    目录例题引入---找到解决问题模版LeetCode经典OJ题1.第一题 2.第二题 3.第三题 其余的一些背包问题1.二维费用的背包问题1.第一题2.第二题2.其余杂题例题引入---找到解决问题模版OJ传送门牛客DP42【模板】完全背包画图分析: 使用动态规划解决(第二问与......
  • 如何通过代码修改网站数据:详细指南
    在某些情况下,您可能需要通过代码直接修改网站的数据。这通常涉及到数据库操作,需要谨慎进行,以避免数据丢失或网站故障。以下是详细的修改步骤和注意事项:备份数据库:在进行任何数据库操作之前,务必备份网站的数据库。您可以使用FTP工具下载数据库文件,或者通过网站托管商提供的备......
  • 基于SpringBoot和Thymeleaf的仿小米电商系统源码下载与安装指南-幽络源
    项目概述这是一个基于SpringBoot2.X和Thymeleaf技术栈的仿小米电商系统。该项目包括了前台商城系统和后台管理系统,经幽络源测试具备完整的电商功能,适合用作学习、参考或作为开发电商系统的基础。前台商城系统:包括首页登录、商品分类、新品上线、首页轮播、商品推荐、......
  • 投稿指南【NO.12_14】【极易投中】期刊投稿(毛纺科技)
               近期有不少同学咨询投稿期刊的问题,大部分院校的研究生都有发学术论文的要求,少部分要求高的甚至需要SCI或者多篇核心期刊论文才可以毕业,但是核心期刊要求论文质量高且审稿周期长,所以本博客梳理一些计算机特别是人工智能相关的期刊,供大家参考投稿。欢......