Опубликовано:

Laravel сайт в Docker на базе PHP-FPM + Nginx + MySQL

Привет!

Чтобы запустить локальный Laravel сайт в Docker на базе PHP-FPM + Nginx совсем не обязательно досконально изучать или знать эти технологии. Сейчас покажу все необходимые куски кода, которые помогут тебе запустить Laravel сайт на домене для локальной разработки.

Существуют множество других способов запустить Laravel в Docker, например Laravel Sail. Однако я предпочитаю все держать под контролем, поэтому развернул собственную систему Docker-контейнеров, которыми полностью могу управлять. Система достаточно проста и примитивна. Сейчас покажу как у меня все устроено

Внимание! Статья рассчитана на пользователей Ubuntu (Linux). Если ты работаешь на Windows, то рекомендую установить WSL и затем воспользоваться этой инструкцией. Ссылка — WSL для WEB-разработчика

Laravel сайт на локальном домене

Первое, что мне кажется нужным и удобным — это использовать “человекопонятный” локальный домен для разработки. Не какой ни будь http://localhost:8080, а http://my-top-client-project.docker. Это придает удобства в процессе работы. При необходимости можно запустить несколько сайтов на индивидуальных доменах для решения различных задач — смотри мою статью “Несколько доменов (хостов) в Docker на одном сервере и IP-адресе”.

И так, первое что необходимо — это добавить Reverse Proxy Container в нашу систем. На моей локальной машине существует следующая схема расположения файлов и папок.

В домашней папке существует директория server. То есть путь выглядит следующим образом:

/home/UserName/server

В этой директории я храню все содержимое, что касается моих локальных сайтов. Для каждого сайта внутри директории server у меня имеются соответствующие директории.

/home/UserName/server/my-top-client-project.docker
/home/UserName/server/subdomen.siteForImportantClient.docker
/home/UserName/server/subdomen.myPetProject.local

Полагаю тут нечего дополнительно объяснять.

Запускаем Reverse Proxy для обслуживания уникальных локальных доменов

Также внутри директории Server у меня хранится еще одна папочка, которая называется proxy, внутри этой папки хранится только один документ:

~/server/proxy/docker-compose.ymlCode language: JavaScript (javascript)

Содержимое файла docker-compose.yml следующее:

version: '3.0'

services:

  proxy:
    image: jwilder/nginx-proxy  # используем внешний image
    container_name: proxy_proxy # задаем конкретное имя контейнеру - будет использоваться в дальнейшем
    restart: always             # всегда перезапускаем контейнер
    privileged: true
    ports:
      - 80:80                   # прокидываем порт 80 для обработки http запросов
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      - proxy                   # указываем, с какой внутренней сетью будет работать контейнер


networks:                       # конфигурируем сеть
  proxy:                        # указываем имя сети
    driver: bridge              # указываем драйверCode language: PHP (php)

Теперь переходим в папку прокси и запускаем Docker контейнер:

cd ~/server/proxy/
docker-compose up -dCode language: JavaScript (javascript)

Устанавливаем и запускаем Laravel в Docker

После того, как запустили Nginx в режиме Reverse Proxy, Выполняем следующее. Создаем папку проекта в папке сервера:

mkdir  ~/server/my-top-client-project.docker
mkdir  ~/server/my-top-client-project.docker/dockerCode language: JavaScript (javascript)

Чтобы запустить laravel на локальном домене, необходимо добавить домен в файл «/etc/hosts». Для пользователей WSL необходимо добавить в файл «C:\Windows\System32\drivers\etc\hosts» от имени администратора

127.0.0.1	my-top-client-project.docker
127.0.0.1	phpmyadmin.my-top-client-project.dockerCode language: CSS (css)

Laravel в Docker Compose

