In this post, i will explain docker images, containers, why you should use them, and how to use them in a laravel application.
What is docker?
Docker is a container based technology that helps in software delivery and infrastructure management in form of packages called containers.
What is an image
A docker image consists of layers of instructions on how to create a container.
You can think of a docker image as the source code and container as the source code in execution or in a running state.
What is a container
A Container is a running instance of an image. So a running docker image is called a container.
Why use docker in a laravel application
Docker streamlines the setup process of running a LEMP stack application like Laravel, mysql, php, nginx.
It makes it easier for new team members to run application without worrying about infrastructural set up and configuration.
It also makes your application deployment ready.
Containerizing laravel/php application
Traditionally when you clone or download a php or laravel application, you need to configure your web server, database server and any other service needed to run the app. But with docker-compose, you can run your app with just a single command and all those services would be readily available with no configuration required.
Here is an example of a project i created that uses a shell script to run a laravel application in a docker container.
The shell script checks for docker and docker-compose installations and installs them if not found.
Next, It creates and runs nginx, mysql and php image using docker-compose.
- Clone the project from github
git clone https://github.com/Naterus/docker-compose-laravel.git
verify you have all files and folders matching with the repository.
navigate to the root directory of the cloned project in your terminal and type
sudo ./launch.sh
Look out for prompts and select Y to all.
You should see nginx-service,mysql-service and php-service all started.
open localhost:8088 in your browser, you should see https://restfulcountries.com app running.
Project Structure
Here is a short description of the files and directories of the project.
launch.sh file
This file builds nginx,mysql,php as docker images using docker-compose build
command and then run them as containers using docker-compose up -d
. Then lastly runs laravel database migration.
#!/bin/bash
#Check for docker installation
if [ -x "$(command -v docker)" ]; then
echo "docker already installed, skipping"
else
echo "Installing docker"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
echo "docker installed successfully"
fi
#Check for docker-compose installation
if [ -x "$(command -v docker-compose)" ]; then
echo "docker-compose already installed, skipping"
else
apt install docker-compose
echo "docker-compose installed successfully"
fi
cd public_html
#change storage permission to enable nginx read and write files
chmod -R 755 storage
cd ../
docker-compose build && docker-compose up -d
docker-compose exec php php /var/www/html/artisan migrate
docker-compose.yml file
This file builds all services and mounts them as docker images.
version: '3'
networks:
appnetwork:
services:
nginx:
image: nginx:stable-alpine
container_name: nginx-service
ports:
- "8088:80"
volumes:
- ./public_html:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/log/error.log:/var/log/nginx/error.log
- ./nginx/log/access.log:/var/log/nginx/access.log
depends_on:
- php
- mysql
networks:
- appnetwork
mysql:
image: mysql:5.7.32
container_name: mysql-service
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/my.cnf
environment:
MYSQL_DATABASE: webapp
MYSQL_USER: root
MYSQL_PASSWORD: password1
MYSQL_ROOT_PASSWORD: password1
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- appnetwork
php:
build:
context: .
dockerfile: Dockerfile
container_name: php-service
volumes:
- ./public_html:/var/www/html
ports:
- "9000:9000"
networks:
- appnetwork
volumes are symbolic links to be used by nginx to write and read files from project directory.
Dockerfile
The Dockerfile retrieves php alpine image from dockerhub and installs pdo mysql when the docker-compose up -d
command executes in launch.sh
FROM php:7.4-fpm-alpine
RUN docker-php-ext-install pdo_mysql
public_html Directory
The laravel application is found in public_html directory which is a symlink to var/www/html on nginx server.
If you want to run your own laravel or custom php application, you can replace the content of public_html with your application files.
Note that custom php applications must be placed in public_html/public directory, because the document root for nginx is the public folder.
nginx directory
This directory is a symlink used by nginx to read configuration (default.conf
) and writes access and error logs (access.log
, error.log
).
mysql directory
This directory is also a symlink used by mysql to read configurations (my.cnf).
Your custom application mysql credentials should match the ones in mysql-service container as seen in docker-compose.yml. here is an example of my laravel .env database credential
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=webapp
DB_USERNAME=root
DB_PASSWORD=password1
Conclusion
The use of containers in development is one of the techniques adopted by DevOps engineers to improve productivity. It makes the workflow seamless, But not compulsory to adopt.
For more information on this project, check out the github repository docker-compose-laravel
Top comments (0)