# Compose规范 - Build
[TOC]
*注意:*Build是Compose规范的可选部分
## 介绍
Compose规范是定义多容器应用程序的一种与平台无关的方法。专注于开发用例以在本地计算机上运行应用程序的Compose实现显然也将支持(重新)从源代码构建应用程序。Compose Build规范允许以可移植的方式在Compose文件中定义构建过程。
## 定义
扩展了Compose Specification,以支持`build`关于服务的OPTIONAL小节。本部分定义了服务容器映像的构建要求。只有Compose文件服务的一个子集可以定义这样的Build子节,其他子集是基于`Image`属性创建的。当服务的构建子节存在时,对于Compose文件而言,错过相应服务的属性是*有效*的`Image`,因为Compose实现可以从源代码构建映像。
构建可以指定为定义上下文路径的单个字符串,也可以指定为详细的构建定义。
在前一种情况下,整个路径都用作Docker上下文来执行Docker构建,`Dockerfile`并在上下文根中查找规范。上下文路径可以是绝对路径,也可以是相对路径,如果是这样,则必须从Compose文件父文件夹解析相对路径。作为防止Compose文件可移植的绝对路径,Compose实现应相应警告用户。
在后一种情况下,可以指定build参数,包括备用`Dockerfile`位置。此路径可以是绝对路径,也可以是相对路径。如果Dockerfile路径是相对路径,则必须从上下文路径解析它。作为绝对路径,防止Compose文件可移植,如果使用绝对替代Dockerfile路径,则Compose实现应警告用户。
## 镜像一致性
当服务定义同时包含`Image`属性和`Build`部分时,Compose实现不能保证提取的镜像严格等同于从源构建相同的镜像。如果没有任何明确的用户指令,带有Build支持的Compose实现必须首先尝试拉取Image,然后在注册表中未找到Image的情况下从源代码进行构建。Compose实现可以提供选项,以根据用户请求自定义此行为。
## 发布构建的镜像
具有构建支持的组合实现应提供一个选项,可将构建的映像推送到注册表。这样做,它一定不要尝试在没有`Image`属性的情况下推送服务映像。Compose实现应向用户发出有关`Image`属性缺失的警告,以防止镜像被推送。
`Image`如果未在yaml文件中明确声明,则撰写实现可以提供一种计算服务属性的机制。在这种情况下,`Image`只要实际的原始yaml文件未显式声明一个有效的属性,就认为所得的Compose配置具有有效的属性。
## 说明性的例子
下面的示例通过一个具体的示例应用程序说明了Compose规范概念。该样本是非规范性的
~~~yaml
services:
frontend:
image: awesome/webapp
build: ./webapp
backend:
image: awesome/database
build:
context: backend
dockerfile: ../backend.Dockerfile
custom:
build: ~/custom
~~~
当用于从源代码构建服务映像时,这样的Compose文件将创建三个docker映像:
* `awesome/webapp`docker映像是使用`webapp`Compose文件父文件夹中的子目录作为docker build上下文构建的。`Dockerfile`此文件夹中缺少会引发错误。
* `awesome/database`使用`backend`Compose文件父文件夹中的子目录构建docker映像。`backend.Dockerfile`文件用于定义构建步骤,相对于上下文路径搜索此文件,这意味着此示例`..`将解析为Compose文件的父文件夹,而`backend.Dockerfile`同级文件也将解析为。
* 使用`custom`用户主目录中的目录作为docker上下文构建docker映像。Compose实现会警告用户有关用于构建映像的非便携式路径。
在推送时,`awesome/webapp`和`awesome/database`docker镜像都被推送到(默认)注册表。`custom`由于未`Image`设置任何属性,因此会跳过服务映像,并警告用户有关此丢失的属性。
## Build定义
The`build`element define configuration options that are applied by Compose implementations to build Docker image from source.`build`can be specified either as a string containing a path to the build context or a detailed structure:
`build`元件定义由Compose实现施加到从源代码编译映像配置选项。`build`可以指定为包含构建上下文路径的字符串或详细结构:
~~~yaml
services:
webapp:
build: ./dir
~~~
使用此字符串语法,只能将构建上下文配置为Compose文件的父文件夹的相对路径。此路径必须是目录,并包含一个`Dockerfile`。
另外,`build`也可以是一个对象,其字段定义如下
### context (必须)
`context`定义包含Dockerfile的目录的路径或git存储库的URL。
如果提供的值是相对路径,则必须将其解释为相对于Compose文件的位置。撰写实现必须警告用户有关用于定义构建上下文的绝对路径,因为它们会阻止撰写文件可移植。
~~~yaml
build:
context: ./dir
~~~
### dockerfile
`dockerfile`允许设置备用Dockerfile。必须从构建上下文中解析相对路径。Compose的实现必须警告用户有关用于定义Dockerfile的绝对路径,因为这些绝对路径会阻止Compose的文件可移植。
~~~yaml
build:
context: .
dockerfile: webapp.Dockerfile
~~~
### args
`args`定义构建参数,即Dockerfile`ARG`值。
使用以下Dockerfile:
~~~dockerfile
ARG GIT_COMMIT
RUN echo "Based on commit: $GIT_COMMIT"
~~~
`args`可以在Compose文件中的`build`定义键下设置`GIT_COMMIT`。`args`可以设置映射或列表:
~~~yaml
build:
context: .
args:
GIT_COMMIT: cdc3b19
~~~
~~~yaml
build:
context: .
args:
- GIT_COMMIT=cdc3b19
~~~
在指定构建参数时可以省略值,在这种情况下,必须在构建时通过用户交互获取其值,否则在构建Docker映像时将不会设置build arg。
~~~yaml
args:
- GIT_COMMIT
~~~
### cache_from
`cache_from`定义图像构建器应用于缓存解析的图像列表。
~~~yaml
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
~~~
### extra_hosts
`extra_hosts`在构建时添加主机名映射。使用与[extra_hosts](spec.md)相同的语法。
~~~yaml
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
~~~
Compose实现必须在容器的网络配置中创建具有IP地址和主机名的匹配条目,这意味着对于Linux,这`/etc/hosts`将获得额外的内容:
~~~
162.242.195.82 somehost
50.31.209.229 otherhost
~~~
### isolation
`isolation`指定构建的容器隔离技术。像[隔离](spec.md)(isolation)一样,受支持的值是特定于平台的。
### labels
`labels`将元数据添加到生成的图像。`labels`可以设置为数组或映射。
反向DNS表示法应用于防止标签与其他软件使用的标签冲突。
~~~yaml
build:
context: .
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
~~~
~~~yaml
build:
context: .
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
~~~
### shm_size
`shm_size`设置`/dev/shm`为构建Docker映像分配的共享内存(Linux上的分区)的大小。指定为表示字节数的整数值或表示[字节值](spec.md)(specifying-byte-values)的字符串。
~~~yaml
build:
context: .
shm_size: '2gb'
~~~
~~~yaml
build:
context: .
shm_size: 10000000
~~~
### target
`target`定义要在multi-stage中定义的构建阶段`Dockerfile`。
~~~yaml
build:
context: .
target: prod
~~~
## 实作
* [docker-compose](https://docs.docker.com/compose)
* [buildX bake](https://docs.docker.com/buildx/working-with-buildx/)