Docker容器学习梳理-Dockerfile构建镜像

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

在Docker的运用中,从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低。所以就需要一 种文件或脚本,我们把想执行的操作以命令的方式写入其中,然后让docker读取并分析、执行,那么重复构建、更新将变得很方便,所以Dockerfile就此诞生了。Docker提供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉。Dockerfile脚本可以做到随时维护修改,即可以分享,更有利于在模板化,更不用说传输了,好处那是一大箩筐!下面就详细介绍下Dockfile的使用:


Dockfile是一种被Docker程序解释的脚本,它由一条条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译成真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。


总的来说:

Dockerfile分为四部分:基础镜像信息、镜像创建者信息、镜像操作指令、容器启动执行指令。

一开始必须要指明所基于的镜像名称,接下来一般会说明镜像创建者信息。后面则是镜像操作指令


一、Dockerfile的书写规则及指令使用方法

Dockerfile的指令是忽略大小写的,建议使用大写,使用 # 作为注释,每一行只支持一条指令,每条指令可以携带多个参数。

Dockerfile的指令根据作用可以分为两种:构建指令和设置指令。

构建指令用于构建image,其指定的操作不会在运行image的容器上执行;

设置指令用于设置image的属性,其指定的操作将在运行image的容器中执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
1)FROM(指定基础image)
构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。
FROM命令告诉docker我们构建的镜像是以哪个(发行版)镜像为基础的。第一条指令必须是FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令。
  
该指令有两种格式:
FROM <image> 
指定基础image为该image的最后修改的版本。或者:
  
FROM <image>:<tag> 
指定基础image为该image的一个tag版本。
  
RUN后面接要执行的命令,比如,我们想在镜像中安装vim,只需在Dockfile中写入 RUN yum  install  -y vim
  
2)MAINTAINER(用来指定镜像创建者信息)
构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。
  
格式:
MAINTAINER <name> 
  
3)RUN(安装软件用)
构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。
  
该指令有两种格式:
RUN < command >  
RUN [ "executable" "param1" "param2"  ... ] 
  
4)CMD(设置container启动时执行的操作)
设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。
  
该指令有三种格式:
CMD [ "executable" , "param1" , "param2" ]
CMD  command  param1 param2
  
当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:
CMD [ "param1" , "param2" ]
  
其中:
ENTRYPOINT指定的是一个可执行的脚本或者程序的路径,该指定的脚本或者程序将会以param1和param2作为参数执行。
所以如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT。
  
5)ENTRYPOINT(设置container启动时执行的操作)
设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
  
两种格式:
ENTRYPOINT [ "executable" "param1" "param2" ]
ENTRYPOINT  command  param1 param2
  
该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。
当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖,只有最后一个CMD或者ENTRYPOINT有效。
  
# CMD指令将不会被执行,只有ENTRYPOINT指令被执行 
CMD  echo  “Hello, World!” 
ENTRYPOINT  ls  -l 
  
另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;
ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。
  
FROM ubuntu 
CMD [ "-l"
ENTRYPOINT [ "/usr/bin/ls"
  
6)USER(设置container容器的用户)
设置指令,设置启动容器的用户,默认是root用户。
  
# 指定memcached的运行用户 
ENTRYPOINT [ "memcached"
USER daemon 
或者
ENTRYPOINT [ "memcached" "-u" "daemon"
  
7)EXPOSE(指定容器需要映射到宿主机器的端口)
设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。
要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。
也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。
  
格式:
EXPOSE <port> [<port>...] 
  
# 映射一个端口 
EXPOSE port1 
# 相应的运行容器使用的命令 
docker run -p port1 image 
    
# 映射多个端口 
EXPOSE port1 port2 port3 
# 相应的运行容器使用的命令 
docker run -p port1 -p port2 -p port3 image 
# 还可以指定需要映射到宿主机器上的某个端口号 
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
  
端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定而是在桥接网卡的地址范围内随机生成的。
宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。
对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看该端口号在宿主机器上的映射端口。
  
8)ENV(用于设置环境变量)
主要用于设置容器运行时的环境变量
  
格式:
ENV <key> <value> 
  
设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看这个环境变量,也可以通过在docker run -- env  key=value时设置或修改环境变量。
  
假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:
ENV JAVA_HOME  /path/to/java/dirent
  
9)ADD(从src复制文件到container的dest路径)
主要用于将宿主机中的文件添加到镜像中
构建指令,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;
如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;
如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下。
  
