Kokoro-FastAPI on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and use of Kokoro-FastAPI on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Kokoro-FastAPI is an open source, self hosted text to speech (TTS) server that wraps the compact Kokoro-82M speech model behind an OpenAI-compatible HTTP API. Any client that already speaks the OpenAI audio format can point at your own endpoint and generate natural speech from text, with no per character cloud bills and no text leaving your VM.
The image installs Kokoro-FastAPI 0.6.0 from the official CPU container image, pinned to a specific version, and runs it under Docker and systemd. The Kokoro-82M model, all 68 built in voices and the language dictionaries are baked into the image, so the server synthesizes speech offline the moment it boots with no model download. The model runs comfortably on CPU, so no GPU is required.
Secure by default — a per-VM API key, no open endpoint. An open TTS endpoint is a compute abuse risk, so this image never exposes one. The application binds to the loopback interface only; an nginx reverse proxy on port 80 is the sole public surface and requires an OpenAI-style Authorization: Bearer API key on every request except the health check. A fresh, unique API key is generated on the first boot of every VM — no default or shared key ships in the image, and until first boot completes every request except /health returns 401.
What is included:
-
Kokoro-FastAPI 0.6.0 (official CPU container), run under Docker + systemd as
kokoro-fastapi.service -
The Kokoro-82M model and 68 built in voices baked into the image for fully offline synthesis
-
An nginx reverse proxy on port 80 that enforces a per-VM Bearer API key, with the application bound to loopback only
-
A unique API key generated on first boot and written to
/root/kokoro-fastapi-credentials.txt(root only, mode 0600) -
The OpenAI-compatible
/v1/audio/speechendpoint with WAV, MP3, FLAC, Opus, AAC and PCM output, plus/v1/audio/voices
Prerequisites
-
Active Azure subscription, SSH public key, VNet + subnet in target region
-
Subscription to the Kokoro-FastAPI listing on Azure Marketplace
-
Network Security Group rules allowing TCP 22 (admin) and TCP 80 (the authenticated API) from the networks you trust
Recommended virtual machine size: Standard_D2s_v5 (2 vCPU, 8 GB RAM) gives responsive synthesis. The model runs on CPU; Standard_B2s (2 vCPU, 4 GB) also works for light use. No GPU is required.
Step 1: Deploy from the Azure Portal
- Open the Kokoro-FastAPI offer on the Azure Marketplace and choose Get It Now, then Create.
- Select your subscription, resource group and region, and choose the
Standard_D2s_v5size. - Provide your SSH public key for the
azureuseraccount. - Allow inbound TCP 22 and TCP 80 from your trusted networks in the Network Security Group, then create the VM.
Step 2: Deploy from the Azure CLI
az vm create \
--resource-group my-rg \
--name kokoro-01 \
--image <kokoro-fastapi-marketplace-image-urn> \
--size Standard_D2s_v5 \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Step 3: First boot
On the first boot of every VM, kokoro-fastapi-firstboot.service generates a fresh, unique API key, writes it into the nginx authentication gate and reloads nginx, brings the TTS container up, and writes the key to /root/kokoro-fastapi-credentials.txt. First boot takes under a minute; give the service a moment before the first request.
Step 4: Confirm the service is running
SSH in as azureuser and confirm Docker, the TTS service and nginx are active, and that the health check answers (the health endpoint is intentionally open, no key required):
systemctl is-active docker kokoro-fastapi nginx
curl -s http://127.0.0.1/health
You should see active for each service and {"status":"healthy"} from the health check.

