Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 51 additions & 26 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,28 +1,53 @@
SECRET_KEY="<Your Secret Key>"
DEBUG=TRUE

# Copy this file to .env and fill in all values.

# ── PostgreSQL ─────────────────────────────────────────────────────────────────
# Used by the postgres container (POSTGRES_*) and by Django (DB_*)
# Keep the values in both sets in sync.
POSTGRES_DB=metron
POSTGRES_USER=<DB User>
POSTGRES_PASSWORD=<DB Password>

DB_NAME=metron
DB_USER=<DB User>
DB_PASSWORD=<DB Password>
DB_HOST=localhost

# ── Redis ──────────────────────────────────────────────────────────────────────
REDIS_URL=redis://localhost:6379/0
THUMBNAIL_REDIS_HOST=localhost

# ── Django ─────────────────────────────────────────────────────────────────────
SECRET_KEY=<Your Secret Key>
DEBUG=True
ALLOWED_HOSTS=.localhost,127.0.0.1

PUSHOVER_TOKEN=""
PUSHOVER_USER_KEY=""

DB_NAME="<DB Name>"
DB_USER="<DB User>"
DB_PASSWORD="<DB Password>"

STATIC_ROOT="/home/user/static"

MEDIA_ROOT="/home/user/media"

EMAIL_BACKEND="django.core.mail.backends.console.EmailBackend"
EMAIL_HOST="smtp.example.org"
EMAIL_USER="postmaster@example.org"
EMAIL_PASSWORD="<Email Passowrd>"

DO_ACCESS_KEY_ID=""
DO_SECRET_ACCESS_KEY=""
DO_STORAGE_BUCKET_NAME=""
DO_S3_ENDPOINT_URL=""
DO_S3_CUSTOM_DOMAIN=""

HCAPTCHA_SECRET_KEY=""
# ── DigitalOcean Spaces (static + media storage) ──────────────────────────────
DO_ACCESS_KEY_ID=<DO Access Key ID>
DO_SECRET_ACCESS_KEY=<DO Secret Access Key>
DO_STORAGE_BUCKET_NAME=<DO Storage Bucket Name>
DO_S3_ENDPOINT_URL=<DO S3 Endpoint URL>
DO_S3_CUSTOM_DOMAIN=<DO S3 Custom Domain>

# ── DigitalOcean Spaces (database backups) ────────────────────────────────────
DO_BACKUP_BUCKET_NAME=<DO Backup Bucket Name>

# ── Email ──────────────────────────────────────────────────────────────────────
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
EMAIL_HOST=<Email Host>
EMAIL_USER=<Email User>
EMAIL_PASSWORD=<Email Password>
EMAIL_FROM=<Email From>

# ── Pushover notifications ─────────────────────────────────────────────────────
PUSHOVER_TOKEN=<Pushover Token>
PUSHOVER_USER_KEY=<Pushover User Key>

# ── hCaptcha / Rapid API ───────────────────────────────────────────────────────
HCAPTCHA_SECRET_KEY=<hCaptcha Secret Key>
RAPID_API_KEY=<Rapid API Key>
RAPID_API_HOST=<Rapid API Host>

# ── Anubis bot protection ──────────────────────────────────────────────────────
# 64-character hex Ed25519 private key used to sign Anubis challenge cookies.
# Generate with: openssl rand -hex 32
ED25519_PRIVATE_KEY_HEX=<Ed25519 Private Key Hex>
89 changes: 89 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Development Setup

## Prerequisites

- Podman
- Python (see `.python-version` for required version)
- A production database dump (optional, see below)

## Container Setup

### PostgreSQL

```bash
podman run -d \
--name metron-postgres \
-e POSTGRES_DB=metron \
-e POSTGRES_USER=<DB User> \
-e POSTGRES_PASSWORD=<DB Password> \
-p 5432:5432 \
-v metron-pgdata:/var/lib/postgresql/data \
postgres:16
```

The named volume (`metron-pgdata`) ensures data persists even if the container is removed.

### Redis

```bash
podman run -d \
--name metron-redis \
-p 6379:6379 \
redis
```

## Environment Variables

Copy `.env.example` to `.env` and fill in the values. Add the following variables that are not in the example:

```ini
DB_HOST=localhost

REDIS_URL=redis://localhost:6379/0
THUMBNAIL_REDIS_HOST=localhost
```

## Database Setup

### Option A: Restore from a production dump

First, set up the required PostgreSQL extensions and the immutable `unaccent` wrapper (needed for trigram indexes):

```bash
podman exec -it metron-postgres psql -U <DB User> -d metron -c "
CREATE EXTENSION IF NOT EXISTS unaccent;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE OR REPLACE FUNCTION public.unaccent(text)
RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
\$\$ SELECT public.unaccent('public.unaccent', \$1) \$\$;
"
```

Then copy the dump into the container and restore it:

```bash
podman cp /path/to/dump.pgdump metron-postgres:/tmp/dump.pgdump
podman exec -it metron-postgres pg_restore -U <DB User> -d metron --no-owner /tmp/dump.pgdump
```

Finally, apply any migrations not yet on production:

```bash
python manage.py migrate
```

### Option B: Fresh database

```bash
python manage.py migrate
```

## Starting and Stopping Containers

```bash
# Start
podman start metron-postgres metron-redis

# Stop
podman stop metron-postgres metron-redis
```
Loading