Dockerfile创建镜像的方法

一、镜像制作的方法

1、本地导入导出镜像

请参考:Docker 架构原理及简单使用

导出:docker save nginx >/tmp/nginx.tar.gz

导入:docker load </tmp/nginx.tar.gz

2、docker commit 命令创建镜像副本

请参考:Docker docker commit 方法镜像制作,后边有时间也会梳理出来。

3、docker file

前面两种方法已经介绍过了,本文主要介绍 docker file,生成环境推荐使用这种方法。

二、docker file 方法制作镜像

1、什么是 docker file

用来全自动构建镜像文件,命名为 Dockerfile

2、Dockerfile 文件编写指令及语法

1)指令

sql 复制代码
FROM
MAINTAINER
RUN
CMD
EXPOSE
ENV
ADD
COPY
ENTRYPOINT
VOLUME
USER
WORKDIR
ONBUILD

2)语法

引用了 docker 中文文档:docker 语法

1. FROM

例子:FROM centos FROM 指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来。 FROM 必须是 Dockerfile 中非注释行的第一个指令,即一个 DockerfileFROM 语句开始 FROM 可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像

2. MAINTAINER

例子:MAINTAINER xyz xyz@163.com 指定创建镜像的用户

3. RUN <executable,parm1,param2>

两种使用方式: RUN RUN "executable", "param1", "param2"

例子:RUN yum install wget -y

每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的 RUN 都在之前 RUN 提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的版本控制 。

exec 方式会被解析为一个 JSON 数组,所以必须使用双引号而不是单引号。exec 方式不会调用一个命令 shell,所以也就不会继承相应的变量,

如:RUN [ "echo", "$HOME" ] #错误,这个个方法不会输出 HOME 变量,下面为正确方式 RUN [ "sh", "-c", "echo", "$HOME" ] RUN 产生的缓存在下一次构建的适合是不会失效的,会被重用,可以使用--no-cache选择,即docker build-no-cache,如此便不会缓存

4. CMD <"executable",>

三种使用方式: CMD "executable","param1","param2" CMD "param1","param2" CMD command param1 param2 (shell form) 例子:CMD["nginx"] CMD 指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效。

CMD 的目的是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会覆盖掉 CMD 指定的命令。

CMD 会在启动容器的时候执行,build 时不执行,而 RUN 只是在构建镜像的时候执行,后续镜像构建完成之后,启动容器就与 RUN 无关了,这个初学者容易弄混这个概念,这里简单注解一下。

5. EXPOSE  [...]

告诉 docker 服务端容器对外映射的本地端口,需要在 docker run 的使用使用-p 或者-P 选项生效

例子:EXPOSE 80

6. ENV

ENV ENV =。。。 指定一个环节变量,会被后续 RUN 指令使用,并在容器运行时保留

例子:

ini 复制代码
ENV myname zxg
ENV myhome beijing
ENV myname="zxg" myhome=beijing
7. ADD

ADD ... ADD 复制本地主机文件、目录或者远程文件 URLS 从并且添加到容器指定路径中 支持通过 Go 的正则模式匹配,具体规则可参见Go filepath.Match 例子:

sql 复制代码
ADD hom* /mydir/  #adds all files starting with "hom"
ADD hom?.txt /mydir/ #?is replaced with any single character
ADD index.html /usr/share/nginx/html/index.html

注意如下: 路径必须是绝对路径,如果不存在,会自动创建对应目录 路径必须是 Dockerfile 所在路径的相对路径 如果是一个目录,只会复制目录下的内容,而目录本身则不会被复制

8. COPY

COPY ... COPY 复制新文件或者目录并且添加到容器指定路径中,用法和 ADD 相同,唯一区别时不能指定远程文件 URLS。

9. ENTRYPOINT
bash 复制代码
ENTRYPOINT "executable","param1","param2"
ENTRYPOINT command param1 param2(shell form)

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,而 CMD 是可以被覆盖的。如果需要覆盖,则可以使用docker run --entrypoint选项。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效。 Exec form ENTRYPOINT例子 通过 ENTRYPOINT 使用 exec form 方式设置稳定的默认命令和选项,而使用 CMD 添加默认之外经常被改动的选项。

