Docker deployment helps you run your Laravel app in a small, consistent container. This makes it easy to share and run your app anywhere without setup problems.
Docker deployment in Laravel
Start learning this pattern below
Jump into concepts and practice - no test required
FROM php:8.2-fpm WORKDIR /var/www/html COPY . . RUN apt-get update && apt-get install -y libzip-dev zip unzip && docker-php-ext-install zip pdo pdo_mysql RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN composer install EXPOSE 9000 CMD ["php-fpm"]
This is a simple Dockerfile for Laravel using PHP 8.2 FPM.
It installs PHP extensions and Composer, then runs your app.
FROM php:8.2-fpm WORKDIR /var/www/html COPY . . RUN apt-get update && apt-get install -y libzip-dev zip unzip && docker-php-ext-install zip pdo pdo_mysql RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN composer install EXPOSE 9000 CMD ["php-fpm"]
version: '3.8' services: app: build: . ports: - "8000:9000" volumes: - .:/var/www/html depends_on: - db db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: laravel MYSQL_USER: user MYSQL_PASSWORD: secret ports: - "3306:3306"
This example shows a Dockerfile to set up PHP and Laravel, and a docker-compose file to run the app with a MySQL database. You can run docker-compose up to start your Laravel app on port 8000.
# Dockerfile FROM php:8.2-fpm WORKDIR /var/www/html COPY . . RUN apt-get update && apt-get install -y libzip-dev zip unzip && docker-php-ext-install zip pdo pdo_mysql RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN composer install EXPOSE 9000 CMD ["php-fpm"] # docker-compose.yml version: '3.8' services: app: build: . ports: - "8000:9000" volumes: - .:/var/www/html depends_on: - db db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: laravel MYSQL_USER: user MYSQL_PASSWORD: secret ports: - "3306:3306"
Remember to set correct permissions on storage and bootstrap/cache folders for Laravel.
Use volumes in docker-compose to sync your code changes without rebuilding the image.
Make sure your .env file is configured to connect to the MySQL service using the service name 'db'.
Docker deployment packages your Laravel app with PHP and dependencies in a container.
Use a Dockerfile to define the app environment and docker-compose to run app and database together.
This makes your app easy to run anywhere with one command.
Practice
Solution
Step 1: Understand Docker's role in deployment
Docker packages the app and its environment so it runs the same everywhere.Step 2: Relate this to Laravel deployment
Laravel apps need PHP, web server, database, and dependencies; Docker bundles these.Final Answer:
To package the Laravel app with all its dependencies for consistent environments -> Option AQuick Check:
Docker ensures consistent app environment = C [OK]
- Thinking Docker speeds up coding
- Confusing Docker with Laravel features
- Believing Docker replaces Laravel's internal functions
Solution
Step 1: Identify Dockerfile's purpose
Dockerfile contains commands to build the Docker image step-by-step.Step 2: Differentiate from other files
docker-compose.yml runs containers; .env holds app configs; composer.json manages PHP packages.Final Answer:
Dockerfile -> Option CQuick Check:
Dockerfile builds image = A [OK]
- Confusing docker-compose.yml with Dockerfile
- Thinking .env defines Docker build steps
- Mixing composer.json with Docker configs
services:
app:
build: .
ports:
- "8000:80"
volumes:
- .:/var/www/html
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
What happens when you run docker-compose up?Solution
Step 1: Analyze docker-compose services
App service builds from current folder, maps port 8000 to container's 80, mounts code volume. DB uses MySQL image with root password set.Step 2: Understand docker-compose up behavior
It builds and starts all defined services, so both app and db run with given configs.Final Answer:
It builds the app image, runs app on port 8000, and starts MySQL with root password -> Option AQuick Check:
Compose runs all services with configs = B [OK]
- Assuming only one service runs
- Missing environment variable for MySQL password
- Confusing port mapping direction
FROM php:8.1-fpm RUN apt-get update && apt-get install -y git zip unzip COPY . /var/www/html RUN composer installWhat is the likely cause of the build failure?
Solution
Step 1: Check Dockerfile commands order
Composer is a separate tool and must be installed before runningcomposer install.Step 2: Identify missing Composer installation
Dockerfile does not install Composer, so the command fails.Final Answer:
Missing installation of Composer before running composer install -> Option DQuick Check:
Composer must be installed before use = D [OK]
- Assuming PHP image includes Composer by default
- Thinking COPY syntax causes build error
- Believing PHP 8.1-fpm is incompatible with Laravel
Solution
Step 1: Check app service configuration
services: app: build: . ports: - "8080:80" volumes: - .:/var/www/html db: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: secret cache: image: redis:latest ports: - "6379:6379" builds app from current folder, maps port 8080 to container port 80, and mounts code volume correctly.Step 2: Verify db and cache services
MySQL uses image mysql:8 with root password set; Redis uses latest image and exposes default port 6379.Step 3: Compare other options for correctness
services: app: image: laravel/php ports: - "80:80" db: image: mysql environment: MYSQL_PASSWORD: secret cache: image: redis ports: - "6379:6379". This option misses the volume mount for app code and uses wrong environment variable for MySQL (MYSQL_PASSWORD instead of MYSQL_ROOT_PASSWORD); the option with app ports "80:8080" has wrong port mapping; the option without ports for Redis misses exposing the Redis port.Final Answer:
services: app: build: . ports: - "8080:80" volumes: - .:/var/www/html db: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: secret cache: image: redis:latest ports: - "6379:6379" -> Option BQuick Check:
Correct service setup with ports and env = A [OK]
- Swapping port mappings (host:container)
- Using wrong environment variable names
- Omitting volume mounts for app code
- Not exposing Redis port
