Developing a Laravel application within a Docker container on WSL2 offers a powerful and efficient workflow. Follow these steps to set up your environment, including installing Docker, creating a Laravel project, and configuring PostgreSQL.

Step 1: Install Docker on WSL2

First, you need to install Docker on WSL2. Follow the official Docker documentation for installing Docker Engine on Ubuntu: Install Docker on Ubuntu.

Step 2: Create a Laravel Project

Next, create a new Laravel project by following the Laravel documentation: Creating a Laravel Project.

composer create-project --prefer-dist laravel/laravel my-laravel-app
cd my-laravel-app

Step 3: Install PostgreSQL

Install PostgreSQL on your system with the following command:

sudo apt install postgresql postgresql-contrib

Step 4: Create a Dockerfile

In the root directory of your Laravel project, create a Dockerfile with the following content:

# Use the official PHP image.
# https://hub.docker.com/_/php
FROM php:8.3-apache

# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
  libfreetype6-dev \
  libjpeg62-turbo-dev \
  libpng-dev \
  libzip-dev \
  libpq-dev \
  libsqlite3-dev \
  zip \
  unzip \
  postgresql-client \
  && docker-php-ext-install -j "$(nproc)" opcache gd zip pdo_pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg

# Configure PHP for Cloud Run.
RUN set -ex; \
  { \
  echo "; Cloud Run enforces memory & timeouts"; \
  echo "memory_limit = -1"; \
  echo "max_execution_time = 0"; \
  echo "; File upload at Cloud Run network limit"; \
  echo "upload_max_filesize = 1G"; \
  echo "post_max_size = 1G"; \
  echo "; Configure Opcache for Containers"; \
  echo "opcache.enable = On"; \
  echo "opcache.validate_timestamps = Off"; \
  echo "; Configure Opcache Memory (Application-specific)"; \
  echo "opcache.memory_consumption = 32"; \
  } > "$PHP_INI_DIR/conf.d/cloud-run.ini"

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Copy in custom code from the host machine.
WORKDIR /var/www/html

COPY . ./

COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

RUN chmod 777 -R /var/www
RUN chown -R www-data:www-data /var/www

# Ensure the storage and cache directories exist
RUN mkdir -p /var/www/html/storage/logs /var/www/html/bootstrap/cache

# Set the correct permissions for Laravel
RUN chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache

# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
ENV PORT=8080

RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

# Configure PHP for development.
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

# Enable Apache modules
RUN a2enmod rewrite

# Expose the port
EXPOSE 8080

COPY entrypoint.sh ./
RUN chmod +x entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]

Step 5: Create Apache Configuration File

Create an 000-default.conf file at the root directory of your project with the following content:

<VirtualHost *:80>
	ServerName localhost
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/public
	<Directory /var/www/html/public/>
		Options Indexes FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
</VirtualHost>

Step 6: Create Docker Compose File

Create a docker-compose.yml file with the following content:

services:
  laravel:
    image: laravel:latest
    env_file:
      - .env
    ports:
      - "8080:8080"
    network_mode: "host"

Step 7: Create Entrypoint Script

Create an entrypoint.sh file at the root directory of your project with the following content:

#!/bin/bash

# Ensure composer dependencies are installed
composer install --no-scripts --no-interaction --prefer-dist

# Run your Laravel artisan command
php artisan migrate:fresh --seed

# Start Apache in the foreground (adjust if needed)
apache2-foreground

Make sure the entrypoint script is executable:

chmod +x entrypoint.sh

Final Steps

  1. Build and Run Docker Containers:

    docker compose up --build
    
  2. Access Your Application:

    Once the containers are up and running, you can access your Laravel application by navigating to http://localhost:8080 in your web browser.

By following these steps, you’ll have a fully functional Laravel development environment running inside Docker on WSL2, complete with PostgreSQL as your database. This setup enhances development efficiency and provides a consistent environment across different machines.