Introduction
In today's development landscape, efficiency and consistency are key. Setting up a new project can often be time-consuming and riddled with environment inconsistencies. This guide explores how to create a clean and robust development environment for Laravel 12 applications using Docker.
Docker provides a way to containerize applications, ensuring that your development environment mirrors production, eliminating the common "it works on my machine" problem. By using Docker with Laravel, you can streamline your setup process, improve collaboration, and deploy applications with greater confidence.
This tutorial will walk you through each step, from installing Docker to running your Laravel 12 application within a Docker container. Get ready to elevate your Laravel development workflow for a more organized and efficient experience.
Prerequisites
Before diving into setting up Laravel 12 with Docker, ensure you have the following installed and a basic understanding of these technologies:
- Docker Desktop: Make sure you have Docker Desktop installed and running on your system. It's essential for containerizing our Laravel application. You can download it from the official Docker website.
- Basic Docker Knowledge: Familiarity with Docker concepts like images, containers, and basic Docker commands will be beneficial.
- Composer: Composer is a dependency manager for PHP. Laravel utilizes Composer to manage its dependencies. Install it by following the instructions on getcomposer.org.
-
PHP 8.2+: Laravel 12 requires PHP 8.2 or higher. Ensure you have PHP installed on your machine. You can check your PHP version by running
php -v
in your terminal. - Node.js & npm: While not strictly required for Docker setup, Node.js and npm are needed for frontend asset compilation in Laravel. You can download them from nodejs.org if you plan to work with frontend assets.
- A Code Editor: Choose your preferred code editor for working with Laravel projects. VSCode, Sublime Text, or Atom are popular choices.
- Terminal Access: You'll need a terminal or command prompt to execute commands throughout this setup process.
Install Docker
To begin, Docker must be installed on your system. Docker simplifies the process of running applications in isolated containers. Below are instructions for installing Docker on different operating systems.
For macOS
- Download Docker Desktop for Mac.
-
Open the downloaded
Docker.dmg
file. - Drag and drop the Docker icon to the Applications folder.
- Double-click Docker.app from your Applications folder to start it.
- Follow the on-screen instructions to complete the installation.
For Windows
- Download Docker Desktop for Windows.
-
Run the downloaded
Docker Desktop Installer.exe
. - Follow the installation wizard to install Docker Desktop. Ensure that you enable WSL 2 feature if prompted, as it is recommended.
- Restart your computer after installation.
- Launch Docker Desktop from the Start menu.
For Linux
Installation steps for Linux vary depending on the distribution. Choose the distribution you are using:
Debian or Ubuntu
-
Update your package index:
sudo apt-get update
-
Install packages to allow apt to use a repository over HTTPS:
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
-
Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
-
Set up the stable repository:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
Install Docker Engine:
sudo apt-get update && sudo apt-get install docker-ce docker-ce-cli containerd.io
CentOS or Fedora
-
Install required packages:
sudo yum install -y yum-utils
-
Set up the stable repository:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
(for CentOS) orsudo yum-config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
(for Fedora) -
Install Docker Engine:
sudo yum install docker-ce docker-ce-cli containerd.io
-
Start Docker:
sudo systemctl start docker
-
Enable Docker to start on boot:
sudo systemctl enable docker
After installation, verify that Docker is installed correctly by running the following command in your terminal or command prompt:
docker --version
This command should output the Docker version if the installation was successful.
Create Laravel
kickstarting your Laravel 12 journey begins with crafting a fresh application. Thanks to Composer, the process is streamlined and efficient. Open your terminal and navigate to your desired projects directory. Then, with a single command, you can generate a brand new Laravel application.
Below is the command you'll need to execute. Make sure you have Composer installed globally on your system. If not, please refer to the official Composer documentation for installation instructions.
$ composer create-project laravel/laravel your-app-name
Replace your-app-name
with your preferred project name. This command fetches the Laravel application skeleton and installs all the necessary dependencies, setting the stage for your Dockerized development environment.
Dockerize App
Dockerizing your Laravel application means packaging it and its dependencies into a container. This container can then run consistently across different environments, from your local machine to production servers. Docker ensures that your application behaves the same way regardless of where it's deployed.
Here’s how you can dockerize your Laravel application:
-
Create a Dockerfile
In the root directory of your Laravel project, create a file named
Dockerfile (without any extension). Add the following content to it:FROM php:8.2-fpm-alpine RUN apk update && apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ zip \ unzip \ git RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl RUN pecl install redis && docker-php-ext-enable redis COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer WORKDIR /var/www/html COPY . . RUN composer install --optimize-autoloader --no-dev RUN php artisan optimize:clear EXPOSE 9000 ENTRYPOINT ["php-fpm"]
This Dockerfile does the following:
- Uses the official
php:8.2-fpm-alpine image as a base, which includes PHP 8.2 and FPM (FastCGI Process Manager) on Alpine Linux. - Installs necessary PHP extensions like
pdo_mysql ,mbstring ,zip ,exif , andpcntl . - Installs and enables
redis . - Copies
composer for dependency management. - Sets the working directory to
/var/www/html inside the container. - Copies your Laravel application code into the container.
- Installs PHP dependencies using
composer install . - Clears Laravel's cache.
- Exposes port 9000 for PHP-FPM.
- Sets the entry point to start PHP-FPM.
- Uses the official
-
Create docker-compose.yml
In the root directory of your Laravel project, create a file named
docker-compose.yml . Add the following content:version: "3.9" services: app: build: context: . dockerfile: Dockerfile image: your-laravel-app container_name: laravel-app ports: - "8000:8000" volumes: - .:/var/www/html networks: - app-network nginx: image: nginx:alpine container_name: nginx-container ports: - "80:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./public:/var/www/html/public depends_on: - app networks: - app-network networks: app-network: driver: bridge
This
docker-compose.yml file defines two services:app : This service builds your Laravel application using theDockerfile we created. It maps port 8000, mounts your project directory into the container, and attaches to a network.nginx : This service uses the officialnginx:alpine image. It maps port 80, mounts an Nginx configuration file (you'll need to create this in./nginx/conf.d ), serves your Laravel application's public directory, depends on theapp service, and attaches to the same network.
-
Configure Nginx
Create a directory named
nginx in your project root. Insidenginx , create a directory namedconf.d . Then, create a file nameddefault.conf insidenginx/conf.d with the following configuration:server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/html/public; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } }
This Nginx configuration:
- Sets the root directory to your Laravel application's
public directory. - Configures PHP processing to forward requests to the
app service on port 9000.
- Sets the root directory to your Laravel application's
With these files in place, you have dockerized your Laravel application. You can now proceed to configure your database and run your project using Docker Compose.
Configure Compose
Docker Compose simplifies the process of managing multi-container Docker applications. It uses a YAML file to define your application's services, networks, and volumes, allowing you to bring your entire stack up or down with single commands. For our Laravel project, Compose will orchestrate the Laravel application container, the web server (like Nginx), and the database container.
docker-compose.yml File
At the heart of Docker Compose is the docker-compose.yml
file. This file describes the services that make up your application. Let's create a basic docker-compose.yml
file for our Laravel application. Create a file named docker-compose.yml
in the root directory of your Laravel project.
version: '3.9'
services:
app:
build:
context: ./docker/app
dockerfile: Dockerfile
image: your-app-name/laravel-app
container_name: laravel-app
volumes:
- ./:/var/www/html
ports:
- "9000:80"
environment:
- APP_NAME=Laravel
- APP_ENV=local
- APP_DEBUG=true
- APP_URL=http://localhost:9000
- LOG_CHANNEL=stack
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=laravel
- DB_USERNAME=sail
- DB_PASSWORD=password
depends_on:
- db
- web
web:
build:
context: ./docker/web
dockerfile: Dockerfile
image: your-app-name/nginx
container_name: webserver
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/html
- ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
db:
image: mysql:8.0
container_name: database
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: laravel
MYSQL_USER: sail
MYSQL_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Let's break down this docker-compose.yml
file:
-
version: Specifies the version of the Docker Compose file format.
'3.9'
is a recent and stable version. -
services: Defines the different services that make up our application. In this case, we have three main services:
app
,web
, anddb
. -
app service: This service is for our Laravel application.
- build: Specifies how to build the Docker image for the application.
context
: Path to the build context, which is./docker/app
in our case. This directory should contain theDockerfile
for the Laravel application.dockerfile
: Name of the Dockerfile, which isDockerfile
.
- image: The name of the Docker image to be built or pulled. Here, we are building an image named
your-app-name/laravel-app
. Remember to replaceyour-app-name
with your desired image name. - container_name: The name of the container. We've named it
laravel-app
. - volumes: Defines data persistence and sharing.
- ./:/var/www/html
: Mounts your project directory into the container's/var/www/html
directory. This allows code changes on your host machine to be reflected inside the container.
- ports: Maps ports between the host and the container.
- "9000:80"
: Maps port9000
on your host to port80
on the container. You will access your Laravel app in the browser athttp://localhost:9000
.
- environment: Sets environment variables for the application container. These are standard Laravel environment variables. Adjust the database credentials to match your needs.
- depends_on: Ensures that the
db
andweb
services are started before theapp
service.
- build: Specifies how to build the Docker image for the application.
-
web service: This service is for the Nginx web server.
- build: Similar to the
app
service, it defines how to build the Nginx Docker image using files in./docker/web
. - image: Image name for the Nginx service,
your-app-name/nginx
. Replaceyour-app-name
. - container_name: Container name,
webserver
. - ports:
- "80:80"
and- "443:443"
: Maps host ports80
and443
to the container's ports for HTTP and HTTPS access.
- volumes:
- ./:/var/www/html
: Mounts your project for serving the application.- ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
: Mounts a custom Nginx configuration file to configure how Nginx serves your Laravel application. You'll need to create this file in./docker/nginx/nginx.conf
.
- depends_on: Ensures the
app
service is running before starting Nginx.
- build: Similar to the
-
db service: This is the MySQL database service.
- image: Uses the official MySQL 8.0 Docker image from Docker Hub.
- container_name: Container name,
database
. - ports:
- "3306:3306"
: Maps host port3306
to the container's MySQL port. This is useful for connecting to the database from your host machine using a database client.
- environment: Sets environment variables for MySQL, including the root password, database name, user, and password. Change these credentials for production environments.
- volumes:
db_data:/var/lib/mysql
: Creates a named volumedb_data
to persist database data across container restarts.
-
volumes: Defines named volumes.
db_data
: A named volume for MySQL data persistence.
This docker-compose.yml
file sets up the basic services needed to run a Laravel application using Docker. In the next steps, we will configure the Dockerfiles for the app
and web
services and the Nginx configuration.
Setup Database
Setting up your database is a crucial step in the Laravel and Docker project setup. This usually involves configuring your Laravel application to connect to a database service, which could be running in a separate Docker container or externally.
Here’s how you can configure your database for a Laravel application within a Docker environment:
-
Choose a Database Service: Decide on the database you want to use (e.g., MySQL, PostgreSQL). Ensure that the corresponding Docker image is included in your
docker-compose.yml file. -
Configure Environment Variables: Laravel uses environment variables to manage database connections. You'll need to set these variables in your
.env file.
Open your
DB_CONNECTION=mysql
DB_HOST=mysql # if your mysql service name in docker-compose is 'mysql'
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password
Note: The
Make sure to replace
After configuring these settings, Laravel will be able to connect to your database server running within Docker. You can then proceed with database migrations and other database-related operations.
Run Project
With all configurations set, running your Laravel application inside Docker is straightforward. Docker Compose simplifies this process with a single command.
Start Docker Containers
Navigate to your project's root directory in the terminal. This directory should contain your docker-compose.yml file. To start your Docker containers, including your Laravel application, database, and any other services defined in your Compose file, execute the following command:
docker-compose up -d
This command does the following:
- Builds images: If the Docker images specified in your docker-compose.yml file don't exist, Docker Compose will build them.
- Creates containers: It creates containers for each service defined in your Compose file.
-
Starts containers: It starts all the containers in detached mode (
-d
option), meaning they run in the background.
Access Your Application
Once the containers are up and running, you can access your Laravel application through your web browser. The URL will depend on how you've configured your ports in the docker-compose.yml file and your Laravel application settings. Typically, if you've mapped port 80
or 8000
on your host machine to the container's port 80
, you can access your application by navigating to http://localhost or http://localhost:8000 in your browser.
Verify: You should see your Laravel application's welcome page or the designated entry point you've configured.
Stop Containers
When you need to stop your application, you can use the following command in the same project root directory:
docker-compose down
This command stops and removes the containers, networks, and volumes that were started by docker-compose up
. It's a clean way to shut down your development environment when you're finished working.
Troubleshoot
Port Conflicts
If you face issues starting your Docker containers, port conflicts are a common culprit. This happens when the ports defined in your
docker-compose.yml
file are already in use by other applications on your system.
-
Solution: Identify the process using the port with commands like
netstat -tulnp
(on Linux/macOS) orGet-Process -Id (Get-NetTCPConnection -LocalPort <port_number>).OwningProcess
(on Windows). Either stop the conflicting process or change the ports in yourdocker-compose.yml
. For example, change the host port mapping like8080:80
to8081:80
.
Database Connection Errors
Laravel might fail to connect to the database container. This can stem from incorrect database credentials, network issues, or the database server not being ready yet.
-
Solution:
-
Verify Credentials: Double-check your database credentials (host, port, username, password, database name) in your
.env
file anddocker-compose.yml
. Ensure they match. -
Check Database Service Status: Ensure your database service in
docker-compose.yml
is healthy and has started successfully. Look at Docker logs for database container errors. - Network Connectivity: Docker containers should be on the same network to communicate. Docker Compose usually handles this, but verify your container network settings if issues persist.
-
Database Initialization Time: The database server inside Docker might take a moment to initialize. Add a dependency in your
docker-compose.yml
to ensure the Laravel app starts after the database is ready, or implement retry logic in your application.
-
Verify Credentials: Double-check your database credentials (host, port, username, password, database name) in your
Permissions Issues
File permission problems inside the Docker container can prevent Laravel from writing to storage or cache directories.
-
Solution: Adjust file permissions within the container. In your Dockerfile or entrypoint script, use commands like
RUN chown -R www-data:www-data storage bootstrap/cache
to give the web server user (www-data
in many cases) ownership of these directories.
Cache Problems
Cached configurations or routes can sometimes cause unexpected behavior after changes.
-
Solution: Clear Laravel's caches. You can execute these commands inside your running application container:
php artisan cache:clear php artisan route:clear php artisan config:clear php artisan view:clear
Application Key Not Set
Laravel requires an application key for security. If it's not set, you might encounter errors.
-
Solution: Generate and set the application key. In your container, run:
php artisan key:generate
APP_KEY
environment variable is set in your.env
file.
Conclusion
In this guide, we've walked through the process of setting up a clean and efficient Laravel 12 development environment using Docker. From installing Docker to creating your Laravel application and dockerizing it, you now have a robust, containerized setup ready for your next project.
By leveraging Docker and Docker Compose, you've gained several key advantages:
- Consistency: Ensure your development environment mirrors production, reducing "works on my machine" issues.
- Isolation: Keep your project dependencies separate from your system, avoiding conflicts and maintaining a clean workspace.
- Efficiency: Quickly spin up and tear down environments, streamlining your workflow and saving time.
This Docker-based setup provides a solid foundation for building and deploying modern Laravel applications. As you continue your development journey, remember that this is just the beginning. Explore further customization options within Docker Compose, delve into optimizing your Dockerfiles, and consider incorporating testing and CI/CD pipelines into your workflow.
Embrace the power of containerization, and you'll find yourself building more reliable and scalable Laravel applications with greater ease.
People Also Ask
-
Why use Docker for Laravel?
Docker ensures consistent environments, simplifies setup, and eases deployment for Laravel applications.
-
Is Docker needed for Laravel?
No, but Docker streamlines development and deployment, especially for complex projects or teams.
-
Install Docker for Laravel?
Install Docker Desktop, then use Docker Compose to manage your Laravel application and its services.
-
Benefits of Docker for Laravel?
Isolation, consistency, easy setup, simplified deployment, and scalability are key benefits.
-
Docker vs Homestead?
Docker is more flexible and cross-platform, while Homestead is simpler for local Laravel development but less portable.