Operations & maintenance
This page covers operating an Inventorix instance over time: upgrading to a new release, running database migrations, backups, reading the activity log and application logs, scheduled tasks, monitoring queues with Horizon, and common troubleshooting steps.
Upgrading
Section titled “Upgrading”Docker deployments
Section titled “Docker deployments”Pull the new image tag and restart the container. The entrypoint script runs the following steps automatically on every start:
- Creates required storage and cache directories.
- Waits for the database to be reachable (MySQL only; skipped if
DB_HOSTis not set). - Runs
php artisan package:discover,filament:upgrade,config:cache,event:cache, andview:cache. - Publishes Filament and Livewire frontend assets.
- Runs
php artisan migrate --forceifRUN_MIGRATIONS=true(the default).
docker pull ghcr.io/noixdev/inventorix:<new-tag># then restart your container / update your compose servicedocker compose up -dMulti-replica deployments
Section titled “Multi-replica deployments”In Kubernetes or Docker Swarm where multiple app replicas run simultaneously, set RUN_MIGRATIONS=false on the app pods to prevent race conditions. Run migrations as a one-shot init container or job before scaling up:
php artisan migrate --forceThen deploy the new image with RUN_MIGRATIONS=false.
Non-Docker (bare-metal / VM)
Section titled “Non-Docker (bare-metal / VM)”After updating the code (e.g. git pull), run the following sequence:
composer install --no-dev --optimize-autoloaderphp artisan package:discover --ansiphp artisan filament:upgrade --ansiphp artisan config:cachephp artisan event:cachephp artisan view:cachephp artisan filament:assetsphp artisan vendor:publish --tag=livewire:assetsphp artisan migrate --forceDatabase migrations
Section titled “Database migrations”Migrations are managed by Laravel’s standard migration system. The RUN_MIGRATIONS environment variable controls automatic migration on container start.
| Value | Behaviour |
|---|---|
true (default) | php artisan migrate --force runs at every container start |
false | Migrations are skipped; operator is responsible for running them manually |
Always back up the database before running migrations on a production instance.
Backups
Section titled “Backups”At minimum, back up the following:
- Database — use your database engine’s native tools (
mysqldump,pg_dump). Schedule this outside the application (cron, managed backup service, etc.). storage/app/— contains user-uploaded files whenFILESYSTEM_DISK=local. Include the fullstorage/app/directory.- S3 bucket — if you use S3 (
FILESYSTEM_DISK=s3), enable versioning or a bucket replication policy on the AWS side.
Test your restore procedure regularly. A backup you have never restored is unproven.
Application logs
Section titled “Application logs”Laravel logging is configured in config/logging.php. The active channel is controlled by the LOG_CHANNEL environment variable (default: stack). The stack channel composes one or more named channels set via LOG_STACK.
| Env var | Default | Description |
|---|---|---|
LOG_CHANNEL | stack | Top-level channel (stack, single, daily, stderr, syslog, slack, …) |
LOG_STACK | single | Comma-separated list of channels used by the stack driver |
LOG_LEVEL | debug | Minimum log level to record (debug, info, notice, warning, error, critical, alert, emergency); debug is the development default, but production deployments should use warning or error |
LOG_DAILY_DAYS | 14 | Retention days when using the daily channel |
LOG_SLACK_WEBHOOK_URL | — | Webhook URL for the slack channel |
Single-file and daily logs are written to storage/logs/laravel.log.
Activity log (audit trail)
Section titled “Activity log (audit trail)”Inventorix uses spatie/laravel-activitylog to record user actions in the database. This is separate from the application log file.
Activity logging is enabled by default (ACTIVITYLOG_ENABLED=true). Records older than 365 days are pruned when you run:
php artisan activitylog:cleanTo disable logging entirely (e.g. on a development instance), set:
ACTIVITYLOG_ENABLED=falseRecorded events are visible to administrators in the Inventorix admin panel under the Activity Log section. No separate log viewer is required.
Scheduled tasks
Section titled “Scheduled tasks”Inventorix registers one scheduled command: the warranty expiry scanner.
| Command | Schedule | Description |
|---|---|---|
warranty:scan-expiries | Daily at 07:00 | Scans asset guarantee end dates and sends a grouped expiry digest email to configured recipients |
The command skips silently if warranty notifications are disabled in Settings or no recipients are configured.
Running the scheduler
Section titled “Running the scheduler”The entrypoint script does not wire up the Laravel scheduler automatically. You must ensure php artisan schedule:run is invoked every minute by an external mechanism.
Docker / container: Add a cron entry to your host or use a separate scheduler container:
* * * * * docker exec <container-name> php artisan schedule:run >> /dev/null 2>&1Or with a compose override, run the scheduler as a separate service:
scheduler: image: ghcr.io/noixdev/inventorix:<tag> command: ["php", "artisan", "schedule:work"] env_file: .envThe schedule:work command is a long-running process that triggers due scheduled tasks every minute, providing a container-friendly alternative to a per-minute * * * * * php artisan schedule:run cron entry on bare metal.
Bare-metal / VM: Add the following to the www-data (or app-user) crontab:
* * * * * cd /var/www/inventorix && php artisan schedule:run >> /dev/null 2>&1Queue and Horizon monitoring
Section titled “Queue and Horizon monitoring”Inventorix uses Laravel Horizon to manage and monitor Redis-backed queues. See Queue configuration for setup.
The Horizon dashboard is available at https://<your-host>/horizon and shows live job throughput, failed jobs, and queue wait times.
Key Horizon defaults (see config/horizon.php):
| Setting | Production default | Description |
|---|---|---|
memory_limit | 64 MB | Horizon supervisor memory limit before restart |
supervisor-1.maxProcesses | 10 | Maximum worker processes in production |
supervisor-1.tries | 1 | Job attempts before marking as failed |
supervisor-1.timeout | 60 s | Maximum job execution time |
Failed jobs remain in Horizon for 10 080 minutes (7 days) and can be retried from the dashboard.
Troubleshooting
Section titled “Troubleshooting”Database connection errors
Section titled “Database connection errors”- Confirm
DB_HOST,DB_PORT,DB_DATABASE,DB_USERNAME, andDB_PASSWORDin.envmatch your database server. - In Docker, verify the database container is healthy before the app container starts. The entrypoint waits up to 120 seconds.
- Check
storage/logs/laravel.logfor the exact PDO error.
Cache issues (stale config, views, or events)
Section titled “Cache issues (stale config, views, or events)”Re-run the cache commands:
php artisan config:cachephp artisan event:cachephp artisan view:cacheTo clear all caches without rebuilding:
php artisan optimize:clearFile / storage permission errors
Section titled “File / storage permission errors”The Docker image runs as www-data. Storage and cache directories are owned at build time. If you mount volumes, ensure the storage/ and bootstrap/cache/ directories are writable by the same user:
chown -R www-data:www-data storage bootstrap/cachechmod -R 775 storage bootstrap/cacheQueue not processing
Section titled “Queue not processing”- Confirm Horizon is running: check
https://<host>/horizon— status should be Active. - Confirm
QUEUE_CONNECTION=redisand Redis is reachable. - Check for failed jobs in the Horizon dashboard and inspect their error messages.
- Restart Horizon:
php artisan horizon:terminate(Horizon restarts automatically if managed by a process supervisor or the container restart policy is set).
Warranty emails not sending
Section titled “Warranty emails not sending”- Confirm the scheduler is running (see Scheduled tasks).
- In the admin panel, verify warranty notifications are enabled in Settings and at least one recipient is configured.
- Confirm
MAIL_MAILERand SMTP settings are correct — by defaultMAIL_MAILER=logwhich discards mail.