© Made by Adam Bellanger
← ProjectsPersonal

Audio transcription web app powered by Whisper, fully containerised and self-hosted.

Preview

whisper.adambellanger.pro
OpenWhisper home page: file upload, language and model selection
whisper.adambellanger.pro
OpenWhisper language picker open
OpenWhisper on mobile

Stack

Languages
  • TypeScript
Front-end
  • React
Back-end
  • Express
  • Flask
  • Whisper
Infra
  • Docker
  • Nginx

Context

Transcribing audio files without sending them to a third party: a simple interface to drop a file, pick the language and model, and get the text back.

Role

End-to-end architecture and development, through to deployment on my server behind Nginx Proxy Manager.

Architecture

  1. Browser

    Audio file upload

  2. Nginx Proxy Manager

    HTTPS, single entry point

  3. nginx frontend

    Compiled React + /api proxy

  4. Express gateway

    :3001, multer upload

  5. whisper-service

    Flask :5000, Whisper + ffmpeg

Only the frontend is exposed: the gateway and the transcription engine stay on the internal Docker network.

Challenges

Splitting the app into three services (nginx frontend, Express gateway, Flask API + Whisper + ffmpeg) and exposing only the frontend: the backend and the transcription engine are never reachable from outside. The model is baked into the image at build time to remove cold starts.

Outcome

An app deployed with a single command (docker compose up), with model choice (small, medium, large), automatic language detection, progress tracking and a local history of recent transcriptions.

Highlights

  • 3 isolated services, only one exposed
  • Whisper model baked into the image, no cold start
  • WAV, MP3, M4A, OGG and FLAC support
Next projectPolyTrack →