Dockerfile详解

文章目录

    • 一、Dockerfile介绍
    • 二、常用指令
    • 三、Dockerfile示例
    • 四、最佳实践

一、Dockerfile介绍

Dockerfile是一个包含创建镜像所有命令的文本文件,通过docker build命令可以根据Dockerfile的内容构建镜像。
一般的,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,其中,‘#’为Dockerfile中的注释。

二、常用指令

  1. FROM

所有Dockerfile都必须以FROM命令开始。FROM命令会指定镜像基于哪个基础镜像创建,接下来的命令也会基于这个基础镜像。FROM命令可以多次使用,表示创建多个镜像。

FROM :
如果本地没有指定的镜像,则会从对应的镜像仓库pull镜像下来,不指定具体镜像仓库,则会从docker hub公共仓库拉取。

如果没有指定标签tag,则默认使用latest标签。

  1. MAINTAINER

设置该镜像的作者。

MAINTAINER 
  1. ENV

设置环境变量,使用键值对,并且该环境变量可以被后续的Dockerfile命令使用

ENV : #设置一个变量
ENV : \ #设置多个变量,可以通过"\"换行
    :
  1. ARG

设置构建环境的环境变量,只在构建容器时生效,在将来容器运行时是不会存在这些环境变量的且在构建时可以使用--build-arg=来指定参数。具体用法如下:

ARG =
不要因此就是用ARG保存密码之类的信息,因为docker history可以看到所有的值。
  1. WORKDIR

设置后续Dockerfile命令,像RUN、CMD、ENTRYPOINT、COPY、ADD的工作目录,如果WORKDIR不存在,会自动创建。

WORKDIR /path/workdir
  1. ADD

复制本地主机文件、目录或者远程文件URLS添加到容器指定路径中,它又两个参数和。source是本地绝对路径或者是Dockerfile所在的相对路径,destination是容器内的路径且如果dest路径不存在,会自动创建对应的目录;如果dest路径不是以斜线结尾,文件会以普通文件形式写入到目标。
如果复制的是压缩文件,会自动解压。

ADD  
  1. COPY

COPY复制文件或者目录,并且添加到容器指定路径中。用法同ADD,不同的是不能指定远程文件URL、不会解压压缩包。

COPY  
  1. EXPOSE

设置容器暴露的端口。

EXPOSE  

运行容器时,需要配合使用-p或-P参数进行端口映射,映射到宿主机
  1. USER

设置RUN/CMD/ENTRYPOINT的用户名或UID。

USER 
  1. VOLUME

设置容器的挂载点。

VOLUME ["/data/]
VOLUME /data1 /data2
  1. RUN

在构建镜像时执行命令。RUN指令会在新创建的镜像上添加新的镜像层。

RUN  # shell风格,即shell命令
RUN ["exec","parm1","parm2"] # exec风格
  1. CMD

设置容器启动命令。

CMD ["exec","parm1","parm2"]
CMD ["parm1","parm2"] # 为ENTRYPOINT提供参数列表
CMD 
  1. ENTRYPOINT

设置容器的入口程序。具体用法如下:

ENTRYPOINT ["exec","parm1","parm2"]
ENTRYPOINT command parm1 parm2  
ENTRYPOINT与CMD的区别在于,ENTRYPOINT的等级更高,一个Dockerfile里边可以既有ENTRYPOINT又有CMD,这个时候CMD后面的命令会作为ENTRYPOINT的参数传递。

推荐ENTRYPOINT和CMD都使用exec的方式来构建。
如果Dockerfile中指定了多条CMD,只有最后一条会被执行;
每个Dockerfile只能有一个ENTRYPOINT,当多个ENTRYPOINT时,只有最后一个生效。

三、Dockerfile示例

基于CentOS7.9,安装并运行redis

  1. 同级目录文件
$ tree
.
├── CentOS-Base.repo #YUM源,可自行下载阿里云镜像源
├── Dockerfile
├── epel.repo #YUM源,可自行下载阿里云镜像源
├── redis-6.2.12.tar.gz #redis安装包
└── redis.conf #redis配置文件
  1. redis配置文件,使用默认即可
$ vim redis. conf

bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/usr/local/redis/log/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /usr/local/redis/data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass 123456
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
  1. Dockerfile
$ vim Dockerfile

FROM centos:centos7.9.2009
MAINTAINER real
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone \
  rm -f /etc/yum.repos.d/*
COPY CentOS-Base.repo epel.repo /etc/yum.repos.d/
RUN yum clean all && yum makecache && yum install -y gcc make
ADD redis-6.2.12.tar.gz /tmp/
RUN cd /tmp/redis-6.2.12 && make MALLOC=libc && make PREFIX=/usr/local/redis install && \
  mkdir -p /usr/local/redis/{data,etc,log}
COPY redis.conf /usr/local/redis/etc/
ENTRYPOINT exec /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
EXPOSE 6379
  1. 构建镜像
注意命令最后的点`.`,是基于当前目录的Dockerfile进行构建
$ docker build -t redis:latest .
  1. 基于redis镜像启动容器
$ docker run -d --name redis-server -p 16379:6379 redis

-d:后台运行容器
--name:为容器指定一个名称
-p:指定端口映射。格式为:宿主机端口:容器端口
最后跟镜像名称
  1. 查看容器
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                         NAMES
e25d95579784   redis     "/bin/sh -c 'exec /u…"   6 seconds ago   Up 5 seconds   0.0.0.0:16379->6379/tcp, :::16379->6379/tcp   redis-server
  1. 使用redis客户端登录redis容器,进行验证
$ redis-cli -h 127.0.0.1 -p 16379
127.0.0.1:16379> auth 123456
OK
127.0.0.1:16379> 

四、最佳实践

  • 减少镜像层数,尽量把一些指令合在一起;
  • 注意清理镜像构建的中间产物,比如一些安装包在安装之后就把它删掉
  • 注意优化网络请求,使用yum源时,用一些网络比较好的源站点,可节约时间,减少失败率
  • 尽量去构建缓存,把一些不变的东西或者变动较少的东西放在前面,因为不变的东西可以被缓存,如果不想使用缓存,则可以在docker build时添加–no-cache=true选项

你可能感兴趣的:(Docker,docker,Dockerfile,容器)