Чтобы объединить PHP + Nginx + MySQL в единую систему и запускать их одной командой, будем использовать Docker Compose. Файл ~/server/my-top-client-project.docker/docker/docker-compose.yml будет иметь следующее содержание:

  version: '3.0'
  
  services:
  
    mtcp_nginx:
      image: nginx
      container_name: mtcp_docker_nginx
      environment:
        - VIRTUAL_HOST=my-top-client-project.docker
      volumes:
        - ./nginx/logs:/var/log/nginx/  # пробрасываем папку для логов
        - ./nginx/conf.d/default.nginx:/etc/nginx/conf.d/default.conf # пробрасываем конфиг nginx
        - ./../laravel/:/var/www/ # пробрасываем содержимое проекта в контейнер
      networks:
        - frontend    # добавляем сеть для проксирования запросов
        - backend     # добавляем внутреннюю сеть для объединения контейнеров
  
    mtcp_php:
      container_name: "mtcp_docker_php"
      build:
        args:
          user: wwwdata
          uid: 1000
        context: ./php
      volumes:
        - ./php/local.ini:/usr/local/etc/php/php.ini
        - ./../laravel/:/var/www/
      networks:
        - frontend  # добавляем сеть для проксирования запросов
        - backend   # добавляем внутреннюю сеть для объединения контейнеров
  
    mtcp_mysql:
      image: mysql:5.7
      container_name: mtcp_docker_mysql
      environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_USER: mtcp
        MYSQL_PASSWORD: mtcp
        MYSQL_DATABASE: mtcp
      volumes:
        - ./mysql/data:/var/lib/mysql # подключаем папку для хранения данных MySQL
      networks:
        - backend   # добавляем внутреннюю сеть для объединения контейнеров
  
    mtcp_phpmyadmin:
      image: phpmyadmin/phpmyadmin:latest
      container_name: mtcp_docker_phpmyadmin
      environment:
        - VIRTUAL_HOST=phpmyadmin.my-top-client-project.docker # указываем хост, на котором будет PhpMyAdmin
        - PMA_HOST=mtcp_mysql
        - PMA_USER=root
        - PMA_PASSWORD=root
      networks:
        - frontend  # добавляем сеть для проксирования запросов
        - backend   # добавляем внутреннюю сеть для объединения контейнеров
  
  networks:
    frontend:     # конфигурируем сеть, которую создали ранее в reverse-proxy контейнере
      external:
        name: proxy_proxy # указываем имя сети, которое соответствует контейнеру в reverse-proxy
    backend:    # создаем внутреннюю сеть для объединения контейнеров
  Code language: PHP (php)

Подготавливаем контейнер с PHP в Docker

Файл ~/server/my-top-client-project.docker/docker/php/Dockerfile будет иметь следующее содержание:

FROM php:7.4-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    redis-server

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install pecl PHP xdebug
#RUN pecl install xdebug

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath

# по необходимости устанавливаем Redis
#RUN pecl install redis && docker-php-ext-enable redis

RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
        && docker-php-ext-install -j$(nproc) gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
    chown -R $user:$user /home/$user

# Set working directory
WORKDIR /var/www

USER $userCode language: PHP (php)

Файл local.ini позволит конфигурировать PHP в Docker. Файл ~/server/my-top-client-project.docker/docker/php/local.ini будет иметь следующее содержание:

upload_max_filesize=200M
post_max_size=200M

Подготавливаем контейнер с Nginx в Docker

Файл ~/server/my-top-client-project.docker/docker/nginx/conf.d/default.nginx будет иметь следующее содержание. Этот файл позволит конфигурировать Nginx для обработки запросов к сайту.

server {
    listen 80;    # слушаем порт 80 для обработки http запросов
    listen [::]:80;
    server_name my-top-client-project.docker;

    root /var/www/public; # указываем директорию в контейнере с файлом index.php

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass mtcp_php:9000; # указываем имя контейнера с PHP и порт
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ /\.ht {
        deny  all;
    }

    access_log  /var/log/nginx/host.access.log  main;
    error_log   /var/log/nginx/host.error.log;
}
Code language: PHP (php)

Запускаем все контейнеры

cd ~/server/my-top-client-project.docker/docker
docker-compose up -dCode language: JavaScript (javascript)

При этом должна произойти загрузка необходимых образов из docker.hub и затем запуск docker контейнеров.

Если возникли ошибки — напиши в комментариях, попробуем разобраться. Если все прошло успешно, то необходимо добавить файлы Laravel в папку с проектом. Для этого выполним в терминале команду ниже, чтобы попасть в контейнер с php:

docker exec -it mtcp_docker_php bash

Будучи в контейнере запустим команду, которая позаимствована из документации:

cd /var/www/
composer create-project laravel/laravel:^8.0 Code language: JavaScript (javascript)

При запуске команды выше произойдет загрузка файлов Laravel в локальную папку.

После этого, если не было допущено ошибок, то по адресу http://my-top-client-project.docker должна открыться страничка с логотипом Laravel. Это означает, что нам удалось запустить Laravel в Docker с помощью Docker Compose.

P.S. Таким образом файлы фреймворка будут располагаться в папке Laravel. Если же необходимо, чтобы файлы располагались непосредственно в корне проекта, то можно просто перенести их в корень и немного поправить docker-compose.yml и просто убрать папку laravel из пути       — ./../laravel/:/var/www/

Опубликовано:
Присоединяйся!

Подписывайся на блог и развивайся вместе со мной.

Внимание! Чтобы получать письма, необходимо подтвердить подписку. Для этого перейдите по ссылке в письме, которое я вам отправил на указанный Email.

Ваши комментарии