feat: 优化整体镜像表达
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
logs
|
||||
.env
|
||||
.test-case-*.sh
|
||||
__pycache__
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
Reference in New Issue
Block a user