Day-2 operations
About 805 wordsAbout 3 min
Day-2 operations
This page covers what you do after install: backups, plugin management, framework updates, log tailing, scheduled workers, and reset.
For a deeper backup strategy, see Backups.
Plugin management
Install plugins via the admin UI at /apps/plugins (admin role required). The UI calls POST /api/v1/plugins. Enable it with:
# In .env:
SPORA_PLUGIN_INSTALL_ENABLED=trueOr via CLI:
php bin/spora plugin:install spora-ai/spora-plugin-tavily
php bin/spora plugin:list
php bin/spora plugin:uninstall spora-ai/spora-plugin-tavily
php bin/spora plugin:update spora-ai/spora-plugin-tavilyThe CLI form is
php bin/spora plugin:install …— without thespora:prefix that some older docs use. Thespora:prefix is the convention for top-level lifecycle commands (spora:install,db:seed,db:reset); plugin commands are under theplugin:namespace.
Plugins land in plugins/<name>/ (routed by spora-ai/installer). Each plugin owns its own migrations, tools, and assets.
Updating the framework
composer update spora-ai/spora-core
php bin/spora spora:install # apply any new migrations
php bin/spora db:seed # also picks up any new mail-template YAMLs shipped in this release
php bin/spora mail:templates:sync --check # (optional) report mail-template drift without changing data — `db:seed` is silent on drifted rowsdb:seed inserts any new mail-template YAMLs from email-templates/ but does NOT report existing rows that drifted from their defaults — mail:templates:sync --check is still the right tool for drift detection. Reconcile drift with php bin/spora mail:templates:sync to confirm each overwrite interactively, or use --force to overwrite without prompting.
Test the upgrade on a staging copy first.
Updating the admin UI
composer update spora-ai/spora-frontend
# public/dist/ is replaced in place; no migrations neededLogs
storage/spora.log— application log (PSR-3, Monolog).storage/php.log— PHP errors (frombin/dev’s PHP server, when applicable).
Tail with tail -f storage/spora.log.
For the full env-var controls on logging (SPORA_LOG_LEVEL, SPORA_LOG_PATH), see Environment variables.
Cron workers (scheduled tasks)
Spora has two runtime modes — see Deployment modes for the full picture. Which command to run depends on the mode:
worker_runtime_mode: server(spora-ai/sporadefault): runphp bin/spora worker:run --daemonunder supervisord / systemd / Docker, orphp bin/spora worker:run --once --include-queuevia cron every minute. Scheduled runs dispatch unattended.worker_runtime_mode: client(set viaSPORA_WORKER_RUNTIME_MODE=clientin.env): no daemon, no cron. Scheduled runs dispatch from/api/v1/worker/housekeeping, driven by any authed browser. The browser must be open for a schedule to fire; see Client-worker mode.
For server-mode cron mode (the fallback when you cannot run a daemon), run php bin/spora worker:run --once --include-queue every minute:
* * * * * cd /path/to/app && php bin/spora worker:run --once --include-queue >> storage/spora.log 2>&1In client mode the same command exits with a docs-link error — remove it from cron.
Reset
Wipe state for a fresh start:
php bin/spora db:reset --force # drops the database, clears schema stamp
rm -rf plugins/* # uninstalls all plugins
composer install # reinstall frontend assets
php bin/spora spora:install
php bin/spora db:seedUnreadable stored settings
db:reset is the wrong tool for this one — it destroys every agent, plugin and task row to fix a single credential. When a stored value cannot be decrypted (usually a rotated or replaced SPORA_SECRET_KEY), delete just the settings rows:
php bin/spora settings:reset # list every row, then confirm
php bin/spora settings:reset --force # non-interactiveThe resolution order is unchanged — only the database layer is dropped — so every setting falls back to config.php / .env / its declared default and the instance boots. Nothing is archived.
If the app boots at all, you do not need this: Settings → Runtime settings shows which stored values could not be decrypted, and re-entering one fixes that key alone. Reach for the CLI when the app will not load far enough to show you the problem.
Repairing the bootstrap admin
If the seeded admin ends up in a broken state (e.g. verified=0 after an upgrade from an older spora-core release), run db:repair-admin instead of db:reset — it promotes the existing row in place without losing agents, plugins, or task history.
php bin/spora db:repair-admindb:seed is insert-only for admin and agent rows — it will not patch an existing admin row, so it is the wrong tool for repairing a stuck admin. Use db:repair-admin for that. (db:seed does, however, reconcile mail templates against email-templates/ — inserting missing YAMLs and preserving operator-customised rows.)
File permissions
chmod -R 775 storage
chmod -R 755 bin publicOn shared hosts, the web user (e.g. nobody, www-data) needs write access to storage/.