update the gitea_modal_build.py
This commit is contained in:
@@ -22,36 +22,40 @@ 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"
|
||||
|
||||
# Modal secret for ECR credentials
|
||||
ECR_SECRET_NAME = "ecr-credentials"
|
||||
APP_NAME = "msk-lumina-backend-builder"
|
||||
|
||||
# =============================================================================
|
||||
# Modal Image Definition - Kaniko-based builder (no Docker daemon required)
|
||||
# Modal Image Definition
|
||||
# =============================================================================
|
||||
# 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")
|
||||
)
|
||||
|
||||
# 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.
|
||||
# 2. Build your final builder image on a clean Debian system that HAS apt-get
|
||||
builder_image = (
|
||||
modal.Image.debian_slim()
|
||||
.apt_install("curl", "ca-certificates")
|
||||
.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",
|
||||
.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",
|
||||
)
|
||||
)
|
||||
|
||||
@@ -60,15 +64,11 @@ app = modal.App(APP_NAME, image=builder_image)
|
||||
# =============================================================================
|
||||
# Build and Push Function (Kaniko)
|
||||
# =============================================================================
|
||||
|
||||
@app.function(
|
||||
timeout=900, # 15 min for heavy ML deps (torch, transformers, etc.)
|
||||
timeout=900,
|
||||
cpu=4,
|
||||
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
|
||||
],
|
||||
memory=8192,
|
||||
secrets=[modal.Secret.from_name("aws-secrets")],
|
||||
)
|
||||
def build_and_push(
|
||||
registry: str = DEFAULT_REGISTRY,
|
||||
@@ -77,73 +77,71 @@ def build_and_push(
|
||||
push: bool = True,
|
||||
platform: str = "linux/amd64",
|
||||
) -> dict:
|
||||
"""
|
||||
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"----------------------------------------")
|
||||
|
||||
import boto3
|
||||
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 from Modal secret '{ECR_SECRET_NAME}'...")
|
||||
print(f"Configuring ECR authentication...")
|
||||
region = os.getenv("AWS_REGION", "us-east-1")
|
||||
|
||||
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}'"
|
||||
)
|
||||
ecr = boto3.client("ecr", region_name=region)
|
||||
auth = ecr.get_authorization_token()
|
||||
token = auth["authorizationData"][0]["authorizationToken"]
|
||||
username, password = base64.b64decode(token).decode().split(":")
|
||||
|
||||
config = {
|
||||
"auths": {
|
||||
registry: {
|
||||
"username": ecr_username,
|
||||
"password": ecr_password,
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
docker_config_dir = project_root / ".kaniko"
|
||||
docker_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
docker_config_dir = workspace_root / ".kaniko"
|
||||
docker_config_dir.mkdir(exist_ok=True)
|
||||
(docker_config_dir / "config.json").write_text(json.dumps(config))
|
||||
print(f"ECR auth configured for {registry}")
|
||||
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")
|
||||
|
||||
# Build with Kaniko
|
||||
kaniko_cmd = [
|
||||
"/usr/local/bin/kaniko",
|
||||
"--context", str(project_root),
|
||||
"/usr/local/bin/kaniko", # Update this line to match where it was copied
|
||||
"--context", str(workspace_root),
|
||||
"--dockerfile", str(dockerfile_path),
|
||||
"--destination", full_image,
|
||||
"--platform", platform,
|
||||
"--custom-platform", platform,
|
||||
"--verbosity", "info",
|
||||
]
|
||||
|
||||
# Configure the environment variables to include DOCKER_CONFIG if auth exists
|
||||
current_env = os.environ.copy()
|
||||
if docker_config_dir:
|
||||
kaniko_cmd.extend(["--docker-config", str(docker_config_dir)])
|
||||
current_env["DOCKER_CONFIG"] = str(docker_config_dir)
|
||||
|
||||
print(f"Running Kaniko: {' '.join(kaniko_cmd)}")
|
||||
result = subprocess.run(kaniko_cmd, capture_output=True, text=True)
|
||||
|
||||
Reference in New Issue
Block a user