Comprehensive Guide to Self-Hosting Kokoro Web on Ubuntu 20.04+ with Docker
Before you start
- 11 min read
- 40 to run in terminal
- 8 file contents
- 4 to open in browser
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

Kokoro Web is a powerful AI text-to-speech solution that lets you create natural-sounding voices directly in your browser without installation requirements. This free and open-source tool can be self-hosted to provide an OpenAI-compatible API for your applications, offering high-quality voice generation capabilities comparable to leading commercial services. This guide will walk you through setting up Kokoro Web on Ubuntu systems using Docker, with special configurations for WSL access and local website integration with Pi-hole.
Introduction to Kokoro Web#
Kokoro Web is powered by the hexgrad/Kokoro-82M model, a lightweight yet capable 82 million parameter text-to-speech model available on Hugging Face. Despite its relatively small size, it delivers impressive quality comparable to larger models while being significantly faster and more resource-efficient. With Apache-licensed weights, you can deploy Kokoro anywhere from production environments to personal projects^2.
Key features include:
- Zero installation requirements for end-users
- Self-hosting capabilities with OpenAI API compatibility
- Support for various language accents
- Voice customization options
- WebGPU acceleration for supported browsers
- Completely free for both personal and commercial use^2
Prerequisites#
Hardware Requirements#
- CPU-only setup: Any modern CPU with at least 2 cores
- GPU-accelerated setup (optional): NVIDIA GPU with CUDA support
- Minimum 4GB RAM (8GB recommended)
- At least 10GB free disk space
Software Requirements#
- Ubuntu 20.04 LTS or newer
- Root or sudo privileges on your system
- Basic knowledge of terminal commands
- Internet connection for downloading required packages and Docker images
Setting Up Docker on Ubuntu#
For Users Who Don't Have Docker Installed#
If you don't already have Docker installed on your Ubuntu system, follow these steps to install Docker Engine and Docker Compose.
Step 1: Set up Docker's repository#
# Update the package index and install dependencies sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg
# Add Docker's official GPG key sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Set up the repository echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Step 2: Install Docker Engine and Docker Compose#
# Update the package index again sudo apt-get update
# Install Docker Engine, containerd, and Docker Compose sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Step 3: Verify the installation#
# Run the hello-world container to verify Docker works sudo docker run hello-world
Step 4: Add your user to the docker group (avoid using sudo with Docker)#
# Add your user to the docker group sudo usermod -aG docker $USER
# Apply the new group membership (alternatively, you can log out and back in) newgrp docker
# Verify you can run Docker commands without sudo docker run hello-world
For Users Who Already Have Docker Installed#
If you already have Docker installed, make sure it's up to date:
# Update your package list sudo apt-get update
# Upgrade Docker packages sudo apt-get upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Verify Docker is working correctly docker --version docker compose version docker run hello-world
Installing and Configuring Kokoro Web with Docker#
Step 1: Create a directory structure for Kokoro Web#
# Create directories for Kokoro Web data and configuration mkdir -p ~/docker_data/kokoro-web/cache
Step 2: Create a Docker Compose file#
# Navigate to the Kokoro Web directory cd ~/docker_data/kokoro-web
# Create a docker-compose.yml file using your preferred text editor nano docker-compose.yml
Paste the following configuration into the file:
version: '3.8'
services:
kokoro-web:
image: ghcr.io/eduardolat/kokoro-web:latest
container_name: kokoro-web
restart: unless-stopped
ports:
- "3000:3000"
environment:
- KW_SECRET_API_KEY=your-secure-api-key # Change this to a strong, unique key
- TZ=UTC # Set to your timezone if needed
volumes:
- ./cache:/kokoro/cache # Cache downloaded models and voices
networks:
- kokoro-network
networks:
kokoro-network:
driver: bridge
Save and exit the editor (in nano, press Ctrl+X, then Y, then Enter).
Step 3: Start the Kokoro Web service#
# Start the Kokoro Web container in detached mode docker compose up -d
# Check if the container is running docker ps
You should see a container named "kokoro-web" in the list, indicating that the service is running.
Step 4: Access the web interface#
After starting the container, you can access the Kokoro Web interface by opening a web browser and navigating to:
http://localhost:3000
The API interface can be accessed at:
http://localhost:3000/api/v1/index.html
Securing Your Kokoro Web Installation#
Step 1: Set a strong API key#
Edit your docker-compose.yml file to change the KW_SECRET_API_KEY to a strong, unique value:
# Generate a secure random string for the API key API_KEY=$(openssl rand -base64 32) echo "Your generated API key: $API_KEY"
# Edit the docker-compose.yml file nano docker-compose.yml
Update the KW_SECRET_API_KEY value, save the file, and restart the container:
# Restart the container to apply changes docker compose down docker compose up -d
Step 2: Using non-root user in Docker (optional but recommended)#
To improve security, you can ensure the Docker container runs as a non-root user by adding user and group settings to your docker-compose.yml:
services:
kokoro-web:
image: ghcr.io/eduardolat/kokoro-web:latest
user: 1000:1000 # Use the user ID and group ID that matches your host user
# ... rest of your configuration
Step 3: Set appropriate file permissions#
# Ensure the cache directory has the right permissions sudo chown -R 1000:1000 ~/docker_data/kokoro-web/cache
Step 4: Implement network restrictions#
If you want to restrict access to your Kokoro Web instance to only your local network, you can modify the ports configuration in docker-compose.yml:
ports: - "127.0.0.1:3000:3000" # Only accessible from localhost # OR - "192.168.1.100:3000:3000" # Only accessible from your specific IP
Integrating with Windows Subsystem for Linux (WSL)#
If you're running Ubuntu through WSL, you can access Kokoro Web both from your WSL environment and from Windows.
Setting up Docker with WSL2#
Step 1: Ensure WSL2 is properly configured#
If you haven't already set up WSL2 with Ubuntu, follow these steps on your Windows machine:
- Enable WSL2 in Windows features
- Install Ubuntu from the Microsoft Store
- Set WSL2 as the default version
# Run these in PowerShell with administrator privileges wsl --install wsl --set-default-version 2
Step 2: Install Docker Desktop for Windows#
For WSL2 integration, it's recommended to use Docker Desktop for Windows:
- Download and install Docker Desktop for Windows
- During installation, ensure "Use WSL 2 instead of Hyper-V" is selected
- After installation, open Docker Desktop settings and enable integration with your Ubuntu distribution under "Resources > WSL Integration"
Step 3: Access Kokoro Web from Windows#
After setting up Docker Desktop with WSL2 integration and running the Kokoro Web container in your Ubuntu WSL distribution, you can access the web interface from Windows through:
http://localhost:3000
Or using the IP address of your WSL2 distribution:
http://wsl-ip-address:3000
You can find your WSL2 IP address using this command in Ubuntu:
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Integrating with Pi-hole for Local Domain Access#
Step 1: Set up a local domain with Pi-hole#
To access your Kokoro Web instance using a friendly domain name (e.g., kokoro.local), you can configure Pi-hole to resolve this domain to your server's IP address.
Method 1: Using Pi-hole's Local DNS Records#
- Access your Pi-hole admin interface (typically http://pi.hole/admin)
- Navigate to "Local DNS > DNS Records"
- Add a new entry with:
- Domain: kokoro.local
- IP Address: [Your server's IP address]
- Save the changes
Method 2: Using /etc/hosts file on the Pi-hole server#
# SSH into your Pi-hole server ssh user@pi-hole-server
# Edit the hosts file sudo nano /etc/hosts
Add this line to the file:
192.168.1.xxx kokoro.local
Replace "192.168.1.xxx" with your Kokoro Web server's IP address.
Save and exit the editor, then restart the DNS service:
# Restart Pi-hole DNS service sudo pihole restartdns
Step 2: Configure Traefik for local domain routing (optional)#
For more advanced setups, you can use Traefik as a reverse proxy to handle local domain routing. This is particularly useful if you're hosting multiple services on the same server.
Step 1: Create a Traefik configuration#
First, create a new directory for Traefik:
mkdir -p ~/docker_data/traefik/{config,data}
cd ~/docker_data/traefik
touch docker-compose.yml
Edit the docker-compose.yml file:
nano docker-compose.yml
Add the following configuration:
version: '3.8'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.yml:/etc/traefik/traefik.yml:ro
- ./config/config.yml:/etc/traefik/config.yml:ro
- ./data/certificates:/certificates
networks:
- proxy
networks:
proxy:
external: true
Create a Traefik configuration file:
mkdir -p ~/docker_data/traefik/config nano ~/docker_data/traefik/config/traefik.yml
Add the following content:
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /etc/traefik/config.yml
log:
level: INFO
Create a configuration file for your services:
nano ~/docker_data/traefik/config/config.yml
Add the following content:
http:
routers:
kokoro:
rule: "Host(`kokoro.local`)"
service: kokoro
entryPoints:
- http
services:
kokoro:
loadBalancer:
servers:
- url: "http://kokoro-web:3000"
Step 2: Create a Docker network#
docker network create proxy
Step 3: Update the Kokoro Web docker-compose.yml file#
Edit your Kokoro Web docker-compose.yml:
nano ~/docker_data/kokoro-web/docker-compose.yml
Update it with network and label configuration:
version: '3.8'
services:
kokoro-web:
image: ghcr.io/eduardolat/kokoro-web:latest
container_name: kokoro-web
restart: unless-stopped
environment:
- KW_SECRET_API_KEY=your-secure-api-key
- TZ=UTC
volumes:
- ./cache:/kokoro/cache
networks:
- kokoro-network
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.kokoro.rule=Host(`kokoro.local`)"
- "traefik.http.services.kokoro.loadbalancer.server.port=3000"
networks:
kokoro-network:
driver: bridge
proxy:
external: true
Step 4: Start Traefik and restart Kokoro Web#
# Start Traefik cd ~/docker_data/traefik docker compose up -d # Restart Kokoro Web with updated configuration cd ~/docker_data/kokoro-web docker compose down docker compose up -d
Verifying Your Installation#
Step 1: Check that the containers are running#
docker ps
You should see your Kokoro Web container (and Traefik if you set it up) in the running containers list.
Step 2: Test the web interface#
Open a web browser and navigate to one of the following URLs:
- http://localhost:3000 (direct access)
- http://kokoro.local (if you set up Pi-hole DNS or hosts file configuration)
You should see the Kokoro Web interface where you can test voice generation.
Step 3: Test the API#
You can test the API using curl:
curl -X POST "http://localhost:3000/api/v1/audio/speech" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "model_q8f16",
"voice": "af_bella",
"input": "Hello, I am testing Kokoro Web API!",
"response_format": "mp3"
}' \
--output test.mp3
# Play the generated audio (requires an audio player like mpg123) mpg123 test.mp3
Maintenance and Updates#
Updating Kokoro Web#
To update to the latest version of Kokoro Web:
# Navigate to your Kokoro Web directory cd ~/docker_data/kokoro-web # Pull the latest image docker compose pull # Restart the container with the new image docker compose down docker compose up -d
Backing up your configuration#
It's good practice to back up your configuration files:
# Create a backup directory mkdir -p ~/backups/kokoro-web # Copy configuration files cp ~/docker_data/kokoro-web/docker-compose.yml ~/backups/kokoro-web/
Monitoring and logs#
Monitor the logs for any issues:
# View real-time logs docker logs -f kokoro-web # View the last 100 lines of logs docker logs --tail 100 kokoro-web
Troubleshooting Common Issues#
Container fails to start#
If the container fails to start, check the logs:
docker logs kokoro-web
Common issues include:
- Permission problems with the cache directory
- Port 3000 already in use by another service
Unable to access web interface#
If you can't access the web interface:
- Verify the container is running:
docker ps - Check if the port is correctly published:
docker port kokoro-web - Try accessing with the IP address instead of localhost
- Check your firewall settings:
sudo ufw status
API authentication issues#
If you're having trouble with API authentication:
- Verify you're using the correct API key
- Check that the API key is correctly set in your docker-compose.yml
- Ensure the Authorization header format is correct:
Authorization: Bearer your-api-key
Security Best Practices#
Container security#
- Keep Docker and the container image updated
- Use specific image version tags instead of "latest" for production
- Don't run containers with elevated privileges
- Use non-root users inside containers when possible
- Limit container capabilities to only what's needed^9
Network security#
- Use a reverse proxy like Traefik or Nginx for TLS termination
- Consider using internal Docker networks for service isolation
- Implement rate limiting for the API endpoints
- Use firewalls to restrict access to your server
API security#
- Use a strong, randomly generated API key
- Rotate API keys periodically
- Implement IP-based restrictions if possible
- Monitor API usage for unusual patterns
Conclusion#
You've now successfully set up Kokoro Web, a powerful open-source AI text-to-speech solution, on your Ubuntu system using Docker. This setup allows you to generate high-quality voice content locally without relying on external services, while maintaining compatibility with the OpenAI API format for easy integration with existing applications.
By following the additional configuration steps, you've also learned how to make Kokoro Web accessible through WSL for Windows users and how to integrate it with Pi-hole for convenient local domain access. The security recommendations will help protect your instance from unauthorized access.
As an open-source project, Kokoro Web continues to evolve, so be sure to check the official repository periodically for updates and new features. With this self-hosted solution, you have complete control over your text-to-speech processing, ensuring privacy and flexibility for your projects.
⁂