Add Django site, Docker packaging, and beta/prod Gitea deploys.
Unignore site/ (was blocked by mkdocs /site rule), add compose/Docker/uv tooling, and split deploys so push to main goes to beta while prod stays manual.
This commit is contained in:
@@ -1,54 +1,92 @@
|
||||
# monica_site
|
||||
|
||||
Django 6.0 marketing platform for a single realtor client — a cheaper replacement for
|
||||
PostcardMania with added social-media automation.
|
||||
|
||||
- **Public site** with a reCAPTCHA-protected contact form.
|
||||
- **Private portal** for the realtor: lead inbox + UTM/campaign analytics.
|
||||
- **Mailing list** with per-channel consent and easy opt-out; outreach over
|
||||
**email + SMS (SMTP2GO)** and **postcard** (pluggable provider, default Lob).
|
||||
- **Social automation** — schedule/post to Facebook, Instagram, and LinkedIn via native APIs.
|
||||
|
||||
See [`docs/monica-site-design.md`](docs/monica-site-design.md) for the full architecture,
|
||||
data model, folder layout, deployment, and phased implementation plan.
|
||||
Django 6 marketing platform for Monica Dhillon / MKDRealtor.com — public site, realtor
|
||||
portal, multi-channel outreach (email + SMS via SMTP2GO, postcards via PCM Integrations), and social
|
||||
scheduling (Facebook / Instagram / LinkedIn) with Ollama-assisted drafting.
|
||||
|
||||
## Stack
|
||||
|
||||
- Django 6.0, Python 3.12
|
||||
- Postgres (production), SQLite (local fallback)
|
||||
- **Django Tasks (`django.tasks`)** for background work (sends, scheduled posts) — Postgres
|
||||
queue store + a single worker process; no Redis/Celery
|
||||
- `uv` package manager
|
||||
- Docker; deployed via the `server-infra` Ansible pipeline onto active/active hosts behind
|
||||
Nginx Proxy Manager (same pattern as `company_site`)
|
||||
- Django 6 + `uv`
|
||||
- Postgres (prod/beta); SQLite locally when `DATABASE_URL` unset
|
||||
- **dj-queue** (Django Tasks backend, Postgres queue, no Redis/Celery)
|
||||
- Docker; deploy via `server-infra` Ansible pipeline
|
||||
|
||||
## Status
|
||||
## Environments
|
||||
|
||||
Design/planning phase. Implementation follows the phases in the design doc:
|
||||
| Env | Domain | Port (host) | Gate |
|
||||
|-----|--------|-------------|------|
|
||||
| prod | `mkdrealtor.com` | 8004 | `SITE_UNDER_CONSTRUCTION=true` (holding page) |
|
||||
| beta | `monica-preview.aimloperations.com` | 8014 | full app (`SITE_UNDER_CONSTRUCTION=false`) |
|
||||
|
||||
0. Scaffolding & deploy skeleton
|
||||
1. Public site + contact form + leads + UTM
|
||||
2. Mailing list + email/SMS outreach + opt-out
|
||||
3. Postcards
|
||||
4. Social automation
|
||||
5. Hardening & polish
|
||||
|
||||
## Local development (planned)
|
||||
|
||||
Once scaffolded:
|
||||
## Local development
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
docker compose up # web + postgres
|
||||
cd site
|
||||
uv run python manage.py migrate
|
||||
uv run python manage.py runserver
|
||||
# Dev uses ImmediateBackend — tasks run inline. For prod-like workers, run worker-entrypoint.
|
||||
# optional: docker compose up # web + postgres (hot reload)
|
||||
# optional worker: docker compose --profile worker up worker
|
||||
```
|
||||
|
||||
## Deployment
|
||||
Docker compose mounts `./site` into the container and runs Django `runserver` when
|
||||
`DJANGO_ENV=dev` (the default). Edit Python/templates → auto-reload; no image rebuild.
|
||||
Rebuild only when Dockerfile / deps (`pyproject.toml`, `uv.lock`) change:
|
||||
|
||||
CI on merge to `main` runs tests, then calls
|
||||
`server-infra/scripts/deploy.sh --app monica_site --env prod --ref <sha>`.
|
||||
Requires a `monica_site` entry in the `server-infra` `app_catalog`, a reserved host port pair,
|
||||
a shared-Postgres database, a singleton django.tasks worker on one host, and a control-node
|
||||
secret env file. Details in the design doc.
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
### Local secrets (SMTP2GO, etc.)
|
||||
|
||||
Copy `.env.example` → `.env` (gitignored). Compose reads `.env` for email vars.
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# fill EMAIL_HOST_USER / EMAIL_HOST_PASSWORD
|
||||
# for real delivery (not console logs):
|
||||
# EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Without `EMAIL_BACKEND=…smtp…`, mail prints to the web container logs (console backend).
|
||||
|
||||
### SMTP2GO delivery webhooks
|
||||
|
||||
See [`site/messaging/README.md`](site/messaging/README.md) for SMTP2GO email/SMS webhooks
|
||||
and PCM Integrations postcard designer + webhook setup (Bearer auth, events).
|
||||
|
||||
Prod compose (`docker-compose.prod.yml`) still uses gunicorn with baked-in image code.
|
||||
|
||||
## Secret env files (control node)
|
||||
|
||||
Create on the deploy host:
|
||||
|
||||
```text
|
||||
~/Documents/secrets/monica_site/monica_site_prod.env
|
||||
~/Documents/secrets/monica_site/monica_site_beta.env
|
||||
```
|
||||
|
||||
Templates: `.env.prod.example` (full var list). Validate with:
|
||||
|
||||
```bash
|
||||
./scripts/validate-env.sh ~/Documents/secrets/monica_site/monica_site_prod.env
|
||||
```
|
||||
|
||||
## Deploy
|
||||
|
||||
CI on merge to `main` → tests → `server-infra/scripts/deploy.sh --app monica_site --env prod --ref <sha>`.
|
||||
|
||||
Start the **dj-queue worker on exactly one host**:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml --profile worker up -d
|
||||
```
|
||||
|
||||
## Apps
|
||||
|
||||
`public` · `accounts` · `dashboard` · `leads` · `contacts` · `analytics` · `messaging` · `social`
|
||||
|
||||
Social AI drafts: `POST /portal/social/api/generate/` → Ollama at `OLLAMA_BASE_URL` (default `http://10.0.0.128:11434`).
|
||||
|
||||
See [`docs/monica-site-design.md`](docs/monica-site-design.md) for architecture.
|
||||
|
||||
Reference in New Issue
Block a user