Docker——dockerfile运用

dockerfile介绍

Dockerfile是由一系列命令和参数构成的脚本,一个Dockerfile里面包含了构建整个image的完整命令。Docker通过docker build执行Dockerfile中的一系列命令自动构建image。

docker脚本结构

Dockerfile 一般分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令

常用指令

FROM:指定基础镜像,必须为第一个命令

  • 语法
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
  • 示例
from mysql:v5.6

LABEL:为镜像生成元数据标签信息

  • 语法
LABEL <key>=<value> <key>=<value> <key>=<value> ...

MAINTAINER:维护者信息

  • 语法
MAINTAINER <name>

RUN:构建镜像时执行的命令

  • 语法
    • shell执行(默认调用/bin/sh)
    RUN <command>
    
    • exec执行(将会调用exec执行,以避免有些时候shell方式执行时的传递参数问题,而且有些基础镜像可能不包含/bin/sh)
    RUN ["executable", "param1", "param2"]
    

注意:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

ADD

  • 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
  • 语法:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
  • 实例:
ADD hom* /mydir/          # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

COPY

  • 功能类似ADD,但是不会自动解压文件,也不能访问网络资源

CMD

  • 构建容器后调用,也就是在容器启动时才进行调用
  • 语法:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
  • 实例:
CMD echo "This is a test."
CMD ["/usr/bin/wc","--help"]

注意:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令

ENTRYPOINT

  • 配置容器,使其可执行化。配合CMD可省去"application",只使用参数。
  • 语法:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
  • 实例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

注意:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

ENV

  • 设置环境变量
  • 语法:
ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ...#可以设置多个变量,每个变量为一个"<key>=<value>"的键值对
  • 实例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy

EXPOSE

  • 指定于外界交互的端口
  • 语法:
EXPOSE <port> [<port>...]
  • 实例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp

VOLUME

  • 用于指定持久化目录
  • 语法:
VOLUME ["/path/to/dir"]
  • 实例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

WORKDIR

  • 工作目录,类似于cd命令
  • 语法:
WORKDIR /path/to/workdir
  • 实例
WORKDIR /a  (这时工作目录为/a)
WORKDIR b  (这时工作目录为/a/b)
WORKDIR c  (这时工作目录为/a/b/c)

注意通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

USER

  • 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
  • 语法:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

注意:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户

ONBUILD

  • 用于设置镜像触发器
  • 语法:
ONBUILD [INSTRUCTION]
  • 实例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src

注意:当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被触发

常见指令图示

利用dockerfile创建nginx容器

  • 下载基础镜像(这里以alpine系统为base image)
[root@localhost ~]# docker pull alpine
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
busybox      latest    a77dce18d0ec   12 days ago   1.24MB
alpine       latest    389fef711851   3 weeks ago   5.58MB
httpd        latest    dd85cdbb9987   4 weeks ago   138MB
nginx        stable    05f64a802c26   4 weeks ago   133MB
ubuntu       latest    f643c72bc252   6 weeks ago   72.9MB
  • 编写dockerfile文件
[root@localhost ~]# mkdir dock_Files
[root@localhost ~]# cd dock_Files/
[root@localhost dock_Files]# vim dockerfile

# 选择基础源 
from alpine

# 基础元信息
label maintainer='sawyer 121692881@qq.com'

# 镜像操作
run sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk update && apk add nginx

run mkdir -p /run/nginx && \
echo -e "\ndaemon off;" >> /etc/nginx/nginx.conf

# 默认进程
cmd ["nginx"]
  • 创建镜像
[root@localhost dock_Files]# docker build -t nginx:test01 dock_Files/

Sending build context to Docker daemon  2.048kB
Step 1/5 : from alpine
 ---> 389fef711851
Step 2/5 : label maintainer='sawyer 121692881@qq.com'
 ---> Using cache
 ---> f8d805c6fe46
Step 3/5 : run sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk update && apk add nginx
 ---> Running in ef7369fac685
