update the gitea_modal_build.py
Some checks failed
Backend EC - Modal Deployment / build-and-push (push) Failing after 34s
Backend EC - Modal Deployment / notify-deploy (push) Has been skipped

This commit is contained in:
DatTT127
2026-07-19 00:21:41 +07:00
parent 2df016dce2
commit 7c63561dac

View File

@@ -22,40 +22,36 @@ import json
import os
from pathlib import Path
import subprocess
import modal
# =============================================================================
# Configuration
# =============================================================================
APP_NAME = "msk-lumina-backend-builder"
# Default registry/image settings
DEFAULT_REGISTRY = "public.ecr.aws/i9a4e3f6/msk-cv-inference-server"
DEFAULT_IMAGE_NAME = "msk-lumina-backend"
DEFAULT_TAG = "latest"
APP_NAME = "msk-lumina-backend-builder"
# Modal secret for ECR credentials
ECR_SECRET_NAME = "ecr-credentials"
# =============================================================================
# Modal Image Definition
# Modal Image Definition - Kaniko-based builder (no Docker daemon required)
# =============================================================================
# 1. Start from Kaniko to extract the binary, and map it to a local folder via an App build
kaniko_image = (
modal.Image.from_registry("gcr.io/kaniko-project/executor:debug")
.add_local_dir(os.getcwd(), remote_path="/workspace")
)
# 2. Build your final builder image on a clean Debian system that HAS apt-get
# We bake the project source into the image at /workspace so Kaniko can access
# the build context and Dockerfile at runtime.
# The Dockerfile path is resolved at runtime, not at image build time.
builder_image = (
modal.Image.debian_slim()
.apt_install("curl", "ca-certificates")
.pip_install("boto3")
# Use standard dockerfile_commands to copy the binary directly from the Kaniko base image layer
.dockerfile_commands(
[
"COPY --from=gcr.io/kaniko-project/executor:debug /kaniko/executor /usr/local/bin/kaniko"
]
)
.add_local_dir(
os.getcwd(),
remote_path="/workspace",
.run_commands(
"curl -sSL https://github.com/chainguard-forks/kaniko/releases/latest/download/kaniko-linux-amd64 -o /usr/local/bin/kaniko",
"chmod +x /usr/local/bin/kaniko",
)
)
@@ -64,11 +60,15 @@ app = modal.App(APP_NAME, image=builder_image)
# =============================================================================
# Build and Push Function (Kaniko)
# =============================================================================
@app.function(
timeout=900,
timeout=900, # 15 min for heavy ML deps (torch, transformers, etc.)
cpu=4,
memory=8192,
secrets=[modal.Secret.from_name("aws-secrets")],
memory=8192, # 8GB RAM - plenty for wheel building
secrets=[
modal.Secret.from_name("aws-secrets"), # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
modal.Secret.from_name(ECR_SECRET_NAME), # ECR_USERNAME, ECR_PASSWORD
],
)
def build_and_push(
registry: str = DEFAULT_REGISTRY,
@@ -77,71 +77,73 @@ def build_and_push(
push: bool = True,
platform: str = "linux/amd64",
) -> dict:
import boto3
"""
Build the backend Docker image with Kaniko and push to registry.
Args:
registry: Container registry hostname (e.g., public.ecr.aws/vkist-project)
image_name: Image name (e.g., vkist-backend)
tag: Image tag (e.g., v1.2.3, latest, git-sha)
push: Whether to push to registry
platform: Target platform (linux/amd64, linux/arm64)
Returns:
Dict with image reference and build status
"""
# Resolve paths at runtime inside Modal.
# The project files are baked into /workspace by the Modal image definition.
workspace = Path("/workspace")
project_root = workspace if (workspace / "backend").exists() else workspace
dockerfile_path = workspace / "deps" / "implementation" / "backend_deploy" / "Dockerfile"
print(f"--- Runtime Path Verification ---")
print(f"Workspace: {workspace} (Exists: {workspace.exists()})")
print(f"PROJECT_ROOT: {project_root} (Exists: {project_root.exists()})")
print(f"DOCKERFILE_PATH: {dockerfile_path} (Exists: {dockerfile_path.exists()})")
print(f"----------------------------------------")
full_image = f"{registry}/{image_name}:{tag}"
print(f"Building {full_image} for {platform}")
# Explicitly use the inside-container paths
workspace_root = Path("/workspace")
# Adjust this path if your Dockerfile lives in a specific subdirectory inside your workspace
dockerfile_path = workspace_root / "Dockerfile"
# Prepare docker config for Kaniko if pushing to ECR
docker_config_dir = None
if push and ("ecr.aws" in registry or "ecr." in registry):
print(f"Configuring ECR authentication...")
region = os.getenv("AWS_REGION", "us-east-1")
print(f"Configuring ECR authentication from Modal secret '{ECR_SECRET_NAME}'...")
ecr = boto3.client("ecr", region_name=region)
auth = ecr.get_authorization_token()
token = auth["authorizationData"][0]["authorizationToken"]
username, password = base64.b64decode(token).decode().split(":")
ecr_username = os.getenv("ECR_USERNAME")
ecr_password = os.getenv("ECR_PASSWORD")
if not ecr_username or not ecr_password:
raise RuntimeError(
f"ECR_USERNAME and ECR_PASSWORD must be set in Modal secret '{ECR_SECRET_NAME}'"
)
config = {
"auths": {
registry: {
"username": username,
"password": password,
"username": ecr_username,
"password": ecr_password,
}
}
}
docker_config_dir = workspace_root / ".kaniko"
docker_config_dir.mkdir(exist_ok=True)
docker_config_dir = project_root / ".kaniko"
docker_config_dir.mkdir(parents=True, exist_ok=True)
(docker_config_dir / "config.json").write_text(json.dumps(config))
print(f"ECR auth configured for {registry}")
# # --- INSPECT MODAL WORKSPACE DIRECTORIES HERE --- Success
# print("\n=== DEBUG: Inspecting Modal Container Filesystem ===")
# try:
# # 1. Print the contents of the /workspace root directory
# print(f"Contents of {workspace_root}:")
# workspace_files = subprocess.run(["ls", "-la", str(workspace_root)], capture_output=True, text=True)
# print(workspace_files.stdout)
# # 2. Verify exactly where the copied Kaniko binary lives
# print("Checking for Kaniko binary location:")
# # kaniko_check = subprocess.run(["ls", "-la", "/usr/local/bin/kaniko"], capture_output=True, text=True)
# # print(kaniko_check.stdout if kaniko_check.returncode == 0 else "❌ Kaniko not found in /usr/local/bin/kaniko\n")
# # except Exception as e:
# # print(f"Failed to run inspection: {e}")
# # print("==================================================\n")
print(f"ECR auth configured for {registry}")
# Build with Kaniko
kaniko_cmd = [
"/usr/local/bin/kaniko", # Update this line to match where it was copied
"--context", str(workspace_root),
"/usr/local/bin/kaniko",
"--context", str(project_root),
"--dockerfile", str(dockerfile_path),
"--destination", full_image,
"--custom-platform", platform,
"--platform", platform,
"--verbosity", "info",
]
# Configure the environment variables to include DOCKER_CONFIG if auth exists
current_env = os.environ.copy()
if docker_config_dir:
current_env["DOCKER_CONFIG"] = str(docker_config_dir)
kaniko_cmd.extend(["--docker-config", str(docker_config_dir)])
print(f"Running Kaniko: {' '.join(kaniko_cmd)}")
result = subprocess.run(kaniko_cmd, capture_output=True, text=True)