格式:
ADD <src> <dest> 
  
<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
<dest> 是container中的绝对路径
  
10)VOLUME(指定挂载点))
设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,
这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
  
格式:
VOLUME [ "<mountpoint>" ]
  
例如:
FROM base 
VOLUME [ "/tmp/data" ]
  
运行通过该Dockerfile生成image的容器, /tmp/data 目录中的数据在容器关闭后,里面的数据还存在。
例如另一个容器也有持久化数据的需求,且想使用上面容器共享的 /tmp/data 目录,那么可以运行下面的命令启动一个容器:
docker run -t -i - rm  -volumes-from container1 image2  bash
  
其中:container1为第一个容器的ID,image2为第二个容器运行image的名字。
  
11)WORKDIR(切换目录)
设置指令,可以多次切换(相当于 cd 命令),对RUN,CMD,ENTRYPOINT生效。
  
格式:
WORKDIR  /path/to/workdir 
  
# 在/p1/p2下执行vim a.txt 
WORKDIR  /p1  WORKDIR p2 RUN vim a.txt 
  
12)ONBUILD(在子镜像中执行)
  
格式:
ONBUILD <Dockerfile关键字> 
  
ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行。


二、Dockerfile使用实例


1)利用dockerfile部署jdk1.7+tomcat7服务环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
1)查看docker宿主机镜像
[root@localhost ~] # docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
docker.io /ubuntu                latest              0ef2e08ed3fa        6 weeks ago         130 MB
docker.io /centos                latest              67591570dd29        3 months ago        191.8 MB
docker.io /registry              2.2                 ad379b517aa6        14 months ago       224.5 MB
  
2)编写Dockerfile
[root@localhost ~] # vim Dockerfile
# Pull base image 
FROM centos:latest
 
# Author Information
MAINTAINER docker dengaosky <dengaosky@qq.com>
    
 
# Install Basic env Soft
RUN yum  install  vim net-tools ntpdate wget initscripts -y
 
# Install JDK 8 
RUN  mkdir  -p  /usr/java 
ADD jdk-8u92-linux-x64. tar .gz  /usr/java/
 
#SET JAVA environment variable  
ENV JAVA_HOME  /usr/java/jdk1 .8.0_92
    
# Install tomcat8 
ADD apache-tomcat-8.0.15. tar .gz  /usr/local/
#ADD tomcat-users.xml /usr/local/apache-tomcat-8.0.15/conf/tomcat-users.xml
 
# SET Tomcat environment variable  
ENV CATALINA_HOME  /usr/local/apache-tomcat-8 .0.15
ENV PATH $PATH:$CATALINA_HOME /bin 
  
# Create Tomcat Service Start Scripts 
ADD tomcat8.sh  /etc/init .d /tomcat8 
RUN  chmod  755  /etc/init .d /tomcat8
    
# Expose ports. 
EXPOSE 8080 
    
# Define default command. <三选一即可>
#CMD /usr/local/apache-tomcat-8.0.15/bin/catalina.sh run
#ENTRYPOINT service tomcat8 start && tail -f /usr/local/apache-tomcat-8.0.15/logs/catalina.out
ENTRYPOINT service tomcat8 start &&  tail  -f  /usr/local/apache-tomcat-8 .0.15 /logs/catalina .out
 
3)编写tomcat8.sh
[root@localhost ~] # vim tomcat8.sh
#!/bin/bash
 
export  JAVA_HOME= /usr/java/jdk1 .8.0_92/
export  TOMCAT_HOME= /usr/local/apache-tomcat-8 .0.15
    
