Set-up Docker Compose for Laravel

This tutorial will help you get started with Laravel on Docker. It’s a better development environment then Vagrant, because you can scale up into production with the same pre-requisites used in the development environment.

Let’s start by creating our project folder.

mkdir myproject && cd myproject

Now create the following directory structure in /myproject using anyway you want.

  • /images
    • /php
      • Dockerfile
  • /mysql
  • /nginx
    • default.conf
  • /src
    • index.html
  • docker-compose.yaml

The docker-compose.yaml file must contain the following content and be in the root of /myproject.

version: '3'

networks:
  laravel:

services:
  nginx:
    image: nginx:stable
    #below name can be anything
    container_name: nginx-server
    ports: 
      - "8088:80"
    volumes: 
      - ./src:/var/www/html/public
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on: 
      - php
      - mysql
    networks:
      - laravel

  mysql:
    image: mysql:5.7.22
    container_name: mysql-server
    restart: unless-stopped
    #allow shell access...
    tty: true
    #match a seperate port for mysql incase xampp is using it
    ports: 
      - 4306:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment: 
      MYSQL_DATABASE: homestead
      MYSQL_USER: homestead
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    networks:
      - laravel

  php:
    #replace the image heading with build, to build a custom php image from dockerfile
    build: 
      context: ./images/php/
      dockerfile: Dockerfile
    container_name: php-server
    volumes: 
      - ./src:/var/www/html
    ports:
      - "9000:9000"
    networks:
      - laravel

And /images/php/Dockerfile will need the following content, the reason behind this file, is PHP needs to be build in docker-compose with extra stuff that Laravel requires. (which are docker-php-ext-install pdo pdo_mysql).

FROM php:7.2-fpm

RUN docker-php-ext-install pdo pdo_mysql

The following nginx config file will need the following content, to make sure it serves the correct files in our volume.

server {
	listen 80;
	index index.php index.html;
	server_name localhost;
	error_log /var/log/nginx/error.log;
	access_log /var/log/nginx/access.log;
	root /var/www/html/public;

	location /{
		try_files $uri $uri/ /index.php?$query_string;
	}

	location ~ \.php$ {
		try_files $uri =404;
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		fastcgi_pass php:9000;
		fastcgi_index index.php;
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_param PATH_INFO $fastcgi_path_info;
	}
}

Then run the following after making sure all the above is correct. It builds the dockerfile before telling docker to initiate the stack.

docker-compose up --build

When setting up the .env file for Laravel make sure to give the DB_HOST the same value as the name of the MySQL container defined in the docker-compose.yaml file. Therefore in your .env file makes sure to have DB_HOST=mysql if you named your database container mysql, and do not enter localhost or 127.0.0.1 as its not the same container as php.

To migrate tables, you must migrate inside the PHP container with the following.

docker-compose exec php php artisan migrate