Dockerfile

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本(Dockerfile就相当于用(多条)指令来说明要执行什么操作来构建镜像的文件)。

图片

Dockerfile通过指令构建镜像,过程就相当于Docker内部容器多次提交形成镜像

大致流程:
图片

常用保留字指令

每条保留字指令都必须为大写字母且后面要跟随至少一个参数。

示例:
tomcat10/jdk8的dockerfile
图片

指令执行时期:

Build Run Both
FROM CMD WORKDIR
MAINTAINER ENV USER
COPY EXPOSE
ADD VOLUME
RUN ENTRYPOINT
ONBUILD

FROM

基础镜像,作为Dockerfile的首条指令。表明当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板。

MAINTAINER

镜像维护者的姓名和邮箱地址。

RUN

容器构建时需要运行的命令。主要用于执行Linux的shell命令,一般是安装过程的命令。
主要有两种格式:

  1. shell格式:RUN <命令行命令>

示例:

1
RUN yum -y install vim
  1. exec格式:RUN ["可执行文件","参数1","参数2"]

示例:

1
2
3
RUN ["./ahzoo.java","dev","offline"]
## 等价于:
RUN ./ahzoo.java dev offline

EXPOSE

当前容器对外暴露出的端口。

WORKDIR

指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点。

USER

指定该镜像通过什么用户去执行,如果都不指定,默认为root。

ENV

用来在构建镜像过程中设置环境变量。
示例:

1
2
3
4
5
## 配置一个环境变量
ENV MY_PATH /usr/ahzoo

## 这个环境变量可以在其它指令使用,比如WORKDIR指令
WORKDIR $MY_PATH

ADD

将宿主机目录下的文件拷贝进镜像,且会自动处理URL和解压tar压缩包

COPY

类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径>位置
格式:COPY 原路径 目标路径

VOLUME

容器数据卷,用于数据保存和持久化工作。

CMD

指定容器启动时要运行的命令。
CMD是在docker run时运行,RUN是在docker build时运行。
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 会被 docker run 之后的参数替换。

和RUN命令相似,同样支持两种格式:

  1. shell格式:CMD <命令行命令>
  2. exec格式:CMD ["可执行文件","参数1","参数2"]

    ENTRYPOINT

    用来指定一个容器启动时要运行的命令。
    类似于 CMD 指令,可以有多个ENTRYPOINT 令,但只有最后一个生效。不同的是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

格式:ENTRYPOINT ["可执行文件","参数1","参数2"]
当指定了ENTRYPOINT后,CMD的含义就发生了变化。不再是直接运行其命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令:
示例:

1
2
3
4
5
6
7
FROM nginx

## 定参
ENTRYPOINT ["nginx","-c"]

## 变参
CMD ["ect/nginx/nginx.conf"]

自定义容器

自定义centos容器

示例:构建一个带vim和ifconfig以及java8的centos容器

编写Dockerfile

编写一个Dockerfile(需要先准备一个linux版本的jdk文件)。
示例:

1
$ vim 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
25
26
27
#基于centos7构建
FROM centos:7
MAINTAINER ahzoo<10987@ahzoo.cn>

ENV MYPATH /usr/local
WORKDIR $MYPATH

#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD是相对路径jar,把jdk添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u351-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_351
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 80

CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
构建

格式:docker build -t 新镜像名字:TAG <**上下文路径/网址>**

可以用.表示当前路径

示例:

1
2
3
4
$ docker build -t centosjava8:3.5 .

## 构建完成后可以查看镜像状态
$ docker imags

图片

运行

示例:

1
2
3
4
5
$ docker run -it centosjava8:3.5

## 运行成功后,在容器内部测试vim和ifconfig命令是否正常执行
$ vim ahzoo.txt
$ ifconfig

图片

构建Java项目容器

和构建自定义的centos容器是一样的。
Dockerfile示例:

1
2
3
4
FROM java:8
MAINTAINER ahzoo<10987@ahzoo.cn>
ADD springboot-ahzoo-demo.jar demo.jar
CMD java -jar demo.jar

虚悬镜像

仓库名、标签都是<none>的镜像,俗称虚悬镜像(dangling image)。一般在构建或删除和修改失败时出现,没有任何价值,可以直接删除。

1
2
3
4
5
## 查看虚悬镜像
$ docker image ls -f dangling=true

## 删除虚悬镜像
$ docker image prune

Docker 网络

Compose(容器编排)

Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。

安装DockerCompose

下面示例的为使用二进制包方式安装:

1
2
3
4
5
6
7
8
##安装
$ curl -L https://github.com/docker/compose/releases/download/1.29.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

