Dockerfile入门指南

基本原则

  • 官方镜像优于非官方的镜像,如果没有官方镜像,则尽量选择Dockerfile开源的
  • 固定版本tag而不是每次都使用latest
  • 尽量选择体积小的镜像

编写第一个Dockerfile文件

# 新建文件夹并进入
mkdir docker-demo && cd docker-demo

# 新增index.html文件
vim index.html

# index.html文件写入内容
echo "<h1>hello docker</h1>" > index.html

# 新增Dockerfile文件
vim Dockerfile

# Dockerfile文件写入内容
echo "FROM nginx:1.21.0-alpine" >> Dockerfile
echo "ADD index.html /usr/share/nginx/html/index.html" >> Dockerfile

# docker镜像build
sudo docker image build -t demonginx .

RUN命令

RUN 主要用于在Image里执行指令,比如安装软件,下载文件等。但是如果有多条RUN命令,建议多条RUN命令合并同一 命令。

# 不建议
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

# 建议
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

ADD和COPY命令

COPY 和 ADD 都可以把local的一个文件复制到镜像里,如果目标目录不存在,则会自动创建。比如把本地的 hello.py 复制到 /app 目录下。 /app这个folder不存在,则会自动创建

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

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

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

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

ARG和ENV命令

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

# Dockerfile.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
# Dockerfile.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和ENTRYPOINT命令

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

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

默认进入到shell是因为在ubuntu的基础镜像里有定义CMD

sudo docker image history ipinfo

IMAGE          CREATED             CREATED BY                                      SIZE      COMMENT
cf84840e9eb6   About an hour ago   /bin/sh -c #(nop) COPY file:419e7704ddc1c481…   26B       
6a94addb9f64   About an hour ago   /bin/sh -c #(nop)  ENV VERSION=2.0.0            0B        
a6eb2a334a9f   16 months ago       /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B        
<missing>      16 months ago       /bin/sh -c #(nop)  STOPSIGNAL SIGQUIT           0B        
<missing>      16 months ago       /bin/sh -c #(nop)  EXPOSE 80                    0B        
<missing>      16 months ago       /bin/sh -c #(nop)  ENTRYPOINT ["/docker-entr…   0B        
<missing>      16 months ago       /bin/sh -c #(nop) COPY file:09a214a3e07c919a…   4.61kB    
<missing>      16 months ago       /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7…   1.04kB    
<missing>      16 months ago       /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0…   1.96kB    
<missing>      16 months ago       /bin/sh -c #(nop) COPY file:65504f71f5855ca0…   1.2kB     
<missing>      16 months ago       /bin/sh -c set -x     && addgroup -g 101 -S …   17MB      
<missing>      16 months ago       /bin/sh -c #(nop)  ENV PKG_RELEASE=1            0B        
<missing>      16 months ago       /bin/sh -c #(nop)  ENV NJS_VERSION=0.5.3        0B        
<missing>      16 months ago       /bin/sh -c #(nop)  ENV NGINX_VERSION=1.21.0     0B        
<missing>      17 months ago       /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B        
<missing>      17 months ago       /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      17 months ago       /bin/sh -c #(nop) ADD file:8ec69d882e7f29f06…   5.61MB    

CMD的镜像,如果执行创建容器,不指定运行时的命令,则会默认执行CMD所定义的命令。

docker container run -it --rm demo-cmd

但是如果我们docker container run的时候指定命令,则该命令会覆盖掉CMD的命令。

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

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

  • CMD 设置的命令,可以在docker container run 时传入其它命令,覆盖掉 CMD 的命令,但是 ENTRYPOINT 所设置的命令是一定会被执行的。
  • ENTRYPOINT 和 CMD 可以联合使用,ENTRYPOINT 设置执行的命令,CMD传递参数
FROM ubuntu:20.04
ENTRYPOINT ["echo", "hello docker"]
CMD ["echo","hello cmd"]

输出的结果是:

# 这是因为ENTRYPOINT将CMD命令当成参数执行在echo后面了
hello docker echo hello cmd

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