How-to
Laravel
Serve a Laravel application from its public/ directory through PHP-FPM, with the Laravel
profile’s deny and cache-bypass rules.
Prerequisites
- ScalWS installed, with
include: sites.d/*.yamlin/etc/scalws/scalws.yaml(see Sites). - The project deployed outside
/home, for example/srv/shop, withcomposer installdone and.envconfigured. Only/srv/shop/publicis served. - The project readable by group
scalws(sudo chmod -R g+rX /srv/shopwith groupscalws). - PHP-FPM: the distribution’s pool under scalws-controller, or a pool ScalWS manages
under
scalwsd.service(see the three services).
Let ScalWS confirm the framework first; detect only reads the directory:
scalwsctl detect /srv/shopWhat the profile does
profile: laravel gives:
- a PHP runtime with root
<root>/public,front_controller: /index.php, a managed pool of 2 to 16 workers andmemory_limit: 256M(used only when the site has nophp:); - deny rules for
/.env,/storage/logsand/vendor(answered404); - cache-bypass rules for the
laravel_sessionandXSRF-TOKENcookies (used whencache:is set).
Under scalws-controller: an existing PHP-FPM pool
The controller refuses managed pools, so give the pool and the public root yourself; the profile’s rules still apply:
# /etc/scalws/sites.d/shop.example.com.yaml
domain: shop.example.com
root: /srv/shop
profile: laravel
php:
fastcgi: unix:/run/php/php8.3-fpm.sock
root: /srv/shop/public
front_controller: /index.php
https_redirect: truerootis the project directory.php.rootis the document root: never serve the project root.php.front_controllersends every path that is not a file topublic/index.php.
User scalws must be able to connect to the pool’s socket (on Debian and Ubuntu:
sudo usermod -aG www-data scalws, then sudo systemctl restart scalws-controller and
sudo scalws-controller reload). PHP-FPM’s pool user needs write access to storage/ and
bootstrap/cache/.
Under scalwsd.service: a managed pool
The profile supplies the whole runtime:
# /etc/scalws/sites.d/shop.example.com.yaml
domain: shop.example.com
root: /srv/shop
profile: laravel
https_redirect: trueOr written out, to change the pool:
domain: shop.example.com
root: /srv/shop
profile: laravel
php:
root: /srv/shop/public
front_controller: /index.php
fpm:
workers: {min: 4, max: 16}
ini: {memory_limit: 256M}
env: {APP_ENV: production}The pool clears the environment and passes only
php.fpm.env. PHP runs as scalws (or the
tenant’s user) inside the unit’s sandbox, where /srv is read-only. Allow Laravel’s
writable directories with a drop-in:
# /etc/systemd/system/scalwsd.service.d/writable.conf
[Service]
ReadWritePaths=/srv/shop/storage /srv/shop/bootstrap/cacheThen sudo systemctl daemon-reload && sudo systemctl restart scalwsd.
Apply
sudo scalwsctl check
sudo scalws-controller reload # under scalws-controller
sudo scalwsctl reload # under scalwsd.serviceCheck it works
curl -sI -H 'Host: shop.example.com' http://127.0.0.1/ # 200 from public/index.php
curl -sI -H 'Host: shop.example.com' http://127.0.0.1/.env # 404
curl -sI -H 'Host: shop.example.com' http://127.0.0.1/up # Laravel 11 health route
sudo scalwsctl site listCommon problems
- The project’s files are reachable, for example
/composer.json: the PHP root is the project root. Setphp.roottopublic/(or use the profile withoutphp:). managed php runtimes are not supported with several instances (ADR-0036): under scalws-controller the site needsphp.fastcgi.public/.htaccessseems ignored: withhtaccess: true,.htaccessfiles are read below the site’sroot(/srv/shop), not belowphp.root. Laravel’s file only routes toindex.php, whichfront_controlleralready does, so you do not need it.- 500 from Laravel, “Permission denied” in
storage/logs: the PHP user cannot writestorage/orbootstrap/cache/. - 502: PHP-FPM is not running or its socket does not let
scalwsconnect; see troubleshooting.
See also: applications, profiles.