Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Installer Laravel Package

photoncms/installer

Photon CMS Installer streamlines setting up Photon CMS in a Laravel application. It walks through the installation workflow, publishing assets, configuring the CMS, and preparing your database so you can get a Photon-powered site running with minimal manual setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat photoncms/installer as a project scaffolder, not a runtime dependency. It exists to produce a working Photon CMS application once, and then it should be gone from your dependency graph. Nothing in the package is meant to be imported into application code.

Read the package metadata before installing anything:

composer show -a photoncms/installer

The type field tells you how it is consumed:

  • type: project — used via composer create-project photoncms/installer my-app. This is the common shape for Laravel CMS installers, and the one to assume first.
  • type: library — you composer require --dev it and then invoke an Artisan command such as php artisan photon:install.

If it's a project template, do this in a throwaway directory:

composer create-project photoncms/installer photo-spike --no-install
cd photo-spike
cat composer.json          # read php + illuminate/* constraints FIRST
composer install           # expect this to fail on modern PHP/Laravel
php artisan list | grep -i photon

Where to look first, in order:

  1. composer.json — the php and illuminate/* constraints are the entire feasibility question. If they target Laravel 5.x / PHP 7.x, stop and treat the package as reference material only.
  2. src/ — find the service provider and any console commands. That is the install flow. Look for vendor:publish calls, Artisan::call('migrate'), .env writes, and seeder invocations.
  3. routes/ — critical. If the installer registers HTTP routes for a browser-based wizard, note whether they are guarded and whether they self-disable.
  4. The seeders — anything that creates the first admin user, and where those credentials come from.

Your first use case should be narrow and disposable: a Docker container or a spike branch, no persistent data, no real identities, with one success criterion — you can log in to the admin and render a content page. "Composer install succeeded" is not success. Time-box it to a few hours; if the framework constraints don't resolve cleanly, stop.

php artisan serve
# then: open /admin, log in with the seeded credentials, create one content type, render it

If your actual goal is "build a one-command install for our own Laravel product," skip the install entirely and read the source as a worked example of the standard sequence: publish config → write environment values → migrate → seed admin → optional demo content → self-disable.

Implementation Patterns

Disposable container pattern (the only safe default). Never run the installer against anything you care about. Put it in a Dockerfile or a one-shot compose service, run it at build/provision time, and throw the container away. This makes re-runs free and partial installs harmless.

FROM php:8.1-cli
# ... extensions, composer ...
RUN composer create-project photoncms/installer /app --no-interaction
WORKDIR /app
RUN php artisan migrate --seed --no-interaction

Pin and lock, never float. If you must adopt it (i.e., you've already committed to Photon CMS), put it in require-dev at an exact version, commit composer.lock, and run it only in CI or an ephemeral provisioning step. It must not appear in the deploy artifact.

Capture the post-install state as an artifact. The whole point of an installer is to be run once; the whole problem is that it may not be reproducible later. After a successful install, snapshot the result — mysqldump --no-data, the generated config files, the seeded admin row, published assets — and commit that as the baseline so the installer never has to run again. This is your insurance against the package being unresolvable six months from now.

Idempotency guard around the invocation. Since these installers commonly rewrite .env and config on every run, gate it:

[ -f storage/app/.photon-installed ] || {
  php artisan photon:install --no-interaction
  touch storage/app/.photon-installed
}

Wrap it in a project-level entry point so the team has one command and one documented sequence:

"scripts": {
  "bootstrap:photon": [
    "@php artisan config:clear",
    "@php artisan migrate --seed --no-interaction"
  ]
}

Reference-implementation pattern (the genuinely useful one). Mirror the installer's sequence in your own Artisan command for a product you control. The shape is consistent and worth copying:

class InstallCommand extends Command
{
    protected $signature = 'app:install';

    public function handle()
    {
        $this->call('vendor:publish', ['--tag' => 'app-config']);   // 1. config
        $this->writeEnv(['APP_KEY' => Str::random(32)]);           // 2. env (never overwrite non-empty)
        $this->call('migrate', ['--force' => true]);               // 3. schema
        $this->createAdmin();                                      // 4. first user, prompted
        if ($this->confirm('Load demo content?')) {                // 5. optional data
            $this->call('db:seed', ['--class' => 'DemoSeeder']);
        }
        $this->call('storage:link');
        $this->info('Done. Remove this command from production routes.');
    }
}

CI smoke test. If the installer is part of your flow, prove it works on every framework bump: a CI job that provisions from scratch and asserts an HTTP 200 on the login page. Upstream almost certainly has no such test.

Onboarding pattern. If more than one developer needs a Photon instance, give them the container or a make install target — not a README telling them to run the installer locally. Local runs are how you get environment drift where each dev has a subtly different schema.

Gotchas and Tips

Version drift is the first wall, not a bug. Photon CMS's lineage is Laravel 5.x / PHP 7.0–7.2. On Laravel 9/10/11 and PHP 8.1+, expect hard dependency-resolution failure, then — if you hand-relax constraints — a cascade of runtime errors: str_*/array_* helpers moved to Str/Arr, changed Illuminate\Console signatures, stricter PHP 8 type handling. Debug with composer why-not photoncms/installer and composer install -vvv before touching anything. Do not "just bump the constraints" and call it done; that starts a fork.

Auto-discovery fails silently. The classic half-install: Composer reports success, the service provider is never registered, and the app dies later at first admin login. Confirm registration explicitly:

php artisan package:discover -v
php artisan route:list | grep -i photon
php artisan list | grep -i photon

An exposed installer route is the highest-severity failure mode. Installers of this class write .env, create an admin user, and run migrations. If those endpoints are reachable in a deployed environment, that is privilege escalation, and it does not throw an error — it only surfaces as a security finding. Check route:list, confirm any post-install self-disable logic, and if there is none, delete the routes yourself before shipping.

.env clobbering on re-run. Assume the installer overwrites .env and config with defaults. Back it up, diff after running, and treat the whole thing as one-shot. Keep an .env.photon.dist in version control so environment-specific values are recoverable.

Cached config masks everything. After any step that writes environment values, run php artisan config:clear (and cache:clear). New .env values silently not taking effect is the single most common "the installer didn't work" false alarm.

Database driver assumptions. Check whether the installer expects MySQL or SQLite. DB_CONNECTION=sqlite with a missing database/database.sqlite is a classic failure; touch it first. Similarly, storage/ and bootstrap/cache/ need write permissions — in non-root containers this fails with an unhelpful error, so chown -R www-data:www-data storage bootstrap/cache up front.

Partial installs have no rollback. A migration or seeder that fails midway leaves a half-built schema. Because you're in a throwaway container, the fix is cheap: drop the database and re-provision. Never attempt a partial install against a persistent database.

Seeded admin credentials are a leak. Find where they come from — hard-coded in a seeder, or printed to console output — and rotate them immediately. Grep the source and the console log; don't assume they're random.

No upstream tests, no issue triage, no security contact. Verification of the install path is entirely yours. Assert the login page renders, not that a command exited zero.

Extension point is the fork. These packages are thin wrappers over Artisan; if you need anything beyond the default flow, publish the configs and override, or fork to a private VCS. There is no maintainer to send a PR to in any meaningful sense — budget the patch burden as a recurring cost.

Don't let installer evaluation substitute for CMS evaluation. A successful install tells you the scaffolding works. It tells you nothing about whether Photon CMS is production-viable — those are separate decisions, and the second one carries all the risk.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums