๐ง Building a Speech-to-Text System with Vosk, Flask & React
Turn voice into text with a modern, containerized web app. This guide walks you through building and deploying a speech recognition systemโฆ
๐ง Building a Speech-to-Text System with Vosk, Flask & React
Turn voice into text with a modern, containerized web app. This guide walks you through building and deploying a speech recognition system using open-source tools like Vosk, Flask, React, Docker, and NGINX.

๐ Project Overview
This project enables real-time speech-to-text transcription using Vosk models. It features:
- ๐ฃ๏ธ Speech Recognition via Vosk
- ๐ค Audio Uploads handled by Flask
- ๐งฑ Frontend built with React (Vite.js)
- ๐ณ Dockerized deployment
- ๐ Secure Hosting with NGINX
๐งฐ Tech Stack
Component Technology Frontend React.js (Vite.js), Backend Flask (Python), Speech Recognition Vosk Models, Database (Optional)MongoDB / PostgreSQL, Containerization Docker & Docker Compose, Reverse Proxy NGINX, Deployment Ubuntu Server / AWS EC2
๐ Folder Structure
project-root/
โโโ frontend/ # React frontend
โโโ backend/ # Flask backend
โโโ models/ # Vosk models
โโโ uploads/ # Audio uploads
โโโ docker-compose.yml
โโโ README.md
๐งช Backend Setup (Flask)
The backend uses Flask and Gunicorn, with Vosk models downloaded during container build.
FROM python:3.10
WORKDIR /app
RUN apt-get update && apt-get install -y ffmpeg wget unzip curl
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt gunicorn python-dotenv
RUN mkdir -p /app/models && \
wget -O /app/models/vosk-model-en-us-0.22.zip https://alphacephei.com/vosk/models/vosk-model-en-us-0.22.zip && \
unzip /app/models/vosk-model-en-us-0.22.zip -d /app/models && \
rm /app/models/vosk-model-en-us-0.22.zip
COPY . .
ENV FLASK_ENV=production
ENV UPLOAD_FOLDER=/app/uploads
ENV VOSK_MODEL_PATH_EN=/app/models/vosk-model-en-us-0.22
EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://localhost:5000/healthz || exit 1
CMD ["gunicorn", "--workers", "4", "--bind", "0.0.0.0:5000", "app:app"]
๐จ Frontend Setup (React + Vite)
FROM node:18
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --frozen-lockfile
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"]
๐ NGINX Configuration
server {
listen 80;
server_name yourdomain.com ;
location / {
proxy_pass http://frontend:3000;
proxy_set_header Host $host;
}
location /api/ {
proxy_pass http://backend:5000;
proxy_set_header Host $host;
}
}
๐งฑ Docker Compose
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
networks:
- app-network
backend:
build: ./backend
ports:
- "5000:5000"
volumes:
- ./backend:/app
- ./models:/app/models
- ./uploads:/app/uploads
networks:
- app-network
networks:
app-network:
driver: bridge
๐ Flask App Entry Point
from flask import Flask, request, jsonify
from vosk import Model, KaldiRecognizer
import wave
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = '/app/uploads'
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB upload limit
@app.route('/api/speech-to-text', methods=['POST'])
def transcribe():
audio_file = request.files['file']
filepath = os.path.join(app.config['UPLOAD_FOLDER'], audio_file.filename)
audio_file.save(filepath)
wf = wave.open(filepath, "rb")
model = Model("/app/models/vosk-model-en-us-0.22")
rec = KaldiRecognizer(model, wf.getframerate())
results = []
while True:
data = wf.readframes(4000)
if len(data) == 0:
break
if rec.AcceptWaveform(data):
results.append(rec.Result())
return jsonify(results)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
โ๏ธ Vite Config for WebSocket & Host Binding
import { defineConfig } from 'vite';
export default defineConfig({
server: {
host: '0.0.0.0',
port: 3000,
strictPort: true,
allowedHosts: ['yourdomain.com'],
hmr: {
protocol: 'wss',
host: 'yourdomain.com',
}
}
});
๐ ๏ธ Troubleshooting Tips
โ Backend Not Accessible
docker logs backend
docker exec -it backend netstat -tulnp
docker restart backend
โ Frontend Not Loading
docker exec -it frontend netstat -tulnp
docker restart frontend
โ Firewall Blocking
sudo ufw allow 3000/tcp
sudo ufw allow 5000/tcp
sudo ufw reload
โ NGINX Not Forwarding
sudo journalctl -u nginx --no-pager | tail -50
sudo systemctl restart nginx
sudo systemctl reload nginx
โ File Upload Limit
# In nginx.conf
http {
client_max_body_size 100M;
}
# In Flask app.py
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024
โ Final Checklist
- Frontend loads at:
[http://yourdomain.com](http://lms.belzir.com) - API accessible at:
[http://yourdomain.com/api/speech-to-text](http://lms.belzir.com/api/speech-to-text) - Ports
3000,5000,80are open
Thank you.
๋ฉํ๋ฐ์ดํฐ
- post_id
- d587d719dfca
- slug
- building-a-speech-to-text-system-with-vosk-flask-react-d587d719dfca
- url
- https://medium.com/@topi9864/building-a-speech-to-text-system-with-vosk-flask-react-d587d719dfca
- canonical_url
- https://medium.com/@topi9864/building-a-speech-to-text-system-with-vosk-flask-react-d587d719dfca
- author_url
- https://medium.com/@topi9864
- status
- ok
- fetched_at
- 2026-06-10 15:53:41