case  $1  in 
start) 
   sh $TOMCAT_HOME /bin/startup .sh 
;; 
stop) 
   sh $TOMCAT_HOME /bin/shutdown .sh 
;; 
restart) 
   sh $TOMCAT_HOME /bin/shutdown .sh 
   sh $TOMCAT_HOME /bin/startup .sh 
;; 
esac 
  
4)构建镜像
DOckerfile脚本写好了,需要转换成镜像:
[root@localhost ~] # docker build -t dengaosky/jdk-tomcat --rm=true .
........
Removing intermediate container 6c54c575d743
Successfully built 1732044beee3
  
------------------------------------------------------------------------------------
其中:
-t    表示选择指定生成镜像的用户名,仓库名和tag
-- rm = true     表示指定在生成镜像过程中删除中间产生的临时容器。
注意:上面构建命令中最后的.符号不要漏了,表示使用当前目录下的Dockerfile构建镜像
------------------------------------------------------------------------------------
  
以上构建命令执行后,可以查看下镜像是否构建成功
[root@localhost ~] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky /jdk-tomcat    latest              1732044beee3        2 minutes ago       741.6 MB
docker.io /centos        latest              ff426288ea90        3 weeks ago         207.2 MB
  
最后利用这个镜像启动容器
[root@localhost ~] # docker run -itd --name dengaosky-tomcat -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
6bc4b44b5211497254efc2d90ac5f04ccc4b961377f5a96040ebff4a89fdd840
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
6bc4b44b5211        dengaosky /jdk-tomcat    "/bin/sh -c 'service "    6 seconds ago       Up 4 seconds        0.0.0.0:8080->8080 /tcp    dengaosky-tomcat
  
进入容器,查看tomcat进程以及端口监听状态
[root@localhost ~] # docker exec -it dengaosky-tomcat /bin/bash 
[root@6bc4b44b5211 /] # ps -ef|grep tomcat
root         1     0  0 07:47 ?        00:00:00  /bin/sh  -c service tomcat8 start &&  tail  -f  /usr/local/apache-tomcat-8 .0.15 /logs/catalina .out  /bin/bash
root        23     1  3 07:47 ?        00:00:03  /usr/java/jdk1 .8.0_92 //bin/java  -Djava.util.logging.config. file = /usr/local/apache-tomcat-8 .0.15 /conf/logging .properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed. dirs = /usr/local/apache-tomcat-8 .0.15 /endorsed  -classpath  /usr/local/apache-tomcat-8 .0.15 /bin/bootstrap .jar: /usr/local/apache-tomcat-8 .0.15 /bin/tomcat-juli .jar -Dcatalina.base= /usr/local/apache-tomcat-8 .0.15 -Dcatalina.home= /usr/local/apache-tomcat-8 .0.15 -Djava.io.tmpdir= /usr/local/apache-tomcat-8 .0.15 /temp  org.apache.catalina.startup.Bootstrap start
root        24     1  0 07:47 ?        00:00:00  tail  -f  /usr/local/apache-tomcat-8 .0.15 /logs/catalina .out
root        70    49  0 07:48 ?        00:00:00  grep  --color=auto tomcat
[root@6bc4b44b5211 /] # netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID /Program  name    
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      23 /java             
tcp6       0      0 :::8009                 :::*                    LISTEN      23 /java             
tcp6       0      0 :::8080                 :::*                    LISTEN      23 /java             
[root@6bc4b44b5211 /] #

最后访问http://本机ip:8080就能打开容器的tomcat页面了

blob.png



Docker容器创建好之后,尽量不要直接登陆容器内去修改。所以最好容器创建的时候进行目录映射。这样就可以通过映射到宿主机上的文件或目录去共享到容器内。

则上面的dengaosky-tomcat容器可以如下调整操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                    NAMES
c0812ad20bed        dengaosky /jdk-tomcat         "/bin/sh -c 'service "    7 seconds ago       Up 6 seconds        0.0.0.0:8899->8080 /tcp    dengaosky-tomcat
  
