|
|
||
|---|---|---|
| .forgejo/workflows | ||
| app | ||
| bootstrap | ||
| config | ||
| database | ||
| docker | ||
| packages/Lvl0/FediDiscover | ||
| public | ||
| resources | ||
| routes | ||
| storage | ||
| tests | ||
| .dockerignore | ||
| .editorconfig | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| .npmrc | ||
| artisan | ||
| composer.json | ||
| composer.lock | ||
| Dockerfile.dev | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| phpstan.neon | ||
| phpunit.xml | ||
| pint.json | ||
| README.md | ||
| shell.nix | ||
| vite.config.js | ||
Trove
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
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 <cmd>, 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 pinnedv*tag). Exposes port8000inside the container. The image runs migrations and warms caches on boot. - PostgreSQL 17. Hostname must be reachable as
db(default) or setDB_HOST. Persist/var/lib/postgresql/data. - Redis 7 with
--appendonly yes(queue jobs persist across restarts). Hostnameredisor setREDIS_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.
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.
AGPL-3.0-or-later. See LICENSE.
Part of lvl0, a collective for horizontal FOSS projects.