Ax
Ax deploys uv Python agents and APIs to a host you control.
It is intentionally narrow: one runner, one reverse proxy, one CLI, and one base hostname or IP for the stack. The goal is to get a Python repo into production without turning every agent or internal API into a new platform project.
When to use Ax
Use Ax when:
- Your app is a
uvPython project. - You want to deploy an agent, worker-facing API, or small web service.
- You have a server or VM where Docker can run.
- You want the deployed app on your own hostname, subdomain, path, or public IP.
- You prefer a CLI workflow from the project directory.
Ax is not trying to replace a full internal platform. It is the first deploy layer for teams that need production control without waiting for a larger platform path.
Mental model
Every Ax stack has a PLATFORM_BASE_DOMAIN. This is the hostname or public IP where the platform is reachable.
Use the same value in both places:
- On the server, when running
./setup.shor writinginfra/.env. - On your laptop, when running
ax login.
There is no vendor-owned domain in the middle. Use a DNS name you control, such as apps.example.com, or use the server IP directly.
What ships in the repo
infra/- Docker Compose plus Caddy. Caddy terminates traffic and routes platform/API/app requests.runner/- API server that receives deploys, builds projects, and runs apps as Docker containers. The runner image usesuv sync --frozenanduv run.cli/- theaxCLI. Use it to generate a token, login to a stack, initialize an app, deploy, inspect processes, read logs, and manage lifecycle.
Request routing
On PLATFORM_BASE_DOMAIN, Caddy serves:
/_ax/health- platform liveness./v1/*and/health- runner API used by the CLI.- App routes - paths, subdomains, or custom domains configured in
ax.toml.
For real hostnames, the CLI uses HTTPS. For localhost, *.localhost, or raw public IPs, the CLI uses HTTP.
Next steps
- Start locally with Quickstart.
- Put Ax on a server with Production & bootstrap.
- Configure an app with
ax.toml.
Source: github.com/narnia-sh/ax.