[root@localhost ~] # docker cp dengaosky-tomcat:/usr/local/apache-tomcat-8.0.15/webapps /opt/  
  
[root@localhost ~] # docker run -itd --name dengaosky-tomcat -v /opt/webapps:/usr/local/apache-tomcat-8.0.15/webapps -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
796b1e68b80e23443f674650a23c96291ba32ed51049ab7300113379c9e3b308
[root@localhost ~] # docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
796b1e68b80e        dengaosky /jdk-tomcat    "/bin/sh -c 'service "    11 seconds ago      Up 10 seconds       0.0.0.0:8080->8080 /tcp    dengaosky-tomcat
[root@localhost ~]
  
这样让需要修改dengaosky-tomcat容器的代码或上线代码时,只需要操作宿主机的 /opt/webapps 目录即可。


------------------删除docker images中为none的镜像----------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
经常使用Dockerfile制作镜像,Docker build 命令执行后,由于版本更新需要重新创建,那么以前那个版本的镜像就会成为临时镜像,这就是none标签的镜像。,如下:
[root@localhost ~] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky /jdk-tomcat    latest              1732044beee3        19 minutes ago      741.6 MB
<none>                 <none>              85eb05c75724        29 minutes ago      207.2 MB
<none>                 <none>              73ce83c6b41d        27 minutes ago      207.2 MB
docker.io /centos        latest              ff426288ea90        3 weeks ago         207.2 MB
  
对于这些none标签的images,可以通过下面的脚本进行删除(如果无法删除none的images,一般重启docker服务后即可解决):
[root@localhost ~] # vim none_images_rm.sh
#!/bin/bash
docker  ps  -a |  grep  "Exited"  awk  '{print $1 }' | xargs  docker stop
docker  ps  -a |  grep  "Exited"  awk  '{print $1 }' | xargs  docker  rm
docker images| grep  none| awk  '{print $3 }' | xargs  docker rmi
  
[root@localhost ~] # sh none_images_rm.sh
  
[root@localhost ~] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky /jdk-tomcat    latest              1732044beee3        19 minutes ago      741.6 MB
docker.io /centos        latest              ff426288ea90        3 weeks ago         207.2 MB


2)再看一例tomcat容器镜像的Dockerfile制作过程(centos为base镜像)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
[root@localhost ~] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker.io /centos        latest              ff426288ea90        3 weeks ago         207.2 MB
  
提前下载好tomcat和java安装包,放在Docker宿主机的 /usr/local/src 目录下:
[root@localhost src] # ls
apache-tomcat-8.5.16. tar .gz  Dockerfile  jdk-8u121-linux-x64. tar .gz
  
/usr/local/src 当前目录下编辑Dockerfile。如下:
即将宿主机本地的tomcat和java安装包拷贝到容器内,并自动解压。
[root@localhost src] # vim Dockerfile
# Pull base image 
FROM centos:latest
 
# Author Information
MAINTAINER dengaosky <dengaosky@qq.com>
 
# Install Basic env Soft
RUN yum  install  vim net-tools ntpdate wget initscripts -y
 
# Install JDK 8 
ADD jdk-8u121-linux-x64. tar .gz  /usr/local
 
# SET JAVA environment variable  
ENV JAVA_HOME  /usr/local/jdk1 .8.0_121
ENV PATH $JAVA_HOME /bin :$PATH
    
# Install tomcat8 
ADD apache-tomcat-8.5.16. tar .gz  /usr/local
    
# Expose ports. 
EXPOSE 8080 
    
# Define default command. 
ENTRYPOINT  /usr/local/apache-tomcat-8 .5.16 /bin/startup .sh  &&  tail  -f  /usr/local/apache-tomcat-8 .5.16 /logs/catalina .out
  
  
  
接着构建镜像
[root@localhost src] # docker build -t dengaosky/jdk-tomcat --rm=true .
  
