Skip to content

Database

One MySQL database backs the whole platform. It is owned by verilib-frontend — the schema, the migrations, and almost all writes live there.

Engine MySQL
Hosting Amazon RDS for MySQL 8 in production — see Managed
Owner verilib-frontend (sql/, public/app/Models/)
Access layer Eloquent / PDO
Schema Scheme

Who connects

Component Access Variables
verilib-frontend Read/write, sole writer for product data DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME, DB_TYPE
verilib-atomizer Read/write, atoms and dependencies only DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
local_validate None
verilib-cli None — talks to the HTTP API

The cert workers being DB-free is deliberate: everything they need arrives on the queue message, and everything they produce goes back as a response for PHP to apply. That keeps the credential surface small and means a cert worker can run anywhere with only broker and S3 reachability.

Two write paths

flowchart LR
  ui[PHP frontend] -->|product data, repos,<br/>certificates, joblogs| db[(MySQL)]
  atomizer[atomize-processor] -->|atoms, dependencies,<br/>code verification status| db
  cert[cert workers] -.->|no DB access| db

Full ownership table: Scheme → Write ownership.

Production hosting

Production runs on Amazon RDS for MySQL 8. AWS operates the instance — backups, patching, host replacement — while the frontend owns the schema and the write paths above.

Endpoint RDS instance endpoint in DB_HOST, port 3306
Reachability Private — inbound 3306 allowed from the app and worker security groups only, public access disabled
Credentials DB_USER / DB_PASSWORD in the host's .env, one password per environment
Backups RDS automated backups and snapshots — see Backup

Provisioning, naming conventions, network rules, connection gotchas, and scaling levers: Managed.

Editing .env is not enough on a server

Dotenv runs in immutable mode, so a variable already present in the PHP process wins over the file. After changing DB_*, reload PHP-FPM and Apache and restart the DB-writing workers. See Managed → Connecting the application.

Local development

Local development uses a MySQL container — it does not point at RDS. The full-stack Compose file seeds MySQL from db.sql plus docker/seed-dev.sql, and exposes phpMyAdmin alongside it:

Service Port
MySQL 3306
phpMyAdmin 8081

PHP inside the container reads DB settings from docker/compose.env, mounted read-only as /var/www/.env, where DB_HOST=mysql and DB_PORT=3306 address the container over the Compose network. Setup commands: Local development.

docker/compose.env is tracked in git

Unlike .env, the Compose env file is committed, so its defaults must stay local-only. Repointing it at an RDS endpoint to test against a real instance leaves an endpoint and a password in a tracked file — revert the change before committing, and never push it.

docker/dev-users.sql seeds test accounts; docker/seed-dev.sql seeds the lookup tables (languages, types, statuses, roles, tasks) and a small amount of sample content.

Dev seed values are not production values

The dev seed populates statuses as 1 = pending, 2 = cancelled, 3 = verified, which does not match the id semantics the atomizer's legacy poll loop assumes. Do not derive production behaviour from the seed. See Error codes.

Operations

Topic Page
Schema, tables, migrations Scheme
Backup concepts and recovery limits Backup
Snapshot, dump, restore commands Database backup and restore
Managed RDS setup and scaling Managed
Connection variables Configuration and environment variables