fetch http://mirrors.aliyun.com/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://mirrors.aliyun.com/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
v3.12.3-47-g3428e040de [http://mirrors.aliyun.com/alpine/v3.12/main]
v3.12.3-48-gea3fd89439 [http://mirrors.aliyun.com/alpine/v3.12/community]
OK: 12746 distinct packages available
(1/2) Installing pcre (8.44-r0)
(2/2) Installing nginx (1.18.0-r1)
Executing nginx-1.18.0-r1.pre-install
Executing busybox-1.31.1-r19.trigger
OK: 7 MiB in 16 packages
Removing intermediate container ef7369fac685
 ---> 7eb3e1570523
Step 4/5 : run mkdir -p /run/nginx && echo -e "\ndaemon off;" >> /etc/nginx/nginx.conf
 ---> Running in a0b04aea9fa3
Removing intermediate container a0b04aea9fa3
 ---> 423a7c839aa9
Step 5/5 : cmd ["nginx"]
 ---> Running in 07745803b14d
Removing intermediate container 07745803b14d
 ---> af5999d77739
Successfully built af5999d77739
Successfully tagged nginx:test01

  • 根据镜像创建容器
[root@localhost dock_Files]# docker run --rm --name test -p 80:80 nginx:test01
  • 查看端口,并访问
[root@localhost ~]# ss -antl
State   Recv-Q   Send-Q      Local Address:Port       Peer Address:Port   
LISTEN  0        128               0.0.0.0:22              0.0.0.0:*      
LISTEN  0        128                     *:80                    *:*      
LISTEN  0        128                  [::]:22                 [::]:*      

## 由于加了端口映射,直接访问本地即可
[root@localhost ~]# curl localhost
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

这里访问404,是因为alpine安装的linux默认测试页面,需要自行配置

dockerfile——源码配置nginx

  • 主机创建容器路径
[root@localhost nginx_dock_Files]# tree
.
├── dockerfile
├── shell
└── soft
    └── nginx-1.18.0.tar.gz
  • 编写dockerfile
FROM alpine
# 基础元信息
LABEL MAINTAINER='sawyer 121692881@qq.com'

# 镜像操作
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk update

## 安装必备组件
ADD soft/nginx-1.18.0.tar.gz /usr/src/
RUN apk add wget gcc g++ make pcre pcre-tools pcre-dev zlib-dev

## 编译nginx
RUN cd /usr/src/nginx-1.18.0/ && \
./configure --prefix=/usr/local/nginx && \
make && make install && \
ln -s /usr/local/nginx/sbin/nginx /usr/sbin &&\
rm -rf /usr/src/nginx*

# 启动nginx
CMD ["nginx","-g","daemon off;"]

# 端口暴露
EXPOSE 80
  • 利用dockerfile创建镜像
[root@localhost nginx_dock_Files]docker build -t nginx:test02 ../nginx_dock_Files/
  • 查看镜像,并根据镜像创建并运行容器(映射到本地80端口)
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        test02    166b2ea89dc5   5 minutes ago   223MB
nginx        test01    af5999d77739   24 hours ago    8.77MB
busybox      latest    a77dce18d0ec   13 days ago     1.24MB
alpine       latest    389fef711851   3 weeks ago     5.58MB
httpd        latest    dd85cdbb9987   4 weeks ago     138MB
nginx        stable    05f64a802c26   4 weeks ago     133MB
ubuntu       latest    f643c72bc252   6 weeks ago     72.9MB

[root@localhost nginx_dock_Files]# docker run --name test -p 80:80 nginx:test02
  • 测试页面
[root@localhost ~]# ss -antl
State       Recv-Q       Send-Q               Local Address:Port               Peer Address:Port       
LISTEN      0            128                        0.0.0.0:22                      0.0.0.0:*          
LISTEN      0            128                              *:80                            *:*          
LISTEN      0            128                           [::]:22                         [::]:* 

[root@localhost ~]# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
......
posted @ 2021-01-11 17:00  阿不思布丁  阅读(171)  评论(0编辑  收藏  举报