Let’s convert the Dockerfiles for both Laravel and MySQL into a docker-compose.yml
file.
The docker-compose.yml
file is a YAML-formatted configuration file used to define and run multi-container Docker applications. Let’s break down the various sections of the docker-compose.yml
file and explain their purpose:
- Version:
- The
version
key specifies the Docker Compose file format version. This indicates which features and syntax are supported in the file. The version number helps Docker Compose interpret the structure of the file correctly.
- The
- Services:
- The
services
key defines the individual services or containers that make up the application. Each service represents a containerized component of the application, such as a web server, database, cache, etc. - Under the
services
key, you define one or more services with their configurations, including the Docker image, environment variables, ports, volumes, networks, and other settings.
- The
- Volumes:
- The
volumes
key defines named volumes that can be used to persist data generated by containers. Volumes provide a way to store and share data between containers or between a container and the host machine. - In the
docker-compose.yml
file, volumes are defined using thevolumes
key followed by a list of named volumes. Each named volume corresponds to a directory or location on the host machine where data can be stored.
- The
- Networks:
- The
networks
key defines named networks that can be used to connect containers and facilitate communication between them. - Networks provide a way to isolate container communication and control network traffic between containers.
- Similar to volumes, networks are defined using the
networks
key followed by a list of named networks.
- The
Now, let’s examine the specific configurations within the services
section of the docker-compose.yml
file:
- laravel Service:
build
: Specifies the build context and Dockerfile for building the Docker image for the Laravel service.ports
: Maps container ports to host ports, allowing external access to the service. In this example, port 80 of the Laravel container is mapped to port 8000 on the host machine.volumes
: Mounts volumes to the container.- A volume was named
laravel_html
and mounted it to/var/www/html
in the Laravel service. This ensures that the contents of thehtml
directory in the Laravel container are persisted even after the container is stopped or removed. - Another volume was named
laravel_storage
and mounted it to/var/www/html/storage
. This volume mount is typically used to persist Laravel application storage files, such as logs, cache, and session data.
- A volume was named
networks
: Specifies the network(s) the container should connect to. In this example, the Laravel container is connected to thelaravel_network
network.
- mysql Service:
image
: Specifies the Docker image to use for the MySQL service. In this example, the latest version of the MySQL image is pulled from the Docker Hub.environment
: Sets environment variables for configuring the MySQL container, such as the root password, database name, and user credentials.ports
: Maps container ports to host ports, allowing external access to the service. In this example, port 3306 of the MySQL container is mapped to port 3306 on the host machine.volumes
: Mounts volumes to the container. In this example, themysql_data
volume is mounted to/var/lib/mysql
in the MySQL container to persist the database files.networks
: Specifies the network(s) the container should connect to. In this example, the MySQL container is also connected to thelaravel_network
network.
Overall, the docker-compose.yml
file defines the configuration for running a multi-container application consisting of Laravel and MySQL services. It specifies how the containers are built, configured, connected to networks, and how data is persisted using volumes.
Here’s how you can do it:
docker-compose.yml
version: '3.8'
services:
laravel:
build:
context: .
dockerfile: Dockerfile.laravel
ports:
- "8000:80"
volumes:
- laravel_html:/var/www/html
- laravel_storage:/var/www/html/storage
networks:
- laravel_network
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: laravel_db
MYSQL_USER: laravel_user
MYSQL_PASSWORD: laravel_password
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- laravel_network
volumes:
laravel_html:
laravel_storage:
mysql_data:
networks:
laravel_network:
In this docker-compose.yml
file:
- We define two services:
laravel
andmysql
. - For the
laravel
service:- We use the
build
key to specify the context and Dockerfile (Dockerfile.laravel
) for building the image. - Port mapping is defined to expose port 8000 on the host to port 80 in the container.
- Two volumes are mounted to persist Laravel storage.
laravel_storage:/var/www/html/storage
andlaravel_html:/var/www/html
- The service is connected to the
laravel_network
network.
- We use the
- For the
mysql
service:- We use the
image
key to specify the MySQL image. - Environment variables are provided for MySQL configuration.
- Port mapping is defined to expose port 3306 on the host to port 3306 in the container.
- A volume is mounted to persist MySQL data.
- The service is also connected to the
laravel_network
network.
- We use the
- Two volumes are defined:
laravel_storage
for Laravel storage andmysql_data
for MySQL data. - A network named
laravel_network
is defined to connect the services.
A NOTE about mounting a second Laravel Volume:
Thelaravel_storage:/var/www/html/storage
volume mount is typically used to persist Laravel application storage files, such as logs, cache, and session data. If your Laravel application doesn't generate or use any storage files, you might not need this volume.
However, it's a common practice to include this volume mount to ensure that any storage-related data generated by the Laravel application is persisted across container restarts or recreations. It helps maintain data consistency and ensures that your application behaves as expected, especially in production environments.
If you're certain that your Laravel application doesn't generate or use any storage files, you can omit this volume mount. Otherwise, it's recommended to include it to ensure proper functionality and data persistence for your Laravel application.
Dockerfile.laravel
# Use the official PHP image with Apache
FROM php:latest
# Update package lists and install dependencies
RUN apt-get update && \
apt-get install -y libpng-dev libjpeg-dev libfreetype6-dev zip unzip && \
docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install gd pdo_mysql && \
a2enmod rewrite
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Set working directory
WORKDIR /var/www/html
# Install the latest version of Laravel
RUN composer create-project --prefer-dist laravel/laravel .
# Set permissions
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
# Generate autoload files and cache
RUN composer dump-autoload && \
php artisan cache:clear && \
php artisan config:cache && \
php artisan route:cache
# Expose port 80 to the outside world
EXPOSE 80
# Define a volume for Laravel storage
VOLUME /var/www/html/storage
Make sure to replace Dockerfile.laravel
with the actual name of your Laravel Dockerfile.
Once you have the docker-compose.yml
file ready, you can use the docker-compose up
command to build and run the services defined in the file.