css 复制代码
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

通过 Dockerfile 使用 ENTRYPOINT 展示前台运行 Apache 服务

sql 复制代码
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Shell form ENTRYPOINT 例子 这种方式会在/bin/sh -c中执行,会忽略任何 CMD 或者docker run命令行选项,为了确保docker stop能够停止长时间运行 ENTRYPOINT 的容器,确保执行的时候使用 exec 选项。

css 复制代码
FROM ubuntu
ENTRYPOINT exec top -b

如果在 ENTRYPOINT 忘记使用 exec 选项,则可以使用 CMD 补上:

css 复制代码
FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1 # --ignored-param2 ... --ignored-param3 ... 依此类推
10. VOLUME

VOLUME ["/data"] 创建一个可以从本地主机或其他容器挂载的挂载点,后续具体介绍

11. USER

USER daemon 指定运行容器时的用户名或 UID,后续 RUN、CMD、ENTERPOINT 也会使用指定用户

12. WORKDIR

WORKDIR /path/to/workdir

为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径

bash 复制代码
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

最终路径是/a/b/c WORKDIR 指令可以在 ENV 设置变量之后调用环境变量:

bash 复制代码
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME

最终路径则为 /path/$DIRNAME

13. ONBUILD

ONBUILD [INSTRUCTION] 配置当所创建的镜像作为其他新创建镜像的基础镜像时,所执行的操作指令 例如:Dockerfile 使用如下的内容创建了镜像 image-A: [...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dri /app/src [...]

3、例子 examples,做一个 centos 安装了 nginx 及 wget 的镜像

ruby 复制代码
[root@web1 docker]# vim Dockerfile
#this is docker file for centos-nginx
FROM centos
MAINTAINER zxg  <victor@docker.com>
RUN yum install wget -y
RUN rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
  N yum install nginx -y
▽DD index.html /usr/share/nginx/html/index.html
RUN echo "daemon off;">>/etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx"]

4、使用 build 命令制作镜像

1)build 命令说明

ini 复制代码
$ docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build a new image from the source code at PATH
--force-rm=false     Always remove intermediate containers, even after unsuccessful builds # 移除过渡容器,即使构建失败
--no-cache=false     Do not use cache when building the image                              # 不实用 cache
-q, --quiet=false    Suppress the verbose output generated by the containers
--rm=true            Remove intermediate containers after a successful build               # 构建成功后移除过渡层容器
-t, --tag=""         Repository name (and optionally a tag) to be applied to the resulting image in case of success

2)制作镜像

docker build -t zxg/nginx1 . //注意后边有个 点

整个过程还挺长,这里就不详细输出了。

5、验证一下,并用 curl 测试

csharp 复制代码
[root@web1 docker]# docker run -d --name my_nginx1 zxg/nginx1 #后台运行整个容器
751a8f9dda48c034d40b8855b3dd6c7aaf785eeaa9ae404c5eb3c0271e434f50
bash 复制代码
[root@web1 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
751a8f9dda48        zxg/nginx1          "nginx"             About a minute ago   Up About a minute   80/tcp              my_nginx1
csharp 复制代码
[root@web1 docker]# docker exec -it my_nginx1 bash #进入容器
csharp 复制代码
[root@751a8f9dda48 /]# cat /usr/share/nginx/html/index.html   #查看文件是否添加到容器
this is docker-centos7-nginx1
ini 复制代码
[root@751a8f9dda48 /]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

daemon off;
[root@751a8f9dda48 /]# exit
exit
[root@web1 docker]#
[root@751a8f9dda48 html]# curl 127.0.0.1 //验证nginx是否生效
this is docker-centos7-nginx1
[root@751a8f9dda48 html]#
[root@web1 ~]# docker inspect my_nginx1 |grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
[root@web1 ~]# curl 172.17.0.2
this is docker-centos7-nginx1
[root@web1 ~]#
相关推荐
2401_857622663 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589363 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没5 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch5 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码6 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries7 小时前
读《show your work》的一点感悟
后端
A尘埃7 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23077 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code7 小时前
(Django)初步使用
后端·python·django
代码之光_19807 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端