Docker-compose 实现一键编译并运行远程项目
众所周知Docker-compose
是可以直接在编排文件里实现自动构建并运行,无需额外docker buiild
,示例配置如下:
services:
app:
build: .
container_name: myapp
ports:
- "3000:3000"
volumes:
- ./app:/app
restart: always
Docker
会自动构建运行编排项目,并自动寻找Dockerfile
文件并根据文件里构建步骤编译镜像,一般也都会将自己的项目文件COPY
到镜像里构建自己的项目镜像。
此时有个小技巧,只需一个编排文件,无需项目文件也能实现同样的需求.
那就是利用Docker-compose
自带的git clone
拉取代码的特性,实现本地构建远程仓库的项目。
参考编排文件如下:
services:
live:
build: https://cnb.cool/wanfeng789/live.git
container_name: live
ports:
- "1935:1935"
- "80:80"
- "443:443"
restart: always
此配置可以直接构建远程仓库的代码,Docker
会先临时将https://cnb.cool/wanfeng789/live.git
远程仓库git clone
到一个临时目录.
并根据仓库中的Dockerfile
进行编译。然后会自动清理刚刚下载的代码。
这样就很方便编译远程仓库的项目并运行,同时不占用空间。很适合有洁癖的用户。
PS:
cnb.cool/wanfeng789/live
是我写的一个简约个人直播间项目
Docker bake介绍
Docker bake
是Docker
官方在BuildKit
里提供的一个高级构建命令
主要作用是支持多目标、多平台的并行构建,并且可以用一个bake
文件(通常是docker-bake.hcl
或者docker-bake.json
)定义复杂的构建任务
Docker bake
命令
执行docker bake
命令,会自动寻找当前目录的docker-bake.hcl
文件来自动构建
配置文件解释
1:docker-bake.hcl
构建多架构镜像,并且每个架构的镜像分开
# 定义一个构建组,组名叫 default
# 这个组包含两个目标:hello1 和 hello2
group "default" {
targets = ["hello1", "hello2"]
}
# 定义第一个构建目标 hello1
target "hello1" {
context = "." # 构建上下文,当前目录(包含 Dockerfile)
dockerfile = "Dockerfile" # 指定 Dockerfile 文件路径
tags = ["hello/alpine:amd64"]
platforms = ["linux/amd64"] # 构建平台为 linux amd64 架构
}
# 定义第二个构建目标 hello2
target "hello2" {
context = "." # 构建上下文,当前目录(包含 Dockerfile)
dockerfile = "Dockerfile" # 指定 Dockerfile 文件路径
tags = ["hello/alpine:arm64"]
platforms = ["linux/arm64"] # 构建平台为 linux arm64 架构
}
2:docker-bake.hcl
构建完成后自动推送到仓库
需要事先docker login
登录仓库
# 定义构建组 default,只包含一个多平台目标 hello
group "default" {
targets = ["hello"]
}
# 定义多平台构建目标 hello
target "hello" {
context = "." # 构建上下文,当前目录(包含 Dockerfile)
dockerfile = "Dockerfile" # 指定 Dockerfile 文件路径
# 镜像标签,自动推送到远程仓库,记得替换 hello 为你的用户名或仓库名
tags = ["hello/alpine:latest"]
# 同时构建 amd64 和 arm64 多个平台
platforms = ["linux/amd64", "linux/arm64"]
# 开启构建完成后自动推送镜像,需要事先docker login登录仓库
push = true
}
3:docker-bake.hcl
同时构建多个任务,并自动推送到仓库
需要事先docker login
登录仓库
group "default" {
targets = ["php", "nginx"]
}
target "php" {
context = "." # 构建上下文
dockerfile = "Dockerfile.php" # 第一个 Dockerfile
tags = ["hello/alpine:latest"]
platforms = ["linux/amd64", "linux/arm64"]
push = true # 动推送到仓库
}
target "nginx" {
context = "." # 构建上下文
dockerfile = "Dockerfile.nginx" # 第二个 Dockerfile 文件
tags = ["hello/ubuntu:latest"]
platforms = ["linux/amd64", "linux/arm64"]
push = true # 动推送到仓库
}
指定某个任务文件构建
docker bake --file my-bake.hcl
利用Docker bake批量并发拉取镜像
众所周知docker是不支持同时批量并发拉取镜像的.
哪怕你把多个镜像放在docker-compose.yml
编排文件里,他也是一个个拉取,不是批量并发拉取的。
此时可以借助Docker bake
的特性来实现批量并发拉取多个镜像。
Dockerfile
:
ARG BASE_IMAGE=scratch
FROM ${BASE_IMAGE}
docker-bake.hcl
:
group "default" {
targets = ["nginx", "alpine", "redis", "mysql", "caddy", "busybox", "python", "node", "golang", "httpd"]
}
target "nginx" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "nginx:latest" }
tags = ["nginx:latest"]
}
target "alpine" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "alpine:latest" }
tags = ["alpine:latest"]
}
target "redis" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "redis:latest" }
tags = ["redis:latest"]
}
target "mysql" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "mysql:latest" }
tags = ["mysql:latest"]
}
target "caddy" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "caddy:latest" }
tags = ["caddy:latest"]
}
target "busybox" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "busybox:latest" }
tags = ["busybox:latest"]
}
target "python" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "python:3.11-slim" }
tags = ["python:3.11-slim"]
}
target "node" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "node:18-alpine" }
tags = ["node:18-alpine"]
}
target "golang" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "golang:1.21-alpine" }
tags = ["golang:1.21-alpine"]
}
target "httpd" {
context = "."
dockerfile = "Dockerfile"
args = { BASE_IMAGE = "httpd:latest" }
tags = ["httpd:latest"]
}
执行拉取命令
docker buildx bake --load