Skip to content
Leon Achata
All work
Web

Enaki

Intercultural bilingual teacher-training school in the Peruvian Amazon

The full web ecosystem of a teacher-training institution: a public site for programs, courses and news, an API for contact and complaints, and a Moodle virtual campus, all on infrastructure I set up and maintain.

Role
Design, front end, back end, infrastructure and operations
Year
2026
Status
Live· enaki.edu.pe
enaki.edu.pe
Enaki

Where it started

Before

  • Site and domain on a shared hosting plan at Punto.pe
  • Nothing in front of the server: no CDN, no DDoS or bot filtering
  • No virtual campus and no backend of its own

Now

  • DNS and proxy on Cloudflare: CDN, DDoS mitigation, bot protection and HTTPS enforced with TLS 1.2+
  • Static front end on Hostinger; API and Moodle on a hardened VPS with Docker
  • The server only accepts traffic from Cloudflare, so its IP is never exposed
  • Encrypted daily backups stored off the server

Architecture

The path of a request, from the browser down to the database.

  1. 01

    Hostinger · enaki.edu.pe

    The site the visitor loads: static files, with no application server to attack. When someone sends a form or opens the virtual campus, the request heads to the VPS.

  2. 02

    Cloudflare

    DNS, CDN and proxy in front of everything. Absorbs DDoS attacks, filters bots and enforces HTTPS before a request reaches the VPS.

  3. 03

    Caddy on the VPS

    The only way into the VPS. Serves Cloudflare's IP ranges only, with a Cloudflare Origin certificate (Full strict) and security headers.

  4. 04

    FastAPI · Moodle

    api.enaki.edu.pe handles contact and complaints; aula.enaki.edu.pe is the virtual campus. Each runs in its own container.

  5. 05

    PostgreSQL · MariaDB

    On private Docker networks: no published port and no route to the internet. Only their own application can reach them.

Security

  • Origin hidden behind Cloudflare

    A firewall on the DOCKER-USER chain (Docker bypasses UFW) and Caddy itself both drop any connection that doesn't come from Cloudflare. Two layers, in case one fails.

  • Rate limiting by real IP

    Limits use the visitor's real address from CF-Connecting-IP, not the proxy's: 5 messages per minute on the contact form, 3 complaints every 10 minutes.

  • Strict validation

    Pydantic checks every field against Peruvian formats (DNI, mobile numbers), and outgoing e-mail rejects header injection.

  • Minimal surface

    The API only accepts POST from the site's own domains, hides its docs in production and doesn't announce server versions. JSON responses can't be framed.

  • Locked-down server access

    No root login and no passwords: Ed25519 SSH keys only, with a least-privilege admin user and a default-deny firewall.

Operations

  • Encrypted daily backups

    Moodle's database and files plus the site's PostgreSQL, encrypted with rclone crypt and shipped to Google Drive with 30 days of retention. Restore steps are documented next to the script.

  • Privacy by schedule

    Contact messages delete themselves after two years, exactly as the privacy policy promises under Peru's data-protection law.

  • Reproducible deploys

    One Docker Compose file describes the whole server, with pinned image versions, health checks, rotated logs and migrations applied on start. CI builds the site and tests the API against a real PostgreSQL.

What I built

  • Moodle virtual campus

    A custom Moodle 5 image on PHP 8.4: document root moved to /public as Moodle now requires, the PHP extensions it asks for, and its cron running every minute.

  • Online complaints book

    The complaints book Peruvian law requires, with yearly correlative numbering protected by a row lock and the mandatory copy e-mailed to the consumer.

  • Public site

    Programs, a 10-cycle curriculum, courses and news, with self-hosted fonts and content kept in versioned data files instead of a CMS.

  • Institutional e-mail

    Mail on the enaki.edu.pe domain with SPF, DKIM and DMARC, so messages from the site land in the inbox and not in spam.

Stack

React 19ViteTailwindFastAPIPostgreSQLMoodleMariaDBDockerCaddyCloudflare

Does your organization need a site like this?

I design, build and run websites with their own back end, security and infrastructure.

Related service: Websites & web apps

Contact me