Skip to content

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.

Pull the new image tag and restart the container. The entrypoint script runs the following steps automatically on every start:

  1. Creates required storage and cache directories.
  2. Waits for the database to be reachable (MySQL only; skipped if DB_HOST is not set).
  3. Runs php artisan package:discover, filament:upgrade, config:cache, event:cache, and view:cache.
  4. Publishes Filament and Livewire frontend assets.
  5. Runs php artisan migrate --force if RUN_MIGRATIONS=true (the default).
Terminal window
docker pull ghcr.io/noixdev/inventorix:<new-tag>
# then restart your container / update your compose service
docker compose up -d

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:

Terminal window
php artisan migrate --force

Then deploy the new image with RUN_MIGRATIONS=false.

After updating the code (e.g. git pull), run the following sequence:

Terminal window
composer install --no-dev --optimize-autoloader
php artisan package:discover --ansi
php artisan filament:upgrade --ansi
php artisan config:cache
php artisan event:cache
php artisan view:cache
php artisan filament:assets
php artisan vendor:publish --tag=livewire:assets
php artisan migrate --force

Migrations are managed by Laravel’s standard migration system. The RUN_MIGRATIONS environment variable controls automatic migration on container start.

ValueBehaviour
true (default)php artisan migrate --force runs at every container start
falseMigrations are skipped; operator is responsible for running them manually

Always back up the database before running migrations on a production instance.

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 when FILESYSTEM_DISK=local. Include the full storage/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.

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 varDefaultDescription
LOG_CHANNELstackTop-level channel (stack, single, daily, stderr, syslog, slack, …)
LOG_STACKsingleComma-separated list of channels used by the stack driver
LOG_LEVELdebugMinimum 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_DAYS14Retention days when using the daily channel
LOG_SLACK_WEBHOOK_URLWebhook URL for the slack channel

Single-file and daily logs are written to storage/logs/laravel.log.

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:

Terminal window
php artisan activitylog:clean

To disable logging entirely (e.g. on a development instance), set:

ACTIVITYLOG_ENABLED=false

Recorded events are visible to administrators in the Inventorix admin panel under the Activity Log section. No separate log viewer is required.

Inventorix registers one scheduled command: the warranty expiry scanner.

CommandScheduleDescription
warranty:scan-expiriesDaily at 07:00Scans 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.

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:

Terminal window
* * * * * docker exec <container-name> php artisan schedule:run >> /dev/null 2>&1

Or 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: .env

The 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:

Terminal window
* * * * * cd /var/www/inventorix && php artisan schedule:run >> /dev/null 2>&1

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):

SettingProduction defaultDescription
memory_limit64 MBHorizon supervisor memory limit before restart
supervisor-1.maxProcesses10Maximum worker processes in production
supervisor-1.tries1Job attempts before marking as failed
supervisor-1.timeout60 sMaximum job execution time

Failed jobs remain in Horizon for 10 080 minutes (7 days) and can be retried from the dashboard.

  1. Confirm DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, and DB_PASSWORD in .env match your database server.
  2. In Docker, verify the database container is healthy before the app container starts. The entrypoint waits up to 120 seconds.
  3. Check storage/logs/laravel.log for 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:

Terminal window
php artisan config:cache
php artisan event:cache
php artisan view:cache

To clear all caches without rebuilding:

Terminal window
php artisan optimize:clear

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:

Terminal window
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
  1. Confirm Horizon is running: check https://<host>/horizon — status should be Active.
  2. Confirm QUEUE_CONNECTION=redis and Redis is reachable.
  3. Check for failed jobs in the Horizon dashboard and inspect their error messages.
  4. Restart Horizon: php artisan horizon:terminate (Horizon restarts automatically if managed by a process supervisor or the container restart policy is set).
  1. Confirm the scheduler is running (see Scheduled tasks).
  2. In the admin panel, verify warranty notifications are enabled in Settings and at least one recipient is configured.
  3. Confirm MAIL_MAILER and SMTP settings are correct — by default MAIL_MAILER=log which discards mail.