For the full binary-level setup flows (marreq-server / marreq-cloud, Docker / local), start with the setup guide. This page stays focused on database initialization, seeding, migration, reset, and verification details.
Marreq now uses a single database strategy:
- Schema creation/evolution:
marreq-core/migrations/*/up.sql(Diesel migrations) - Sample/demo data:
marreq-core/scripts/init_complete.sql(seed data only)
marreq-core/scripts/init_complete.sql does not create tables, indexes, triggers, or extensions.
All configuration is driven by environment variables. The application loads them
from a .env file in the project root (via dotenvy) if the file exists.
.env is gitignored and must never be committed. Copy the template to get
started:
cp .env.example .env| Variable | Required | Default in .env.example |
Description |
|---|---|---|---|
DATABASE_URL |
Yes | postgres://rust:rust@127.0.0.1:5433/marreq |
PostgreSQL connection string (host port from docker-compose.yml) |
ROCKET_SECRET_KEY |
Production | (auto-generated in dev) | 256-bit base64 key for cookie signing. Generate with openssl rand -base64 32. |
EMBEDDINGS_ENABLED |
No | false |
Enable pgvector semantic search |
EMBEDDING_PROVIDER |
No | ollama |
ollama or openai |
EMBEDDING_MODEL |
No | nomic-embed-text |
Embedding model name |
OLLAMA_URL |
No | http://localhost:11434 |
Ollama API base URL |
RAG_ENABLED |
No | false |
Enable LLM-assisted search |
RAG_MODEL |
No | llama3.2 |
LLM model for RAG |
In development,
ROCKET_SECRET_KEYcan be omitted — Rocket auto-generates an ephemeral key (sessions expire on restart, which is fine locally). In production, always set a stable key so sessions survive restarts.
- Ensure Docker is running:
docker --version
- Install the Diesel CLI (once per machine):
cargo install diesel_cli --no-default-features --features postgres
- Create a
.envfile in the project root from the provided template:The default values work for a local Docker setup. Edit the file if your database URL or optional services (Ollama, embeddings) differ.cp .env.example .env
.envis gitignored — never commit it. - Run the setup script:
./marreq-core/scripts/db_setup.sh
- (Optional) Load demo/test data:
./marreq-core/scripts/db_seed.sh
- Start the application:
cargo run -p marreq-server
- Access the app at
http://localhost:8000and log in with seeded users (password:ChangeMe123!).
- Create the database:
docker compose -f docker/docker-compose.yml exec -T db psql -U rust -d postgres -c "CREATE DATABASE marreq;"
- Apply migrations (schema):
diesel migration run
- Seed sample data:
docker compose -f docker/docker-compose.yml exec -T db psql -U rust -d marreq < marreq-core/scripts/init_complete.sql
For the full scripts reference, see marreq-core/scripts/README.md.
| Table | Description |
|---|---|
projects |
Multi-project support with project metadata |
users |
User accounts with authentication and permissions |
project_members |
Membership and role per project |
project_reviewers |
Users allowed to change requirement/verification status and version approval for that project |
requirements |
Requirement containers with immutable versions in requirement_versions |
verifications |
Verification items (name, reference, status, author/reviewer, optional method) |
matrix |
Traceability links between requirements and verifications |
categories |
User-defined requirement categories |
applicability |
Requirement applicability definitions |
verification_methods |
Methods attachable to requirement versions and optionally to verifications |
verification_status |
Per-project statuses for verifications |
requirement_status |
Requirement status definitions |
logs |
Audit trail for system activities |
- Multi-project scoping
- Immutable requirement versions
- Traceability matrix
- Immutable baselines
- Semantic-search tables (
pgvector+ queue) - User authentication and role-aware access
- Space Project: Space exploration satellite requirements
- Marreq Project: Requirements management system development
- Empty Project: Empty sandbox project
| Username | Name | Role | Project |
|---|---|---|---|
alice |
Alice Johnson | Admin | Marreq Project |
dr_smith |
Dr. Sarah Smith | Admin | Space Project |
eng_jones |
Engineer Mike Jones | User | Space Project |
tech_lee |
Technician Lisa Lee | User | Space Project |
qa_wilson |
QA Specialist Tom Wilson | User | Space Project |
admin |
System Administrator | Admin | Marreq Project |
- 8 categories
- 6 applicability definitions
- 4 verification methods
- 5 requirements (with initial versions)
- 5 verifications
- 5 matrix links
Seeds also populate project_reviewers (from Admin/Reviewer roles) so approval and status gates work for demo users; adjust via Project settings → Reviewers or PUT /api/projects/<id>/reviewers.
Schema source of truth:
- Tables and constraints
- Indexes
- Triggers/functions
- Extensions (including
vector)
Seed data only:
- Sample projects/users
- Statuses/categories/applicability/verification
- Sample requirements/tests/matrix links
- Sample logs and custom-field data
Fresh install script that:
- Starts the Docker
dbservice if not running - Creates the
marreqdatabase if absent - Runs
diesel migration run(schema source of truth)
Use --seed flag to also load demo data in one step.
Loads demo/test data from init_complete.sql. Not for production.
Wrapper for diesel migration run / revert / list. Use after pulling updates:
./marreq-core/scripts/db_migrate.sh up # apply pending migrations
./marreq-core/scripts/db_migrate.sh list # check statusRuns pg_dump and saves a compressed archive to ./backups/.
Drops the marreq database entirely. Development use only.
# Check tables
docker compose -f docker/docker-compose.yml exec -T db psql -U rust -d marreq -c "\dt"
# Check users
docker compose -f docker/docker-compose.yml exec -T db psql -U rust -d marreq -c "SELECT username, name, is_admin FROM users ORDER BY id;"
# Check sample data
docker compose -f docker/docker-compose.yml exec -T db psql -U rust -d marreq -c "SELECT COUNT(*) AS requirements FROM requirements;"- Docker not running:
docker info
- DB container not running:
docker compose -f docker/docker-compose.yml up -d db
diesel: command not found:- Install the Diesel CLI:
cargo install diesel_cli --no-default-features --features postgres
- Install the Diesel CLI:
- Seed script fails with
projects table is not empty:marreq-core/scripts/init_complete.sqlis seed-only for fresh DBs.- Reset with:
./marreq-core/scripts/db_reset.sh ./marreq-core/scripts/db_setup.sh --seed
./marreq-core/scripts/db_reset.sh
./marreq-core/scripts/db_setup.sh --seed- Seeded users share the demo password
ChangeMe123!. - Change passwords outside local/demo environments.
From the SPA (self-hosted, administrators): Admin → Backup → Download backup downloads marreq-backup_<timestamp>.tar.gz (issue #341). The server runs pg_dump against DATABASE_URL (the Docker image ships postgresql-client; set MARREQ_PG_DUMP to use another binary) and packs the dump with the attachment files:
marreq-backup_<timestamp>/database.sql plain SQL from pg_dump
marreq-backup_<timestamp>/attachments/ab/cd/… the attachment store (MARREQ_ATTACHMENTS_DIR)
marreq-backup_<timestamp>/manifest.json format, time, file count and size
Untick Include attachment files for a database-only archive
(POST /api/admin/backup?attachments=false). The files are copied right after
the dump: a file uploaded meanwhile may be extra (harmless), one deleted
meanwhile is left out. While the archive is built the server needs free space
in its temp directory for about the dump plus the compressed archive.
From a shell (database only; back up the attachments volume as shown below):
./marreq-core/scripts/db_backup.sh
# Saves to ./backups/marreq_<timestamp>.sql.gzRestore into an empty database (the backend runs migrations on start, so restore before starting it, or into a freshly created database).
An Admin → Backup archive:
tar xzf marreq-backup_<timestamp>.tar.gz
docker compose -f docker/docker-compose.yml exec -T db \
psql -U rust -d marreq -v ON_ERROR_STOP=1 < marreq-backup_<timestamp>/database.sqlthen put marreq-backup_<timestamp>/attachments/ back into the attachments
volume (Attachment files below).
A db_backup.sh dump:
gunzip -c backups/marreq_<timestamp>.sql.gz | \
docker compose -f docker/docker-compose.yml exec -T db \
psql -U rust -d marreq -v ON_ERROR_STOP=1Use psql from PostgreSQL 17 or newer: dumps written by pg_dump 17 (the
Docker image and Admin → Backup) can contain commands older clients reject.
An Admin → Backup archive contains the attachment files unless they were
left out; a db_backup.sh dump never does (issue #241). The server stores them under MARREQ_ATTACHMENTS_DIR (/var/lib/marreq/attachments in
the Docker image), which the compose files mount from the marreq_attachments
volume (marreq_attachments_cloud for marreq-cloud). Compose prefixes volume
names with the project name, so with the default project it is
docker_marreq_attachments; check with docker volume ls | grep attachments.
Without an Admin → Backup archive, back up the volume right after the database dump so both describe the same moment:
docker run --rm \
-v docker_marreq_attachments:/data:ro \
-v "$PWD/backups":/backup \
alpine tar czf /backup/attachments_<timestamp>.tar.gz -C /data .Restore it into the (empty) volume before starting the backend:
docker run --rm \
-v docker_marreq_attachments:/data \
-v "$PWD/backups":/backup \
alpine sh -c 'tar xzf /backup/attachments_<timestamp>.tar.gz -C /data && chown -R 10001:10001 /data'From an unpacked Admin → Backup archive:
docker run --rm \
-v docker_marreq_attachments:/data \
-v "$PWD/marreq-backup_<timestamp>/attachments":/backup:ro \
alpine sh -c 'cp -a /backup/. /data/ && chown -R 10001:10001 /data'Files are named by their SHA-256 (ab/cd/<hash>), so a restored directory
can be checked with sha256sum. Files that no database row references are
harmless. A row whose file is missing gives a 404 on download.
login_rate_limits (migration 2026-10-06-000001_login_rate_limits) holds
the shared failed-login counters and lockouts (issue #286; see Login rate
limiting in authentication.md). It needs no maintenance:
rows are deleted on a successful login and swept after
MARREQ_RATE_LIMIT_RETENTION_HOURS. To lift every lockout at once, for example
after a misconfigured client locked out an account:
DELETE FROM login_rate_limits; -- everything
DELETE FROM login_rate_limits WHERE scope_key = 'alice'; -- one username (canonical, lower case)The Compose stack uses PostgreSQL 17 (pgvector/pgvector:pg17-trixie) on a new
volume, pgdata17. PostgreSQL cannot open a data directory from an older major
version, so an existing installation moves its data with a dump and restore. The
old PostgreSQL 15 volume (pgdata) is not touched, which keeps rollback simple.
- Before updating, with the old stack still running, take a backup:
Admin → Backup → Download backup (a
.tar.gz; the files can be left out, the attachments volume is not affected by this upgrade), orNote a few numbers to compare later (for example the requirement count on the dashboard of each project)../marreq-core/scripts/db_backup.sh # -> backups/marreq_<timestamp>.sql.gz - Stop the stack and update to this release (
git pull, or pull the new images):docker compose -f docker/docker-compose.yml down
- Start only the new database. This creates the empty
pgdata17volume:docker compose -f docker/docker-compose.yml up -d db docker compose -f docker/docker-compose.yml exec db pg_isready -U rust -d marreq - Restore the backup before the backend starts (it would otherwise create
the tables first and the restore would fail):
# Admin → Backup archive: tar xzf marreq-backup_<timestamp>.tar.gz docker compose -f docker/docker-compose.yml exec -T db \ psql -U rust -d marreq -v ON_ERROR_STOP=1 < marreq-backup_<timestamp>/database.sql # or a db_backup.sh dump: gunzip -c backups/marreq_<timestamp>.sql.gz | \ docker compose -f docker/docker-compose.yml exec -T db \ psql -U rust -d marreq -v ON_ERROR_STOP=1
- Start the rest of the stack and check the data (log in, compare the numbers
from step 1):
docker compose -f docker/docker-compose.yml up -d
Use the same -f files you normally run with (for example add
-f docker/docker-compose.prod.yml, or use docker-compose.light.yml).
Rollback: check out (or pull) the previous release and start it again. It still uses the untouched PostgreSQL 15 volume.
Clean-up: once the upgrade is confirmed, remove the old volume. Its name is
prefixed with the Compose project name; docker volume ls shows it (for
example docker_pgdata):
docker volume rm docker_pgdataManaged PostgreSQL (not Compose): upgrade the server with your provider's
major-version upgrade (or dump and restore as above), and run the backend image
from this release so its pg_dump (17) matches the server.