Laravel on CloudMagnus

Laravel with composer-create-project done and your .env connected to the database we just provisioned. php artisan key:generate already ran. You handle migrations and your app code.

What our scaffold installs

  • composer create-project --prefer-dist laravel/laravel into your htdocs/
  • .env with APP_URL set to your domain, plus all four DB_* entries (connection, host, port, database, username, password) wired to the MySQL database we provisioned
  • php artisan key:generate already executed; APP_KEY populated
  • A MySQL database scoped to your site, owned by a per-site MySQL user
  • nginx vhost configured for Laravel's public/ directory as the document root, with the standard try_files rewriting
  • PHP-FPM pool tuned to the platform default (adjustable in CloudPanel per site)

What you do next

  1. SSH or SFTP into your site (credentials on the site detail page).
  2. Run migrations: php artisan migrate.
  3. Build your app on top of the Laravel skeleton, or replace the skeleton with your own Laravel codebase.

Where your files live

/home/<site-user>/
├── htdocs/                      ← Laravel app root
│   ├── app/
│   ├── bootstrap/
│   ├── config/
│   ├── database/
│   ├── public/                  ← document root (nginx points here)
│   ├── resources/
│   ├── routes/
│   ├── storage/                 ← writable; logs, sessions, cache
│   ├── vendor/                  ← composer install output
│   ├── .env                     ← DB creds + APP_KEY (mode 600)
│   └── artisan
└── logs/                        ← nginx + php-fpm logs

The .env file

The platform writes .env with mode 600 (read/write only by your site user). The DB credentials reach the file via a tee heredoc invoked through sudo -u <siteUser>; the password is never in argv or any process listing.

If you regenerate .env manually (php artisan key:generate --force or by replacing it with your own), make sure to keep the DB lines or your app loses access to its database. Our scaffold writes them as:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<your-db-name>
DB_USERNAME=<your-db-user>
DB_PASSWORD=<generated>

The actual values are visible on Site Detail → Database (except the password, which is only in the .env on the server).

Deploying changes

  • Single-file edits via SFTP. Connect, edit, save. Fine for tweaks.
  • Git-based deploys. SSH in, cd htdocs, set up a remote, and pull. The repo lives where Laravel does. Run composer install --no-dev --optimize-autoloader and php artisan migrate --force after pulling.
  • CI-built artifacts. Build in your CI (composer install, npm run build, etc.), tar the result, scp it to the server, swap the htdocs directory atomically. Standard zero-downtime deploy pattern.

The platform doesn't include a deploy hook or a build pipeline. Whatever process you set up over SSH is yours to maintain.

Build pipeline

CloudMagnus does not run composer install or npm run build for you on deploy. If your Laravel app uses Mix or Vite for assets, build locally (or in CI) and ship the build artifacts via SFTP.

If you want builds to happen on the server, the standard pattern is a post-receive git hook that runs composer install --no-dev, npm install, npm run build, then php artisan migrate --force. Set this up via SSH; we don't manage it.

Queue workers and scheduled tasks

Laravel's queue worker (php artisan queue:work) needs a process supervisor. Two reasonable options:

  • Supervisor (recommended for production queues): install via SSH (sudo apt install supervisor if you have sudo, otherwise contact support and we'll install it once globally). Configure a /etc/supervisor/conf.d/<site>-queue.conf per Laravel's queue documentation.
  • Cron-driven for low-volume: add a cron job that runs php artisan queue:work --stop-when-empty --max-time=300 every minute. Cheap and good enough for small sites.

For the scheduler (php artisan schedule:run): add a 1-minute cron job from Site Detail → Cron with the command cd /home/<site-user>/htdocs && php artisan schedule:run >> /dev/null 2>&1.

PHP version

The wizard lets you pick PHP 8.1, 8.2, or 8.3 at site creation. Laravel 10 requires 8.1+; Laravel 11 requires 8.2+. Change versions later from Site Detail → Overview → PHP Version. Switches take effect on the next request.

Database access

  • Tinker: php artisan tinker over SSH for quick queries via Eloquent.
  • phpMyAdmin: Site Detail → Database → "Open phpMyAdmin".
  • mysql CLI: SSH in, mysql -u <db-user> -p <db-name> with the password from .env.

Logs

storage/logs/laravel.log       ← Laravel's own log channel
~/logs/nginx/error.log         ← nginx errors (502s, etc.)
~/logs/nginx/access.log        ← request log
~/logs/php-fpm/<site>.error.log ← PHP-FPM errors

Laravel's log channel is configurable via config/logging.php; defaults write to storage/logs/laravel.log with a daily rotation. For production, consider switching to stderr so logs flow into your central observability instead of disk.

Migrating from another host

  1. Add the site on CloudMagnus and let it provision.
  2. On the source: dump the database (mysqldump --single-transaction <db> > dump.sql) and tar your app/, config/, database/, resources/, routes/, public/, and any custom dirs (storage/app/ if you store user uploads there).
  3. On CloudMagnus: SFTP-upload the tar, extract over htdocs/ preserving the existing .env (the DB credentials are different here).
  4. Import the database via phpMyAdmin or mysql < dump.sql over SSH.
  5. Run composer install --no-dev --optimize-autoloader.
  6. Switch DNS A records to point at CloudMagnus.

Common Laravel issues

500 error after deploying changes

Most likely: composer install wasn't run after pulling new dependencies, or the .env got stomped. Check storage/logs/laravel.log for the actual error.

"No application encryption key has been specified"

Means APP_KEY got cleared from .env. Run php artisan key:generate --force over SSH. Note: existing encrypted data (sessions, cookies, encrypted DB columns) becomes unreadable when the key changes.

403 errors on every page

Almost always a permissions issue on storage/ or bootstrap/cache/. SSH in and: chmod -R 775 storage bootstrap/cache. If your code runs as a different user than your shell (it doesn't on CloudMagnus, but on transferred apps it might), also fix ownership: chown -R <site-user>:<site-user> storage bootstrap/cache.

Sessions logging out randomly

If you've set SESSION_DRIVER=file and have multiple PHP-FPM workers, file-based sessions can race. Switch to database sessions: SESSION_DRIVER=database and run php artisan session:table && php artisan migrate.

Composer fails on the server with "memory exhausted"

The default PHP CLI memory limit can be too low for composer on a complex project. Run php -d memory_limit=-1 /usr/local/bin/composer install. If that's still tight, contact support and we'll bump the per-site PHP CLI memory permanently.

Mail isn't being sent

Laravel uses its own mail config. The platform's SMTP2GO setup is for our own transactional mail (signup verification, etc.) — it isn't shared with your Laravel app. Configure your own mail provider in .env (MAIL_* entries); SMTP2GO works fine if you bring your own API key.

What CloudMagnus doesn't do for Laravel

  • Run migrations on deploy. You handle that explicitly.
  • Run composer install on deploy. Build locally, in CI, or via your own SSH-side hook.
  • Asset builds (Vite, Mix). Run on your machine or your CI.
  • Manage queue workers or schedulers. SSH and set them up via supervisor or cron.

Going further

For per-site nginx tuning (rate limits on /login, custom error pages, additional security headers), open CloudPanel from the site detail page. Our wizard ships sane defaults; everything beyond that is exposed in CP's vhost editor.