Dockerfile的基本操作

定制docker镜像的两种方式

  • 手动修改容器内容,导出并保存新的镜像
  • 基于Dockerfile自行编写指令,基于指令流程创建镜像

镜像是多层存储,每一层在前一层的基础上进行修改

容器也是多层存储,以镜像为基础层,在其基础上加一层作为容器运行时的存储层

Dockerfile简单介绍

  • 通过在dockerfile中定义一系列的命令和参数构成的脚本,然后将这些命令应用于基础镜像,依次添加添加层,最终生成一个新的镜像

CentOS官方提供的dockerfile实例

Nginx的dockerfile 为例

# "ported" by Adam Miller <maxamillion@fedoraproject.org> from
#   https://github.com/fedora-cloud/Fedora-Dockerfiles
#
# Originally written for Fedora-Dockerfiles by
#   scollier <scollier@redhat.com>
#
# Enriched by patterns found at https://github.com/openshift/postgresql/blob/master/9.4/Dockerfile.rhel7 by
#   Christoph Görn <goern@redhat.com>

FROM centos:centos7
MAINTAINER The CentOS Project <cloud-ops@centos.org>

# Labels consumed by Red Hat build service
LABEL Component="nginx" \
      Name="centos/nginx-180-centos7" \
      Version="1.8.0" \
      Release="1"

# Labels could be consumed by OpenShift
LABEL io.k8s.description="nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev." \
      io.k8s.display-name="nginx 1.8.0" \
      io.openshift.expose-services="80:http" \
      io.openshift.tags="nginx"

RUN yum -y install --setopt=tsflags=nodocs centos-release-scl-rh && \
    yum -y update --setopt=tsflags=nodocs && \
    yum -y install --setopt=tsflags=nodocs scl-utils rh-nginx18 && \
    yum clean all && \
    mkdir -p /usr/share/nginx/html

# Get prefix path and path to scripts rather than hard-code them in scripts
ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/nginx \
ENABLED_COLLECTIONS=rh-nginx18

# When bash is started non-interactively, to run a shell script, for example it
# looks for this variable and source the content of this file. This will enable
# the SCL for all scripts without need to do 'scl enable'.
ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \
    ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \
    PROMPT_COMMAND=". ${CONTAINER_SCRIPTS_PATH}/scl_enable"

ADD root /

# ADD https://git.centos.org/sources/httpd/c7/acf5cccf4afaecf3afeb18c50ae59fd5c6504910 /usr/share/nginx/html/
# RUN sed -i -e 's/Apache/nginx/g' -e '/apache_pb.gif/d' /usr/share/nginx/html/index.html
RUN echo "nginx on CentOS7" > /usr/share/nginx/html/index.html

EXPOSE 80

USER nginx

ENTRYPOINT ["container-entrypoint"]
CMD [ "nginx18" ]

Dockerfile的主要组成部分

  1. 基础镜像信息 FROM

  2. 制作镜像的操作指令 RUNADD

  3. 容器启动时执行指令 CMD docker run 镜像名

