Docker Build创建指定应用容器镜像:

docker build: Build an image from a Dockerfile. 从Dockerfile文件创建构建一个镜像。

定义:按照Dockerfile文件所定义内容创建新的临时性容器,把Dockerfile中所定义的每行命令在临时容器中执行,然后生成镜像分层,所有命令执行结束后,生成一个新的镜像,中间过程为commit操作。

分析点:

1)先生成一个临时性的容器;

2)然后有“每行命令”,这些命令都是Shell命令,Shell命令很熟悉的话,就相对来说很容易。执行命令越多,最终得到的容器应用镜像越大,所以要做优化。

3)命令执行结束后,才能生成一个新的镜像。

4)commit:提交操作。

5)Dockerfile的首字母大写。

Dockerfile的工作原理

在Dockerfile定义所要执行的命令,使用docker build创建镜像,过程中会按照Dockerfile所定义的内容打开临时性容器(使用docker commit进行提交),把Dockerfile文件中的命令全部执行完成,就得到一个容器应用镜像。

执行命令越多,最终得到的容器应用镜像越大,所以要做优化。

Dockerfile的关键字:

1)FROM(指定基础镜像)

        FROM <image>: 指定基础镜像为image的最后修改的版本

        FROM <image>:<tag> : 指定基础镜像为该镜像的一个tag版本

2)MAINTAINER(用来指定镜像创建者信息)(英文maintainer:维护者)

        MAINTAINER <name>

        例如:MAINTAINER "changchunhua changchunhua@qq.com”

3)RUN (运行命令,运行安装软件命令等 )

        RUN <command> 

        RUN ["executable", "param1", “param2”,...]

4)CMD (设置container启动时执行的操作)

        CMD ["executable", "param1", “param2”,...]

        CMD command param1 param2 (as a shell)

当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:

        CMD ["param1", "param2"] (as default parameters to ENTRYPOINT)

        注意点:果容器镜像中有此命令,启动容器时,不要手动让容器执行其他命令。

        

5)ENTRYPOINT(设置Container启动时执行的操作)

        与CMD相比,CMD只可以执行一条命令,而ENTRYPOINT可以执行多条命令。

        CMD ["executable", "param1", “param2”,...](like an exec, the preferred form)

        CMD command param1 param2 (as a shell)

        

  6)USER (设置container容器的用户)

        USER daemon

        设置某些进程使用的用户。

7)EXPOSE(指定容器需要映射到宿主机器的端口)(英文意思:暴露端口)

        EXPOSE <port>

8)ENV (用于设置环境变量)

        ENV <key> <value>

9)ADD (从dockerhost主机的src目录的文件复制到container的dest目录中

        ADD <src>  <dest>

        有点像拷贝的意思。

10)VOLUME (指定挂载点)

        VOLUME ["<mountpoint>"]

11)WORKDIR (指定工作目录)

        WORKDIR /path/to/workdir

        原来是在根目录下的,我们需要切换到/opt目录下,那这个WORKDIR关键字来执行。

12)ONBUILD(在子镜像中执行)

        ONBUILD <Dockerfile 关键字>

Dockerfile应用案例:

目的:通过Dockerfile创建一个可以在启动容器时就直接启动httpd的应用的镜像。

步骤:

1)创建一个文件夹(目录),文件夹也是一个命名空间,用于存储Dockerfile所使用的文件:

2)在文件夹(目录)中创建Dockerfile文件和制作镜像所使用到的其他文件,比如网页,用来执行apache启动的脚本。

3)在此目录中,使用docker build命令创建镜像(读取Dockerfile文件)

4)使用创建的镜像启动容器(镜像的验证过程)

思考:

1)基础镜像是谁?centos7u6

2)安装httpd,用yum -y install httpd

3)启动httpd:httpd -k start,使用Shell脚本来启动httpd。

4)把httpd放在前段执行还是放在后端执行?前端。

5)暴露端口:tcp的80端口。

6)添加一个测试文件用于验证apache是否可用。

第一步:创建目录test目录:

mkdir test

cd test

