Docker

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#

Run in terminalbash
# Update the package index and install dependencies
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
Run in terminalbash
# 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
Run in terminalbash
# 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#

Run in terminalbash
# Update the package index again
sudo apt-get update
Run in terminalbash
# 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 in terminal
# 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)#

Run in terminalbash
# Add your user to the docker group
sudo usermod -aG docker $USER
Run in terminalbash
# Apply the new group membership (alternatively, you can log out and back in)
newgrp docker
Run in terminalbash
# 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:

Run in terminalbash
# Update your package list
sudo apt-get update
Run in terminalbash
# Upgrade Docker packages
sudo apt-get upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Run in terminalbash
# 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#

Run in terminalbash
# Create directories for Kokoro Web data and configuration
mkdir -p ~/docker_data/kokoro-web/cache

Step 2: Create a Docker Compose file#

Run in terminalbash
# Navigate to the Kokoro Web directory
cd ~/docker_data/kokoro-web
Run in terminalbash
# Create a docker-compose.yml file using your preferred text editor
nano docker-compose.yml

Paste the following configuration into the file:

File contentbash
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#

Run in terminalbash
# Start the Kokoro Web container in detached mode
docker compose up -d
Run in terminalbash
# 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:

Open in your browserbash
http://localhost:3000

The API interface can be accessed at:

Open in your browserbash
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:

Run in terminalbash
# Generate a secure random string for the API key
API_KEY=$(openssl rand -base64 32)
echo "Your generated API key: $API_KEY"
Run in terminalbash
# Edit the docker-compose.yml file
nano docker-compose.yml

Update the KW_SECRET_API_KEY value, save the file, and restart the container:

Run in terminalbash
# Restart the container to apply changes
docker compose down
docker compose up -d

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:

File contentbash
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#

Run in terminalbash
# 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:

File contentbash
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:

  1. Enable WSL2 in Windows features
  2. Install Ubuntu from the Microsoft Store
  3. Set WSL2 as the default version
Run in terminalbash
# 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:

  1. Download and install Docker Desktop for Windows
  2. During installation, ensure "Use WSL 2 instead of Hyper-V" is selected
  3. 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:

Open in your browserbash
http://localhost:3000

Or using the IP address of your WSL2 distribution:

Open in your browserbash
http://wsl-ip-address:3000

You can find your WSL2 IP address using this command in Ubuntu:

Run in terminalbash
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#

  1. Access your Pi-hole admin interface (typically http://pi.hole/admin)
  2. Navigate to "Local DNS > DNS Records"
  3. Add a new entry with:
    • Domain: kokoro.local
    • IP Address: [Your server's IP address]
  4. Save the changes

Method 2: Using /etc/hosts file on the Pi-hole server#

Run in terminalbash
# SSH into your Pi-hole server
ssh user@pi-hole-server
Run in terminalbash
# Edit the hosts file
sudo nano /etc/hosts

Add this line to the file:

File contentbash
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:

Run in terminalbash
# 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:

Run in terminalbash
mkdir -p ~/docker_data/traefik/{config,data}
cd ~/docker_data/traefik
touch docker-compose.yml

Edit the docker-compose.yml file:

Run in terminalbash
nano docker-compose.yml

Add the following configuration:

File contentbash
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:

Run in terminalbash
mkdir -p ~/docker_data/traefik/config
nano ~/docker_data/traefik/config/traefik.yml

Add the following content:

File contentbash
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:

Run in terminalbash
nano ~/docker_data/traefik/config/config.yml

Add the following content:

File contentbash
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#

Run in terminalbash
docker network create proxy

Step 3: Update the Kokoro Web docker-compose.yml file#

Edit your Kokoro Web docker-compose.yml:

Run in terminalbash
nano ~/docker_data/kokoro-web/docker-compose.yml

Update it with network and label configuration:

File contentbash
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#

Run in terminalbash
# 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#

Run in terminalbash
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:

Run in terminalbash
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
Run in terminalbash
# 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:

Run in terminalbash
# 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:

Run in terminalbash
# 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:

Run in terminalbash
# 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:

Run in terminalbash
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:

  1. Verify the container is running: docker ps
  2. Check if the port is correctly published: docker port kokoro-web
  3. Try accessing with the IP address instead of localhost
  4. Check your firewall settings: sudo ufw status

API authentication issues#

If you're having trouble with API authentication:

  1. Verify you're using the correct API key
  2. Check that the API key is correctly set in your docker-compose.yml
  3. Ensure the Authorization header format is correct: Authorization: Bearer your-api-key

Security Best Practices#

Container security#

  1. Keep Docker and the container image updated
  2. Use specific image version tags instead of "latest" for production
  3. Don't run containers with elevated privileges
  4. Use non-root users inside containers when possible
  5. Limit container capabilities to only what's needed^9

Network security#

  1. Use a reverse proxy like Traefik or Nginx for TLS termination
  2. Consider using internal Docker networks for service isolation
  3. Implement rate limiting for the API endpoints
  4. Use firewalls to restrict access to your server

API security#

  1. Use a strong, randomly generated API key
  2. Rotate API keys periodically
  3. Implement IP-based restrictions if possible
  4. 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.

⁂