Dockerfile构建

引用菜鸟教程

主要有大量的命令需要记一下

脚本命令

Dockerfile 指令 说明
FROM 指定基础镜像,用于后续的指令构建。
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
LABEL 添加镜像的元数据,使用键值对的形式。
RUN 在构建过程中在镜像中执行环境本身的命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像中。会自动处理url和解压tar
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
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
#------FROM------
# 通过FROM指定的镜像名称必须是一个已经存在的镜像,这个镜像称之为基础镜像,必须位于第一条非注释指令
FROM <IMAGE>
FROM <IMAGE>:<TAG>
#------FROM------


#------MAINTAINER------
# 作者,已废弃,用 LABLE
MAINTAINER kewen
#------MAINTAINER------


#------LABEL------
#LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
#比如我们可以添加镜像的作者:
LABEL org.opencontainers.image.authors="kw"
#------LABEL------


#------ADD和COPY------
#作用都是将文件或目录复制到Dockerfile构建的镜像中
# 一般src为相对路径 dest为容器中的绝对路径
COPY <src> <dest>
COPY ["<src>" "<dest>"] (适用于文件路径包含空格的情况)
ADD <src> <dest>
ADD ["<src>" "<dest>"] (适用于文件路径包含空格的情况)
#区别 COPY单纯的复制文件,ADD在文件是压缩文件的时候会执行解压
#------ADD和COPY------


#------ENV与ARG------
#ENV用于设置环境变量,
ENV <KEY> <VALUE>
ENV <KEY>=<VALUE>
#ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效
ARG <参数名>[=<默认值>]
#------ENV与ARG------


#------WORKDIR------
#工作目录,在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录
WORKDIR <工作目录路径>
#docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
#------WORKDIR------


#------USER------
# 规定后续命令执行的用户
#用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)
USER <用户名>[:<用户组>] (用户组可选)
#------USER------


#------VOLUME-----
#定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
#避免重要的数据,因容器重启而丢失,这是非常致命的。
#避免容器不断变大。
#在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
#------VOLUME-----


#------EXPOSE------
#指定运行该镜像的容器使用的端口,可以是多个,只是告诉容器要使用这个端口,还需要在run的时候映射(host模式是否直接使用?)
EXPOSE <PORT>
#运行时 docker run -p 80:<port>
#------EXPOSE------


#------RUN------
#用于指定构建镜像时运行的命令,两种模式:
RUN <command> (shell模式)
RUN [ "executable", "param1", "param2" ] (exec模式)
# 在shell模式下,是使用/bin/sh -c COMMAND来运行命令的
# 在exec模式下可以指定其他的shell来运行命令RUN [“/bin/bash”, “-c”, “echo hello”]

#多条RUN指令可以合并为一条,减小层数
#Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
RUN yum install httpd && yum install ftp && echo 'hello'
#------RUN------


#------CMD------
#用于提供容器运行的默认命令,如果在docker run时指定了运行的命令,则CMD命令不会执行。CMD有三种模式:
CMD <command> (shell模式)
CMD [ "executable", "param1", "param2" ] (exec模式)
CMD [ 'param1', 'param2'] (通常与ENTRYPOINT搭配指定ENTRYPOINT的默认参数)
#------CMD------
#------ENTRYPOINT------
#与CMD类似,ENTRYPOINT不会被docker run中指定的命令覆盖,如果想覆盖ENTRYPOINT,则需要在docker run中指定--entrypoint选项
#它有两种模式:
ENTRYPOINT <command> (shell模式)
ENTRYPOINT [ "executable", "param1", "param2" ] (exec模式)
#可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。如
# FROM nginx
# ENTRYPOINT ["nginx", "-c"] # 定参
# CMD ["/etc/nginx/nginx.conf"] # 变参
#docker run nginx:test 默认指定CMD参数
#docker run nginx:test -c /etc/nginx/new.conf # 覆盖CMD参数,
#------ENTRYPOINT------


构建Java应用

基本java程序

编写App.java程序

1
2
3
4
5
6
7
8
9
10
11
12
13
public class App{
public static void main(String[] args){
System.out.println("hello world");
String os = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");

System.out.println(os);
System.out.println(osArch);
System.out.println(osVersion);
}
}

编写Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
## 设置基础镜像
FROM openjdk:8

## 设置进入容器时的工作目录
WORKDIR /root/app
## 将本地目录复制进容器目录中
COPY App.java /root/app

## 镜像制作时执行的命令
RUN javac App.java

## 容器启动时执行的命令
ENTRYPOINT java App

构建

1
2
3
docker build .
# 或者打标签构建
docker build . -t firsttest:0.1

.代表Dockerfile的路径,因为在本路径执行的,就直接当前路径

查看镜像,启动执行

1
2
3
4
# 查看镜像
docker images
#运行
docker run <id>

也可以打tag docker tag 镜像ID 存储:版本

1
docker tag <image-id> firsttest:0.1

再查看images如下

1
2
3
4
[root@centos d1-first]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
firsttest 0.1 af0028165c88 43 minutes ago 526 MB
docker.io/openjdk 8 e24ac15e052e 2 years ago 526 MB

参考

准备springboot程序

准备好普通的springboot-web应用

创建Dockerfile

1
2
3
4
5
6
7
FROM openjdk:8
WORKDIR /root/app
COPY D7-springboot-source-1.0-SNAPSHOT.jar /root/app
EXPOSE 8081
#RUN java -jar D7-springboot-source-1.0-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","D7-springboot-source-1.0-SNAPSHOT.jar"]

构建

1
docker buiild -t java-web-demo .

会得到一个id

启动

1
2
3
4
5
6
7
docker run -p 8081:8081 -itd  <构建的镜像ID> 
# 查看日志
docker logs <容器ID>

# 验证
curl http://localhost:8081/hello/hello