Sign inSign up

zzelav/ediurnum

By zzelav

•Updated about 7 hours ago

Private, self-hosted encrypted journal for daily reflection with reminders and optional AI insights

Image
Security
Content management system
0

576

zzelav/ediurnum repository overview

⁠ediurnum

A private, self-hosted journal for daily reflection – all content encrypted at rest, with guided questions, weekly and monthly reviews, reminders and optional AI insights through the AI chat of your choice.

diurnum (Latin for “diary”) + e for digital. Source code, documentation and changelog: github.com/ZZELAV/ediurnum⁠ · License: AGPL-3.0

⁠Features

  • One entry per day in 5–10 minutes: guided questions (experienced, feelings, learning & growth), free thoughts, mood
  • Search across all entries and a calendar that shows your mood per day
  • Statistics: writing streaks, mood over time, mood and energy per month and weekday, most frequent feelings
  • “Your first steps” on the dashboard to get started (first entry, About me, reminders, PIN, backup)
  • Weekly and monthly reviews, your own reminders and push notifications (also on iPhone as an installed web app)
  • About me: a short self-assessment (personality, values, goals) as background for AI insights
  • AI insights without API keys: a Markdown file for ChatGPT, Claude, Gemini, … with customisable instructions – ediurnum never sends anything to an AI on its own; focus points appear on the dashboard
  • Version history per entry (one version per day, changes highlighted), “on this day”, focus mode, German, English and Italian, light and dark theme, installable web app
  • Encryption: AES-256-GCM with a random master key (= recovery key), password via Argon2id, PIN-locked entries, encrypted backups, recovery key test in the settings; the journal locks itself shortly after you leave the app
  • Readable export as Markdown, JSON or PDF, and a backup converter that turns an encrypted backup into these formats without a running app: docker run --rm -it -v "$PWD:/work" -u "$(id -u):$(id -g)" zzelav/ediurnum node scripts/convert.ts /work/<backup>.ediurnum

⁠Quick start

A reverse proxy with HTTPS in front of it (e.g. NGINX Proxy Manager) is recommended – browsers only allow push notifications and installing the app on secure origins. Without it, ediurnum also runs over plain http://.

mkdir ediurnum && cd ediurnum
curl -fsSLO https://raw.githubusercontent.com/ZZELAV/ediurnum/main/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/ZZELAV/ediurnum/main/.env.example
cp .env.example .env            # set ORIGIN to your public https address
mkdir -p data && sudo chown 1000:1000 data
docker compose up -d

Then open your address and create the journal. Store the recovery key safely – without password and recovery key your entries cannot be recovered.

Step-by-step guide (proxy, push notifications, updates, backups): docs/DEPLOYMENT.md⁠

⁠Tags

TagMeaning
latestnewest release
1.1.0, …a specific release – see the changelog⁠

Images are built for linux/amd64 and linux/arm64 (e.g. Raspberry Pi 4/5). Pin a version in .env with EDIURNUM_VERSION=1.1.0.

⁠Configuration

VariableRequiredDescription
ORIGINyesExact public address, e.g. https://journal.example.com (cross-site protection, secure cookies, push sender). Without HTTPS use the http:// address – push and app installation then do not work
TZrecommendedTime zone for “today”, the version history and reminder times, default Europe/Zurich
ADDRESS_HEADER, XFF_DEPTHbehind a proxyReal client IP from the proxy, e.g. X-Forwarded-For and 1 (slows down password guessing)
BODY_SIZE_LIMITnoMaximum upload size for restoring a backup, default 50M
COOKIE_SECUREnotrue/false: mark the session cookie Secure (HTTPS only). Default follows ORIGIN (https:// → on)
VAPID_SUBJECTnoSender for push services (mailto: or https:), defaults to ORIGIN
LOG_LEVELnoerror, warn, info (default) or debug (every request). Logs never contain journal content
WIDGET_TOKENnoEnables /api/widget for dashboards (number of entries, time of the latest save, written today, current streak); at least 16 characters, sent as Authorization: Bearer <token>
Container
Port3000 (HTTP – put the HTTPS proxy in front)
Volume/data – the encrypted SQLite database; owned by user 1000
Userruns as non-root user node (1000); works with read_only: true and cap_drop: ALL
Health checkbuilt in (/login)

⁠Updates

docker compose pull && docker compose up -d

Database migrations run automatically. Download an encrypted backup in the app before larger updates.

⁠Privacy

Plaintext on disk is limited to dates, timestamps, flags and which sections an entry contains. To send reminders while the journal is closed, the reminder schedule and the push addresses of your devices are stored unencrypted; notifications never contain journal content.

Tag summary

Content type

Image

Digest

sha256:16458c840…

Size

71.7 MB

Last updated

about 7 hours ago

docker pull zzelav/ediurnum