import { Tabs, Tab, Callout } from 'nextra/components';
It is possible to run web applications (running with the FPM runtime) locally.
To run **event-driven functions** locally, read [Local development for event-driven functions](./local-development/event-driven-functions.mdx) instead.To keep things simple, you can run your applications locally like you did without Bref.
<Tabs items={['Laravel', 'Symfony', 'PHP']}>
With Laravel, run HTTP applications locally using php artisan serve, Laravel Valet, or Laravel Sail.
You can test CLI commands locally by running them in your terminal using `php artisan my-command`.
You can test CLI commands locally by running them in your terminal using `bin/console my-command`.
```bash
php -S localhost:8000
# The application is now available at http://localhost:8000/
```
In order to run the application locally in an environment closer to production, you can run your application using the Bref Docker images. For example, create the following docker-compose.yml:
services:
app:
image: bref/php-84-dev:3
ports: [ '8000:8000' ]
volumes:
- .:/var/task
environment:
HANDLER: public/index.php
# Assets will be served from this directory
DOCUMENT_ROOT: publicYou can then run:
docker-compose upThe application will be available at http://localhost:8000/.
The HANDLER environment variable lets you define which PHP file will be handling all HTTP requests. This should be the same handler that you have defined in serverless.yml for your HTTP function.
Currently, the Docker image supports only one PHP handler. If you have multiple HTTP functions in
serverless.yml, you can duplicate the service indocker-compose.ymlto have one container per lambda function.
The code will be mounted in /var/task, just like in Lambda. But in Lambda, /var/task is read-only.
When developing locally, it is common to regenerate cache files on the fly (for example Symfony or Laravel cache). You have 2 options:
-
either mount the whole codebase as writable (per the example above):
volumes: - .:/var/task
-
or mount a specific cache directory as writable (better):
volumes: - .:/var/task:ro - ./storage:/var/task/storage
If you want to serve assets locally, you can define a DOCUMENT_ROOT environment variable:
services:
app:
# ...
environment:
HANDLER: public/index.php
# Assets will be served from this directory
DOCUMENT_ROOT: publicIn the example above, a public/assets/style.css file will be accessible at http://localhost:8000/assets/style.css.
You can run console commands in Docker via:
# Laravel (artisan)
docker-compose run app php artisan ...
# Symfony (bin/console)
docker-compose run app php bin/console ...The development container (bref/php-<version>-dev) comes with Xdebug pre-installed.
To enable it, create a php/conf.dev.d/php.ini file in your project containing:
zend_extension=xdebug.soNow start the debug session by issuing a request to your application in the browser.
Docker for Mac uses a virtual machine for running docker. That means you need to use a special host name (host.docker.internal) that is mapped to the host machine's IP address.
Edit the php/conf.dev.d/php.ini file:
zend_extension=xdebug.so
[xdebug]
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = 'host.docker.internal'