SYSTEM
How this site works
This page describes the site itself: how it is built, how it is tested and released, and how it is doing right now. The live values are read from this server, on this request.
Current state
- Health
- Operational
- Release
bd8800e- Deployed
- Checked
Health is one verdict over the database and media storage checks; the details are shown in the admin only. The result is cached for at most 15 seconds. The release is the tag of the running release: its short commit SHA. No uptime percentage, no made-up graphs.
Architecture
All services run with Docker Compose on a single server, on a private network. nginx is the only service open to the outside; the API, the database and the backup service stay on the internal network.
- CLIENT
- BrowserPages arrive as ready HTML; JavaScript only adds interaction.
HTTPS
- EDGE
- nginxTLS (Let's Encrypt), HSTS and security headers, request size and rate limits, compression.
/ → web · /api → api
- APPLICATION
- webAngular 22, server-rendered on Node.js 24. Draws each page on request and writes its own CSP into every response.
- api.NET 10 modular monolith: REST API, authentication, media processing, e-mail queue.
private Docker network
- DATA
- PostgreSQL 18One database, tables per module.
- Media storageUploaded files and the generated image sizes.
- OPERATIONS
- backupDatabase dump and media archive, daily and before every deploy, encrypted.
- metricsPrometheus format; not public, read from the internal network only.
Pages rendered on the server
- SSR
- Every public page is rendered on the server at request time, from live content. Search engines and visitors without JavaScript read the same page.
- Hydration
- The browser takes over the server's HTML instead of drawing it again. Home page sections become interactive as they scroll into view (incremental hydration); data the server fetched is not requested again.
- Zoneless Angular
- No zone.js: signals drive change detection.
- Languages
- Each language has its own address (/tr, /en). The root address follows the last choice or the browser language; content without a translation is shown in the default language.
- Content
- Text comes from the admin. Markdown is turned into HTML on the server and cleaned against an allow-list; no unsanitized HTML reaches the browser.
The 3D sky
- Loaded apart
- three.js is not in the initial JavaScript; the scene arrives in a separate, deferred chunk. The size of the initial load is held to a budget.
- Quality
- The lowest of the owner's setting, the visitor's choice and the device's capability. On a slow or data-saving connection 3D starts off; if the frame rate drops, quality steps down one level.
- Reduced motion
- When the system asks for reduced motion, the scene turns into a still frame and entrance animations stop. The “3D background” button in the footer switches 3D off and remembers the choice.
- Without WebGL
- A still CSS sky and a static map of the solar system are drawn; the same information is also there as a list. The site works in full without 3D.
Privacy and security
- Visit counter
- When on, it sets no cookies and calls no third-party service. It counts per day and page; unique visitors come from the IP and browser hashed with a key that changes daily, and the hashes of past days are deleted.
- Content Security Policy
- Every response carries its own nonce: only this site's own scripts run, eval is off and the site cannot be framed by another page. The end-to-end tests look for CSP violations on every page.
- Breached passwords
- Admin accounts reject a password that appears in known data breaches. Only the first 5 characters of the password's SHA-1 hash go to Have I Been Pwned (k-anonymity); the password itself never leaves the server.
- Errors
- API errors come back in a standard format (RFC 9457) without internal details.
Delivery pipeline
- Local quality gate
- No hosted CI: every gate runs on the developer's machine with one command. Formatting and lint, unit tests, integration tests against a real PostgreSQL, module boundary tests, the API contract matching its TypeScript types, documentation links, secret scanning, dependency and container image vulnerability scans.
- End to end
- Browser tests on a real Docker Compose stack: accessibility scans (axe) on the public pages, a CSP violation check in every test, visual comparison with reference images and a Lighthouse budget (performance ≥ 90, accessibility ≥ 95, best practices ≥ 95, SEO 100).
- Release
- Images are tagged with the commit SHA, built locally and loaded onto the server over SSH; no registry.
- Deploy
- A backup first, then the database migration. If the new release fails its health check, the previous one comes back automatically.
Operations
- Backups
- The database dump and the media archive are encrypted with age. The sets of the last 7 days, 4 weeks and 6 months are kept, and copied off-site when configured. Restoring is rehearsed by a script.
- Alerts
- With an alert address set, a failed or overdue backup sends the owner one e-mail per event, and one more when it recovers.
- Metrics
- Request duration, error rate, cache hits and the e-mail queue are measured. The metrics endpoint is read from the internal network only and cannot be reached through this site.
- E-mail queue
- E-mails are written to a queue (outbox) in the same transaction as the data and retried with increasing delays; a passing failure does not lose an e-mail.