A minimalistic, self-hosted diary and journaling web app. https://piruet.app
  • Python 55.1%
  • CSS 18.8%
  • HTML 14%
  • JavaScript 11%
  • Just 0.9%
  • Other 0.2%
Find a file
PatillaCode ea690da882
All checks were successful
Test and publish Docker image / test (push) Successful in 30s
Test and publish Docker image / e2e (push) Successful in 3m25s
Test and publish Docker image / build (push) Has been skipped
fix: fix domain in README
2026-04-27 21:07:53 +02:00
.forgejo/workflows test: boost coverage to 100%, add Firefox e2e, fix test speed (#11) 2026-04-23 10:13:39 +02:00
app feature/public-launch (#15) 2026-04-27 18:43:57 +02:00
screenshots Add demo user with auto-reset and README enhancements 2026-04-18 03:33:03 +02:00
scripts feat: self-host fonts and Tiptap, add admin task scheduler (#10) 2026-04-22 17:49:19 +02:00
tests feature/public-launch (#15) 2026-04-27 18:43:57 +02:00
.env.example feat: self-host fonts and Tiptap, add admin task scheduler (#10) 2026-04-22 17:49:19 +02:00
.gitignore fix: commit package-lock.json so npm ci works in Docker CI builds 2026-04-23 10:27:04 +02:00
CLAUDE.md docs: add CC details 2026-04-22 17:34:03 +02:00
COMMERCIAL_LICENSE.md feature/ux-improvements (#6) 2026-04-21 16:55:26 +02:00
compose.yml Initial commit — Piruetas v0.1.0 2026-04-18 02:00:32 +02:00
CONFIGURATION.md feature/modal-logo-mobile (#8) 2026-04-21 22:42:36 +02:00
Dockerfile feat: self-host fonts and Tiptap, add admin task scheduler (#10) 2026-04-22 17:49:19 +02:00
justfile test: boost coverage to 100%, add Firefox e2e, fix test speed (#11) 2026-04-23 10:13:39 +02:00
LICENSE feature/ux-improvements (#6) 2026-04-21 16:55:26 +02:00
package-lock.json fix: commit package-lock.json so npm ci works in Docker CI builds 2026-04-23 10:27:04 +02:00
package.json feat: self-host fonts and Tiptap, add admin task scheduler (#10) 2026-04-22 17:49:19 +02:00
pyproject.toml feature/data-management-tab (#12) 2026-04-24 16:11:16 +02:00
pyrightconfig.json chore: add pyrightconfig.json to resolve venv imports 2026-04-18 18:55:01 +02:00
README.md fix: fix domain in README 2026-04-27 21:07:53 +02:00
uv.lock feature/data-management-tab (#12) 2026-04-24 16:11:16 +02:00

Piruetas

A minimalistic, self-hosted diary and journaling web app.

Piruetas gives each day its own page with a clean writing experience, multi-user support, and full control over your data.

Try it

A live demo is available at piruet.app. Log in with demo / piruetas, content resets every 30 minutes.

Dark Light
Dark theme Light theme

Features

  • Day-per-page diary with month calendar navigation
  • Rich text editing (bold, italic, links, inline images) via Tiptap
  • Auto-save with 2-second debounce and "Saved" toast
  • Drag-and-drop image uploads (JPEG, PNG, GIF, WebP, max 10 MB)
  • Public entry sharing via unique link (with revocation)
  • Multi-user with admin panel (create, delete, reset passwords)
  • English and Spanish UI (locale switcher in header, cookie-persisted)
  • Configurable calendar week start (Monday or Sunday)
  • Light and dark theme (persisted in localStorage)
  • Mobile responsive with bottom toolbar above keyboard
  • Docker deployable with CI/CD via Forgejo

Quick start (Docker)

Create a compose.yml:

services:
  piruetas:
    image: forgejo.patilla.es/patillacode/piruetas:latest
    ports:
      - "8000:8000"
    volumes:
      - ./data:/data
    environment:
      SECRET_KEY: change-me-to-a-random-string
      ADMIN_USERNAME: admin
      ADMIN_PASSWORD: changeme
    restart: unless-stopped
docker compose up -d

Open http://localhost:8000 and log in with your admin credentials.

To update: docker compose pull && docker compose up -d

Running behind a reverse proxy (nginx, Caddy, Traefik)? Set TRUST_PROXY: "true" in your environment so rate limiting uses the real client IP.

Local development

Requirements: Python 3.12+, uv, just.

git clone ssh://git@forgejo.patilla.es:2223/patillacode/piruetas.git
cd piruetas
cp .env.example .env
# Edit .env: set SECRET_KEY to any string, set SECURE_COOKIES=false
just install
just dev

Open http://localhost:8000.

Run just to see all available recipes.

JS bundle

The Tiptap editor library is bundled from npm into app/static/js/vendor/tiptap.bundle.js using esbuild. This file is committed to the repo so no Node tooling is needed to run the app — it's treated as a vendored asset, the same as self-hosted font files.

To rebuild after upgrading Tiptap (bump versions in package.json first):

just build-js

The Docker build always rebuilds the bundle from source in a Node build stage, so the committed bundle is only used for local development without Docker.

Running tests

Unit and integration tests (no browser required):

just test

E2E tests with Playwright (one-time browser install needed first):

just install-e2e   # downloads Chromium and Firefox — run once
just test-e2e      # headless
just test-e2e-headed  # with visible browser (useful for debugging)

Configuration

See CONFIGURATION.md for all available environment variables.

License

Piruetas is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

For use in proprietary or commercial products without complying with the AGPL-3.0, a commercial license is available. See COMMERCIAL_LICENSE.md or contact patillacode@gmail.com.