Write diary entries in your own language. LingoDiary turns them into TPRS-style audio lessons — translated sentences, Q&A pairs, and multiple grammatical variants — ready to listen on your phone or in the browser.
You need: Docker, Docker Compose, and an OpenAI API key.
Create a docker-compose.yml anywhere on your machine:
services:
lingo-diary:
image: lozzaroo/lingodiary
ports:
- 8083:8084
volumes:
- ~/.config/lingoDiary/:/app/.config/lingoDiary/
- ~/Documents/lingodiary/:/data/
environment:
# Generate with: python3 -c "import secrets; print(secrets.token_hex(32))"
# IMPORTANT: rotate this key — do not commit real secrets to source control.
SECRET_KEY: "change-me-to-a-random-string"Use the interactive ./scripts/manage-config.py script to create and manage user configurations:
# From the repo directory
python scripts/manage-config.py add-userThe script will guide you through:
- Username — your login name
- Password — stored with bcrypt hashing
- Primary Language — language you write your diary in (menu: english, norwegian, french, etc.)
- Study Language — language you're learning (menu: english, norwegian, french, etc.)
- Gender — for grammatical output (male/female)
- Voice selections — TTS voices for study language and primary language
- OpenAI API key — for translation and tips generation
This automatically creates the necessary config files by looking at the path in the docker-compose.yml and placing configs in the right location, for example:
~/.config/lingoDiary/users.yaml(if not exists)~/.config/lingoDiary/{username}/config.yaml
# List all registered users
python scripts/manage-config.py list-users
# Modify an existing user's config
python scripts/manage-config.py modify-user myuser
# Delete a user (backs up config automatically)
python scripts/manage-config.py delete-user myuserIf you prefer to create configs manually, replace myuser with your username:
mkdir -p ~/.config/lingoDiary/myuser
mkdir -p ~/Documents/lingodiary/myuserGenerate a bcrypt hash for your password:
python3 -c "import bcrypt; print(bcrypt.hashpw(b'yourpassword', bcrypt.gensalt()).decode())"Create ~/.config/lingoDiary/users.yaml:
users:
myuser:
password: "$2b$12$..." # paste your bcrypt hash here
language: "en"Create ~/.config/lingoDiary/myuser/config.yaml:
output_dir: "/data/myuser/"
create_diary_answers_auto: true
openai:
key: "sk-..."
model: "gpt-4o-mini"
languages:
primary_language: "english"
primary_language_code: "en"
study_language: "norwegian"
study_language_code: "no"
gender: "male"
tts:
model: "piper"
piper:
piper_length_scale_tprs: 2
piper_length_scale_diary: 2
voice: "talesyntese-medium"
piper_input_language:
voice: "alan-low"
repeat_sentence_tprs: 2
repeat_sentence_diary: 2
pause_between_sentences_duration: 600
answer_silence_duration: 5000Pull the image and start:
docker compose pull
docker compose up -dThe server runs by default at http://localhost:8083.
Open http://localhost:8083 in your browser and log in. Write diary entries, trigger generation, and listen to lessons — all from the browser.
Download the latest APK from the Releases tab and install it on your phone.
Open the app, and enter your server URL (e.g. http://192.168.1.x:8083). Log in with your username and password.
| Home Screen | Lesson Screen |
|---|---|
![]() |
![]() |
Only needed if you want to modify the code. The first build is slow (compiles PyTorch, Whisper, and Piper TTS).
git clone https://github.com/lbesnard/LingoDiary.git
cd LingoDiary
docker compose up --build -dTo build the Android APK locally:
cd android_app && flutter build apk --release
# APK: android_app/build/app/outputs/flutter-apk/app-release.apk
# alternatively, run using docker:
docker compose run --build --rm apk-debug