第二步:创建用于启动httpd的脚本文件

#!/bin/bash

# 删除httpd的进程
rm -rf /run/httpd*

# 让apache前端执行
exec /sbin/httpd -D FOREGROUND

第三步:创建用于测试httpd是否可用的index.html

vim index.html

It's working.

第四步:创建Dockerfile文件:

FROM centos
MAINTAINER "changchunhua changchunhua@qq.com"
RUN cd /etc/yum.repos.d
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum makecache
RUN yum install -y httpd
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh
ADD index.html /var/www/html
EXPOSE 80
WORKDIR /
CMD ["/bin/bash", "/run-httpd.sh"]

第五步:使用docker build创建容器应用镜像,镜像名称为centos-base-httpd,版本为v1。

-t  --tag list:   Name and optionally a tag in the "name:tag" format 创建容器镜像的过程中,创建一个镜像名称和可选的tag版本号。

Name:镜像名称,命名

tag:版本号

[root@vm1 dockerbuild]# docker build -t centos-base-httpd:v1 .
[+] Building 126.5s (14/14) FINISHED
 => [internal] load build definition from Dockerfile                                      0.1s
 => => transferring dockerfile: 484B                                                      0.0s
 => [internal] load .dockerignore                                                         0.0s
 => => transferring context: 2B                                                           0.0s
 => [internal] load metadata for docker.io/library/centos:latest                          0.0s
 => [internal] load build context                                                         0.1s
 => => transferring context: 156B                                                         0.0s
 => [ 1/10] FROM docker.io/library/centos                                                 0.0s
 => [ 2/10] RUN cd /etc/yum.repos.d                                                       0.9s
 => [ 3/10] RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*             0.5s
 => [ 4/10] RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.  0.5s
 => [ 5/10] RUN yum makecache                                                           105.5s
 => [ 6/10] RUN yum install -y httpd                                                     17.7s
 => [ 7/10] ADD run-httpd.sh /run-httpd.sh                                                0.0s
 => [ 8/10] RUN chmod -v +x /run-httpd.sh                                                 0.5s
 => [ 9/10] ADD index.html /var/www/html                                                  0.0s
 => exporting to image                                                                    0.6s
 => => exporting layers                                                                   0.6s
 => => writing image sha256:c4e7e3152d40a1166593408de294928d3495f0d678cc36512e856e0ae0a4  0.0s
 => => naming to docker.io/library/centos-base-httpd:v1                                   0.0s

这个给出的信息跟之前的版本不太一样。

第六步:使用docker images,检查生成的镜像文件:

[root@vm1 dockerbuild]# docker images
REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
centos-base-httpd   v1        c4e7e3152d40   2 minutes ago   280MB
centos7u6-httpd     v1        4090500d5d7a   4 hours ago     280MB
centos-httpd        v1        a769afc16a9e   2 days ago      351MB
centos              latest    5d0da3dc9764   21 months ago   231MB

第七步:启动一个容器:

docker run -d centos-base-httpd:v1

-d 选项:

--detach: Run container in background and print container ID.

在后端运行一个容器并打印容器ID。

[root@vm1 dockerbuild]# docker run -d centos-base-httpd:v1
73544485f7be1cdc2efbd8ba46e42d79551e213378c1bcfd56eee334e928894c
[root@vm1 dockerbuild]# docker ps -a
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                   NAMES
73544485f7be   centos-base-httpd:v1   "/bin/bash /run-http…"   5 seconds ago   Up 4 seconds   80/tcp                                  serene_bohr

可以看到端口80已暴露

容器名称在运行的时候没有指定,容器名称是随机生成的。

使用docker inspect 容器ID,可以查到容器的IP地址。

然后使用curl http://172.17.0.14 可以看到It's working。

在这个过程中,需要解决的一个问题,是centos的yum源的问题。

替换原网站的内容的案例:

mkdir /wwwroot

echo "wwwroot" >> /wwwroot/index.html

docker run -d -v /wwwroot:/var/www/html centos-base-httpd:v1

docker inspect 415
curl http://172.17.0.12

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