Docker deployment in Laravel - Mini Project: Build & Apply
Start learning this pattern below
Jump into concepts and practice - no test required
Dockerfile in your Laravel project root. Write these exact lines to set up PHP 8.1 with Composer and copy your app code:
FROM php:8.1-fpm
RUN docker-php-ext-install pdo pdo_mysql
COPY . /var/www/html
WORKDIR /var/www/html
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install
Use the official PHP 8.1 FPM image. Install the pdo_mysql extension for database support. Copy your Laravel app code into the container. Set the working directory. Install Composer and run composer install to get dependencies.
docker-compose.yml in your project root. Add a version key set to '3.8'. Define two services: app and db. For app, use the Dockerfile you created, map port 8000 to container port 9000, and mount the current directory to /var/www/html. For db, use the mysql:8.0 image, set environment variables MYSQL_ROOT_PASSWORD to secret and MYSQL_DATABASE to laravel, and expose port 3306. Your docker-compose.yml should look like this structure:Use build: . to build the app service from your Dockerfile. Map ports so you can access Laravel on localhost:8000. Mount your code so changes update live. Use the official MySQL 8 image for the database with environment variables for root password and database name.
.env file. Change the database connection settings to match the Docker MySQL service. Set DB_HOST to db, DB_PORT to 3306, DB_DATABASE to laravel, DB_USERNAME to root, and DB_PASSWORD to secret. Your changes should look like this:
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=secretSet DB_HOST to the service name db so Laravel connects to the MySQL container. Use the same database name, username, and password as in docker-compose.yml.
app service in docker-compose.yml to start the PHP built-in server on port 9000 serving the Laravel public folder. Add this line under app::
command: php artisan serve --host=0.0.0.0 --port=9000
This will let you access your Laravel app at http://localhost:8000.Use the command key in docker-compose.yml under the app service to start Laravel's built-in server listening on all interfaces at port 9000.
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