Step 5: Retrieve your per-VM API key
The API key is unique to this VM and is stored in a root only file:
sudo cat /root/kokoro-fastapi-credentials.txt
The KOKORO_API_KEY value is your Bearer token. Keep it secret. Set it into a shell variable for the next steps (from your own workstation, use the value you just read):
KEY=$(sudo grep '^KOKORO_API_KEY=' /root/kokoro-fastapi-credentials.txt | cut -d= -f2)
Step 6: Prove the endpoint is authenticated
An unauthenticated request to the speech endpoint is rejected, while an authenticated one succeeds. This is the security guarantee of the image:
KEY=$(sudo grep '^KOKORO_API_KEY=' /root/kokoro-fastapi-credentials.txt | cut -d= -f2)
# No key -> 401 Unauthorized
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{"model":"kokoro","input":"hello","voice":"af_bella","response_format":"wav"}'
# With the per-VM key -> 200 OK
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1/v1/audio/speech \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"model":"kokoro","input":"hello","voice":"af_bella","response_format":"wav"}'
The first call prints 401; the second prints 200.

Step 7: Generate speech
Generate a WAV file from text using the OpenAI-compatible endpoint and your API key:
KEY=$(sudo grep '^KOKORO_API_KEY=' /root/kokoro-fastapi-credentials.txt | cut -d= -f2)
curl -s -X POST http://127.0.0.1/v1/audio/speech \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"model":"kokoro","input":"Hello world, this is Kokoro FastAPI running on Azure.","voice":"af_bella","response_format":"wav"}' \
--output hello.wav
file hello.wav
file hello.wav reports a RIFF WAVE audio file. Supported response_format values are wav, mp3, flac, opus, aac and pcm.

Step 8: List the built in voices
All 68 voices are baked into the image. List them through the authenticated endpoint:
KEY=$(sudo grep '^KOKORO_API_KEY=' /root/kokoro-fastapi-credentials.txt | cut -d= -f2)
curl -s http://127.0.0.1/v1/audio/voices -H "Authorization: Bearer $KEY" \
| python3 -c "import sys,json; v=json.load(sys.stdin)['voices']; names=[x['id'] if isinstance(x,dict) else x for x in v]; print('voices:',len(names)); print(', '.join(names[:12]))"
You will see the voice count and a sample of the available voices (for example af_bella, af_heart, af_nicole, am_michael, bf_emma). Combine voices by joining names with + in the voice field (for example af_bella+af_sky).

Step 9: Use it from the OpenAI Python client
Because the API is OpenAI-compatible, point the official client at your VM and use your per-VM key. Replace <vm-ip> and <your-key>:
from openai import OpenAI
client = OpenAI(base_url="http://<vm-ip>/v1", api_key="<your-key>")
with client.audio.speech.with_streaming_response.create(
model="kokoro", voice="af_bella", input="Hello from the OpenAI client.",
response_format="wav",
) as response:
response.stream_to_file("out.wav")
Step 10: Rotate the API key
To issue a new key, edit the nginx gate and reload nginx. This example is illustrative — generate a strong random key:
NEWKEY=$(openssl rand -hex 32)
sudo sed -i "s#\"Bearer .*\" 1;#\"Bearer ${NEWKEY}\" 1;#" /etc/nginx/conf.d/cloudimg-kokoro-key.conf
sudo nginx -t && sudo systemctl reload nginx
# record the new key somewhere safe; update /root/kokoro-fastapi-credentials.txt if you rely on it
echo "$NEWKEY"
Step 11: Security recommendations
- Keep port 80 open only to the clients that need it via a tightly scoped NSG rule; the endpoint is authenticated but the model still consumes CPU per request.
- Terminate TLS in front of the API for production (add a certificate to nginx, or place the VM behind an Azure Application Gateway / Load Balancer with HTTPS) so the Bearer key is never sent in clear text.
- Treat the contents of
/root/kokoro-fastapi-credentials.txtas a secret and rotate the key (Step 10) on any suspected exposure. - Keep the OS patched. The image ships fully updated with unattended security upgrades enabled.
Step 12: Support and Licensing
Kokoro-FastAPI is free and open source software distributed under the Apache License 2.0. This image bundles Kokoro-FastAPI unmodified; your use of it is governed by its license, and the Kokoro model and voices are governed by their respective licenses.
cloudimg images include 24/7 support. If you need help deploying or configuring Kokoro-FastAPI on Azure, contact us.
Deploy on Azure
Find this image on the Azure Marketplace and deploy in minutes.
Need Help?
Email support@cloudimg.co.uk and our team will help you get up and running.