Dockerfile的基本指令

  • FROM 指定基础镜像

  • MAINTAINER 指定维护者信息,可以缺失

  • RUN 运行命令行指令

  • ADD 复制文件,会自动进行解压

  • WORKDIR 设置当前工作目录

  • VOLUME 设置卷,挂载主机目录(docker run -v 参数

  • EXPOSE 指定对外的端口号(docker run -p 参数

  • CMD 指定容器启动后要执行的任务

  • COPY 仅复制文件

  • ENV 定义环境变量

  • ENTERPOINT 容器启动后执行的任务

快速入门Dockerfile

示例:dockerfile构建nginx镜像,并修改nginx的index.html文件

[root@centos /]$ cd /home/eishin/
[root@centos eishin]$ mkdir ./LearnDockerfile
[root@centos eishin]$ cd LearnDockerfile/

[root@centos LearnDockerfile]$ touch Dockerfile
[root@centos LearnDockerfile]$ vim Dockerfile

# 构建dockerfile
[root@centos LearnDockerfile]$ docker build .
[+] Building 0.1s (4/5)
[+] Building 0.3s (4/5)
[+] Building 0.3s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 150B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/nginx:latest                                                    0.0s
 => [1/2] FROM docker.io/library/nginx                                                                             0.1s
 => [2/2] RUN echo '<meta charset=utf8>通过dockerfile创建的nginx服务' > /usr/share/nginx/html/index.html                  0.2s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:6e4b25c52bc0efcd92d6def8a3a9c73c3989862df4f4944c771aa831ef40959b

[root@centos LearnDockerfile]$ docker images
REPOSITORY   TAG        IMAGE ID       CREATED              SIZE
<none>       <none>     6e4b25c52bc0   About a minute ago   142MB
centos_vim   latest     66a5241671c2   3 weeks ago          457MB
redis        latest     ec466c2297ad   3 weeks ago          117MB
nginx        latest     9eee96112def   3 weeks ago          142MB
ubuntu       latest     58db3edaf2be   5 weeks ago          77.8MB
centos       7.8.2003   afb6fca791e0   2 years ago          203MB

# 取名
[root@centos LearnDockerfile]$ docker tag 6e4b25c52bc0 my_nginx

# 运行镜像
[root@centos LearnDockerfile]$ docker run -d -p 80:80 my_nginx

# 宿主机浏览器访问80端口

dockerfile内容

FROM nginx
RUN echo '<meta charset=utf8>通过dockerfile创建的nginx服务' > /usr/share/nginx/html/index.html

Dockerfile指令的用法

Tips: 采用dockerfile创建镜像时所有操作都应该是非交互式的,对配置文件的修改应该采用 sed 命令

Copy(官方更推荐)

COPY指令从宿主机复制文件(或目录)到新的一层镜像内
例如
COPY project.py /home/

# 支持多个文件,以及通配符形式复制,语法满足Golang的filepath.match
COPY project* /tmp/cc?.txt /home/

COPY指令能够保留源文件的元数据,例如权限、访问时间等等

ADD

特性和COPY基本一致,增加了如下的功能
1. 源文件是一个url时,会下载该链接,放入目标路径,且权限为600
2. 源文件是一个url,且是一个压缩包时,不会自动解压
3. 源文件是一个压缩文件,且是gzip, bzip2, xz, tar时,会自动解压该文件
到目标目录下

CMD

CMD ["参数1", "参数2", ...]

运行shell命令,会被转化为shell形式
例如 CMD echo $PATH
会转化为 CMD ["sh", "-c", "echo $PATH"]

ENTRYPOINT

在指定了ENTRYPOINT后,命令行指令的语义发生了变化,将命令行指令的内容当作参数传递给ENTRYPOINT指令

准备一个dockerfile文件

FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
CMD ["curl", "-s", "http://ipinfo.io/ip"]

命令行操作

[root@centos LearnDockerfile]$ echo > Dockerfile
[root@centos LearnDockerfile]$ vim Dockerfile

[root@centos LearnDockerfile]$ docker build .
[+] Building 355.1s (7/7) FINISHED
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 196B                                                                               0.0s
 => [internal] load metadata for docker.io/library/centos:7.8.2003                                                 0.0s
 => CACHED [1/3] FROM docker.io/library/centos:7.8.2003                                                            0.0s
 => [2/3] RUN rpm --rebuilddb && yum install epel-release -y                                                     344.3s
 => [3/3] RUN rpm --rebuilddb && yum install curl -y                                                              10.1s
 => exporting to image                                                                                             0.6s
 => => exporting layers                                                                                            0.6s
 => => writing image sha256:fa211f6f8a29777b7484ec6f0accf7eeb6eacf03dc19b28a5da2873a64d0b6d1

[root@centos LearnDockerfile]$ docker tag fa211f6f8a29 my_centos
[root@centos LearnDockerfile]$ docker run my_centos
183.173.90.208

# 不支持额外参数
[root@centos LearnDockerfile]$ docker run my_centos -I
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-I": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled

不支持额外参数的解决办法

  • 传入完整的命令

    • docker run my_centos curl -s http://ipinfo.io/ip -I
  • 使用ENTRYPOINT指令,修改dockerfile如下

    FROM centos:7.8.2003
    RUN rpm --rebuilddb && yum install epel-release -y
    RUN rpm --rebuilddb && yum install curl -y
    ENTRYPOINT ["curl", "-s", "http://ipinfo.io/ip"]
    

ARG和ENV指令

设置环境变量

维护dockerfile脚本更方便
ENV <Key1>="<value1>" <Key2>="<value2>" ...
例如
ENV MYSQL_VERSION=5.6
RUN yum install mysql-${MYSQL_VERSION}
ENV设置的环境变量在容器构建时和容器运行时都可以使用

ARG也是设置环境变量,但是只能用于容器构建

VOLUME

Tips: 容器在运行时,应该保证在存储层不写入任何数据。运行时在容器内产生的数据,推荐挂载并写入到宿主机上进行维护。

VOLUME /data
# 容器内的/data文件夹在容器运行时,该目录自动挂载为匿名卷,
# 任何向该目录中写入数据的操作都不会被容器记录

也支持写入列表
VOLUME ["/data1", "/data2"]

EXPOSE

用于指定容器运行时对外提供的端口服务

docker port 容器 # 查看容器的端口信息
docker run -p 宿主机端口:容器内端口
docker run -P # 表示 随机宿主机端口:容器内端口

WORKDIR

用于在dockerfile脚本中更改工作目录,类似Linux命令行窗口下的cd命令

USER

用于改变环境,用于切换用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值