总结这几天使用Dockerfile和docker-Compose的经验

dockerfile

基本知识点

  • 镜像的构建步骤按照dockerfile里的指令顺序来构建。
  • docker镜像是分层的,通过dockerfile构建镜像时,每一句指令就是一层,每执行一句就填加一层,最底层则是基础镜像,即from指令所指定的镜像。
  • docker的容器=docker镜像+读写层。
  • 构建过程中的删除操作只在所在的指令语句的那一层中起作用,并影响后续的层,但该删除操作的目标文件在整个镜像中并未被删除,因为在删除指令之前的层中目标文件仍会存在。
  • 形象的形容镜像的构建,构建镜像其实就像是堆叠衣服或者是砌砖木,都是一层一层地往上叠。
  • docker的规范规定,dockerfile的文件名必须是dockerfile,但dockerfile这两个单词的首字母不区分大小写。
  • 镜像名称的表现形式有两种:一种是只有镜像名称——image[:tag],在该情况下代表着如果本地不存在该名称的镜像的话,docker会从docker hub查询并下载;另一种是IP+镜像名(ip[:port][/folder]/image[:port])或域名+镜像名(domain[:port][/folder]/image[:port]),在该情况下代表着如果本地不存在指定的镜像的话将会从指定的网络资源地址上下载对应的镜像,而且如果下载的镜像如果是私有镜像的话还需要先在终端执行docker login ip[:port]docker login domain登录后才可以下载。

指令关键字的作用

  • FROM:该关键字所在的指令必须要放在dockerfile文件的第一行,用于指定dockerfile所构建的镜像的基础镜像是什么,该关键字后接镜像名称作为值
  • RUN:该关键字表示在构建过程中需要执行的bash命令。如 RUN: uname -a
  • LABEL:用于自定义镜像的元数据,如LABEL author="AlexC"定义了改镜像的作者是我
  • ARG:定义了构建镜像时的环境变量。如ARG a=1,那么如果我在后面的指令中有用到变量a的值的地方的话,我只需要使用美元符+变量名,即$a就可以了
  • COPY:用于复制外部文件进镜像。对外部文件支持相对路径和绝对路径。使用格式为COPY {file or folder url} {path url}

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
# 本镜像的基础镜像
FROM tomcat:8-slim
# 记录作者到镜像的元数据
LABEL maintainer="alex.chen@astasys.com"
# 设置工作目录
WORKDIR /root
# 定义构建变量,以下变量只在构建镜像过程中起作用,不会写入到镜像中的操作系统里
ARG tomcat="/usr/local/tomcat"
ARG web="${tomcat}/webapps"
ARG log="${tomcat}/logs"
ARG workspace="/home/ProjectWorkspace"
# 表示以root用户操作镜像内的系统
USER root

# 执行更新系统的操作
RUN apt update -y \
&& apt upgrade -y

# 安装软件
RUN apt install -y imagemagick

RUN rm -rf ${web}/*

# 复制与dockerfile文件在同一目录下的一个叫index.html的文件到镜像内的root目录下
COPY index.html /root/
RUN mkdir ${web}/ROOT \
&& unzip /root/dms2.0.war -d ${web}/ROOT/

docker-compose

基本知识点

  • docker-compose是一个docker镜像编排工具,其配置文件名称为docker-compose.yml,docker-compose将会根据该配置文件里的设置构建出单个或多个docker容器以及其他和容器相关的东西
  • docker-compose一般来说在安装docker的时候也会一同安装到本机上,不过我公司的电脑上安装的docker for Mac并没有附带docker-compose,需要我另外安装。

根属性

​ 用过yaml做配置文件的应该都知道yml文件的写法其实和json的格式是类似的,都是键值对。在docker-compose的配置文件里有两大根配置是必要的,他们分别是serviceVERSION

  • VERSION:该属性的用法是用于指定docker-compose在根据配置文件执行时编排操作时使用的API版本,现在最新版是3,所以一般来说该标签的写法都是VERSION: "3"
  • services:可能对于docker来说,一个容器相当于一个服务,所以在services下的都是服务节点。每一个容器节点都需要指定一个容器所基于的镜像。
  • NETWORK:表示网段,其下的节点表示不同的隔离网络,每个网络可以使用driver属性定义网络的连接模式。模式有三种,分别是桥接模式bridge、宿主模式host和容器模式container [container name]
  • VOLUMES:表示数据卷,其下不同节点表示不同的数据卷。当声明一个空数据卷时(即只有一个数据卷名字且不存在任何属性),该数据卷会根据docker自身的缺省值在/var/lib/docker/volumes/{hash值}/_data里存放被挂载映射的数据。

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
# 声明docker-compose执行编排是使用的api版本
version: '3'

networks:
# 声明了一个名字叫app的隔离网络,该网络的连接模式为桥接模式
app:
driver: bridge

volumes:
# 声明了一个名字叫db的数据卷,且不做设置,即一切设置都是用dock的缺省值
db:
services:
# 定义了一个,名字叫mysql的服务
mysql:
# 声明该服务所使用的镜像是来自于docker hub的mysql:latest镜像
image: mysql
# 声明本次启动的基于mysql:latest镜像的容器的名字为mysql
container_name: mysql
# 为容器提权,避免容器在启动时遇到权限不足导致启动失败的情况
privileged: true
# 表示该容器会随着宿主机的重启而重启
restart: always
# 表示对外暴露的端口,这里是要将镜像内的3306端口映射到宿主机的3306端口,冒号左边是宿主机的端口,右边是镜像内的端口
ports:
- "3306:3306"
# 这里表示本容器的网络放在名字为app的独立网络里
networks:
- app
# 这里表示向存在相同隔离网络内的其他容器暴露3306端口,其他容器可以通过3306端口访问本容器内3306端口
expose:
- "3306"
# 这里表示将容器内的/var/lib/mysql目录下的所有文件挂在到名为db的数据卷里
volumes:
- "db:/var/lib/mysql"
# 这里表示本服务依赖于一个叫abc的服务。在docker-compose中,服务的启动顺序是一个服务被越多的其它服务依赖,那么这个服务的启动优先度越高,但docker-compose的启动并不会等待当前服务启动完毕才会启动下一个服务,而是只是排好启动顺序后按顺序发送启动指令,所以当一个叫“甲”的服务启动时间长而未启动完成时,依赖于“甲”的服务“乙”需要调用“甲”时,“乙就会报错”。所以注意这一点。
depend_on:
- "abc"
AlexC wechat
博客与公众号同步发文,欢迎关注
感谢你的支持