Dockerized Flask application for Yealink phonebook provisioning over HTTP.
- German documentation: README.de.md
- Manage multiple phonebooks
- Edit phonebook name/description
- Add, edit, and delete contacts
- Import/export CSV
- Import/export Yealink XML
- AX86R local phonebook import (manual + scheduled device sync)
- HTTP provisioning endpoint per phonebook:
/<slug>.xml - Safe phonebook deletion with slug confirmation
- Web authentication with admin user management
- UI language switch (EN/DE)
- Light/Dark theme toggle with system auto-detection
- Favicon included
- Functional tests with pytest
- CI and GHCR release pipeline
- Passwords are stored as hashes
- Session-based login for WebUI
- Admin-only user management
- Non-root container user
- Automatic startup database migrations for persistent volume compatibility
PUID/PGIDsupport for bind-mounted host volumes- Saved AX86R web credentials are stored encrypted at rest (derived from
SECRET_KEY)
Example docker-compose.yml:
version: "3.9"
services:
yeabook:
image: ghcr.io/itsh-neumeier/yeabook:latest
container_name: yeabook
restart: unless-stopped
ports:
- "8080:8080"
environment:
SECRET_KEY: "change-me"
BASE_HTTP_URL: "https://phonebook.neumeier.cloud"
ACCESS_DEFAULT_USERNAME: "yeabook_demo_u82"
ACCESS_DEFAULT_PASSWORD: "YbDemo!9K2xP4"
ADMIN_USERNAME: "admin"
ADMIN_PASSWORD: "change-me-now"
PUID: "1000"
PGID: "1000"
volumes:
- ./data:/dataStart:
docker compose up --buildWebUI:
- URL:
http://localhost:8080/login - Default admin user:
admin - Default admin password:
change-me-now
List WebUI users:
docker exec yeabook python -m app.admin_cli list-usersReset a WebUI password:
docker exec yeabook python -m app.admin_cli reset-password admin "new-strong-password"Per phonebook:
- HTTP:
http://<host>:8080/<slug>.xml - HTTP (with auth in URL):
http://<user>:<password>@<host>/<slug>.xml
Default bootstrap credential env vars:
ACCESS_DEFAULT_USERNAMEACCESS_DEFAULT_PASSWORD
Additional credentials are managed in the Access List admin page in the header.
- Open
Device Sync(admin menu). - Create a device link with AX86R IP/host, Yealink web login and target YeaBook phonebook.
- Set an interval in minutes and enable the profile.
- Use
Run nowfor immediate import.
Behavior:
- Import replaces all existing entries in the linked local phonebook on each run.
- Ringtones are synchronized from AX86R local contacts.
- Photos are synchronized only when they match YeaBook's allowed Yealink standard photo set.
If you use a host path (./data:/data or /docker-volumes/...:/data), the mounted folder must be writable by the container user.
- Set
PUIDandPGIDto your host user/group ID. - Ensure the host directory owner matches these IDs.
- If startup fails, YeaBook now prints a clear permission error for
/data/phonebooks.
name,office,mobile,other,line,groupRules:
namerequired- At least one of
office,mobile,otherrequired
python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows PowerShell
# .venv\Scripts\Activate.ps1
pip install -r requirements.txt -r requirements-dev.txt
python -m app.mainRun tests:
python -m pytest -q- The app runs automatic schema migrations on startup.
- Existing SQLite data in mounted volumes is migrated forward when new versions add schema changes.
- Migration is additive and designed to keep existing phonebooks/users/credentials usable across image upgrades.
Semantic Versioning 2.0.0: https://semver.org/spec/v2.0.0.html
See CHANGELOG.md.
MIT, see LICENSE.