No description
  • HTML 39.4%
  • Python 27.6%
  • CSS 23.1%
  • JavaScript 9.3%
  • Dockerfile 0.6%
Find a file
2026-07-20 14:03:05 -05:00
.scratch/conversion-flow-seo feat: env-gated Google Search Console + Bing site verification 2026-07-20 13:48:02 -05:00
backend feat: env-gated Google Search Console + Bing site verification 2026-07-20 13:48:02 -05:00
docs docs: grilling context, no-fabrication ADR, and conversion-flow-seo spec + tickets 2026-07-17 16:09:52 -05:00
.env.example feat: env-gated Google Search Console + Bing site verification 2026-07-20 13:48:02 -05:00
.gitignore fix: switch analytics to Umami Cloud, drop the self-hosted stack 2026-07-17 16:49:25 -05:00
Caddyfile fix: switch analytics to Umami Cloud, drop the self-hosted stack 2026-07-17 16:49:25 -05:00
CLAUDE.md fix: switch analytics to Umami Cloud, drop the self-hosted stack 2026-07-17 16:49:25 -05:00
CONTEXT.md docs: grilling context, no-fabrication ADR, and conversion-flow-seo spec + tickets 2026-07-17 16:09:52 -05:00
docker-compose.prod.yml Rebrand to marketing site and scrap the client portal 2026-07-01 16:40:46 -05:00
docker-compose.yml Rebrand to marketing site and scrap the client portal 2026-07-01 16:40:46 -05:00
LICENSE Initial commit 2026-06-10 14:48:55 -05:00
README.md Rebrand to marketing site and scrap the client portal 2026-07-01 16:40:46 -05:00
ruff.toml Rebrand to marketing site and scrap the client portal 2026-07-01 16:40:46 -05:00

Avian Technologies Group — marketing site

A single-page marketing website built with FastAPI + Jinja2, served behind a Caddy reverse proxy via Docker Compose. It renders the home page and handles a contact form that emails submissions over SMTP. No database, no login, no persistent state.


Architecture

Internet → :8080 → Caddy (reverse proxy) → backend:8000 → FastAPI / Jinja2
  • Caddy — TLS termination and reverse proxy to the backend
  • Backend — FastAPI app rendering the home page and a POST /api/contact endpoint
  • Static assets — served by FastAPI via a StaticFiles mount at /static

Routes: / (home), /api/contact, /robots.txt, /sitemap.xml, /favicon.ico. Everything else returns the styled 404 page.


Quick start (Docker Compose)

Prerequisites: Docker + Docker Compose v2.

cp .env.example .env      # optional — defaults work out of the box
docker compose up -d --build
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/   # → 200

The site is at http://localhost:8080.

Production (automatic HTTPS)

Point the Caddyfile at your domain:

your-domain.com {
	reverse_proxy backend:8000
}

Then launch with the production overlay (publishes 80/443, persists certs):

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

Set SITE_BASE_URL=https://your-domain.com in .env so sitemap.xml and robots.txt emit the right URLs.


Configuration

All settings are environment variables (see .env.example); all are optional with sensible defaults.

Variable Purpose
SITE_BASE_URL Public base URL used in sitemap.xml / robots.txt
CONTACT_EMAIL / CONTACT_PHONE / CONTACT_LOCATION Contact details shown on the site
AFTER_HOURS_PHONE Optional after-hours number
NOTIFY_TO Where contact-form submissions are emailed
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_FROM SMTP delivery for the contact form

If SMTP isn't configured, contact submissions are logged to the container output instead of emailed — the form still returns success to the visitor.


Local development

cd backend
pip install -r requirements.txt
TEMPLATES_DIR=templates STATIC_DIR=static uvicorn main:app --reload --port 8000

Tests and lint:

pytest backend/tests
ruff check backend