## 修改权限
$ chmod +x /usr/local/bin/docker-compose

## 查看版本
$ docker-compose --version

设置自动补全命令:

1
2
## 补全命令
$ curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

卸载:

1
2
## 二进制包方式安装的,直接删除文件即可
$ rm /usr/local/bin/docker-compose

使用

docker compose文件常用属性

compose文件语法详情可以参考官方文档

serivces

顶级属性,用于定义一个所有需要运行的服务。
如果用于创建当前服务镜像的Dockerfile文件不是默认名称,则需要 build 下的 context 属性指定Dockerfile 的路径。
示例:

1
2
3
build:
context: ./
dockerfile: myDockerfile
image

用户指定当前服务所需要使用的镜像,这个镜像可以是本地镜像,也可以是远程镜像仓库中的镜像(会自动 pull)。
如果设置了 build,此时再设置的 image 属性即为构建出的镜像的名称与 Tag。

ports

将容器内应用端口绑定到主机端口,若不写映射,则容器启动时会将容器内端口随机绑定到主机端口。可以是配置多个端口映射。

1
2
3
4
ports:
# 前面为主机端口,后面为容器内端口
- 8080:80 # 将容器内80端口绑定到主机的808端口
- 443 # 将容器内443端口绑定到主机的任意端口
volumes

映射容器数据卷,可以配置多个映射。
示例:

1
2
3
4
5
6
db:
image: mariadb:latest
ports:
- "3306:3306"
volumes:
- /etc/mysql:/var/lib/mysql
depends_on

用于指定当前服务的启动所依赖的应用名称。参数可以是多个服务,指定的服务会先于当前服务启动。

command

用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令。如果直接按照 Dockerfile 中的 CMD 指令内容执行即可,则compose 文件中无需该 command 属性。

编写docker compose文件

1
2
## 创建docker-compose.yml文件,并编写
$ vim docker-compose.yml

示例:

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

# services下面编写要启动的服务
services:
# 启动自定义的app项目“myapp”
myapp:
# 通过默认的dockerfile构建,如果不是默认需要使用context指定
# build: ./
image: myapp
# 依赖的服务
depends_on:
- mysql
- myredis
# 端口号
ports:
- "8080"

# 启动nginx
nginx:
# nginx镜像名
image: nginx
# 端口号
ports:
- 80:80
# 当前项目挂载到“myapp”项目上
link:
- myapp
# 挂载路径(路径映射)
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d

# 启动mysql服务
mysql:
# mysql对应的镜像名及其版本
image: mysql:5.7.25
# mysql环境
environment:
MYSQL_ROOT_PASSWORD: ahzoo.cn
# 挂载路径(路径映射),可以挂载多个路径
volumes:
- "/tmp/mysql/data:/var/lib/mysql"
- "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"

# 启动redis
myredis:
image: redis:7.0
port:
-6379:6379
volumes:
- /root/redis/redis.conf:/etc/redis/refis.conf
- /root/redis/data:data
# 服务启动时执行该命令
command: redis-server /etc/redis/redis.conf

以nginx为例:根据文件中的地址路径,创建nginx配置文件

1
2
# -p表示创建父级路径
$ mkdir -p ./nginx/conf.d

在./nginx/conf.d路径下,编写nginx配置文件nginx.conf文件:

1
2
$ cd ./nginx/conf.d
$ vim nginx.conf
1
2
3
4
5
6
7
8
9
server {
listen 80;
access_log off;

# 反向代理,访问80端口时,代理到http://myapp:8080地址
location / {
proxy_pass http://myapp:8080
}
}

注意将 mysql 与 redis 的主机名修改为它们相应服务的名称。
即:

1
2
3
4
5
6
...
url: jdbc:mysql://mysql:3306/ahzoo


redis:
host: myredis

启动docker compose

回到docker-compose.yml的根路径,并启动docker-compose

1
$ docker-compose up

常用命令

  • docker-compose -h # 查看帮助
  • docker-compose up # 启动所有docker-compose服务
  • docker-compose up -d # 启动所有docker-compose服务并后台运行
  • docker-compose down # 停止并删除容器、网络、卷、镜像。
  • docker-compose exec [yml里面的服务id] # 进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
  • docker-compose ps # 展示当前docker-compose编排过的运行的所有容器
  • docker-compose top # 展示当前docker-compose编排过的容器进程
  • docker-compose logs [yml里面的服务id] # 查看容器输出日志
  • docker-compose config # 检查配置
  • docker-compose config -q # 检查配置,有问题才有输出
  • docker-compose restart # 重启服务
  • docker-compose start # 启动服务
  • docker-compose stop # 停止服务