Skip to content

Choose and set up a local server for Pollora: artisan serve, Valet, Herd, MAMP, DDEV, Apache or nginx, with the document root, APP_URL and a checklist for blank pages and 404s.

Pollora runs on any server that can serve a PHP application from a document root. The table lists what was set up and run for each tool, so you can see what has been checked and what has not. It is not a ranking: pick the tool you already use.

EnvironmentDocument rootAPP_URLKnown trapTested
php artisan servepublic/, set by Laravelhttp://localhost:8000Nothing to configuremacOS 15, PHP 8.4
Laravel Valetpublic/, set by Valethttp://my-project.test, or https:// after valet secureA default site answers every unknown .test domainmacOS 15, PHP 8.4, HTTP and HTTPS (Valet 4.12)
Laravel Herdpublic/, set by Herdhttp://my-project.testwp-login.php and wp-admin answer 404 without LocalValetDriver.phpmacOS 15, PHP 8.4 (Herd 1.30), with the driver
MAMPSet it to public/ yourselfhttp://localhost:8888A document root on the project folder serves .env; a PHP version older than the one that ran composer stops the sitemacOS 15, PHP 8.3.30 (MAMP 7.4)
DDEVpublic/, set by ddev config --docroot=publichttps://my-project.ddev.siteThe database host is db, not localhostLinux, nginx-fpm and Apache-fpm. Not tested on macOS or Windows
Apache with PHP-FPMSet it to public/ yourselfThe address of the virtual hostA document root on the project folder serves .envmacOS 15 (Homebrew, Apache 2.4, PHP 8.4); Linux (DDEV)
nginx with PHP-FPMSet it to public/ yourselfThe address of the server blockSee Server ConfigurationLinux (DDEV, nginx-fpm). Not tested on macOS
LaradockNot coveredNot coveredNot coveredNot tested

Whatever the server, three things must agree:

  1. The document root is the project’s public/ folder. public/ holds the front controller (index.php), WordPress core (cms/) and the content folder (content/). A server pointed at the project folder answers a 404 on the home page and, worse, serves /.env as a text file with the application key and the database password.
  2. The site is opened at the same address as APP_URL. WordPress sends /cms/wp-admin/ to the host written in APP_URL. Open the site on another address (127.0.0.1 instead of my-project.test) and the admin redirects you to the APP_URL host, where you are not logged in.
  3. APP_URL names a scheme, http:// or https://. Pollora reads APP_URL=my-project.test as http://my-project.test, but everything else that reads the setting (Laravel’s URL helpers in the console, mails, a queue worker) gets the bare host. php artisan pollora:doctor warns about it.

Nothing to configure. In .env:

APP_URL=http://localhost:8000
Terminal window
php artisan serve

Open http://localhost:8000/cms/wp-admin/: the login page is shown. PHP’s built-in server (php -S localhost:8000 -t public) gives the same result.

Valet names the site after the project folder, or after the name given to valet link.

Terminal window
cd my-project
valet link
APP_URL=http://my-project.test

To serve the site over HTTPS, run valet secure and write the scheme in .env:

Terminal window
valet secure
APP_URL=https://my-project.test

Open http://my-project.test/cms/wp-admin/: the login page is shown.

Valet runs the site through its own server.php, not public/index.php. Pollora handles that since 13.38.1: update the framework if the home page redirects to itself.

Note
A default site (valet default, stored in ~/.config/valet/config.json) answers for every .test domain Valet does not know. If the site shown is not your project, run valet which in the project folder to see which site Valet serves.

Add the project folder to Herd, then write the address Herd gives the site in .env:

APP_URL=http://my-project.test