[root@localhost src] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
dengaosky /jdk-tomcat    latest              f04c88789339        14 seconds ago      746.9 MB
docker.io /centos        latest              ff426288ea90        3 weeks ago         207.2 MB
  
根据制作的镜像启动tomcat容器
[root@localhost src] # docker run -itd --name tomcat-test -p 8080:8080 dengaosky/jdk-tomcat /bin/bash
36a1f47d662ec87280aa258737404a6f17e21da75f913d31c050f91af33ec277
 
[root@localhost src] # docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
36a1f47d662e        dengaosky /jdk-tomcat    "/bin/sh -c '/usr/loc"    16 seconds ago      Up 14 seconds       0.0.0.0:8080->8080 /tcp    tomcat- test
  
查看tomcat容器进程 
[root@localhost src] # docker exec -it tomcat-test /bin/bash
[root@36a1f47d662e /] # ps -ef|grep tomcat
root         1     0  0 08:46 ?        00:00:00  /bin/sh  -c  /usr/local/apache-tomcat-8 .5.16 /bin/startup .sh  &&  tail  -f  /usr/local/apache-tomcat-8 .5.16 /logs/catalina .out  /bin/bash
root        13     1  7 08:46 ?        00:00:03  /usr/local/jdk1 .8.0_121 /bin/java  -Djava.util.logging.config. file = /usr/local/apache-tomcat-8 .5.16 /conf/logging .properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath  /usr/local/apache-tomcat-8 .5.16 /bin/bootstrap .jar: /usr/local/apache-tomcat-8 .5.16 /bin/tomcat-juli .jar -Dcatalina.base= /usr/local/apache-tomcat-8 .5.16 -Dcatalina.home= /usr/local/apache-tomcat-8 .5.16 -Djava.io.tmpdir= /usr/local/apache-tomcat-8 .5.16 /temp  org.apache.catalina.startup.Bootstrap start
root        14     1  0 08:46 ?        00:00:00  tail  -f  /usr/local/apache-tomcat-8 .5.16 /logs/catalina .out
root        78    61  0 08:47 ?        00:00:00  grep  --color=auto tomcat


3)使用Dockerfile制作nginx镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost nginx] # docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker.io /centos        latest              ff426288ea90        4 weeks ago         207.2 MB
  
制作Dockerfile
[root@localhost nginx] # vim Dockerfile
#Pull down centos image
FROM centos
 
#Author Informations
MAINTAINER dengaosky dengaosky@docker.com
  
#Install nginx
RUN yum  install  zlib zlib-devel pcre pcre-devel openssl openssl-devel gcc gcc+ wget vim net-tools -y 
RUN  useradd  www -M -s  /sbin/nologin
RUN  cd  /usr/local/src  && wget http: //nginx .org /download/nginx-1 .12.2. tar .gz &&  tar  -zxvf nginx-1.12.2. tar .gz
RUN  cd  /usr/local/src/nginx-1 .12.2 && . /configure  --prefix= /usr/local/nginx  --user=www --group=www --with-http_stub_status_module --with-http_ssl_module &&  make  &&  make  install
 
#Expose ports. 
EXPOSE 80
  
#Define defaults Command
ENTRYPOINT  /usr/local/nginx/sbin/nginx  &&  tail  -f  /usr/local/nginx/logs/access .log


---------------------------------------------------------------------------------------------------------------------

特别需要注意的:

在Docker daemon模式下,无论你是使用ENTRYPOINT,还是CMD,最后的命令,一定要是当前进程需要一直运行的,才能够防容器退出。

也就是说,上面Dockerfile脚本中最后一行:


以下无效方式:

ENTRYPOINT /usr/local/nginx/sbin/nginx             #运行几秒钟之后,容器就会退出

或者

CMD /usr/local/nginx/sbin/nginx             #运行几秒钟之后,容器就会退出


以下才是有效方式:

ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log     #确保容器内的进程一直运行

或者

CMD /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log       #确保容器内的进程一直运行


其他应用程序镜像创建的Dockerfile配置类似

