We are going to build a deployment planning agent that turns a plain-English service description into production-ready artifacts: a Dockerfile, a Kubernetes manifest, and a GitHub Actions workflow. If you are tired of copy-pasting boilerplate every time a new microservice ships, this tool automates the first draft and catches common misconfigurations before they reach a cluster.
What you'll need
Before starting, make sure you have the following ready:
- Python 3.10 or newer
- The OpenAI Python SDK installed:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Oxlo.ai is a developer-first inference platform with flat per-request pricing. That matters here because we are going to feed the agent detailed stack descriptions, and with token-based providers long inputs get expensive fast. On Oxlo.ai, the cost stays the same whether your prompt is two lines or two hundred lines.
Step 1: Initialize the Oxlo.ai client
Because Oxlo.ai is fully OpenAI-compatible, the only change from a standard OpenAI setup is the base URL. Point the SDK at Oxlo.ai and load your key from an environment variable.
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.environ.get("OXLO_API_KEY")
)
Step 2: Lock down the system prompt
The system prompt is the contract that keeps the model in SRE mode and forces a predictable output structure. We will parse these sections later, so the formatting rules are strict.
SYSTEM_PROMPT = """You are a senior site-reliability engineer. The user will describe a service stack. Your job is to generate three artifacts:
1. Dockerfile - optimized for production, non-root user, explicit base image tags, multi-stage if beneficial.
2. Kubernetes manifest - a Deployment and a Service. Include resource requests/limits, liveness probe, and readiness probe.
3. GitHub Actions workflow - build the image, run a security scan with Trivy, and deploy to the cluster.
Output your response in the following exact structure:
---DOCKERFILE---
```dockerfile
...
```
---K8S---
```yaml
...
```
---CI---
```yaml
...
```
---NOTES---
Brief notes on any security or performance decisions made.
"""
Step 3: Generate artifacts via Oxlo.ai
This function sends the user description to the model and returns the raw markdown. I use kimi-k2.6 because its reasoning and coding strengths handle multi-file infrastructure logic well, and Oxlo.ai's request-based pricing means I do not have to worry about token count when I expand the prompt with extra context later.
def generate_deployment(description: str) -> str:
response = client.chat.completions.create(
model="kimi-k2.6",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": description},
],
temperature=0.2,
)
return response.choices[0].message.content
Step 4: Validate for deployment anti-patterns
Generated code is still a first draft. We will run a lightweight validator that regex-searches the output for common mistakes: floating image tags, missing health checks, and containers running as root.
import re
def validate_artifacts(raw_output: str) -> dict:
findings = []
if "latest" in raw_output.lower():
findings.append("Warning: 'latest' tag detected. Pin to a digest or explicit version.")
if not re.search(r"USER\s+\d+|USER\s+\w+", raw_output):
findings.append("Warning: Dockerfile may be missing a non-root USER directive.")
if "HEALTHCHECK" not in raw_output.upper():
findings.append("Warning: No HEALTHCHECK found in Dockerfile.")
if "readinessProbe" not in raw_output:
findings.append("Warning: Kubernetes manifest may be missing a readinessProbe.")
return {
"passed": len(findings) == 0,
"findings": findings,
"raw_output": raw_output,
}
Step 5: Wrap it in a CLI loop
This ties the pieces together. It accepts a description, calls Oxlo.ai, validates the result, and prints the artifacts along with any warnings.
def main():
print("Complex Coding Deployment Agent")
print("Describe your service (e.g., 'FastAPI + Postgres + Redis on K3s'):")
try:
while True:
user_input = input("\n> ").strip()
if not user_input:
continue
if user_input.lower() in ("exit", "quit"):
break
print("\nGenerating artifacts via Oxlo.ai...")
raw = generate_deployment(user_input)
result = validate_artifacts(raw)
print("\n=== GENERATED ARTIFACTS ===")
print(result["raw_output"])
if result["findings"]:
print("\n=== VALIDATION FINDINGS ===")
for f in result["findings"]:
print(f)
else:
print("\nValidation passed with no major warnings.")
except KeyboardInterrupt:
print("\nShutting down.")
if __name__ == "__main__":
main()
Run it
Save the script as deploy_agent.py, export your key, and run it. Here is a real interaction where I described a Python worker stack. The output below is truncated for brevity, but the structure is exactly what the agent returns.
$ export OXLO_API_KEY="sk-oxlo.ai-..."
$ python deploy_agent.py
Complex Coding Deployment Agent
Describe your service (e.g., 'FastAPI + Postgres + Redis on K3s'):
> Python 3.11 FastAPI app with Celery worker, Redis broker, Postgres 15. Target is a single-node K3s cluster.
Generating artifacts via Oxlo.ai...
=== GENERATED ARTIFACTS ===
---DOCKERFILE---
```dockerfile
FROM python:3.11-slim-bookworm AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y gcc libpq-dev
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.11-slim-bookworm
WORKDIR /app
RUN apt-get update && apt-get install -y libpq5 && rm -rf /var/lib/apt/lists/*
COPY --from=builder /root/.local /root/.local
COPY ./app ./app
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8000
USER 1000
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
```
---K8S---
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-celery
spec:
replicas: 2
selector:
matchLabels:
app: fastapi-celery
template:
metadata:
labels:
app: fastapi-celery
spec:
containers:
- name: api
image: fastapi-celery:1.0.0
ports:
- containerPort: 8000
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: fastapi-celery-service
spec:
selector:
app: fastapi-celery
ports:
- port: 80
targetPort: 8000
```
---CI---
```yaml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t fastapi-celery:${{ github.sha }} .
- name: Run Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: fastapi-celery:${{ github.sha }}
format: sarif
output: trivy-results.sarif
- name: Deploy to K3s
run: kubectl set image deployment/fastapi-celery api=fastapi-celery:${{ github.sha }}
```
---NOTES---
Used a multi-stage build to keep the final image small. Pinned to python:3.11-slim-bookworm instead of latest. Added non-root USER 1000. Included both liveness and readiness probes so K3s can roll out safely.
=== VALIDATION FINDINGS ===
Validation passed with no major warnings.
Wrap-up and next steps
This agent gives you a consistent starting point for every new service. Because Oxlo.ai uses flat per-request pricing, you can afford to iterate on the prompt, feed it lengthy existing compose files for refactoring, or run it in a CI loop without token costs creeping up on long contexts.
Two concrete ways to extend this:
- Wire the script into a pre-commit hook so every new repository gets an initial Dockerfile and K8s manifest automatically.
- Add a retrieval layer over your internal base image catalog so the agent defaults to your hardened, approved images instead of public Docker Hub tags.
Top comments (0)