DEV Community

loading...
Cover image for How to install and set up Laravel's local development environment with Docker Compose

How to install and set up Laravel's local development environment with Docker Compose

ucan_lab profile image ucan_lab Updated on ・5 min read

Introduction

This article explains how to build a LEMP environment for PHP, nginx, and MySQL with Docker and Docker Compose.

Prerequisites

  • Docker
  • Git
$ docker -v
Docker version 20.10.5, build 55c4c88

$ git --version
git version 2.31.1
Enter fullscreen mode Exit fullscreen mode

How to enable Docker Content Trust (DCT)

DCT is a security feature that protects your Docker image from spoofing and tampering.
It works automatically when the push, build, create, pull, or run command is executed.

$ echo export DOCKER_CONTENT_TRUST=1 >> ~/.zshrc
Enter fullscreen mode Exit fullscreen mode

Repository

Container Structures

It has a three-tier structure consisting of an application server, a web server, and a database server.

├── app - service running php-fpm
├── web - service running nginx
└── db - service running mysql
Enter fullscreen mode Exit fullscreen mode

How to use a new project

Step1. Create a new repository from template

Click Use this template.

Create a repository for my-project.

If you use the template repository, all commits will be combined into one.

Step2. Clone your GitHub repository

$ git clone git@github.com:ucan-lab/my-project.git
$ cd my-project
Enter fullscreen mode Exit fullscreen mode

Step3. Create a Laravel Project

$ make create-project
Enter fullscreen mode Exit fullscreen mode

Step4. Show the Laravel Welcome page

http://localhost

Step5. First commit and push

$ git add .
$ git commit -m "laravel install"
$ git push -u origin HEAD
Enter fullscreen mode Exit fullscreen mode

How to use an existing project

(Optional) Delete the local repository

$ docker-compose down -v --rmi all
$ cd ..
$ rm -rf my-project
Enter fullscreen mode Exit fullscreen mode

Step1. Clone your GitHub repository

$ git clone git@github.com:ucan-lab/my-project.git
$ cd my-project
Enter fullscreen mode Exit fullscreen mode

Step2. Initialize your local environment

$ make init
Enter fullscreen mode Exit fullscreen mode

Step3. Show Laravel Welcome page

http://localhost

If you want to specify the version of Laravel

Rewrite Makefile and execute.

laravel-install:
    docker-compose exec app composer create-project --prefer-dist "laravel/laravel=6.*" .
Enter fullscreen mode Exit fullscreen mode

Remarks

docker-compose.yml

version: "3.9"
volumes:
  php-fpm-socket:
  db-store:
services:
  app:
    build:
      context: .
      dockerfile: ./infra/docker/php/Dockerfile
    volumes:
      - type: volume
        source: php-fpm-socket
        target: /var/run/php-fpm
        volume:
          nocopy: true
      - type: bind
        source: ./backend
        target: /work/backend
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_NAME:-laravel_local}
      - DB_USERNAME=${DB_USER:-phper}
      - DB_PASSWORD=${DB_PASS:-secret}

  web:
    build:
      context: .
      dockerfile: ./infra/docker/nginx/Dockerfile
    ports:
      - target: 80
        published: ${WEB_PORT:-80}
        protocol: tcp
        mode: host
    volumes:
      - type: volume
        source: php-fpm-socket
        target: /var/run/php-fpm
        volume:
          nocopy: true
      - type: bind
        source: ./backend
        target: /work/backend

  db:
    build:
      context: .
      dockerfile: ./infra/docker/mysql/Dockerfile
    ports:
      - target: 3306
        published: ${DB_PORT:-3306}
        protocol: tcp
        mode: host
    volumes:
      - type: volume
        source: db-store
        target: /var/lib/mysql
        volume:
          nocopy: true
    environment:
      - MYSQL_DATABASE=${DB_NAME:-laravel_local}
      - MYSQL_USER=${DB_USER:-phper}
      - MYSQL_PASSWORD=${DB_PASS:-secret}
      - MYSQL_ROOT_PASSWORD=${DB_PASS:-secret}
Enter fullscreen mode Exit fullscreen mode

version

Docker Compose file version

Note: When specifying the Compose file version to use, make sure to specify both the major and minor numbers. If no minor version is given, 0 is used by default and not the latest minor version. As a result, features added in later versions will not be supported. For example:

version: "3"
Enter fullscreen mode Exit fullscreen mode

version: "3"

version: "3.0"
Enter fullscreen mode Exit fullscreen mode

volumes

Define named volumes with the top-level volumes key to reuse volumes across multiple services.

services.*.build

services.*.ports

services.*.volumes

services.*.environment

app service

./infra/docker/php/Dockerfile

FROM php:8.0-fpm-buster
LABEL maintainer="ucan-lab <yes@u-can.pro>"
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

# timezone environment
ENV TZ=UTC \
  # locale
  LANG=en_US.UTF-8 \
  LANGUAGE=en_US:en \
  LC_ALL=en_US.UTF-8 \
  # composer environment
  COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
  apt-get -y install git libicu-dev libonig-dev libzip-dev unzip locales && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  locale-gen en_US.UTF-8 && \
  localedef -f UTF-8 -i en_US en_US.UTF-8 && \
  mkdir /var/run/php-fpm && \
  docker-php-ext-install intl pdo_mysql zip bcmath && \
  composer config -g process-timeout 3600 && \
  composer config -g repos.packagist composer https://packagist.org

COPY ./infra/docker/php/php-fpm.d/zzz-www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
COPY ./infra/docker/php/php.ini /usr/local/etc/php/php.ini

WORKDIR /work/backend
Enter fullscreen mode Exit fullscreen mode

./infra/docker/php/php.ini

zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8

[Date]
date.timezone = ${TZ}

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Neutral
Enter fullscreen mode Exit fullscreen mode

./infra/docker/php/php-fpm.d/zzz-www.conf

[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
access.log = /dev/stdout
Enter fullscreen mode Exit fullscreen mode

web service

./infra/docker/nginx/Dockerfile

FROM node:16-alpine as node
FROM nginx:1.20-alpine
LABEL maintainer="ucan-lab <yes@u-can.pro>"
SHELL ["/bin/ash", "-oeux", "pipefail", "-c"]

ENV TZ=UTC

RUN apk update && \
  apk add --update --no-cache --virtual=.build-dependencies g++

# node command
COPY --from=node /usr/local/bin /usr/local/bin
# npm command
COPY --from=node /usr/local/lib /usr/local/lib
# yarn command
COPY --from=node /opt /opt
# nginx config file
COPY ./infra/docker/nginx/*.conf /etc/nginx/conf.d/

WORKDIR /work/backend
Enter fullscreen mode Exit fullscreen mode

./infra/docker/nginx/default.conf

access_log /dev/stdout main;
error_log /dev/stderr warn;

server {
    listen 80;
    root /work/backend/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

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

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
Enter fullscreen mode Exit fullscreen mode

db service

./infra/docker/mysql/Dockerfile

FROM mysql/mysql-server:8.0
LABEL maintainer="ucan-lab <yes@u-can.pro>"

ENV TZ=UTC

COPY ./infra/docker/mysql/my.cnf /etc/my.cnf
Enter fullscreen mode Exit fullscreen mode

./infra/docker/mysql/my.cnf

[mysqld]
# default
skip-host-cache
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
secure-file-priv = /var/lib/mysql-files
user = mysql

pid-file = /var/run/mysqld/mysqld.pid

# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4
Enter fullscreen mode Exit fullscreen mode

Discussion (0)

Forem Open with the Forem app