Self-Host Your Voice AI App: Complete Deployment Guide
Introduction If you’ve ever wanted to turn a simple script into a full‑blown voice assistant that can speak with a custom‑cloned voice, you’re in the right place. In this guide we’ll walk through the entire process—fro
Introduction
If you’ve ever wanted to turn a simple script into a full‑blown voice assistant that can speak with a custom‑cloned voice, you’re in the right place. In this guide we’ll walk through the entire process—from generating a voice with ElevenLabs to deploying a lightweight Flask API on a cheap, reliable host. By the end you’ll have a self‑hosted voice AI app that you can call from any front‑end (web, mobile, or even a smart speaker).
TL;DR: Use ElevenLabs for text‑to‑speech (TTS) and voice cloning, then spin up a Flask service and push it to a Bluehost shared‑hosting account. The whole stack fits in under 30 lines of code and costs less than a cup of coffee per month.
Prerequisites
| What you need | Why it matters |
|---|---|
| Python 3.9+ | Our backend runs on Flask. |
| ElevenLabs account | Provides the TTS and cloning API. Sign up here. |
| Bluehost hosting | An affordable, beginner‑friendly place to run the Flask app. Grab a plan at Bluehost. |
| Git (optional) | For version control and easy deployment. |
| cURL or Postman | To test the endpoints locally. |
Make sure you have pip and virtualenv installed. If you’re on a fresh Bluehost account, you’ll have SSH access – enable it from the control panel before proceeding.
Setting Up ElevenLabs API
ElevenLabs offers a clean REST API for both text‑to‑speech and voice cloning. After creating an account, grab your API key from the dashboard.
# Store the key securely (Linux/macOS)
export ELEVENLABS_API_KEY="your_api_key_here"
Quick cURL test
curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/voice_id" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello, world! This is my first ElevenLabs TTS call."}'
If everything is set up correctly you’ll receive a binary audio payload (MP3). For more advanced usage—like uploading a reference audio file to clone a new voice—refer to the ElevenLabs docs at the same link: ElevenLabs API.
Building the Voice AI Backend
We’ll create a tiny Flask service with two endpoints:
-
/speak– Convert arbitrary text to speech using a pre‑selected voice. -
/clone– Upload a short audio sample and receive a new voice ID.
Create a project folder and set up a virtual environment:
mkdir voice-ai && cd voice-ai
python -m venv venv
source venv/bin/activate
pip install flask requests python-dotenv
Create a .env file (never commit this to Git!):
ELEVENLABS_API_KEY=your_api_key_here
DEFAULT_VOICE_ID=YOUR_DEFAULT_VOICE_ID # e.g., "EXAVITQu4vr4xnSDxMaL"
app.py
import os
from flask import Flask, request, send_file, jsonify
import requests
from dotenv import load_dotenv
from io import BytesIO
load_dotenv()
app = Flask(__name__)
ELEVEN_API = "https://api.elevenlabs.io/v1"
HEADERS = {
"xi-api-key": os.getenv("ELEVENLABS_API_KEY"),
"Content-Type": "application/json"
}
@app.route("/speak", methods=["POST"])
def speak():
data = request.get_json()
text = data.get("text")
voice_id = data.get("voice_id") or os.getenv("DEFAULT_VOICE_ID")
if not text:
return jsonify({"error": "Missing 'text'"}), 400
payload = {"text": text}
resp = requests.post(
f"{ELEVEN_API}/text-to-speech/{voice_id}",
headers=HEADERS,
json=payload,
stream=True,
)
resp.raise_for_status()
audio = BytesIO(resp.content)
return send_file(audio, mimetype="audio/mpeg", as_attachment=False)
@app.route("/clone", methods=["POST"])
def clone():
# Expect a multipart/form-data request with 'audio' file
if "audio" not in request.files:
return jsonify({"error": "Missing audio file"}), 400
audio_file = request.files["audio"]
files = {"audio_file": (audio_file.filename, audio_file.stream, audio_file.mimetype)}
resp = requests.post(
f"{ELEVEN_API}/voices/add",
headers={"xi-api-key": os.getenv("ELEVENLABS_API_KEY")},
files=files,
)
resp.raise_for_status()
return jsonify(resp.json())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
What this does
-
/speakforwards the incoming text to ElevenLabs and streams the MP3 back to the caller. -
/clonelets you upload a 10‑second sample; ElevenLabs returns a brand‑new voice ID you can store and reuse.
Run it locally to make sure everything works:
python app.py
Test with cURL:
curl -X POST http://localhost:5000/speak \
-H "Content-Type: application/json" \
-d '{"text":"Testing my self‑hosted voice AI!"}'
You should hear a short audio clip in your terminal (or saved file if you pipe the output).
Deploying to Bluehost
Why Bluehost?
Bluehost offers a one‑click Python app setup, cheap shared‑hosting plans, and a straightforward control panel. It’s the easy, affordable way to get your voice AI service online without wrestling with Docker or Kubernetes.
Step‑by‑step deployment
- Create a new hosting account – Use the affiliate link to sign up: Bluehost.
- Enable SSH – In the Bluehost dashboard, go to Advanced → SSH Access and enable it.
- Upload your code
# From your local machine
git init
git remote add origin ssh://[email protected]/home/username/voice-ai.git
git add .
git commit -m "Initial commit"
git push -u origin master
(If you prefer the file manager, just zip the folder and upload it.)
- Create a virtual environment on the server
ssh [email protected]
cd voice-ai
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Configure environment variables
In the Bluehost MultiPHP INI Editor or via a.envfile, setELEVENLABS_API_KEYandDEFAULT_VOICE_ID.Run the app with a process manager
Bluehost shared hosting doesn’t support systemd, but you can use Gunicorn with Supervisor (both are pre‑installed on most plans).
pip install gunicorn supervisor
echo "[program:voice_ai]
directory=/home/username/voice-ai
command=/home/username/voice-ai/venv/bin/gunicorn -b 0.0.0.0:8000 app:app
autostart=true
autorestart=true
stdout_logfile=/home/username/voice-ai/logs/out.log
stderr_logfile=/home/username/voice-ai/logs/err.log
" > supervisor.conf
supervisord -c supervisor.conf
-
Expose via Apache/Nginx
Bluehost’s control panel lets you add a ProxyPass rule. Point
/apitohttp://127.0.0.1:8000. After saving, your endpoint becomeshttps://yourdomain.com/api/speak.
That’s it – your voice AI service is live!
Tip: If you run into permission issues, double‑check file ownership (use chown to set everything to your Bluehost user) and ensure the logs/ directory exists.
Testing the Live Service
curl -X POST https://yourdomain.com/api/speak \
-H "Content-Type: application/json" \
-d '{"text":"Hello from Bluehost!"}' --output hello.mp3
Play hello.mp3 locally to confirm the audio matches the ElevenLabs voice you selected.
You can also try cloning a new voice directly from the hosted endpoint:
curl -X POST https://yourdomain.com/api/clone \
-F "audio=@my_sample.wav"
The JSON response will contain a new voice_id you can feed back into /speak.
Wrapping Up
You now have a self‑hosted voice AI app that leverages the state‑of‑the‑art ElevenLabs TTS engine and runs on an inexpensive Bluehost server. The stack is intentionally minimal:
- ElevenLabs for high‑quality, neural voice synthesis and cloning.
- Flask for a lightweight API layer.
- Bluehost for a hassle‑free, affordable hosting environment.
Feel free to extend the project—add authentication, cache generated audio files, or integrate with a front‑end framework like React or Vue. The sky’s the limit once the core pipeline is in place.
Ready to give your app a real voice? Sign up for ElevenLabs via the link below and start cloning your own voice today:
And when you need a simple, cost‑effective place to host your service, remember that Bluehost makes deployment painless:
Happy coding, and may your AI always sound crystal clear!
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.