diff --git a/README.md b/README.md index 4f73b2a..2d5a5d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,111 @@ -# trove +# Trove -A small web search engine. +A federated search engine for the small web. Seeded by fediverse attention, ranked by domain coherence rather than commercial authority. + +## Tech stack + +Laravel 13 · Livewire 4 · PostgreSQL 17 (tsvector FTS) · Redis 7 · FrankenPHP · Vite 8 · Tailwind 4. + +## Local development + +Requires [Nix](https://nixos.org/download/) and [Podman](https://podman.io/). + +```sh +nix-shell # enter dev shell +dev-up # start app, db, redis +``` + +App: `http://localhost:8200` · Vite HMR: `http://localhost:5175` + +Other helpers inside the nix shell: `dev-down`, `dev-rebuild`, `dev-shell`, `dev-artisan `, `dev-logs`. + +## Self-hosting + +Trove ships as a Docker image published to `forge.lvl0.xyz/lvl0/trove`. You provide the compose/stack config. + +### Required environment + +| Variable | Purpose | +|---|---| +| `APP_KEY` | Laravel app key. Generate with `docker run --rm forge.lvl0.xyz/lvl0/trove:latest php artisan key:generate --show`. **Must persist across deployments** or sessions/encrypted data break. | +| `APP_URL` | Public URL, e.g. `https://trove.example.org` | +| `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD` | PostgreSQL credentials | +| `DB_HOST` | Hostname of the PostgreSQL service. Default `db`. Override if your service is named differently. | +| `REDIS_HOST` | Hostname of the Redis service. Default `redis`. Override if your service is named differently. | + +### Services you need to provide + +- **App**: pull `forge.lvl0.xyz/lvl0/trove:latest` (or a pinned `v*` tag). Exposes port `8000` inside the container. The image runs migrations and warms caches on boot. +- **PostgreSQL 17**. Hostname must be reachable as `db` (default) or set `DB_HOST`. Persist `/var/lib/postgresql/data`. +- **Redis 7** with `--appendonly yes` (queue jobs persist across restarts). Hostname `redis` or set `REDIS_HOST`. + +On first boot the startup script waits for PostgreSQL, warms caches, then runs `php artisan migrate --force` automatically. The 60-second wait loop covers slow PG init; it exits with a clear error if PG never becomes reachable. + +### Volumes + +- `/app/storage` — Laravel writable paths (logs, cached views, uploads). Persist this. + +### Healthcheck + +The image exposes `GET /up` (Laravel's built-in health route). The Dockerfile declares a HEALTHCHECK; your orchestrator can use `curl -fsS http://localhost:8000/up` for liveness. + +### Example compose stack + +A minimal reference — adapt for your infra. DockGE, Portainer, `docker compose`, Kubernetes, and bare `podman play kube` all work with equivalent configs. + +```yaml +services: + app: + image: forge.lvl0.xyz/lvl0/trove:latest + restart: always + ports: ["${APP_PORT:-8400}:8000"] + environment: + APP_KEY: "${APP_KEY}" + APP_URL: "${APP_URL}" + DB_DATABASE: "${DB_DATABASE}" + DB_USERNAME: "${DB_USERNAME}" + DB_PASSWORD: "${DB_PASSWORD}" + volumes: + - app_storage:/app/storage + depends_on: + db: { condition: service_healthy } + redis: { condition: service_healthy } + + db: + image: postgres:17-alpine + restart: always + environment: + POSTGRES_DB: "${DB_DATABASE}" + POSTGRES_USER: "${DB_USERNAME}" + POSTGRES_PASSWORD: "${DB_PASSWORD}" + volumes: + - db_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] + interval: 10s + retries: 5 + start_period: 10s + + redis: + image: redis:7-alpine + restart: always + command: redis-server --appendonly yes + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + retries: 5 + +volumes: + db_data: + redis_data: + app_storage: +``` + +### Upgrades + +Pull the new image tag, recreate the app container. Migrations run on boot (`php artisan migrate --force` in the startup script). Rollback by pointing at the previous `v*` tag. ----