Preparación de imágenes de contenedor
Preparar, crear y transferir una imagen de contenedor de agente para despliegues alojados.
Utilice las directrices de este tema para preparar imágenes de Docker.
Arquitectura de imagen de contenedor soportada
Para las imágenes, el servicio de IA generativa admite la arquitectura x86 de 64 bits, nombre de código amd64. Al crear imágenes de contenedor, utilice linux/amd64 como tipo de plataforma.
Por ejemplo,
docker buildx build --platform linux/amd64 -t myimage:latestPreparación de código
El contenedor de Docker debe cumplir los siguientes requisitos para ejecutarse en el entorno de despliegue alojado.
- Host y puerto
-
- El contenedor debe recibir en el host
0.0.0.0. - El contenedor debe recibir en el puerto
8080.
- El contenedor debe recibir en el host
- Tipo contenido respuesta HTTP
-
El contenedor debe exponer un servicio basado en HTTP que implante puntos finales de solicitud y respuesta de estilo REST mediante métodos como GET, PUT, POST, DELETE y PATCH con rutas definidas por el usuario.
La plataforma determina si una solicitud espera una respuesta de transmisión inspeccionando la cabecera Accept.
- Si la cabecera Accept incluye texto/flujo de eventos, el punto final debe devolver una respuesta de eventos enviados por el servidor (SSE) con el tipo de contenido texto/flujo de eventos.
- De lo contrario, el punto final debe devolver una respuesta JSON estándar con el tipo de contenido application/json.
Esta configuración admite un punto final para interacciones de flujo y no de flujo de forma coherente y compatible con versiones anteriores.
- Punto final de preparación
-
El contenedor de Docker debe exponer un punto final de preparación para verificar que la aplicación esté completamente inicializada y lista para manejar solicitudes.
- Ruta de acceso:
/ready - Propósito: indica si el contenedor está listo para recibir tráfico
- Formato de respuesta: solo código de estado HTTP
- Tipo de contenido:
application/json - Código de estado correcto:
200 OK(la aplicación está lista)
- Ruta de acceso:
- Punto final de vida
-
El contenedor de Docker debe exponer un punto final activo para verificar que la aplicación se está ejecutando correctamente y no necesita reiniciar.
- Ruta de acceso:
/health - Propósito: detecta si el contenedor está activo y en funcionamiento
- Formato de respuesta: solo código de estado HTTP
- Tipo de contenido:
application/json - Código de estado correcto:
200 OK(la aplicación está en buen estado)
- Ruta de acceso:
- Arquitectura de imagen
-
El servicio admite
amd64.Nota
Le recomendamos que utilice imágenes base proporcionadas por Oracle Container Registry. Las imágenes de ese sitio pasan el análisis de vulnerabilidades. - Variables de entorno reservadas
-
Las siguientes variables de entorno están reservadas para uso del sistema. No los defina en el código de contenedor:
PORT
K_SERVICE
K_CONFIGURATION
K_REVISION
OCI_RESOURCE_PRINCIPAL_VERSION
OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM
OCI_RESOURCE_PRINCIPAL_RPST
KUBERNETES_*
Arquitectura de imagen
La imagen se debe crear para la plataforma linux/amd64, como se muestra en el siguiente ejemplo.
Acceso a archivos
El sistema de archivos de contenedor es de solo lectura, excepto para el directorio /tmp, en el que se puede escribir. Si la aplicación necesita escribir archivos localmente, escríbalos a /tmp.
Análisis de vulnerabilidades
Antes del despliegue, la imagen se explora mediante el servicio de análisis de vulnerabilidades de OCI. El despliegue falla si se detectan vulnerabilidades críticas.
Oracle recomienda utilizar imágenes base de OCI Container Registry:
https://container-registry.oracle.com/, donde las imágenes ya han pasado el análisis de vulnerabilidades.
Otras restricciones
- Los comandos de punto de entrada personalizados no están soportados. Defina el comando de entrada en Dockerfile mediante CMD o ENTRYPOINT.
- No se admite la asignación de volumen. Los contenedores no deben tener estado porque los datos del archivo local no se conservan durante el nuevo despliegue o la sustitución de nodos.
Código de ejemplo
En el siguiente ejemplo se muestra un agente simple desarrollado en LangGraph y envuelto con FastAPI.
from contextlib import asynccontextmanager
import os
import sys
from typing import Any, Dict
from dotenv import load_dotenv
from fastapi import FastAPI
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
from langgraph.prebuilt import create_react_agent
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
TEMPERATURE = float(os.getenv("OPENAI_TEMPERATURE", "0.7"))
OPENAI_MOCK_MODE_ENV = os.getenv("OPENAI_MOCK_MODE")
if OPENAI_MOCK_MODE_ENV is None:
OPENAI_MOCK_MODE = not bool(OPENAI_API_KEY)
else:
OPENAI_MOCK_MODE = OPENAI_MOCK_MODE_ENV.strip().lower() in (
"1",
"true",
"yes",
"on",
)
app_graph = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global app_graph
if OPENAI_MOCK_MODE and not OPENAI_API_KEY:
print(
"OPENAI_API_KEY is not set; running in OPENAI_MOCK_MODE.",
file=sys.stderr,
)
yield
return
if not OPENAI_API_KEY:
raise RuntimeError("OPENAI_API_KEY is not set in environment.")
model = ChatOpenAI(
model=OPENAI_MODEL,
temperature=TEMPERATURE,
api_key=OPENAI_API_KEY,
streaming=True,
)
app_graph = create_react_agent(
model=model,
tools=[],
checkpointer=MemorySaver(),
)
yield
app = FastAPI(lifespan=lifespan)
@app.post("/chat")
async def chat(body: Dict[str, Any]):
thread_id = body["thread_id"]
msg = body["message"]
if OPENAI_MOCK_MODE and not OPENAI_API_KEY:
return {
"reply": f"[MOCK] OPENAI_API_KEY missing. Echo: {msg}",
"thread_id": thread_id,
}
response = await app_graph.ainvoke(
{"messages": [HumanMessage(content=msg)]},
config={"configurable": {"thread_id": thread_id}},
)
if "messages" in response and response["messages"]:
last_message = response["messages"][-1]
ai_content = getattr(last_message, "content", str(last_message))
else:
ai_content = "I'm not sure how to respond to that."
return {"reply": ai_content}
@app.get("/health")
async def health():
return {
"status": "Healthy",
"mode": "mock" if (OPENAI_MOCK_MODE and not OPENAI_API_KEY) else "normal",
}
@app.get("/ready")
async def ready():
if OPENAI_MOCK_MODE and not OPENAI_API_KEY:
return {"status": "Ready", "mode": "mock"}
return {"status": "Ready"}
Estructura de Proyecto
project_directory/
├── agent_example.py # Your main agent code
├── pyproject.toml # Dependencies for your agent
├── Dockerfile # docker file for building image
├── uv.lock # auto generated by uv
└── __init__.py # Makes the directory a Python package
Crear imagen de contenedor
A continuación, se muestra un ejemplo de archivo de Docker en un directorio de proyecto.
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
# Copy project files
COPY pyproject.toml uv.lock ./
COPY *.py ./
# Install dependencies using uv
RUN uv sync --frozen
# Expose port
EXPOSE 8080
# Run the application using uv
CMD ["uv", "run", "python", "agent_example.py"]Crear la imagen de docker en la arquitectura amd64
docker buildx build --platform linux/amd64 -t my_agent:v1 .Insertar imagen en registro
Cree un registro de contenedor. Consulte Visión general de Container Registry.
Utilice la CLI de docker para transferir imágenes de docker al registro de contenedores.
Paso 1: Iniciar sesión en el registro de contenedores Código de ejemplo:
docker login kix.ocir.ioPaso 2: Etiquete la imagen con la URL y el espacio de nombres del registro de contenedor. Código de ejemplo:
docker tag my_agent:v1 ap-osaka-1.ocir.io/{your_tenancy_namespace}/my_agent:v1Paso 3: Insertar imagen Código de ejemplo:
docker push ap-osaka-1.ocir.io/<your_tenancy_namespace>/my_agent:v1Escanear imágenes para vulnerabilidades (recomendado y opcional)
No es raro que los paquetes del sistema operativo incluidos en las imágenes tengan vulnerabilidades. La gestión de estas vulnerabilidades le permite reforzar la estrategia de seguridad de su sistema y responder rápidamente cuando se descubran nuevas vulnerabilidades.
Consulte Exploración de imágenes para vulnerabilidades para crear una receta de exploración y un destino de exploración.