Instrument and Deploy an Agent
Add structured JSON logging to a minimal agent, containerize it with a non-root Dockerfile and a healthcheck, run it via Docker Compose bound to localhost, and prove it survives a crash by restarting on its own.
PremiumProblem
Getting an agent to answer correctly in a notebook is the easy 80%. The remaining 20% — the part that determines whether it survives contact with real traffic — is operational: can you tell what it did and how long it took after the fact, does it run as a container you can hand to an ops team without a security review flagging "runs as root", and does it come back on its own if the process dies at 3am? In this lab you'll take a small, self-contained agent (a minimal HTTP service simulating a model call and a tool call — no external API key required) and take it from "runs on my machine" to "runs as a monitored container with a restart policy." Concretely: add structured JSON logging of every model call and tool call (latency, an estimated token count, success or failure), write a `Dockerfile` that runs as a non-root user with a `HEALTHCHECK`, write a minimal `docker-compose.yml` binding the service to `127.0.0.1` only, bring it up and confirm the healthcheck actually reports `healthy` (not just "the container is running"), and finally kill the process inside the container on purpose and confirm Docker restarts it without you doing anything. None of these steps are exotic — this is the same checklist a production-minded engineer runs through for any service, agent or otherwise. The point of this lab is making sure you've actually done it once, end to end, rather than only read about each piece in isolation.
Objectives
By the end of this lab you will be able to:
- Add structured (JSON) logging to an agent capturing latency,
estimated token usage, and success/failure for both model calls and
tool calls. - Write a
Dockerfilethat runs a Python service as a non-root user
with a workingHEALTHCHECKinstruction. - Write a minimal
docker-compose.ymlthat binds a service to
127.0.0.1only and sets a restart policy. - Verify a container's health status programmatically with
docker inspect, not just by assuming it's fine because it's running. - Simulate a crash and confirm a restart policy actually recovers the
service automatically.
Prerequisites
To complete this lab you'll need:
- Docker and Docker Compose installed.
- Python 3.10+ installed locally (to run and test the agent before
containerizing it). -
pip install fastapi "uvicorn[standard]". - A terminal and
curl(or an equivalent HTTP client).
What "instrumented and deployed" actually means here
agent.py (structured logs)
│
▼
Dockerfile (non-root user, HEALTHCHECK)
│
▼
docker-compose.yml (127.0.0.1 bind, restart policy)
│
▼
docker inspect → "healthy"
│
▼
kill the process → container restarts on its own
Each layer in this stack is a real, separately-verifiable claim. "It's
instrumented" means you can point at a JSON log line and read latency
and status off it. "It's healthy" means docker inspect says so, not
that you eyeballed docker ps and it wasn't red. "It recovers" means
you personally killed it and watched it come back, not that the
restart: line is present in the YAML.
Why a fake model call, not a real API
This lab's agent simulates the "model call" and "tool call" with
deterministic local logic instead of calling a real LLM provider. That
is deliberate: the skill being taught here is instrumentation and
deployment, not prompt engineering, and keeping the agent free of
external API keys means every checkpoint in this lab works the same way
for everyone, with nothing to fail because of a missing credential or a
provider outage.
How to work through this lab
Get the logging right locally first (Step 1) before you containerize
anything — debugging Python inside a container you're also debugging
for the first time is strictly harder than debugging it on its own.
Steps 2–5 then move it into Docker one concern at a time.