1192 字
6 分钟
你绝对不知道的Docker高级实用技巧
2025-08-12

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 bakeDocker官方在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
你绝对不知道的Docker高级实用技巧
https://emohe.cn/posts/32/
作者
阿涛の小破站
发布于
2025-08-12
许可协议
CC BY-NC-SA 4.0