Herd sends every .php URL to the front controller. WordPress’s own entry points (wp-login.php, wp-admin/*.php, wp-cron.php, xmlrpc.php) never run: they answer the site’s 404, and there is no way to log in. The skeleton ships a LocalValetDriver.php at the project root that fixes this. Valet and Herd both read a driver of that name from the project. It hands an existing .php file under public/ to PHP, as a web server with a document root does, and never one under uploads/. Everything else goes to the front controller as before.

A project created with the 13.38.1 skeleton or later has the file. For an existing project, copy LocalValetDriver.php from the skeleton to the project root.

Open http://my-project.test/cms/wp-admin/: the login page is shown.

MAMP uses Apache, and its document root is a setting you must change.

  1. Preferences › Server › Document root: choose the public/ folder of the project, not the project folder.
  2. Preferences › PHP: choose PHP 8.3 or 8.4.
  3. In .env:
APP_URL=http://localhost:8888

MAMP’s MySQL user is root with the password root. See The Database.

The PHP version that serves the site must be at least the one composer resolved the dependencies for. A project whose lock was resolved on PHP 8.4 and that MAMP serves with its default PHP 8.3 stops with Your Composer dependencies require a PHP version ">= 8.4.1". You are running 8.3.30. The skeleton has resolved its lock for PHP 8.3 since 13.38.1. For an older project, tell Composer to resolve for PHP 8.3, then update the Symfony packages:

Terminal window
composer config platform.php 8.3.0
composer update "symfony/*" --with-all-dependencies

Open http://localhost:8888/cms/wp-admin/: the login page is shown.

[!WARNING] Do not point MAMP at the project folder. The site answers a 404 and .env is served as a text file. If Site Health reports it (Tools › Site Health, Document root), fix the document root, then change APP_KEY and the passwords in .env.

DDEV runs the site in containers. The Pollora CLI sets the whole thing up:

Terminal window
pollora new example-app --ddev

With --ddev, the CLI runs ddev config --project-type=wordpress --docroot=public --php-version=8.4 --database=mariadb:10.11 --disable-settings-management, starts the project, installs Pollora inside the container, writes the connection settings to .env, and runs the WordPress installation:

APP_URL=https://example-app.ddev.site
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=db
DB_USERNAME=db
DB_PASSWORD=db

The site is at https://example-app.ddev.site: open https://example-app.ddev.site/cms/wp-admin/ for the login page. Run Artisan commands inside the container, for example ddev exec php artisan pollora:doctor.

Inside a DDEV container (IS_DDEV_PROJECT=true), the questions pollora:env:setup asks are pre-filled from DDEV: the site URL from DDEV_PRIMARY_URL, the port, and the database host (db), name and user (PGDATABASE and PGUSER, db when missing). The password is always asked; type db, the DDEV default.

Note
For a project that already exists, configure DDEV with the same ddev config options as above, then run ddev start.

Point the document root of the virtual host to the public/ folder of the project, and write the address of the virtual host in APP_URL. The skeleton’s public/.htaccess sends requests to the front controller. Server Configuration covers the document root, the directory browsing protection and HTTPS behind a proxy.

[!WARNING] Do not point Apache at the project folder: .env is then served as a text file.

Point the document root of the server block to the public/ folder and write the address of the server in APP_URL. Server Configuration has the configuration; it is not repeated here.

The framework recognizes a Laradock environment (LARADOCK_PHP_VERSION is set) and pre-fills the questions of pollora:env:setup from its MYSQL_* variables. Laradock has not been run for this documentation: nothing else is claimed about it.

Several fixes for local servers shipped with 13.38.1. In a project created before it:

Terminal window
composer update pollora/framework

Then, depending on your server, add the LocalValetDriver.php file (Herd and Valet) or the platform.php setting shown for MAMP.

Pollora needs MySQL 5.7+ or MariaDB 10.3+. WordPress is only loaded when Laravel’s default connection uses the mysql driver, so SQLite and PostgreSQL are not supported. Set the connection in .env with Laravel’s names (DB_CONNECTION=mysql, DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD).

An empty password is accepted: the MySQL root user installed with Homebrew has none, so leave the password empty when pollora:install asks for it. MAMP’s MySQL user is root with the password root. On macOS, DBngin installs MySQL or MariaDB. DDEV provides its own database; see DDEV.

Start with the doctor:

Terminal window
php artisan pollora:doctor

For a local setup, four of its checks matter:

CheckWhat it catchesRuns in
Environment file.env names Pollora does not read (DB_NAME, DB_USER, WP_HOME…), MySQL settings on a sqlite connectionConsole, Site Health
Application URLAPP_URL without a schemeConsole, Site Health
Configuration and route cachesEdits to .env or routes/ ignored because the configuration or the routes are cached outside productionConsole, Site Health
Document rootThe web server serves .env: it exposes the project folder, not public/Site Health only

The Document root check needs a web request, so it appears in WordPress’s Tools › Site Health, not in the console. The doctor has more checks, for the theme, the patches, the blocks and the other modules: see Diagnosing a project.

If the site does not behave, find your symptom:

SymptomCauseFix
Blank page, or Your Composer dependencies require a PHP version ">= 8.4.1"The PHP that serves the site (MAMP, Herd) is older than the one that ran composerCompare php -v with the PHP chosen in the server’s settings; use 8.3 or 8.4, or see MAMP
404 on the home page, and /.env is readableThe document root is the project folderPoint it to public/, then change APP_KEY and the passwords
Redirect to another address, or logged out of the adminThe site is opened on another address than APP_URLOpen the site at the address written in APP_URL
The home page redirects to itself (Valet, Herd)Framework older than 13.38.1composer update pollora/framework
/cms/wp-admin/ answers 404 (Valet, Herd)Framework older than 13.38.1composer update pollora/framework
wp-login.php and wp-admin answer 404, no login (Herd)Herd sends every .php URL to the front controllerCopy LocalValetDriver.php to the project root
Artisan commands crash, or the admin answers 404, with APP_URL=my-project.testAPP_URL has no schemeWrite http:// or https:// in APP_URL
The site shown is not your project (Valet, Herd)A default site answers every unknown .test domainvalet which, or check the site in Herd’s settings

If it still fails, these are what we need to see: php -v and the PHP version chosen in your server’s settings, the output of php artisan pollora:doctor, and what curl -I answers for / and /cms/wp-login.php (status line and Location). When the page is blank, add the last lines of the server’s error log and of storage/logs/laravel.log.

Check that the site works:

  1. The home page answers 200: curl -I http://my-project.test/ (use your APP_URL).
  2. /cms/wp-admin/ shows the WordPress login page, and the admin credentials you chose during the installation log you in.
  3. php artisan pollora:doctor ends without an error.

Then: