layout: post
title: DockerFile基础
date: 2018-04-14
tags: [“Docker”,”自动化运维工具”]


一、dockerfile简介

Docker可以通过从Dockerfile读取指令自动构建映像。 Dockerfile是一个文本文档,其中包含用户可以在命令行上调用以组装图像的所有命令。使用docker build用户可以创建一个自动构建,它可以连续执行几条命令行指令。

二、dockerfile编写

1、简单编写测试

  1. [root@ansible_master file_01]# cp -r /etc/yum.repos.d/ repofiles
  2. [root@ansible_master file_01]# cp -r /etc/hosts ./
  3. [root@ansible_master file_01]# vim Dockerfile
  4. #编辑dockerfile
  5. FROM alpine:latest #FROM必须为file第一个项目,标识从哪个容器作为基础源
  6. LABEL maintainer="zhangshang<zhangshangbj@163.com>"\ #LABEL指令为图像添加元数据。 LABEL是一个键值对。要在LABEL值中包含空格,请像在命令行解析中一样使用引号和反斜杠。
  7. build_host="come on baby!"
  8. COPY repofiles /etc/yum.repos.d/ #COPY指令从中复制新的文件或目录,并将它们添加到路径处的容器的文件系统中。注意:src如果是目录会递归复制其下的文件和目录到指定位置,但其自身不会进行递归,而dest必须是个目录且以"/"结尾。
  9. COPY hosts /tmp/hosts

制作镜像文件

  1. [root@ansible_master file_01]# docker build .
  2. Sending build context to Docker daemon 25.09kB
  3. Step 1/4 : FROM alpine:latest
  4. ---> 3fd9065eaf02
  5. Step 2/4 : LABEL maintainer="zhangshang<zhangshangbj@163.com>" build_host="come on baby!"
  6. ---> Running in 412695267e1a
  7. Removing intermediate container 412695267e1a
  8. ---> 060f161977d3
  9. Step 3/4 : COPY repofiles /etc/yum.repos.d/
  10. ---> 12dcb96039e3
  11. Step 4/4 : COPY hosts /tmp/hosts
  12. ---> ce6d874d791c
  13. Successfully built ce6d874d791c

为新生成的镜像打标签

  1. [root@ansible_master file_01]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. <none> <none> ce6d874d791c About a minute ago 4.16MB
  4. nginx 1.23-alpine.041418 26fce246aebb 27 hours ago 15.5MB
  5. zhangshangbj/nginx 1.12-alpine.041418 26fce246aebb 27 hours ago 15.5MB
  6. busybox latest 8ac48589692a 10 days ago 1.15MB
  7. nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
  8. alpine latest 3fd9065eaf02 3 months ago 4.15MB
  9. [root@ansible_master file_01]# docker tag ce6d alpine:test1
  10. [root@ansible_master file_01]# docker images
  11. REPOSITORY TAG IMAGE ID CREATED SIZE
  12. alpine test1 ce6d874d791c 2 minutes ago 4.16MB #OK
  13. nginx 1.23-alpine.041418 26fce246aebb 27 hours ago 15.5MB
  14. zhangshangbj/nginx 1.12-alpine.041418 26fce246aebb 27 hours ago 15.5MB
  15. busybox latest 8ac48589692a 10 days ago 1.15MB
  16. nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
  17. alpine latest 3fd9065eaf02 3 months ago 4.15MB

运行这个镜像

  1. [root@ansible_master file_01]# docker run --name test1 -itd alpine:test1 /bin/sh #创建并运行容器
  2. 8e8cced850401f0dbc291d8fed347d7da69315043ee961ba4bf0acbb784ff216
  3. [root@ansible_master file_01]# docker exec -it test1 /bin/sh #切入容器
  4. / # ls /etc/yum.repos.d/
  5. CentOS-Base.repo CentOS-Sources.repo docker-ce.repo #目标文件已创建
  6. CentOS-CR.repo CentOS-Vault.repo epel.repo
  7. CentOS-Debuginfo.repo CentOS-fasttrack.repo
  8. CentOS-Media.repo bak
  9. / # ls /tmp/ #目标文件已创建
  10. hosts

2、ADD指令

Syntax:

ADD
ADD [““,…”“]

操作准侧:

1)、ADD指令与COPY指令类似,ADD指令支持展开TAR文件和URL路径(将URL路径文件下载到本地,但URL的方式不支持tar文件展开)
2)、如果有多个,或其简介或直接使用了通配符,则必须是一个以”/“结尾的目录路径;如果不以”/“结尾,则其被视作一个普通文件,的内容将被直接写入到;

练习

  1. [root@ansible_master file_01]# vim Dockerfile
  2. FROM alpine:latest
  3. LABEL maintainer="zhangshang<zhangshangbj@163.com>"\
  4. build_host="come on baby!"
  5. COPY repofiles /etc/yum.repos.d/
  6. COPY hosts /tmp/hosts
  7. ADD sysfile.tar.gz /tmp/
  8. ADD http://blog.vservices.top/myblog/?p=595 /tmp/http
  9. [root@ansible_master file_01]# docker build .

查看打包结果

  1. [root@ansible_master file_01]# docker tag 9d16 alpine:test2
  2. [root@ansible_master file_01]# docker run -it --rm --name test2 alpine:test2
  3. / # cd /tmp/
  4. /tmp # ls
  5. etc hosts http

3、WORKDIR 指令

在Dockerfile中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对于此前一个WORKDIR指令指定的路径;另外,WORKDIR也可以调用由ENV指定定义的变量。

4、VOLUME 指令

指定挂载点,如果挂载点目录路径下此前已有文件存在,docker run命令会讲卷挂载完成后将此前的所有文件复制到新挂载的卷中。

  1. [root@ansible_master file_01]# vim Dockerfile
  2. FROM alpine:latest
  3. LABEL maintainer="zhangshang<zhangshangbj@163.com>"\
  4. build_host="come on baby!"
  5. COPY repofiles /etc/yum.repos.d/
  6. COPY hosts /tmp/hosts
  7. ADD sysfile.tar.gz /tmp/
  8. VOLUME "/data/web/html"
  9. [root@ansible_master file_01]# docker build .

进入容器

  1. [root@ansible_master file_01]# docker run -it --name test2 ef6d2 /bin/sh
  2. / # ls /data/web/html/

5、EXPOSE指令

用于实现容器打开指定端口实现与外部通信

Syntax:

EXPOSE [/protocol] []

构建暴露端口的http服务:

  1. [root@ansible_master file_02]# echo "<html>h1</html>" >index.html
  2. [root@ansible_master file_02]# vim Dockerfile
  3. FROM busybox:latest
  4. LABEL maintainer="zhangshang<zhangshangbj@163.com>"
  5. ADD index.html /data/web/html/
  6. EXPOSE 80/tcp #暴露端口
  7. [root@ansible_master file_02]# docker build -t httpd:v1 .
  8. Sending build context to Docker daemon 3.072kB
  9. Step 1/4 : FROM busybox:latest
  10. ---> 8ac48589692a
  11. Step 2/4 : LABEL maintainer="zhangshang<zhangshangbj@163.com>"
  12. ---> Using cache
  13. ---> 7cee9591fed5
  14. Step 3/4 : ADD index.html /data/web/html/
  15. ---> 1c32cc393166
  16. Step 4/4 : EXPOSE 80/tcp
  17. ---> Running in 16c3d49fafee
  18. Removing intermediate container 16c3d49fafee
  19. ---> f30dbac9ae19
  20. Successfully built f30dbac9ae19
  21. Successfully tagged httpd:v1

运行查看

  1. ~ # httpd -h
  2. httpd: option requires an argument -- h
  3. BusyBox v1.28.3 (2018-04-03 20:29:50 UTC) multi-call binary.
  4. Usage: httpd [-ifv[v]] [-c CONFFILE] [-p [IP:]PORT] [-u USER[:GRP]] [-r REALM] [-h HOME]
  5. or httpd -d/-e/-m STRING
  6. Listen for incoming HTTP requests
  7. -i Inetd mode
  8. -f Don't daemonize
  9. -v[v] Verbose
  10. -p [IP:]PORT Bind to IP:PORT (default *:80)
  11. -u USER[:GRP] Set uid/gid after binding to port
  12. -r REALM Authentication Realm for Basic Authentication
  13. -h HOME Home directory (default .)
  14. -c FILE Configuration file (default {/etc,HOME}/httpd.conf)
  15. -m STRING MD5 crypt STRING
  16. -e STRING HTML encode STRING
  17. -d STRING URL decode STRING
  18. ~ # httpd -h /data/web/html
  19. ~ # netstat -lant
  20. Active Internet connections (servers and established)
  21. Proto Recv-Q Send-Q Local Address Foreign Address State
  22. tcp 0 0 :::80 :::* LISTEN
  23. ~ #

在宿主机上查看端口

  1. [root@ansible_master ~]# docker port h1 #未查找到暴露端口,是因为启动容器时没有加 -P选项,使用-p选项可以指定端口的映射。
  2. [root@ansible_master ~]# curl 172.17.0.2
  3. <html>h1</html>
  4. [root@ansible_master file_02]# docker run -itd --name h1 --rm -P httpd:v1 /bin/httpd -h /data/web/html #启动容器失败,因为docker容器默认只能有一个进程启动,且必须是前台,而busybox模拟的httpd命令执行完成之后,将进程放在了后台,所以容器自动关闭
  5. [root@ansible_master file_02]# docker run -itd --name h1 --rm -P httpd:v1 /bin/sh #-P指定暴露默认端口
  6. [root@ansible_master file_02]# docker exec h1 /bin/httpd -h /data/web/html
  7. [root@ansible_master file_02]# docker ps
  8. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  9. 31d8d1ab1f27 httpd:v1 "/bin/sh" 34 seconds ago Up 33 seconds 0.0.0.0:10006->80/tcp h1
  10. [root@ansible_master file_02]# curl 127.0.0.1:10006
  11. <html>h1</html>
  12. [root@ansible_master file_02]# docker port h1
  13. 80/tcp -> 0.0.0.0:10006

6、USER指令

USER指令设置用户名(或UID)和可选的用户组(或GID),以在运行映像时以及在Dockerfile中执行后续的任何RUN,CMD和ENTRYPOINT指令。

Syntax:

  1. USER <user>[:<group>] or
  2. USER <UID>[:<GID>]

例:

  1. FROM microsoft/windowsservercore
  2. # Create Windows user in the container
  3. RUN net user /add patrick
  4. # Set it for subsequent commands
  5. USER patrick

 

文档更新时间: 2020-03-27 13:42   作者:张尚