feat: 优化整体镜像表达

This commit is contained in:
chuan
2026-05-18 00:50:46 +08:00
Unverified
parent 185bad7f53
commit 636f71cacc
7 changed files with 205 additions and 4 deletions
+1
View File
@@ -1,3 +1,4 @@
logs
.env
.test-case-*.sh
__pycache__
+1 -1
View File
@@ -1,3 +1,3 @@
BASE_IMAGE=ubuntu-xray-transparent-test
BASE_IMAGE=docker.pchuan.top/forge/ubuntu:latest
IMAGE=bun-test
BUN_REGISTRY=https://registry.npmmirror.com/
+1 -1
View File
@@ -1,4 +1,4 @@
ARG BASE_IMAGE=ubuntu-xray-transparent-test
ARG BASE_IMAGE=docker.pchuan.top/forge/ubuntu:latest
FROM ${BASE_IMAGE}
ARG BUN_REGISTRY=https://registry.npmmirror.com/
+1 -1
View File
@@ -3,7 +3,7 @@ services:
build:
context: .
args:
BASE_IMAGE: ${BASE_IMAGE:-ubuntu-xray-transparent-test}
BASE_IMAGE: ${BASE_IMAGE:-docker.pchuan.top/forge/ubuntu:latest}
BUN_REGISTRY: ${BUN_REGISTRY:-https://registry.npmmirror.com/}
image: ${IMAGE:-bun-test}
environment:
+1 -1
View File
@@ -24,7 +24,7 @@ RUN set -eux; \
{} +; \
fi; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates curl iptables jq unzip xz-utils; \
apt-get install -y --no-install-recommends ca-certificates curl git iptables jq unzip xz-utils; \
rm -rf /var/lib/apt/lists/*
# Install s6-overlay as PID 1 / service supervisor.
+71
View File
@@ -0,0 +1,71 @@
"""
构建并上传全部 forge 编译环境镜像
默认按依赖顺序构建 ubuntu 和 bun
1. 先构建并上传 docker.pchuan.top/forge/ubuntu:latest
2. 再构建并上传 docker.pchuan.top/forge/bun:latest
3. bun 默认依赖刚上传的 ubuntu 镜像
- --no-push 只构建不上传
- --force-build 使用 docker build --no-cache
- --platform linux/amd64 指定构建平台
"""
import argparse
import subprocess
import sys
from pathlib import Path
# 基础配置
ROOT = Path(__file__).resolve().parents[1]
BUILD_SCRIPT = ROOT / "scripts" / "build.py"
TARGETS = ["ubuntu", "bun"]
parser = argparse.ArgumentParser(description="构建并上传全部 forge 编译环境镜像")
parser.add_argument("--registry", default="docker.pchuan.top", help="镜像仓库地址")
parser.add_argument("--namespace", default="forge", help="镜像命名空间")
parser.add_argument("--tag", default="latest", help="镜像 tag")
parser.add_argument("--no-push", action="store_true", help="只构建不上传")
parser.add_argument("--force-build", action="store_true", help="强制无缓存构建")
parser.add_argument("--platform", default="", help="目标平台,例如 linux/amd64")
parser.add_argument("--bun-registry", default="", help="覆盖 bun 的 npm registry")
args = parser.parse_args()
ubuntu_image = f"{args.registry.rstrip('/')}/{args.namespace.strip('/')}/ubuntu:{args.tag}"
for target in TARGETS:
command = [
sys.executable,
str(BUILD_SCRIPT),
target,
"--registry",
args.registry,
"--namespace",
args.namespace,
"--tag",
args.tag,
]
if args.no_push:
command += ["--no-push"]
if args.force_build:
command += ["--force-build"]
if args.platform:
command += ["--platform", args.platform]
# bun 必须显式依赖本次构建的 ubuntu 镜像地址
if target == "bun":
command += ["--base-image", ubuntu_image]
if args.bun_registry:
command += ["--bun-registry", args.bun_registry]
print(f"[RUN] Build target {target}")
print("[INFO] " + " ".join(command))
subprocess.run(command, cwd=ROOT, check=True)
print(f"[PASS] Build target {target}")
print("[PASS] build all completed")
+129
View File
@@ -0,0 +1,129 @@
"""
构建并上传 forge 编译环境镜像
默认仓库是 docker.pchuan.top/forge
1. 读取目标容器配置
2. 检查目标 Dockerfile
3. 根据目标目录源码时间生成 SOURCE_VERSION
4. 执行 docker build 并打上目标 tag
5. 默认执行 docker push 上传镜像
- target 支持 ubuntu 和 bun
- --no-push 只构建不上传
- --force-build 使用 docker build --no-cache
- --platform linux/amd64 指定构建平台
"""
import argparse
import subprocess
from pathlib import Path
# 基础配置
ROOT = Path(__file__).resolve().parents[1]
REGISTRY = "docker.pchuan.top"
NAMESPACE = "forge"
# 目标容器配置
TARGETS = {
"ubuntu": {
"context": "ubuntu",
"image_name": "ubuntu",
"build_args": {},
},
"bun": {
"context": "bun",
"image_name": "bun",
"build_args": {
"BASE_IMAGE": "docker.pchuan.top/forge/ubuntu:latest",
"BUN_REGISTRY": "https://registry.npmmirror.com/",
},
},
}
parser = argparse.ArgumentParser(description="构建并上传 forge 编译环境镜像")
parser.add_argument("target", choices=TARGETS.keys(), help="目标容器")
parser.add_argument("--registry", default=REGISTRY, help="镜像仓库地址")
parser.add_argument("--namespace", default=NAMESPACE, help="镜像命名空间")
parser.add_argument("--tag", default="latest", help="镜像 tag")
parser.add_argument("--no-push", action="store_true", help="只构建不上传")
parser.add_argument("--force-build", action="store_true", help="强制无缓存构建")
parser.add_argument("--platform", default="", help="目标平台,例如 linux/amd64")
parser.add_argument("--base-image", default="", help="覆盖 bun 的基础镜像")
parser.add_argument("--bun-registry", default="", help="覆盖 bun 的 npm registry")
args = parser.parse_args()
target = TARGETS[args.target]
context = ROOT / target["context"]
dockerfile = context / "Dockerfile"
image = (
f"{args.registry.rstrip('/')}/"
f"{args.namespace.strip('/')}/"
f"{target['image_name']}:{args.tag}"
)
if not dockerfile.exists():
print(f"[NO] {args.target} Dockerfile exists")
print(f"reason: not found: {dockerfile}")
raise SystemExit(1)
# 真实 .env 和 logs 不参与 SOURCE_VERSION
source_files = [
path
for path in context.rglob("*")
if path.is_file()
and path.name != ".env"
and "logs" not in path.relative_to(context).parts
]
source_version = str(max((path.stat().st_mtime_ns for path in source_files), default=0))
build_args = dict(target["build_args"])
build_args["SOURCE_VERSION"] = source_version
if args.target == "bun" and args.base_image:
build_args["BASE_IMAGE"] = args.base_image
if args.target == "bun" and args.bun_registry:
build_args["BUN_REGISTRY"] = args.bun_registry
# 直接使用 Dockerfile 构建,不读取目标目录里的 .env
build_command = [
"docker",
"build",
"--file",
str(dockerfile),
"--tag",
image,
]
for name, value in build_args.items():
build_command += ["--build-arg", f"{name}={value}"]
if args.platform:
build_command += ["--platform", args.platform]
if args.force_build:
build_command += ["--no-cache"]
build_command += [str(context)]
print(f"[INFO] target={args.target}")
print(f"[INFO] image={image}")
print("[RUN] Build image")
print("[INFO] " + " ".join(build_command))
subprocess.run(build_command, cwd=ROOT, check=True)
print("[PASS] Build image")
# 默认上传镜像,使用 --no-push 可以只构建不上传
if not args.no_push:
push_command = ["docker", "push", image]
print("[RUN] Push image")
print("[INFO] " + " ".join(push_command))
subprocess.run(push_command, cwd=ROOT, check=True)
print("[PASS] Push image")
else:
print("[INFO] --no-push, skip docker push")
print("[PASS] build script completed")