{"id":35070302,"url":"https://github.com/devuni-cz/notifier-package","last_synced_at":"2026-04-06T14:03:30.750Z","repository":{"id":304008987,"uuid":"1017395987","full_name":"devuni-cz/notifier-package","owner":"devuni-cz","description":"A Laravel 12 package for automated database backups and notifications.","archived":false,"fork":false,"pushed_at":"2026-03-06T01:12:42.000Z","size":234,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-06T05:36:02.411Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://devuni.cz","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devuni-cz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-10T13:20:08.000Z","updated_at":"2026-03-06T01:12:43.000Z","dependencies_parsed_at":"2025-07-10T22:24:49.108Z","dependency_job_id":"3f2ae68f-8a1a-4469-83c0-e8e8a18b30e5","html_url":"https://github.com/devuni-cz/notifier-package","commit_stats":null,"previous_names":["devuni-cz/notifier-package"],"tags_count":57,"template":false,"template_full_name":null,"purl":"pkg:github/devuni-cz/notifier-package","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devuni-cz%2Fnotifier-package","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devuni-cz%2Fnotifier-package/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devuni-cz%2Fnotifier-package/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devuni-cz%2Fnotifier-package/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devuni-cz","download_url":"https://codeload.github.com/devuni-cz/notifier-package/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devuni-cz%2Fnotifier-package/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30639073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-18T00:09:27.587Z","status":"ssl_error","status_checked_at":"2026-03-18T00:09:26.123Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-27T11:55:32.849Z","updated_at":"2026-03-18T01:10:22.567Z","avatar_url":"https://github.com/devuni-cz.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Devuni Notifier Package\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/devuni/notifier-package.svg?style=flat-square)](https://packagist.org/packages/devuni/notifier-package)\n[![Total Downloads](https://img.shields.io/packagist/dt/devuni/notifier-package.svg?style=flat-square)](https://packagist.org/packages/devuni/notifier-package)\n[![Tests](https://github.com/devuni-cz/notifier-package/actions/workflows/ci.yml/badge.svg)](https://github.com/devuni-cz/notifier-package/actions/workflows/ci.yml)\n[![PHP 8.4](https://img.shields.io/badge/PHP-8.4-777BB4?style=flat-square\u0026logo=php\u0026logoColor=white)](https://www.php.net)\n[![Laravel 12](https://img.shields.io/badge/Laravel-12-FF2D20?style=flat-square\u0026logo=laravel\u0026logoColor=white)](https://laravel.com)\n[![PHPStan Level 5](https://img.shields.io/badge/PHPStan-level%205-blue?style=flat-square)](https://phpstan.org)\n[![Code Style](https://img.shields.io/badge/code%20style-pint-orange?style=flat-square)](https://laravel.com/docs/pint)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE.md)\n\nA Laravel package for automated, encrypted database and storage backups with secure remote delivery. Supports Artisan commands, HTTP API triggers, queue offloading, and AES-256 ZIP encryption out of the box.\n\n## Features\n\n-   **Database backups** — `mysqldump` with `--single-transaction` and `--quick` for consistent, low-memory dumps\n-   **Storage backups** — Archives `storage/app/public` into password-protected ZIP (AES-256)\n-   **Pluggable ZIP strategy** — CLI `7z` (recommended) with PHP `ZipArchive` fallback\n-   **Chunked uploads** — Large backup files split into configurable chunks (default 20 MB) for reliable transfer\n-   **Token-based authentication** — `X-Notifier-Token` header validated with constant-time comparison\n-   **Queue support** — Offload backup jobs to any Laravel queue driver to avoid HTTP timeout limits\n-   **Remote API trigger** — Rate-limited REST endpoint to trigger backups from an external scheduler\n-   **Exclusion lists** — Ignore specific database tables and storage files/directories\n-   **Configurable routing** — Custom route prefix, or disable routes entirely\n-   **Comprehensive logging** — Dedicated configurable logging channel with automatic fallback\n-   **Automatic cleanup** — Temporary backup files removed after successful upload\n\n## Requirements\n\n-   PHP `^8.4`\n-   Laravel `^12.2`\n-   `mysqldump` binary for database backups\n-   `7z` (`p7zip-full`) recommended for storage backups, or PHP `zip` extension as fallback\n\n## Installation\n\n### 1. Install via Composer\n\n```bash\ncomposer require devuni/notifier-package\n```\n\n### 2. Publish the configuration\n\n```bash\nphp artisan vendor:publish --tag=\"notifier-config\"\n```\n\nThis copies `config/notifier.php` into your application's `config/` directory.\n\n### 3. Configure environment variables\n\nRun the interactive installer to write the required values to your `.env`:\n\n```bash\nphp artisan notifier:install\n```\n\n### 4. Verify your setup\n\n```bash\nphp artisan notifier:check\n```\n\nThis command validates your environment variables, database connectivity, storage access, system tools (`mysqldump`, `7z`), logging channel, and backup URL reachability.\n\n---\n\n## Configuration\n\nAfter publishing, edit `config/notifier.php` or set values via environment variables.\n\n### Environment Variables\n\n```bash\n# Required\nNOTIFIER_BACKUP_CODE=your-secret-token       # Authentication token (must match the central notifier)\nNOTIFIER_URL=https://your-backup-server.com  # Endpoint that receives backup uploads\nNOTIFIER_BACKUP_PASSWORD=your-zip-password   # AES-256 ZIP encryption password\n\n# Optional\nNOTIFIER_LOGGING_CHANNEL=backup              # Laravel logging channel (default: backup)\nNOTIFIER_ROUTES_ENABLED=true                 # Enable/disable the API route (default: true)\nNOTIFIER_ROUTE_PREFIX=api/notifier           # API route prefix (default: api/notifier)\nNOTIFIER_ZIP_STRATEGY=auto                   # ZIP strategy: auto, cli, php (default: auto)\nNOTIFIER_CHUNK_SIZE=20971520                 # Upload chunk size in bytes (default: 20 MB)\nNOTIFIER_QUEUE_CONNECTION=sync               # Queue driver for API-triggered backups (default: sync)\n```\n\n### All Configuration Options\n\n| Key | Env Variable | Default | Description |\n|-----|-------------|---------|-------------|\n| `backup_code` | `NOTIFIER_BACKUP_CODE` | — | Authentication token matched against `X-Notifier-Token` header |\n| `backup_url` | `NOTIFIER_URL` | — | Central notifier endpoint for backup uploads |\n| `backup_zip_password` | `NOTIFIER_BACKUP_PASSWORD` | — | Password used to encrypt backup ZIP archives |\n| `excluded_tables` | — | `[]` | Database tables excluded from backup (e.g. `telescope_entries`, `sessions`) |\n| `excluded_files` | — | `['.gitignore']` | Files/dirs excluded from storage backup (relative to `storage/app/public`) |\n| `logging_channel` | `NOTIFIER_LOGGING_CHANNEL` | `backup` | Laravel log channel; falls back to `daily` if channel doesn't exist |\n| `routes_enabled` | `NOTIFIER_ROUTES_ENABLED` | `true` | Whether to register the package's API route |\n| `route_prefix` | `NOTIFIER_ROUTE_PREFIX` | `api/notifier` | URL prefix for the API route |\n| `zip_strategy` | `NOTIFIER_ZIP_STRATEGY` | `auto` | ZIP strategy: `auto` (detect), `cli` (force 7z), `php` (force ZipArchive) |\n| `chunk_size` | `NOTIFIER_CHUNK_SIZE` | `20971520` | Upload chunk size in bytes. Keep under your proxy's limit (e.g. Cloudflare free: 100 MB) |\n| `queue_connection` | `NOTIFIER_QUEUE_CONNECTION` | `sync` | Queue driver for API-triggered backups. Artisan commands always run synchronously. |\n\n---\n\n## Artisan Commands\n\n### `notifier:install`\n\nInteractive wizard that writes the three required environment variables to your `.env` file.\n\n```bash\nphp artisan notifier:install\n\n# Overwrite existing values\nphp artisan notifier:install --force\n```\n\n### `notifier:check`\n\nValidates the full environment and system requirements. Checks:\n\n- `NOTIFIER_BACKUP_CODE`, `NOTIFIER_URL`, `NOTIFIER_BACKUP_PASSWORD` are set\n- Database connection is healthy\n- `storage/app/public` is accessible\n- `mysqldump` is available on `$PATH`\n- ZIP tool is available (`7z` or PHP `zip` extension)\n- Logging channel is configured\n- Queue connection is set up\n- Backup URL is reachable over HTTPS\n\n```bash\nphp artisan notifier:check\n```\n\n### `notifier:database-backup`\n\nCreates a `mysqldump` of the application database and uploads it to the central notifier.\n\n```bash\nphp artisan notifier:database-backup\n```\n\n### `notifier:storage-backup`\n\nArchives `storage/app/public` into an encrypted ZIP and uploads it to the central notifier.\n\n```bash\nphp artisan notifier:storage-backup\n```\n\n---\n\n## API Endpoint\n\nThe package registers a single POST endpoint for triggering backups remotely (e.g. from a central scheduler):\n\n```\nPOST /{route_prefix}/backup\n```\n\n**Authentication:** `X-Notifier-Token` header — must match `NOTIFIER_BACKUP_CODE`.  \n**Rate limit:** 10 requests per 60 seconds.\n\n### Request\n\n| Parameter | Type | Required | Values |\n|-----------|------|----------|--------|\n| `type` | string | ✓ | `backup_database`, `backup_storage` |\n\n### Examples\n\n```bash\n# Trigger a database backup\ncurl -X POST https://your-app.com/api/notifier/backup \\\n  -H \"X-Notifier-Token: your-secret-token\" \\\n  -d \"type=backup_database\"\n\n# Trigger a storage backup\ncurl -X POST https://your-app.com/api/notifier/backup \\\n  -H \"X-Notifier-Token: your-secret-token\" \\\n  -d \"type=backup_storage\"\n```\n\n### Response\n\n**Success (synchronous):**\n```json\n{\n    \"success\": true,\n    \"message\": \"Database backup completed successfully.\",\n    \"backup_type\": \"database\",\n    \"duration_seconds\": 12.34,\n    \"timestamp\": \"2025-01-15T10:30:45+00:00\"\n}\n```\n\n**Success (queued):**\n```json\n{\n    \"success\": true,\n    \"message\": \"Backup job dispatched to queue.\",\n    \"backup_type\": \"storage\",\n    \"queued\": true,\n    \"timestamp\": \"2025-01-15T10:30:45+00:00\"\n}\n```\n\n**Error:**\n```json\n{\n    \"success\": false,\n    \"message\": \"Database backup failed.\",\n    \"backup_type\": \"database\",\n    \"error\": \"mysqldump: command not found\",\n    \"timestamp\": \"2025-01-15T10:30:45+00:00\"\n}\n```\n\n---\n\n## ZIP Strategy\n\nStorage backups use AES-256 encryption regardless of the strategy chosen.\n\n| Strategy | Tool | Memory usage | Best for |\n|----------|------|-------------|----------|\n| `auto` *(default)* | 7z if available, else ZipArchive | — | All environments |\n| `cli` | 7z (`p7zip-full`) | Low — separate process | Production servers |\n| `php` | PHP `ZipArchive` | Higher — PHP heap | Environments without 7z |\n\nInstall `7z` for best performance on Linux servers:\n\n```bash\nsudo apt install p7zip-full\n```\n\n---\n\n## Queue Support\n\nBy default, API-triggered backups run synchronously inside the HTTP request. For large backups this may hit PHP's `max_execution_time`. Set `NOTIFIER_QUEUE_CONNECTION` to any async queue driver to offload backup jobs:\n\n```bash\nNOTIFIER_QUEUE_CONNECTION=database   # requires php artisan queue:table\nNOTIFIER_QUEUE_CONNECTION=redis      # requires phpredis or predis\n```\n\n\u003e **Note:** Artisan commands (`notifier:database-backup`, `notifier:storage-backup`) always run synchronously and are not affected by this setting.\n\n---\n\n## Programmatic Usage\n\nThe services can be resolved from the container or injected directly:\n\n```php\nuse Devuni\\Notifier\\Services\\NotifierDatabaseService;\nuse Devuni\\Notifier\\Services\\NotifierStorageService;\n\n$db = app(NotifierDatabaseService::class);\n$storage = app(NotifierStorageService::class);\n\n// Database backup\n$path = $db-\u003ecreateDatabaseBackup();\n$db-\u003esendDatabaseBackup($path);\n\n// Storage backup\n$path = $storage-\u003ecreateStorageBackup();\n$storage-\u003esendStorageBackup($path);\n```\n\n---\n\n## Testing\n\nThis package uses [Pest](https://pestphp.com) for testing.\n\n```bash\ncomposer test            # Run all tests\ncomposer test-unit       # Unit tests only\ncomposer test-feature    # Feature tests only\ncomposer test-coverage   # Tests with coverage report\n```\n\n### Test Structure\n\n```\ntests/\n├── Unit/\n│   ├── Commands/         # Artisan command tests\n│   ├── Controllers/      # API controller tests\n│   ├── Services/         # Service class tests\n│   └── NotifierServiceProviderTest.php\n└── Feature/\n    ├── BackupWorkflowTest.php\n    ├── NotifierPackageTest.php\n    └── PackageInstallationTest.php\n```\n\n---\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Security Vulnerabilities\n\nPlease review [our security policy](../../security/policy) on how to report security vulnerabilities.\n\n## Credits\n\n-   [Ludwig Tomas](https://github.com/ludwigtomas)\n-   [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevuni-cz%2Fnotifier-package","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevuni-cz%2Fnotifier-package","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevuni-cz%2Fnotifier-package/lists"}