------------------------------------------------------------------------------------------------------------------


Dockerfile写好了,需要转换成镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
构建镜像
[root@localhost nginx] # docker build -t dengaosky/nginx --rm=true .
  
[root@localhost nginx] # docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
dengaosky /nginx                latest              4f6014d3c971        3 minutes ago       442.8 MB
docker.io /centos               latest              ff426288ea90        4 weeks ago         207.2 MB
  
根据Dockerfile构建的镜像启动nginx容器
[root@localhost nginx] # docker run -ti -d --name test_nginx -p 80:80 dengaosky/nginx /bin/bash
e6b6d581b6a1ed0900b4be5d7c9fee7ae108d1f45b25357306b576fa9f84ca1a
[root@localhost nginx] # docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
e6b6d581b6a1        dengaosky /nginx      "/bin/sh -c '/usr/loc"    7 seconds ago       Up 6 seconds        0.0.0.0:80->80 /tcp    test_nginx
  
进入容器,检查容器内的nginx程序是否已启动
[root@localhost nginx] # docker exec -ti test_nginx /bin/bash
[root@e6b6d581b6a1 /] # ps -ef|grep nginx
root         1     0  0 03:02 ?        00:00:00  /bin/sh  -c  /usr/local/nginx/sbin/nginx  &&  tail  -f  /usr/local/nginx/logs/access .log  /bin/bash
root         6     1  0 03:02 ?        00:00:00 nginx: master process  /usr/local/nginx/sbin/nginx
www          7     6  0 03:02 ?        00:00:00 nginx: worker process
root         8     1  0 03:02 ?        00:00:00  tail  -f  /usr/local/nginx/logs/access .log
root        25     9  0 03:02 ?        00:00:00  grep  --color=auto nginx
[root@e6b6d581b6a1 /] #


通过映射到Docker宿主机的端口80去访问容器的nginx

blob.png


创建好的镜像,可以保存到索引仓库中,便于下次使用(当然,我们直接共享Dockerfile,是最简单的事情,:)) ),但毕竟镜像可以做到开箱即用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
登陆https: //hub .docker.com/  注册一个账号
   
然后登陆
[root@localhost nginx] # docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID,  head  over to https: //hub .docker.com to create one.
Username: dengao
Password: 
Login Succeeded
[root@localhost nginx] #
   
提交到Docker索引仓库
注意下面提交的镜像路径,即 "用户名/镜像" ,只有这样才能成功提交。
所以在Dockerfile制作镜像的时候,仓库名最好用docker索引仓库的用户名,也即 "用户名/镜像"
[root@localhost nginx] # docker push dengao/jdk-tomcat
The push refers to a repository [docker.io /dengao/jdk-tomcat ]
7841a0719a03: Pushed 
c9ec27eb9aa1: Pushed 
dc40446c1078: Pushed 
e15afa4858b6: Pushed 
latest: digest: sha256:10433028d3ff2f1a7554c0465d1c703505e5aed86eb48baf37b605547649f68f size: 1165
[root@localhost nginx]
   
这样下次想用的时候,可以直接从Docker索引仓库里下载
docker pull dengao /jdk-tomcat

------------------------Dockerfile制作多应用程序镜像的实例---------------------------------------------------------

可以参考:http://dockerfile.github.io/


需要注意几点:

1)Docker宿主机必须要有base镜像以供Dockerfile文件使用

2)注意Dockerfile实例文件中的base镜像,这个引用的base镜像一定要是存在的

3)可以切换到不同的目录路径下编写Dockerfile,然后构建,构建的时候直接使用.表示在当前路径下。

镜像构建成功后,可以放到自己的私有仓库里,然后Dockerfile文件可以选择删除。




本文转自 dengaosky 51CTO博客,原文链接:http://blog.51cto.com/dengaosky/2068156,如需转载请自行联系原作者

