4 · Installer + harden
Objective — install the app the CodeCanyon way (a web wizard, not artisan migrations): temporarily unblock /install, run the wizard against the staging DB, verify the app loads, then immediately re-block /install + /update and re-harden permissions — because you opened a writable, installable surface to the public web.
Background
Section titled “Background”CodeCanyon apps install through a web wizard, not artisan migrations. Phase 3 blocked /install and /update for safety, so this page temporarily unblocks them, runs the wizard, then re-blocks and re-hardens. The harden step is not optional — you opened a writable, installable surface to the public web.
1. Temporarily unblock the /install route
Section titled “1. Temporarily unblock the /install route”Phase 3 added .htaccess rules (and possibly a Cloudflare WAF rule) blocking /install, /update, and /upgrade-script. Comment them out so the wizard can load.
-
Unblock the install routes and remove any stale lock.
Terminal window # Is /install currently blocked?ssh <staging-alias> "grep 'RewriteRule ^install' ~/domains/staging.yourapp.com/deploy/current/public/.htaccess 2>/dev/null"# Comment out the blocking rules (idempotent — skip lines already commented)ssh <staging-alias> 'cd ~/domains/staging.yourapp.com/deploy/current/public && \grep -q "^RewriteRule ^install" .htaccess && \sed -i "s/^RewriteRule ^install/# RewriteRule ^install/" .htaccess; \grep -q "^RewriteRule ^update" .htaccess && \sed -i "s/^RewriteRule ^update/# RewriteRule ^update/" .htaccess; \grep -q "^RewriteRule ^upgrade-script" .htaccess && \sed -i "s/^RewriteRule ^upgrade-script/# RewriteRule ^upgrade-script/" .htaccess; \echo "install/update unblocked"'# Remove any stale install lockssh <staging-alias> "rm -f ~/domains/staging.yourapp.com/deploy/shared/storage/installed 2>/dev/null && echo 'lock removed'"# Expected: "install/update unblocked" and "lock removed"- ✅ The blocking rules are commented out and any stale
installedlock is removed.
- ✅ The blocking rules are commented out and any stale
-
Confirm the wizard is reachable.
Terminal window curl -sI https://staging.yourapp.com/install 2>&1 | head -1 # expect HTTP/2 200# Expected: HTTP/2 200- ✅
/installreturnsHTTP/2 200.
- ✅
If you created a Cloudflare WAF rule in Phase 3, toggle it OFF now (👤): Cloudflare → Security → WAF → “Block install and update routes” → OFF.
2. Run the installer wizard
Section titled “2. Run the installer wizard”The wizard is browser-only — an agent can’t click through it. Open https://staging.yourapp.com/install and walk the screens.
-
Requirements — all checks green → Next. (Reds usually mean a missing PHP extension or a permission the page-3
chmod 777should have fixed.)- ✅ Every requirement check is green.
-
Database — Host
localhost; database / username / password from.env.staging; Test Connection → Next.- ✅ Test Connection succeeds against the staging DB.
-
Admin account — name, a staging admin email, and a strong password saved to your password manager now.
- ✅ The admin account is created and its password is in the vault.
-
Settings — app name (e.g. “Your App — Staging”), URL
https://staging.yourapp.com.- ✅ App name and URL are set for staging.
-
Install / Finish → confirm “Installation Complete”.
- ✅ The wizard reports “Installation Complete”.
Use the table to recover from a wizard that won’t load or stalls:
| Installer result | Action |
|---|---|
| Wizard loads | Continue |
| 403 Forbidden | .htaccess still blocking — re-run section 1 |
| 404 | Installer route missing — confirm the app ships one |
| 500 | tail -50 …/deploy/current/storage/logs/laravel.log |
| 504 Gateway Timeout | PHP timeout too low — confirm shared/.user.ini has max_execution_time = 300 (page 1, step 7), then retry |
| ”Access Denied” mid-wizard | Stale cached config with old DB values — optimize:clear with the versioned PHP binary (page 3, step 2), then retry |
| ”Already installed” | Remove storage/installed (section 1) |
3. Verify the installation
Section titled “3. Verify the installation”Sign in and confirm the app is healthy after the wizard.
-
Sign in at
/loginand walk the post-install checks.Visit
https://staging.yourapp.com/loginand sign in with the admin account.Check Pass Dashboard loads [ ] Navigation works [ ] No PHP errors [ ] CSS/JS loading [ ] SSL padlock shows [ ] - ✅ Admin login works and all five post-install checks pass.
4. Re-block /install and /update
Section titled “4. Re-block /install and /update”The writable, installable surface must close as soon as the wizard finishes.
-
Re-comment the blocking rules and confirm
/installis forbidden.Terminal window ssh <staging-alias> 'cd ~/domains/staging.yourapp.com/deploy/current/public && \grep -q "^# RewriteRule ^install" .htaccess && \sed -i "s/^# RewriteRule ^install/RewriteRule ^install/" .htaccess; \grep -q "^# RewriteRule ^update" .htaccess && \sed -i "s/^# RewriteRule ^update/RewriteRule ^update/" .htaccess; \grep -q "^# RewriteRule ^upgrade-script" .htaccess && \sed -i "s/^# RewriteRule ^upgrade-script/RewriteRule ^upgrade-script/" .htaccess; \echo "install/update re-blocked"'curl -sI https://staging.yourapp.com/install 2>&1 | head -1 # expect HTTP/2 403# Expected: "install/update re-blocked" then HTTP/2 403- ✅ The rules are restored and
/installreturnsHTTP/2 403.
- ✅ The rules are restored and
Re-enable the Cloudflare WAF rule if you toggled it off (👤).
5. Re-harden permissions
Section titled “5. Re-harden permissions”Walk back the temporary 777 from page 3 to least-privilege.
-
Restore least-privilege on storage and
.env.Terminal window # storage: dirs 775, files 664ssh <staging-alias> "cd ~/domains/staging.yourapp.com/deploy/shared/storage && \find . -type d -exec chmod 775 {} \; && find . -type f -exec chmod 664 {} \;"# .env: 640ssh <staging-alias> "chmod 640 ~/domains/staging.yourapp.com/deploy/shared/.env"# Expected: storage dirs 775 / files 664; .env 640- ✅ Storage dirs are
775, files664, and.envis640.
- ✅ Storage dirs are
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 👤 Wizard completed —
/installreachable (200), wizard completed, “Installation Complete” shown. - 👤 App verified — all five post-install checks pass; admin login works.
- 🔀 Routes re-blocked —
/installre-blocked (403); Cloudflare WAF rule restored. - 🤖 Permissions re-hardened — storage dirs
775/ files664;.env640.