No description
- Python 66.2%
- Jinja 16.1%
- JavaScript 9.7%
- CSS 5.7%
- Shell 1.4%
- Other 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Security Scans / Trivy filesystem/dependency/config scan (push) Successful in 11s
Security Scans / Semgrep SAST (push) Successful in 20s
CI Checks / lint-and-budget (push) Successful in 32s
Security Scans / Trivy image scan (push) Successful in 24s
Build CI Images / build-and-push (docker/openpl-sync.Dockerfile, plisrael-openpl-sync) (push) Successful in 1m1s
Build CI Images / build-and-push (docker/site-renderer.Dockerfile, plisrael-site-renderer) (push) Successful in 1m1s
Security Scans / Trivy image scan-1 (push) Successful in 42s
Security Scans / Trivy image scan-2 (push) Successful in 33s
Build CI Images / build-and-push (docker/nginx.Dockerfile, plisrael-frontend) (push) Successful in 31s
|
||
| .forgejo | ||
| db/init | ||
| deploy | ||
| directus | ||
| docker | ||
| docs | ||
| scripts | ||
| services | ||
| static | ||
| templates | ||
| tests | ||
| .gitignore | ||
| .trivyignore | ||
| docker-compose.website.yml | ||
| env.website.example | ||
| Makefile | ||
| README.md | ||
| renovate.json | ||
| requirements.txt | ||
powerliftingisrael
Compose-based bilingual powerlifting website with Directus CMS and automatic OpenPowerlifting records sync.
Services
frontend: Nginx serving generated static HTML + Markdown content negotiation.site-renderer: Python renderer that generates Hebrew/English pages from CMS + DB data. Also produces.mdcopies of all pages for AI agent consumption.openpl-sync: Python worker that pulls OpenPowerlifting updates hourly and recomputes Israeli records.directus: Headless CMS for editable content, behind Cloudflare Access.- Shared infra
postgres(external ongitgudnetwork): database for CMS and records data.
Architecture
Cloudflare → Caddy (TLS) → nginx → static HTML / JSON / MD
↑
site-renderer (5min cycle) ← PostgreSQL ← openpl-sync (hourly)
↑ ↑
Directus CMS OpenPowerlifting CSV
- Cache: Aggressive Cloudflare caching (31d assets, 10m HTML) with markdown bypass.
- Security: WAF blocks probes + injection, rate-limited,
.well-known/exempted. - Email: SPF
-all+ DMARCp=reject— no email sending/receiving, spoofing impossible. - DNSSEC: Active (algo 13) — DNS responses cryptographically signed.
Quick start
- Copy env file:
cp env.website.example .env- or start from
.env.dev.example/.env.prod.example
- Install Python deps:
python3 -m pip install -r requirements.txt
- Start stack:
docker compose -p plisrael-dev -f docker-compose.website.yml --env-file .env up -d --build
- Open site:
http://localhost:${FRONTEND_PORT}
- Directus admin:
http://localhost:${DIRECTUS_PORT}
Useful commands
make migrate- apply SQL and bootstrap tables.make seed- insert sample content.make build- render static pages now.make check14- run 14KB gzip budget check on critical pages.make directus-check- verify the Directus manifest matches bootstrap SQL, renderer collections, and permission expectations.make logs- tail logs.
SEO
- Structured data: Organization, WebSite (SearchAction), BreadcrumbList, Article, CollectionPage, ProfilePage, ItemList, WebPage.
- Server-rendered top-20 lifter rankings as
ItemListschema. - Bilingual
hreflangtags (he/en/x-default) on every page. - Sitemap with
lastmod,priority,changefreq, and language alternates. - Open Graph + Twitter card metadata with image dimensions.
- Favicon with multi-resolution
.icofallback andsizesattribute. - Canonical URLs, meta descriptions, branded titles on all pages.
AI Discoverability
- Link headers (RFC 8288):
Link: </sitemap.xml>, </records-data.json>, </.well-known/agent.json>on every response. - agent.json: Self-describing AI card at
/.well-known/agent.jsonwith resources + search endpoint. - DNS-AID:
_index._agents.powerliftingisrael.comSVCB record (alpn=h2, port=443). - Content Signals:
ai-train=yes, search=yes, ai-input=yesinrobots.txt. - Markdown for Agents:
Accept: text/markdown→ nginx serves.mdcopies (generated by renderer viahtml2text). Cloudflare bypasses cache for markdown requests.
14KB Budget
Critical pages must stay under 14KB gzip (including CSS + JS payload):
/index.html /en/index.html
/records/index.html /en/records/index.html
Checked in CI via make check14 → runs scripts/check_14kb.py.
Forgejo pipelines
.forgejo/workflows/build.yml- run tests + build/push renderer and sync images..forgejo/workflows/ci.yml- syntax checks, migrations, static build, 14KB budget..forgejo/workflows/deploy-dev.yml- deploy dev via Compose..forgejo/workflows/deploy-prod.yml- deploy prod via Compose..forgejo/workflows/renovate.yml- automated dependency updates every 6h.
Production/dev stack uses the shared external gitgud Docker network and the existing infra Postgres host (postgres:5432).
Content model
| Collection | Source | Purpose |
|---|---|---|
posts |
Directus / DB | Blog posts (bilingual, slug-based) |
updates |
Directus / DB | Short updates (bilingual, slug-based) |
pages |
Directus / DB | Static pages (about, contact) — nav-aware |
sponsors |
Directus / DB | Sponsor/partner listings with tiers |
site_settings |
Directus / DB | Singleton: site name, tagline, footer, contact |
Records are sourced from OpenPowerlifting, strict Country = Israel, read-only.