Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions catalog/components.yml
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,9 @@ components:
- {id: vercel, name: Vercel, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: railway, name: Railway, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: hf-spaces, name: Hugging Face Spaces, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: modal, name: Modal, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: runpod, name: RunPod, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: bentocloud, name: BentoCloud, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: modal, name: Modal, layer: deploy, tier: platform, python: ">=3.11,<3.15", packages: ["modal>=1.5.3,<2"]}
- {id: runpod, name: RunPod, layer: deploy, tier: platform, python: ">=3.11,<3.15", packages: ["runpod>=1.11.0,<2"]}
- {id: bentocloud, name: BentoCloud, layer: deploy, tier: platform, python: ">=3.11,<3.15", packages: ["bentoml>=1.4.39,<2"]}
- {id: aws-ecs, name: AWS ECS, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: aws-sagemaker, name: AWS SageMaker, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
- {id: cloud-run, name: Google Cloud Run, layer: deploy, tier: platform, python: ">=3.11,<3.15"}
Expand Down
12 changes: 9 additions & 3 deletions catalog/generated/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,9 @@
"python": ">=3.11,<3.15",
"workloads": [],
"roles": [],
"packages": []
"packages": [
"modal>=1.5.3,<2"
]
},
{
"id": "runpod",
Expand All @@ -1487,7 +1489,9 @@
"python": ">=3.11,<3.15",
"workloads": [],
"roles": [],
"packages": []
"packages": [
"runpod>=1.11.0,<2"
]
},
{
"id": "bentocloud",
Expand All @@ -1497,7 +1501,9 @@
"python": ">=3.11,<3.15",
"workloads": [],
"roles": [],
"packages": []
"packages": [
"bentoml>=1.4.39,<2"
]
},
{
"id": "aws-ecs",
Expand Down
14 changes: 12 additions & 2 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,16 @@ deploy_target:
Vertex AI: vertex-ai
Azure Container Apps: azure-container-apps
Azure ML: azure-ml
validator: >-
{% if workload == 'library' and deploy_target != 'none' %}
Libraries are published as packages; choose no deployment target
{% elif deploy_target in ['runpod', 'aws-sagemaker', 'vertex-ai', 'azure-ml'] and workload not in ['inference', 'hybrid'] %}
The selected ML platform requires an inference or hybrid workload
{% elif deploy_target in ['vercel', 'modal'] and workload in ['mcp', 'training'] %}
The selected serverless platform requires an HTTP-oriented workload
{% elif deploy_target == 'vercel' and workload == 'hybrid' %}
Vercel functions are not suitable for a hybrid training workspace
{% endif %}

iac_provider:
type: str
Expand All @@ -505,7 +515,7 @@ iac_provider:
None: none
Pulumi with Python: pulumi
Terraform: terraform
when: "{{ deploy_target not in ['none', 'docker', 'vercel', 'hf-spaces'] }}"
when: "{{ deploy_target in ['aws-ecs', 'aws-sagemaker', 'cloud-run', 'vertex-ai', 'azure-container-apps', 'azure-ml'] }}"

python_version:
type: str
Expand Down Expand Up @@ -565,7 +575,7 @@ publish_to_pypi:
use_docker:
type: bool
help: Include a multi-stage Dockerfile?
default: "{{ workload not in ['library', 'cli'] }}"
default: "{{ deploy_target != 'none' or workload not in ['library', 'cli'] }}"

use_devcontainer:
type: bool
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package = false
dev = [
"copier>=9.17.1",
"pydantic>=2.13.4,<3",
"python-hcl2>=8.1.2,<9",
"pyyaml>=6.0.3,<7",
"pytest>=9.1.1",
"pytest-copie>=0.3.1",
Expand Down
5 changes: 5 additions & 0 deletions scripts/compile_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def build_artifacts(
" + ([sql_abstraction | default('none', true)] if sql_store not in ['none', 'supabase'] else [])",
" + [auth | default('none', true)]",
" + [serving | default('none', true)]",
" + [deploy_target | default('none', true)]",
" + (training_extensions | default([]))",
" + (mlops_tools | default([]))",
" + (quality_tools | default([])) -%}",
Expand All @@ -187,6 +188,10 @@ def build_artifacts(
"{%- if framework == 'pydantic-ai' and pydantic_ai_harness | default([]) %}",
" \"pydantic-ai-harness[{{ pydantic_ai_harness | join(',') }}]>=0.18.0,<0.19\",",
"{%- endif %}",
"{%- if deploy_target | default('none', true) != 'none' and workload not in ['api', 'mcp', 'training'] and 'fastapi' not in interfaces | default([]) %}",
' "fastapi[standard]>=0.141.1,<1",',
' "uvicorn>=0.52.1,<1",',
"{%- endif %}",
"",
]
)
Expand Down
7 changes: 6 additions & 1 deletion template/_catalog_dependencies.jinja
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{# Generated by scripts/compile_catalog.py. Do not edit. #}
{%- set component_packages = {"accelerate": ["accelerate>=1.14.0,<2"], "ag2": ["ag2>=1.0.1,<2"], "agno": ["agno>=2.8.7,<3"], "anthropic": ["anthropic>=0.121.0,<1"], "autogen": ["autogen-agentchat>=0.7.5,<1"], "azure-openai": ["openai>=2.53.0,<3"], "beaver": ["beaver-db>=2.3.0,<3"], "bedrock": ["boto3>=1.43.67,<2"], "bentoml": ["bentoml>=1.4.39,<2"], "celery": ["celery>=5.6.3,<6"], "chainlit": ["chainlit>=2.11.1,<3"], "chroma": ["chromadb>=1.5.9,<2"], "cohere": ["cohere>=7.0.8,<8"], "crewai": ["crewai>=1.15.13,<2"], "dagster": ["dagster>=1.13.17,<2"], "datasets": ["datasets>=5.0.1,<6"], "deepeval": ["deepeval>=4.1.5,<5"], "deepseek": ["openai>=2.53.0,<3"], "dspy": ["dspy>=3.3.0,<4"], "duckdb": ["duckdb>=1.5.5,<2", "duckdb-engine>=0.17.0,<1"], "dvc": ["dvc>=3.67.1,<4"], "evidently": ["evidently>=0.7.21,<1"], "fastapi": ["fastapi[standard]>=0.141.1,<1", "pydantic>=2.13.4,<3", "uvicorn>=0.52.1,<1"], "fasthtml": ["python-fasthtml>=0.14.11,<0.15"], "fastmcp": ["fastmcp>=3.4.6,<4"], "feast": ["feast>=0.65.0,<1"], "fireworks": ["fireworks-ai>=1.2.6,<2"], "flask": ["flask>=3.1.2,<4"], "gemini": ["google-genai>=2.17.0,<3"], "google-adk": ["google-adk>=2.6.3,<3"], "gradio": ["gradio>=6.22.0,<7"], "groq": ["groq>=1.6.0,<2"], "haystack": ["haystack-ai>=3.0.0,<4"], "huggingface": ["huggingface-hub>=1.27.0,<2"], "jax": ["jax>=0.11.0,<0.12"], "jupyterlab": ["jupyterlab>=4.6.2,<5"], "keras": ["keras>=3.15.1,<4", "tensorflow>=2.21.0,<3"], "lancedb": ["lancedb>=0.36.0,<1"], "langchain": ["langchain>=1.3.14,<2"], "langfuse": ["langfuse>=4.14.3,<5"], "langgraph": ["langgraph>=1.2.10,<2"], "langsmith": ["langsmith>=0.10.17,<0.11"], "lightning": ["lightning>=2.6.5,<3"], "lingo": ["lingo-ai>=2.1.0,<3"], "litellm": ["litellm>=1.95.0,<2"], "llamaindex": ["llama-index>=0.14.23,<0.15"], "milvus": ["pymilvus>=3.0.1,<4"], "mistral": ["mistralai>=2.9.1,<3"], "mlflow": ["mlflow>=3.15.1,<4"], "mongodb": ["pymongo>=4.17.0,<5"], "mysql": ["pymysql>=1.2.0,<2"], "neo4j": ["neo4j>=6.2.0,<7"], "nicegui": ["nicegui>=3.15.0,<4"], "oidc": ["authlib>=1.7.2,<2"], "ollama": ["ollama>=0.6.2,<1"], "ollama-serving": ["ollama>=0.6.2,<1"], "openai": ["openai>=2.53.0,<3"], "openai-agents": ["openai-agents>=0.19.4,<1"], "openai-compatible": ["openai>=2.53.0,<3"], "openrouter": ["openrouter>=1.1.37,<2"], "opentelemetry": ["opentelemetry-sdk>=1.44.0,<2"], "optuna": ["optuna>=4.9.0,<5"], "pandera": ["pandera>=0.32.1,<0.33"], "peft": ["peft>=0.20.0,<0.21"], "pgvector": ["pgvector>=0.5.0,<1"], "phoenix": ["arize-phoenix>=19.19.1,<20"], "pinecone": ["pinecone>=9.1.0,<10"], "polars": ["polars>=1.43.2,<2"], "postgresql": ["psycopg[binary]>=3.3.4,<4"], "prefect": ["prefect>=3.8.2,<4"], "pydantic-ai": ["pydantic-ai>=2.27.0,<3"], "pydantic-evals": ["pydantic-evals>=2.27.0,<3"], "pytorch": ["torch>=2.13.0,<3"], "qdrant": ["qdrant-client>=1.19.0,<2"], "ragas": ["ragas>=0.4.3,<0.5"], "ray-serve": ["ray[serve]>=2.56.1,<3"], "redis": ["redis>=8.1.0,<9"], "scikit-learn": ["scikit-learn>=1.9.0,<2"], "sentence-transformers": ["sentence-transformers>=5.7.0,<6"], "smolagents": ["smolagents>=1.26.0,<2"], "sqlalchemy": ["sqlalchemy>=2.0.51,<3", "alembic>=1.19.1,<2"], "sqlmodel": ["sqlmodel>=0.0.39,<0.1", "sqlalchemy>=2.0.51,<3", "alembic>=1.19.1,<2"], "strands-agents": ["strands-agents>=1.51.0,<2"], "streamlit": ["streamlit>=1.61.1,<2"], "supabase": ["supabase>=2.31.0,<3"], "supabase-auth": ["supabase>=2.31.0,<3"], "temporal": ["temporalio>=1.31.0,<2"], "textual": ["textual>=8.2.8,<9"], "together": ["together>=2.30.0,<3"], "transformers": ["transformers>=5.14.1,<6", "torch>=2.13.0,<3"], "trl": ["trl>=1.9.2,<2"], "typer": ["typer>=0.27.1,<1"], "violetear": ["violetear[server]>=1.4.1,<2"], "vllm": ["vllm>=0.26.0,<0.27"], "wandb": ["wandb>=0.28.1,<0.29"], "weaviate": ["weaviate-client>=4.22.0,<5"], "xai": ["xai-sdk>=1.17.0,<2"], "xgboost": ["xgboost>=3.4.0,<4"]} -%}
{%- set component_packages = {"accelerate": ["accelerate>=1.14.0,<2"], "ag2": ["ag2>=1.0.1,<2"], "agno": ["agno>=2.8.7,<3"], "anthropic": ["anthropic>=0.121.0,<1"], "autogen": ["autogen-agentchat>=0.7.5,<1"], "azure-openai": ["openai>=2.53.0,<3"], "beaver": ["beaver-db>=2.3.0,<3"], "bedrock": ["boto3>=1.43.67,<2"], "bentocloud": ["bentoml>=1.4.39,<2"], "bentoml": ["bentoml>=1.4.39,<2"], "celery": ["celery>=5.6.3,<6"], "chainlit": ["chainlit>=2.11.1,<3"], "chroma": ["chromadb>=1.5.9,<2"], "cohere": ["cohere>=7.0.8,<8"], "crewai": ["crewai>=1.15.13,<2"], "dagster": ["dagster>=1.13.17,<2"], "datasets": ["datasets>=5.0.1,<6"], "deepeval": ["deepeval>=4.1.5,<5"], "deepseek": ["openai>=2.53.0,<3"], "dspy": ["dspy>=3.3.0,<4"], "duckdb": ["duckdb>=1.5.5,<2", "duckdb-engine>=0.17.0,<1"], "dvc": ["dvc>=3.67.1,<4"], "evidently": ["evidently>=0.7.21,<1"], "fastapi": ["fastapi[standard]>=0.141.1,<1", "pydantic>=2.13.4,<3", "uvicorn>=0.52.1,<1"], "fasthtml": ["python-fasthtml>=0.14.11,<0.15"], "fastmcp": ["fastmcp>=3.4.6,<4"], "feast": ["feast>=0.65.0,<1"], "fireworks": ["fireworks-ai>=1.2.6,<2"], "flask": ["flask>=3.1.2,<4"], "gemini": ["google-genai>=2.17.0,<3"], "google-adk": ["google-adk>=2.6.3,<3"], "gradio": ["gradio>=6.22.0,<7"], "groq": ["groq>=1.6.0,<2"], "haystack": ["haystack-ai>=3.0.0,<4"], "huggingface": ["huggingface-hub>=1.27.0,<2"], "jax": ["jax>=0.11.0,<0.12"], "jupyterlab": ["jupyterlab>=4.6.2,<5"], "keras": ["keras>=3.15.1,<4", "tensorflow>=2.21.0,<3"], "lancedb": ["lancedb>=0.36.0,<1"], "langchain": ["langchain>=1.3.14,<2"], "langfuse": ["langfuse>=4.14.3,<5"], "langgraph": ["langgraph>=1.2.10,<2"], "langsmith": ["langsmith>=0.10.17,<0.11"], "lightning": ["lightning>=2.6.5,<3"], "lingo": ["lingo-ai>=2.1.0,<3"], "litellm": ["litellm>=1.95.0,<2"], "llamaindex": ["llama-index>=0.14.23,<0.15"], "milvus": ["pymilvus>=3.0.1,<4"], "mistral": ["mistralai>=2.9.1,<3"], "mlflow": ["mlflow>=3.15.1,<4"], "modal": ["modal>=1.5.3,<2"], "mongodb": ["pymongo>=4.17.0,<5"], "mysql": ["pymysql>=1.2.0,<2"], "neo4j": ["neo4j>=6.2.0,<7"], "nicegui": ["nicegui>=3.15.0,<4"], "oidc": ["authlib>=1.7.2,<2"], "ollama": ["ollama>=0.6.2,<1"], "ollama-serving": ["ollama>=0.6.2,<1"], "openai": ["openai>=2.53.0,<3"], "openai-agents": ["openai-agents>=0.19.4,<1"], "openai-compatible": ["openai>=2.53.0,<3"], "openrouter": ["openrouter>=1.1.37,<2"], "opentelemetry": ["opentelemetry-sdk>=1.44.0,<2"], "optuna": ["optuna>=4.9.0,<5"], "pandera": ["pandera>=0.32.1,<0.33"], "peft": ["peft>=0.20.0,<0.21"], "pgvector": ["pgvector>=0.5.0,<1"], "phoenix": ["arize-phoenix>=19.19.1,<20"], "pinecone": ["pinecone>=9.1.0,<10"], "polars": ["polars>=1.43.2,<2"], "postgresql": ["psycopg[binary]>=3.3.4,<4"], "prefect": ["prefect>=3.8.2,<4"], "pydantic-ai": ["pydantic-ai>=2.27.0,<3"], "pydantic-evals": ["pydantic-evals>=2.27.0,<3"], "pytorch": ["torch>=2.13.0,<3"], "qdrant": ["qdrant-client>=1.19.0,<2"], "ragas": ["ragas>=0.4.3,<0.5"], "ray-serve": ["ray[serve]>=2.56.1,<3"], "redis": ["redis>=8.1.0,<9"], "runpod": ["runpod>=1.11.0,<2"], "scikit-learn": ["scikit-learn>=1.9.0,<2"], "sentence-transformers": ["sentence-transformers>=5.7.0,<6"], "smolagents": ["smolagents>=1.26.0,<2"], "sqlalchemy": ["sqlalchemy>=2.0.51,<3", "alembic>=1.19.1,<2"], "sqlmodel": ["sqlmodel>=0.0.39,<0.1", "sqlalchemy>=2.0.51,<3", "alembic>=1.19.1,<2"], "strands-agents": ["strands-agents>=1.51.0,<2"], "streamlit": ["streamlit>=1.61.1,<2"], "supabase": ["supabase>=2.31.0,<3"], "supabase-auth": ["supabase>=2.31.0,<3"], "temporal": ["temporalio>=1.31.0,<2"], "textual": ["textual>=8.2.8,<9"], "together": ["together>=2.30.0,<3"], "transformers": ["transformers>=5.14.1,<6", "torch>=2.13.0,<3"], "trl": ["trl>=1.9.2,<2"], "typer": ["typer>=0.27.1,<1"], "violetear": ["violetear[server]>=1.4.1,<2"], "vllm": ["vllm>=0.26.0,<0.27"], "wandb": ["wandb>=0.28.1,<0.29"], "weaviate": ["weaviate-client>=4.22.0,<5"], "xai": ["xai-sdk>=1.17.0,<2"], "xgboost": ["xgboost>=3.4.0,<4"]} -%}
{%- set selected_components = [framework]
+ (interfaces | default([]))
+ ([model_provider] if ai_capabilities in ['agents', 'rag', 'inference'] else [])
Expand All @@ -8,6 +8,7 @@
+ ([sql_abstraction | default('none', true)] if sql_store not in ['none', 'supabase'] else [])
+ [auth | default('none', true)]
+ [serving | default('none', true)]
+ [deploy_target | default('none', true)]
+ (training_extensions | default([]))
+ (mlops_tools | default([]))
+ (quality_tools | default([])) -%}
Expand All @@ -29,3 +30,7 @@
{%- if framework == 'pydantic-ai' and pydantic_ai_harness | default([]) %}
"pydantic-ai-harness[{{ pydantic_ai_harness | join(',') }}]>=0.18.0,<0.19",
{%- endif %}
{%- if deploy_target | default('none', true) != 'none' and workload not in ['api', 'mcp', 'training'] and 'fastapi' not in interfaces | default([]) %}
"fastapi[standard]>=0.141.1,<1",
"uvicorn>=0.52.1,<1",
{%- endif %}
2 changes: 1 addition & 1 deletion template/readme.md.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ uv run poe --help # list every task
> reaches 1.0, drop `continue-on-error` from the `quality` job in
> `.github/workflows/ci.yml`.

{% if use_docker -%}
{% if use_docker or deploy_target != 'none' -%}
## Docker

```bash
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Portable HTTP entrypoint for the selected deployment target."""

from typing import Any

from fastapi import FastAPI

app = FastAPI(title="{{ project_name }}", version="0.1.0")


@app.get("/health")
async def health() -> dict[str, str]:
"""Report deployment health without loading remote models."""
return {"status": "ok"}


@app.get("/ping")
async def ping() -> dict[str, str]:
"""Implement the health contract used by managed ML endpoints."""
return {"status": "ok"}


@app.post("/predict")
@app.post("/invocations")
async def predict(payload: dict[str, Any]) -> dict[str, Any]:
"""Echo a validated envelope until project-specific inference is connected."""
return {"input": payload, "serving": "{{ serving }}"}


@app.get("/")
async def deployment_info() -> dict[str, str]:
"""Describe the generated stack."""
return {
"project": "{{ project_slug }}",
"workload": "{{ workload }}",
"framework": "{{ framework }}",
"deployment": "{{ deploy_target }}",
}


def main() -> None:
"""Run the portable deployment entrypoint."""
import uvicorn

uvicorn.run(app, host="0.0.0.0", port=8000)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""BentoCloud service adapter."""

import bentoml


@bentoml.service
class ProjectService:
"""Minimal online service ready for model loading at startup."""

@bentoml.api
def health(self) -> dict[str, str]:
return {"status": "ok", "project": "{{ project_slug }}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Modal deployment adapter."""

import modal

{% if workload == 'api' -%}
from {{ module_name }}.api import app as web_app
{%- elif 'fastapi' in interfaces | default([]) -%}
from {{ module_name }}.interfaces.fastapi_app import app as web_app
{%- else -%}
from {{ module_name }}.deployment import app as web_app
{%- endif %}

app = modal.App("{{ project_slug }}")


@app.function()
@modal.asgi_app()
def asgi_app(): # type: ignore[no-untyped-def]
"""Expose the generated ASGI app through Modal."""
return web_app
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""RunPod Serverless worker implementation."""

from typing import Any

import runpod


def handler(job: dict[str, Any]) -> dict[str, Any]:
"""Return a deterministic envelope ready for model inference code."""
return {
"input": job.get("input", {}),
"project": "{{ project_slug }}",
"serving": "{{ serving }}",
}


RUNPOD_START = runpod.serverless.start
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Platform-specific deployment adapters."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from fastapi.testclient import TestClient

from {{ module_name }}.deployment import app


def test_deployment_health() -> None:
response = TestClient(app).get("/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}

prediction = TestClient(app).post("/predict", json={"value": 42})
assert prediction.status_code == 200
assert prediction.json()["input"] == {"value": 42}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Deployment: {{ deploy_target }}

The checked-in `Dockerfile` is the portable deployment contract. Build and
exercise it locally before publishing it to a registry:

```bash
docker build -t {{ project_slug }} .
docker run --rm -p 8000:8000 {{ project_slug }}
```

Keep credentials out of images and configuration files. Configure the values
documented in `.env.example` through the target platform's secret manager.

{% if deploy_target == 'docker' -%}
Start the local service with `docker compose up --build`.
{%- elif deploy_target == 'render' -%}
Create a Blueprint from this GitHub repository; Render discovers `render.yaml`
and builds the root Dockerfile.
{%- elif deploy_target == 'fly' -%}
Run `fly launch --copy-config --no-deploy`, review `fly.toml`, set secrets with
`fly secrets set`, then run `fly deploy`.
{%- elif deploy_target == 'vercel' -%}
Run `vercel link` once and `vercel deploy`; `api/index.py` exports the Python
WSGI/ASGI application and `vercel.json` routes requests to it.
{%- elif deploy_target == 'railway' -%}
Create a service from the GitHub repository. Railway discovers `railway.toml`
and the Dockerfile; configure variables in the service environment.
{%- elif deploy_target == 'hf-spaces' -%}
Push the repository to a Hugging Face Space. The uppercase `README.md` contains
the required Docker Space metadata; development docs remain in `readme.md`.
{%- elif deploy_target == 'modal' -%}
Authenticate with `modal setup`, then run `modal deploy deploy/modal_app.py`.
{%- elif deploy_target == 'runpod' -%}
Build and push the image, create a Serverless endpoint from it, and set the
container command to `python handler.py`.
{%- elif deploy_target == 'bentocloud' -%}
Run `bentoml build`, test the resulting Bento, then run `bentoml deploy`.
{%- elif deploy_target == 'cloud-run' -%}
Replace `IMAGE_URI` in `service.yaml`, then run
`gcloud run services replace service.yaml`.
{%- elif deploy_target == 'aws-ecs' -%}
Push the image to ECR, replace placeholders in `deploy/task-definition.json`,
register it with `aws ecs register-task-definition`, then update your service.
{%- elif deploy_target == 'aws-sagemaker' -%}
Push an inference image to ECR, replace placeholders in
`deploy/sagemaker-model.json`, and create the model and endpoint resources.
{%- elif deploy_target == 'vertex-ai' -%}
Push the image to Artifact Registry, replace `IMAGE_URI` in
`deploy/vertex-model.json`, upload the model, and deploy it to an endpoint.
{%- elif deploy_target == 'azure-container-apps' -%}
Push the image to ACR, replace placeholders in `deploy/container-app.yaml`, and
run `az containerapp create --yaml deploy/container-app.yaml`.
{%- elif deploy_target == 'azure-ml' -%}
Replace the model/image placeholders, create `deploy/endpoint.yml`, then create
`deploy/deployment.yml` with the Azure ML CLI v2.
{%- endif %}

{% if iac_provider != 'none' -%}
The selected `{{ iac_provider }}` project lives under `infra/{{ iac_provider }}`.
Its configuration intentionally requires registry images, roles, networks and
regions as inputs instead of creating broad privileged infrastructure silently.
{%- endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"family": "{{ project_slug }}",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "EXECUTION_ROLE_ARN",
"containerDefinitions": [
{
"name": "app",
"image": "IMAGE_URI",
"essential": true,
"portMappings": [{"containerPort": 8000, "protocol": "tcp"}]
}
]
}
Loading
Loading