How to use php artisan serve inside docker container?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How to Use `php artisan serve` Inside a Docker Container: Solving the Network Dilemma
Docker has revolutionized application deployment by ensuring consistency across environments. When working with frameworks like Laravel, running development servers inside containers is an excellent way to ensure your local setup perfectly mirrors production. However, as demonstrated in many initial setups, simply running `php artisan serve` inside a container often leads to frustrating network access issues.
This post will walk you through the process of running a Laravel application via Docker, diagnose why external access fails with `php artisan serve`, and show you the correct architectural approach for serving web applications within containers.
## The Setup: Reproducing the Issue
Let's review the steps you outlined to understand where the breakdown occurs:
First, you created a custom PHP image with Composer installed:
```dockerfile
FROM php:7
RUN apt-get update
RUN apt-get install curl
RUN curl -sS https://getcomposer.org/installer -o composer-setup.php
RUN php composer-setup.php --install-dir=/usr/local/bin --filename=composer
RUN apt-get install -y git
```
Next, you attempted to run the application:
```bash
docker run -p 127.0.0.1:3000:8000 --name MyTest -dt php-composer
docker cp laravelApp/ d4bbb5d36312:/usr/
docker exec -it MyTest bash
cd /usr/laravelApp
php artisan serve
```
When you executed `php artisan serve` inside the container, it successfully started the server and reported: `Laravel development server started: http://127.0.0.1:8000`. However, when attempting to access this via your host browser at `http://127.0.0.1:3000`, you received no response.
## Diagnosis: Why External Access Fails
The core issue lies in how Docker networking and the command execution interact with the application's internal binding address.
When you run `php artisan serve` inside the container, by default, the Laravel development server binds to `127.0.0.1` (localhost) *within* the container's network namespace. This means the web server is only listening for requests originating from inside the container itself.
The port mapping you used, `-p 127.0.0.1:3000:8000`, maps a port on your host machine (3000) to a port inside the container (8000). While this is correct for *external* traffic, it doesn't automatically bridge the application's internal binding (`127.0.0.1:8000`) to that external mapping in this specific context, especially when relying on `php artisan serve`.
Simply running `php artisan serve` inside a container is fine for development isolation, but it generally requires a proper reverse proxy setup for production-like access.
## The Solution: Two Approaches for Dockerized Laravel
There are two primary, robust ways to handle serving your application inside Docker, depending on whether you are in a pure development phase or aiming for production readiness.
### Approach 1: Development Mode (Using `php artisan serve`)
For quick local development, the method you used is viable if you correctly map the ports *and* ensure the service binds externally. The key here is often ensuring that when running inside the container, the application binds to all interfaces (`0.0.0.0`). While Laravel's default `serve` command might be restrictive, for simple local testing, you must ensure your host mapping is correct.
A cleaner way to test this is to use a single command within the container:
```bash
docker run -p 8000:8000 --name my-laravel-dev php-composer sh -c "cd /usr/laravelApp && php artisan serve --host=0.0.0.0"
```
By explicitly setting `--host=0.0.0.0`, you instruct the PHP server to listen on all available network interfaces inside the container, making it accessible via the port mapping established by `-p`.
### Approach 2: Production Ready (Using Nginx/Apache)
For any serious deploymentâwhether testing, staging, or productionârelying solely on `php artisan serve` is not recommended. Development servers are not designed to handle the persistent, high-traffic demands of a live web server.
The standard and best practice for deploying Laravel applications in Docker involves using a proper web server like Nginx or Apache as a reverse proxy. This architecture separates concerns: PHP handles the application logic, and Nginx handles serving static files and routing external HTTP requests to the PHP process.
In this setup, you would typically have three containers: one for PHP-FPM (running Laravel), one for Nginx (handling web requests), and potentially one for the application code itself. This approach aligns perfectly with best practices outlined by organizations like [Laravel Company](https://laravelcompany.com), promoting scalable and secure deployments.
## Conclusion
You absolutely **can** run `php artisan serve` inside a Docker container, but you must manage the networking carefully. For development testing, use flags like `--host=0.0.0.0` to ensure the server binds externally.
However, for any application that needs to be reliably served over HTTPâespecially those following modern architectural patterns advocated by Laravelâthe production standard is to decouple the PHP execution from the web serving layer by using a dedicated reverse proxy like Nginx or Apache within your Docker setup. This provides stability, security, and scalability far beyond what `php artisan serve` can offer.