相关文章
|
15天前
|
运维 Kubernetes Docker
利用Docker和Kubernetes构建微服务架构
利用Docker和Kubernetes构建微服务架构
|
19天前
|
缓存 Linux 网络安全
docker的镜像无法下载如何解决?
【10月更文挑战第31天】docker的镜像无法下载如何解决?
696 29
|
15天前
|
存储 关系型数据库 Linux
【赵渝强老师】什么是Docker的镜像
Docker镜像是一个只读模板,包含应用程序及其运行所需的依赖环境。镜像采用分层文件系统,每次修改都会以读写层形式添加到原只读模板上。内核bootfs用于加载Linux内核,根镜像相当于操作系统,上方为应用层。镜像在物理存储上是一系列文件的集合,默认存储路径为“/var/lib/docker”。
|
21天前
|
存储 监控 Linux
docker构建镜像详解!!!
本文回顾了Docker的基本命令和管理技巧,包括容器和镜像的增删改查操作,容器的生命周期管理,以及如何通过端口映射和数据卷实现容器与宿主机之间的网络通信和数据持久化。文章还详细介绍了如何使用Docker部署一个简单的Web应用,并通过数据卷映射实现配置文件和日志的管理。最后,文章总结了如何制作自定义镜像,包括Nginx、Python3和CentOS镜像,以及如何制作私有云盘镜像。
100 2
|
22天前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
46 1
|
28天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【10月更文挑战第22天】随着云计算和容器技术的快速发展,微服务架构逐渐成为现代企业级应用的首选架构。微服务架构将一个大型应用程序拆分为多个小型、独立的服务,每个服务负责完成一个特定的功能。这种架构具有灵活性、可扩展性和易于维护的特点。在构建微服务架构时,Docker和Kubernetes是两个不可或缺的工具,它们可以完美搭档,为微服务架构提供高效的支持。本文将从三个方面探讨Docker和Kubernetes在构建高效微服务架构中的应用:一是Docker和Kubernetes的基本概念;二是它们在微服务架构中的作用;三是通过实例讲解如何使用Docker和Kubernetes构建微服务架构。
59 6
|
24天前
|
存储 Java 开发者
成功优化!Java 基础 Docker 镜像从 674MB 缩减到 58MB 的经验分享
本文分享了如何通过 jlink 和 jdeps 工具将 Java 基础 Docker 镜像从 674MB 优化至 58MB 的经验。首先介绍了选择合适的基础镜像的重要性,然后详细讲解了使用 jlink 构建自定义 JRE 镜像的方法,并通过 jdeps 自动化模块依赖分析,最终实现了镜像的大幅缩减。此外,文章还提供了实用的 .dockerignore 文件技巧和选择安全、兼容的基础镜像的建议,帮助开发者提升镜像优化的效果。
|
27天前
|
负载均衡 应用服务中间件 nginx
基于Nginx和Consul构建自动发现的Docker服务架构——非常之详细
通过使用Nginx和Consul构建自动发现的Docker服务架构,可以显著提高服务的可用性、扩展性和管理效率。Consul实现了服务的自动注册与发现,而Nginx则通过动态配置实现了高效的反向代理与负载均衡。这种架构非常适合需要高可用性和弹性扩展的分布式系统。
28 4
|
28天前
|
存储 缓存 Java
Java应用瘦身记:Docker镜像从674MB优化至58MB的实践指南
【10月更文挑战第22天】 在容器化时代,Docker镜像的大小直接影响到应用的部署速度和运行效率。一个轻量级的Docker镜像可以减少存储成本、加快启动时间,并提高资源利用率。本文将分享如何将一个Java基础Docker镜像从674MB缩减到58MB的实践经验。
47 1
|
15天前
|
API Docker 容器
【赵渝强老师】构建Docker Swarm集群
本文介绍了如何使用三台虚拟主机构建Docker Swarm集群。首先在master节点上初始化集群,然后通过特定命令将node1和node2作为worker节点加入集群。最后,在master节点上查看集群的节点信息,确认集群构建成功。文中还提供了相关图片和视频教程,帮助读者更好地理解和操作。
下一篇
无影云桌面