4.6 KiB
Molodetz
Blog roll of the Molodetz community. Quiet, serif, slightly provocative. Posts are markdown in SQLite, written by retoor through an admin area. Flyers and memes are galleries. Join is a real sign-up form ("I'm in"). The whole site is in English; the old Dutch paths (/rol, /standaard, /mensen, /binnen, /voorwaarden) redirect with 301.
Built to the frozen DPP template (/workspace/dpp/dptemplate.md). See SELECTION.md for the module choice and COMPLIANCE.md for the review.
Running
make install # venv in .venv, pip install -e ".[dev]", Chromium, git hooks
cp .env.example .env # only when there is no .env yet; chmod 600 .env
make dev # http://127.0.0.1:8088, reload
make prod # workers, pinned static version
make install needs a python3 with the venv module (Debian/Ubuntu ship it as python3-venv).
Without make:
.venv/bin/python -m uvicorn molodetz.main:app --host 127.0.0.1 --port 8088
The first start creates the administrator from MOLODETZ_ADMIN_USERNAME / MOLODETZ_ADMIN_EMAIL / MOLODETZ_ADMIN_PASSWORD in .env, seeds the placeholder posts once and syncs the gallery. A one-time migration (system.migrate.english) translates content seeded by older Dutch versions. Log in at /auth/login, admin at /admin.
Testing
make test # unit + api + e2e (Playwright, headless)
make test-headed # visible with slow motion
make check-ui # six static gates + em-dash + json_error order
make preflight # import, pyflakes, JS syntax, sqlglot lint, check-ui
make coverage
make locust-headless
Tests boot their own server on port 8099; set MOLODETZ_TEST_PORT to a free port when 8099 is taken. Browser tests wait up to 60 seconds per step and retry a stalled page load once via goto_ready in tests/conftest.py.
Docker
docker compose up -d --build # dev server on http://127.0.0.1:19847, reload on change
docker compose logs -f # follow logs
docker compose down # stop
The container runs the dev server (uvicorn --reload) with ./molodetz mounted, so every saved change is live within seconds. Data lives in the file mount /var/lib/molodetz-staging (plain files, no named volumes anywhere). The admin account comes from MOLODETZ_ADMIN_USERNAME / MOLODETZ_ADMIN_EMAIL / MOLODETZ_ADMIN_PASSWORD (default password staging-admin-pass-1, override per shell); an empty password skips admin bootstrap. The compose port is fixed at 127.0.0.1:19847 and is what staging.app.molodetz.nl proxies to, so keep it stable.
make staging-refresh # copy the holy prod database over staging, then verify
Refresh snapshots /var/lib/molodetz (online backup API, production keeps running), integrity-checks the copy, stops staging, swaps the staging file mount content, restarts, and verifies health. After a refresh the staging admin password is the production one, so pass it to make screenshots-staging STAGING_ADMIN_PASSWORD=....
Screenshots
make screenshots # test gallery into ../static/pizdetz/test
make screenshots-staging # staging gallery into ../static/pizdetz/staging
make screenshots-production SCREENSHOTS_ADMIN_PASSWORD=... # production gallery into ../static/pizdetz/production
Each run captures 32 full-page desktop shots (public, docs, admin) plus a 25-cell responsive matrix (home, roll, flyers, join, docs at 1440x900, 768x1024, 390x844, 360x740, 320x568) with a horizontal-overflow check per cell, then rebuilds the hub page at ../static/pizdetz/index.html from whichever environments exist on disk.
Rules, exactly: test always boots its own throwaway server and seeds one join request; staging and production shoot a live base URL and never seed. Staging logs in with STAGING_ADMIN_PASSWORD (default staging-admin-pass-1, must match the compose admin password); production has no default and fails loudly without SCREENSHOTS_ADMIN_PASSWORD. Any overflow is reported and exits nonzero. Override the output root with SCREENSHOTS_DIR=....
CLI
molodetz --help: roles, API keys, posts list/import (.md and .pdf via pypdf), join requests, backups, prunes, sql-lint, emoji regenerate.
Data
Everything lives under data/ (database molodetz.db, uploads, backups, keys, locks). .env and data/ are in .gitignore.
Operations
Production serving runs through molohttp on this box. molohttp_deploy.md is the operator guide: access, file owners, the backup specification, site changes, and static publishing.