jcergolj / metator-for-laravel
Laravel package that installs Deployer deployment scaffolding into an application.
Package info
github.com/jcergolj/metator-for-laravel
Language:Shell
pkg:composer/jcergolj/metator-for-laravel
Requires
- php: ^8.2
- deployer/deployer: ^8.0
- illuminate/console: ^12.0 || ^13.0
- illuminate/filesystem: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- laravel/prompts: ^0.3
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v5
- v4
- v3
- v2
- v1
- dev-issue-83-sqlite-noop
- dev-issue-84-caddy-readiness
- dev-issue-85-permissions-noop
- dev-issue-86-ssh-order
- dev-issue-87-mariadb-rerun
- dev-issue-88-environment-noop
- dev-issue-90-preparation-noop
- dev-issue-90-base
- dev-fix/worker-sudoers-reruns
- dev-feat/optional-node-capability
- dev-fix/provisioning-confirmation
- dev-fix/provisioning-review
- dev-fix/activate-caddy-preparation
- dev-fix/verify-composer-preparation
- dev-fix/prepare-server-php-fpm
- dev-fix-null-site-id-default
- dev-issue-60-release-gate-os-matrix
- dev-issue-51-refactor
- dev-issue-59-ubuntu-2604-support
- dev-issue-37-release-gate
- dev-issue-34-reconcile-disabled
- dev-issue-33-site-workers
- dev-issue-32-deployer-integration
- dev-issue-36-custom-steps-dns
- dev-issue-12-caddy-routing
- dev-agent/issue-35-environment
- dev-agent/issue-31-scheduler
- dev-agent/issue-30-redis
- dev-feat/29-local-mariadb
- dev-feat/28-github-deploy-key
- dev-feat/27-owned-sqlite-site
- dev-feat/26-ubuntu-php-baseline
- dev-feat/25-remote-provisioning
- dev-feat/minimal-deployer-recipe
- dev-feat/provisioning-behavioral-ci
- dev-feat/local-site-configuration
- dev-fix/9-production-environment-generation
- dev-fix/remaining-installation-bugs
- dev-fix/queue-worker-timeout
- dev-fix/preserve-dotenv-secrets
- dev-fix/restart-workers-in-scaffolding
This package is auto-updated.
Last update: 2026-09-18 12:32:31 UTC
README
Metator installs deployment scaffolding for Laravel applications. It combines Deployer with a metadata-driven server bootstrap pipeline.
Metator can prepare:
- PHP-FPM and CLI
- Caddy and optional Cloudflare DNS
- SQLite or site-owned local MariaDB
- Redis cache and runtime databases
- Scheduler and optional queue or Horizon workers
- GitHub deploy-key access
Metator prepares infrastructure. You run Deployer separately to release the application.
Requirements
Before installation, provide:
- A Laravel application with
.env.example - PHP 8.2 or newer locally
- Composer
- An already secured Ubuntu server
- Noninteractive SSH access with administrative
sudo - Git, Composer, PHP-FPM, systemd, and
sudoon the server
The supported server baseline is Ubuntu 24.04 with PHP 8.4 or 8.5. Basic OS hardening and operator SSH access are outside Metator's scope.
Quick Start
Install the package in your Laravel application:
composer require --dev jcergolj/metator-for-laravel php artisan metator:install
The installer creates:
metator.<name>.php: non-secret site configurationdeploy.php: editable Deployer recipescripts/: selected server bootstrap pipeline- A copy of the application's
.env.example
Then prepare, provision, and deploy:
php artisan metator:prepare-server --config=metator.production.php php artisan metator:provision --config=metator.production.php vendor/bin/dep deploy production
Provisioning does not deploy application code. Register the generated read-only GitHub deploy key when provisioning requests it.
Installation Choices
metator:install asks for the settings needed by one site:
- Site ID
- Repository and deployment branch
- SSH host and deployment user
- Domain
- PHP version
- SQLite or local MariaDB
- Redis, scheduler, and worker capabilities
- Deployment steps
The site ID is immutable and identifies the remote resources. It is not the repository name, domain, filename, or local checkout name.
The generated site configuration contains no secrets. Cloudflare credentials, when needed, are stored separately in an untracked local companion file.
Use --force only when deliberately regenerating an existing installation:
php artisan metator:install --force
Forced regeneration removes only files tracked in
scripts/.metator-manifest.json. Untracked custom files are preserved.
Server Workflow
Run the commands in this order:
- Install the local scaffolding.
- Prepare the shared server baseline when needed.
- Provision the selected site.
- Register the GitHub deploy key.
- Deploy the application with Deployer.
- Verify the URL, database, scheduler, and workers selected for the site.
prepare-server installs shared packages and capabilities. provision creates
only the selected site's resources and reuses the prepared baseline.
The remote commands:
- Upload the exact local
scripts/directory - Use a fresh, site-owned staging directory
- Stream remote output locally
- Return the remote exit status
- Do not read from remote stdin
If SSH disconnects, inspect the server before retrying. The remote operation may have completed.
Deploying
Review deploy.php before the first deployment. It reads the selected site
configuration for the repository, SSH target, deployment path, PHP binary,
database mode, and worker lifecycle.
Deploy with:
vendor/bin/dep deploy production
The generated recipe verifies the provisioned PHP runtime before making release changes. It supports no workers, queue workers, or Horizon.
Custom deployment scripts
Add application-specific release work to the editable deploy.php. Define a
task, then attach it to a Deployer lifecycle task:
task('deploy:build-assets', function (): void { run('cd {{release_path}} && npm ci'); run('cd {{release_path}} && npm run build'); }); after('deploy:vendors', 'deploy:build-assets');
Use:
{{release_path}}for files in the new release{{bin/php}}for the configured PHP binary- A hook before
deploy:symlinkfor required release files
For Tailwind:
task('deploy:build-tailwind', function (): void { run('cd {{release_path}} && {{bin/php}} artisan tailwindcss:download --force'); run('cd {{release_path}} && {{bin/php}} artisan tailwindcss:build --prod --no-tty'); }); after('deploy:vendors', 'deploy:build-tailwind');
If the Tailwind binary is already installed on the server, omit the download command. A failed task stops deployment before the new release is symlinked.
Verify generated files in the release directory:
test -f /var/www/<site-id>/releases/<release>/public/.tailwindcss-manifest.json find /var/www/<site-id>/releases/<release>/public/dist/css -name 'app-*.css' -type f
Keep deployment tasks in deploy.php. Do not add release commands to the
Metator server bootstrap scripts.
Custom Server Steps
Custom server steps are shell files in metator/steps/. Publish the catalogue
first if you want to inspect or edit the built-in steps:
php artisan vendor:publish --tag=metator-steps
Each custom step needs metadata and a matching function:
# @id: install-imagemagick # @title: Install ImageMagick # @group: none # @required: false # @default: false # @order: 65 step_install_imagemagick() { sudo apt-get install -y imagemagick }
Metadata rules:
@id: lowercase letters, numbers, and single hyphens@title: label shown by the installer@group: exclusive group, ornone@required:trueorfalse@default:trueorfalse@order: non-negative execution order
Available variables and helpers include APP_FOLDER, DOMAIN, PHP_VERSION,
PHP_PACKAGE_PREFIX, sudo, ok, warn, and die.
Custom steps must return a nonzero status on failure. The pipeline stops and reports the failed operation. Correct the step and rerun provisioning.
After adding a step:
php artisan metator:install
Select the custom step during installation. The generated scripts/steps/
directory is copied to the server and should not be edited there.
Optional Services
Web server
Caddy is the default web server and manages public HTTPS. Before provisioning:
- Point DNS to the server
- Allow inbound HTTP and HTTPS
- Ensure the configured domain resolves correctly
To use Nginx instead, add an Nginx step to metator/steps/ with the
web-server group, then select it and deselect Configure Caddy. Only one
web-server step may be selected.
Cloudflare DNS
Cloudflare DNS is optional. Leave Configure Cloudflare DNS unchecked when you do not want API credentials or DNS API calls.
Cloudflare does not replace Caddy. The web server and DNS choices are separate.
Workers and scheduler
Select only the capabilities used by the application:
- No workers
- Standard queue workers
- Horizon
- Scheduler
Worker and scheduler configuration is scoped to the site. Unrelated sites are not restarted when one site changes.
Multiple Sites
Multiple sites may use the same repository. Give each site a unique site ID.
For every site:
- Create a separate
metator.<name>.php - Use a unique site ID
- Register its generated GitHub deploy key
- Select its PHP, database, Redis, worker, and scheduler settings
- Provision and deploy separately
Prepare the server again only when a new shared capability is needed. Existing sites keep their configuration, credentials, data, deploy keys, and running work.
Updating Environment Values
Put application-specific production values in a Git-ignored local dotenv file:
php artisan metator:update-env \ --config=metator.production.php \ --input=.env.production.local
Metator preserves its managed identity, runtime, database, Redis, and key values. It does not refresh Laravel's cached configuration or restart workers; use the normal Deployer and application lifecycle for those actions.
Retries and Changes
An unchanged provisioning rerun verifies existing resources without:
- Rotating credentials or keys
- Rewriting configuration
- Reloading shared services
- Restarting unrelated workers
- Duplicating cron entries
If provisioning fails, it returns a nonzero status and does not report the site as ready. Existing site-owned resources are preserved for recovery.
Metator rejects unmanaged ownership conflicts and ordinary PHP or database engine changes. Resolve those explicitly instead of deleting site data.
Troubleshooting
Missing shared capability
Run metator:prepare-server for a configuration that selects the capability,
then rerun metator:provision.
Provisioning failed
Use the step summary and remote error as the source of truth. Inspect the server before retrying.
Ownership conflict
Keep the existing resource unchanged. Resolve the site ID or conflicting managed resource manually; Metator will not adopt unmarked resources.
HTTPS unavailable
Check DNS and inbound HTTP/HTTPS access. Caddy obtains the certificate only when the configured domain resolves correctly.
Deployment failed
Review:
deploy.php- GitHub deploy-key registration
- The selected PHP binary
- The application's
.env - Custom deployment tasks
Provisioning and deployment are separate operations, so rerun Deployer after fixing the deployment issue.
Resource Ownership
Metator manages site-owned resources including:
- Site directory and metadata
- Shared environment
- Database and MariaDB credentials
- Redis allocations
- GitHub deploy key and SSH block
- Caddy route
- Scheduler entry
- Worker configuration
Metator does not provide a full uninstall command or delete site data. Stop the site lifecycle, archive required data, confirm no other site uses the resources, and remove them manually. Shared PHP, MariaDB, Redis, cron, Supervisor, and Caddy services remain in place.