Среда WEB разработки на базе Docker. Часть 1

Примечение: В этой статье мы пошагово создадим рабочее окружение, для Web разработки, с помощью Docker. Статья будет дополняться, весь проект будет размещен на GitHub и обновляться. Все вопросы можно будет оставить, через сервис GitHub https://github.com/LukaS0lncev/workspace

Установка Docker на Windows

Примечание: Подробно рассматривать установку Docker и Docker compose на Windows мы не будем, просто укажем ссылки на нужный софт.

Нам необходим будет:


Быстрый старт

Примечание: Если вам нужен быстрый старт, скачал, запустил и работаешь, то ниже команды для быстрого запуска проекта:

git clone https://github.com/LukaS0lncev/workspace.git
cd workspace
docker-compose up -d

Создание структуры

После установки нужного софта, создайте каталог, где будет храниться ваше окружение и ваши рабочие проекты, в нем мы будем создавать наше рабочее окружение.

Создайте структуру каталогов, как показано ниже или сделайте просто копию проекта с гитхаба https://github.com/LukaS0lncev/workspace

Финальная структура нашего проекта

.
├── php
│   ├── 5.6
│   │   ├── ini
│   │   ├── workers
│   │   └── workspace
│   │       └── Dockerfile
│   ├── 7.1
│   │   ├── ini
│   │   ├── workers
│   │   └── workspace
│   │       └── Dockerfile
│   ├── 7.2
│   │   ├── ini
│   │   ├── workers
│   │   └── workspace
│   │       └── Dockerfile
│   └── 7.3
│       ├── ini
│       ├── workers
│       └── workspace
│           └── Dockerfile
├── nginx
│   ├── conf.d
│   │   ├── default.conf
│   │   └── vhost.conf
│   └── logs
├── mysql
│   ├── 5.7
│   │   ├── conf.d
│   │   ├── data
│   │   ├── dump
│   │   └── logs
│   └── 8
│       ├── conf.d
│       ├── data
│       ├── dump
│       └── logs
├── www
│   ├── site-1.local
│   │   ├── adminer.php
│   │   └── info.php
│   ├── site-2.local
│   │   ├── adminer.php
│   │   └── info.php
│   ├── site-3.local
│   │   ├── adminer.php
│   │   └── info.php
│   └── site-4.local
│       ├── adminer.php
│       └── info.php
├── .env
└── docker-compose.yml

Структура .env

Примечание: В файле .env хранятся ваши настройки, логины, пароли, номера портов локальной машины, временная зона и др.

Создайте файл .env в корне вашего проекта и скопируйте туда, настройки ниже. Можете поменять номера портов, timezone или доступы к БД на свои до сборки проекта, но для проверки работоспособности, рекомендую не менять настройки на свои. Или скопируйте его https://github.com/LukaS0lncev/workspace/blob/main/.env

# Временная зона
WORKSPACE_TIMEZONE=Europe/Moscow

# XDEBUG
DOCKER_PHP_ENABLE_XDEBUG='on'

# Настройки Nginx
# Порт, который следует использовать
# для соединения с локального компьютера
NGINX_PORT=80

# Настройки общие для MySQL 8.x и MySQL 5.7.x
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=test

# Настройки MySQL 8.x
# Порт, который следует использовать
# для соединения с локального компьютера
MYSQL_8_PORT=4308

# Настройки MySQL 5.7.x
# Порт, который следует использовать
# для соединения с локального компьютера
MYSQL_5_7_PORT=4307

# Настройки PHP 5.6
# Внешний порт, доступен с локального компьютера
PHP_5_6_PORT=9056

# Настройки PHP 7.1
# Внешний порт, доступен с локального компьютера
PHP_7_1_PORT=9071

# Настройки PHP 7.2
# Внешний порт, доступен с локального компьютера
PHP_7_2_PORT=9072

# Настройки PHP 7.3
# Внешний порт, доступен с локального компьютера
PHP_7_3_PORT=9073

Структура docker-compose.yml

Примечание: Это основной файл для сборки Рабочей среды. К каждой команде мы комментарий добавили, чтобы было понятно, что и куда

Создайте файл docker-compose.yml в корне вашего проекта и скопируйте туда, настройки ниже. Или скопируйте его https://github.com/LukaS0lncev/workspace/blob/main/docker-compose.yml

version: '3' #версия синтатксиса docker-compose

networks: #создаем сеть
  backend:

services: #создаем сервисы
  nginx: #наш основной Web сервер (Nginx)
    image: nginx:stable-alpine #название контейнера с hub.docker.com и его версия
    container_name: nginx-workspace #задаем имя контейнера
    ports: #указываем порты локальная_машина:контейнер
      - "${NGINX_PORT}:80" #берем значение порта локальной машины из .env и указываем порт контейнера (80)
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./www:/var/www 
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/logs:/var/log/nginx/
    depends_on: #определяем порядок запуска койнера, nginx будет последним запущен, после остальных в списке
      - php-7.1
      - php-7.3
      - mysql-8
      - mysql-5.7
    environment: #устанавливаем переменные среды
      TZ: ${WORKSPACE_TIMEZONE} #значение timezome берем из .env
    networks: #опеределяем сеть для контейнера
      - backend

  mysql-5.7: #наша база данных (mysql версия 5.7)
    image: mysql:5.7 #название контейнера с hub.docker.com и его версия
    container_name: mysql-5.7-workspace #задаем имя контейнера
    restart: unless-stopped
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./mysql/5.7/data:/var/lib/mysql
      - ./mysql/5.7/conf.d:/etc/mysql/conf.d
      - ./mysql/5.7/logs:/var/log/mysql/
      - ./mysql/5.7/dump:/dump
    ports: #указываем порты локальная_машина:контейнер
      - "${MYSQL_5_7_PORT}:3306" #берем значение порта локальной машины из .env и указываем порт контейнера (3306)
    security_opt:
      - seccomp:unconfined
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: ${WORKSPACE_TIMEZONE}
    networks: #опеределяем сеть для контейнера
      - backend

  mysql-8: #наша база данных (mysql версия 8)
    image: mysql:8.0.21
    command: --default-authentication-plugin=mysql_native_password --skip_name_resolve
    container_name: mysql-8-workspace #задаем имя контейнера
    restart: unless-stopped
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./mysql/8/data:/var/lib/mysql
      - ./mysql/8/conf.d:/etc/mysql/conf.d
      - ./mysql/8/logs:/var/log/mysql/
      - ./mysql/8/dump:/dump
    ports: #указываем порты локальная_машина:контейнер
      - "${MYSQL_8_PORT}:3306" #берем значение порта локальной машины из .env и указываем порт контейнера (3306)
    security_opt:
      - seccomp:unconfined
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: ${WORKSPACE_TIMEZONE}
    networks: #опеределяем сеть для контейнера
      - backend

  php-5.6:
    build:
      context: php/5.6/workspace #каталог где будет находиться Dockerfile
      dockerfile: Dockerfile #имя Dockerfile, в нашем случае это "Dockerfile"
      args: #передаем аргуенты в Dockerfile
        DOCKER_PHP_VERSION: '5.6'
        DOCKER_PHP_ENABLE_XDEBUG: ${DOCKER_PHP_ENABLE_XDEBUG}
        TZ: ${WORKSPACE_TIMEZONE}
    working_dir: /var/www
    container_name: php-5.6-workspace #задаем имя контейнера
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./.ssh:/home/www-data/.ssh
      - ./www:/var/www
      - ./php/5.6/ini/php.ini:/usr/local/etc/php/php.ini
      - ./php/5.6/workers/supervisor.d:/etc/supervisor.d
    ports: #указываем порты локальная_машина:контейнер
      - "${PHP_5_6_PORT}:9000" #берем значение порта локальной машины из .env и указываем порт контейнера (9000)
    networks: #опеределяем сеть для контейнера
      - backend

  php-7.1:
    build:
      context: php/7.1/workspace #каталог где будет находиться Dockerfile
      dockerfile: Dockerfile #имя Dockerfile, в нашем случае это "Dockerfile"
      args: #передаем аргуенты в Dockerfile
        DOCKER_PHP_VERSION: '7.1'
        DOCKER_PHP_ENABLE_XDEBUG: ${DOCKER_PHP_ENABLE_XDEBUG}
        TZ: ${WORKSPACE_TIMEZONE}
    working_dir: /var/www
    container_name: php-7.1-workspace #задаем имя контейнера
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./.ssh:/home/www-data/.ssh
      - ./www:/var/www
      - ./php/7.1/ini/php.ini:/usr/local/etc/php/php.ini
      - ./php/7.1/workers/supervisor.d:/etc/supervisor.d
    ports: #указываем порты локальная_машина:контейнер
      - "${PHP_7_1_PORT}:9000" #берем значение порта локальной машины из .env и указываем порт контейнера (9000)
    networks: #опеределяем сеть для контейнера
      - backend

  php-7.2:
    build:
      context: php/7.2/workspace #каталог где будет находиться Dockerfile
      dockerfile: Dockerfile #имя Dockerfile, в нашем случае это "Dockerfile"
      args: #передаем аргуенты в Dockerfile
        DOCKER_PHP_VERSION: '7.2'
        DOCKER_PHP_ENABLE_XDEBUG: ${DOCKER_PHP_ENABLE_XDEBUG}
        TZ: ${WORKSPACE_TIMEZONE}
    working_dir: /var/www
    container_name: php-7.2-workspace #задаем имя контейнера
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./.ssh:/home/www-data/.ssh
      - ./www:/var/www
      - ./php/7.2/ini/php.ini:/usr/local/etc/php/php.ini
      - ./php/7.2/workers/supervisor.d:/etc/supervisor.d
    ports: #указываем порты локальная_машина:контейнер
      - "${PHP_7_2_PORT}:9000" #берем значение порта локальной машины из .env и указываем порт контейнера (9000)
    networks: #опеределяем сеть для контейнера
      - backend

  php-7.3:
    build:
      context: php/7.3/workspace #каталог где будет находиться Dockerfile
      dockerfile: Dockerfile #имя Dockerfile, в нашем случае это "Dockerfile"
      args: #передаем аргуенты в Dockerfile
        DOCKER_PHP_VERSION: '7.3'
        DOCKER_PHP_ENABLE_XDEBUG: ${DOCKER_PHP_ENABLE_XDEBUG}
        TZ: ${WORKSPACE_TIMEZONE}
    working_dir: /var/www
    container_name: php-7.3-workspace #задаем имя контейнера
    volumes: #указываем связь по каталогам  локальный_пк:контейнер
      - ./.ssh:/home/www-data/.ssh
      - ./www:/var/www
      - ./php/7.3/ini/php.ini:/usr/local/etc/php/php.ini
      - ./php/7.3/workers/supervisor.d:/etc/supervisor.d
    ports: #указываем порты локальная_машина:контейнер
      - "${PHP_7_3_PORT}:9000" #берем значение порта локальной машины из .env и указываем порт контейнера (9000)
    networks: #опеределяем сеть для контейнера
      - backend

Структура DockerFile для php

Примечание: DockerFile для всех версих php похожи, мы могли их объеденить в один и сделать более универсальным. Но мы решили их разделить, чтобы вы могли самостоятельно контролировать процесс сборки и версии расширений. т.к. некоторые расширения, как mongo, xdebug и redis для версии 5.6 отличаются от версии 7.1, 7.2, 7.3. У вас получится более универсальная рабочая среда.

Создайте файл DockerFile в этих каталогах:

  • php\5.6\workspace
  • php\7.1\workspace
  • php\7.2\workspace
  • php\7.3\workspace

В каждый файл скопируйте содержимое из этих файлов:

Пример файла для версии 7.3:

ARG DOCKER_PHP_VERSION=7.3

FROM php:${DOCKER_PHP_VERSION}-fpm-alpine

ARG DOCKER_PHP_ENABLE_XDEBUG='off'
ARG TZ='UTC'

# https://wiki.alpinelinux.org/wiki/Setting_the_timezone
RUN echo "${TZ}" && apk --update add tzdata && \
    cp /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone && \
    apk del tzdata

RUN apk add --update --no-cache icu-libs \
        libintl \
        build-base \
        zlib-dev \
        cyrus-sasl-dev \
        libgsasl-dev \
        oniguruma-dev \
        procps \
        imagemagick \
        patch \
        bash \
        htop \
        acl \
        apk-cron \
        augeas-dev \
        autoconf \
        curl \
        ca-certificates \
        dialog \
        freetype-dev \
        gomplate \
        git \
        gcc \
        gettext-dev \
        icu-dev \
        libcurl \
        libffi-dev \
        libgcrypt-dev \
        libjpeg-turbo-dev \
        libpng-dev \
        libmcrypt-dev \
        libressl-dev \
        libxslt-dev \
        libzip-dev \
        linux-headers \
        libxml2-dev \
        ldb-dev \
        make \
        musl-dev \
        mysql-client \
        openssh-client \
        pcre-dev \
        ssmtp \
        sqlite-dev \
        supervisor \
        su-exec \
        wget \
        nodejs \
        npm

#  Install php extensions
RUN php -m && \
    docker-php-ext-configure bcmath --enable-bcmath && \
    docker-php-ext-configure gd \
      --with-freetype-dir=/usr/include/ \
      --with-jpeg-dir=/usr/include/ \
      --with-png-dir=/usr/include/ && \
    docker-php-ext-configure gettext && \
    docker-php-ext-configure intl --enable-intl && \
    docker-php-ext-configure opcache --enable-opcache && \
    docker-php-ext-configure pcntl --enable-pcntl && \
    docker-php-ext-configure soap && \
    docker-php-ext-configure zip --enable-zip --with-libzip && \
    docker-php-ext-install exif \
        mysqli \
        opcache \
        xsl \
        bcmath \
        gd \
        gettext \
        intl \
        opcache \
        pcntl \
        soap \
        zip \
        calendar \
        pdo_mysql && \
    pecl install redis && \
    docker-php-ext-enable redis && \
    apk add --update --no-cache --virtual .docker-php-mongodb-dependencies \
    heimdal-dev && \
    pecl install mongodb && \
    docker-php-ext-enable mongodb && \
    apk del .docker-php-mongodb-dependencies && \
    apk add --update --no-cache \
        libpq && \
    # Build dependancies for PostgreSQL \
    apk add --update --no-cache --virtual .docker-php-postgresql-dependencies \
        postgresql-client \
        postgresql-dev && \
    docker-php-ext-configure pdo_pgsql && \
    docker-php-ext-configure pgsql && \
    docker-php-ext-install pdo_pgsql \
        pgsql && \
    apk del .docker-php-postgresql-dependencies

# Enable Xdebug
RUN if [ "${DOCKER_PHP_ENABLE_XDEBUG}" == "on" ]; then \
      yes | pecl install xdebug && \
      echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini && \
      echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini && \
      echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini && \
      php -m; \
    else \
      echo "Skip xdebug support"; \
    fi

# Clean
RUN rm -rf /var/cache/apk/* && docker-php-source delete

USER root

RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

USER www-data:www-data

WORKDIR /var/www/

Настройки для Nginx


Скопируйте свой проект

Теперь ваши проекты можете расположить по пути www\site-1.local В качестве примера мы создали 4 сайта и каждый со своей версией php:

  • www\site-1.local => php-5.6-fpm
  • www\site-2.local => php-7.1-fpm
  • www\site-3.local => php-7.2-fpm
  • www\site-4.local => php-7.3-fpm

Запуск проекта

В корне вашего проекта, где лежит файл docker-compose.yml пропишите команду

docker-compose up -d

И ждите выполнения, в конец у вас будет указано, что контейнеры запущены

C:\blog.project\docker.blog\workspace>docker-compose up -d
Starting php-7.2-workspace   ... done
Starting mysql-8-workspace   ... done
Starting php-7.1-workspace   ... done
Starting php-5.6-workspace   ... done
Starting mysql-5.7-workspace ... done
Starting php-7.3-workspace   ... done
Starting nginx-workspace     ... done

Проверить все запущенные контейнеры можно командой

docker ps

Пример:

C:\blog.project\docker.blog\workspace>docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED             STATUS          PORTS                               NAMES
6b721bceba14   workspace_php-5.6     "docker-php-entrypoi…"   About an hour ago   Up 57 seconds   0.0.0.0:9056->9000/tcp              php-5.6-workspace
f91d2e148302   workspace_php-7.2     "docker-php-entrypoi…"   16 hours ago        Up 58 seconds   0.0.0.0:9072->9000/tcp              php-7.2-workspace
589aaa667c36   nginx:stable-alpine   "/docker-entrypoint.…"   16 hours ago        Up 56 seconds   0.0.0.0:80->80/tcp                  nginx-workspace
74b098d4d48b   workspace_php-7.1     "docker-php-entrypoi…"   16 hours ago        Up 57 seconds   0.0.0.0:9071->9000/tcp              php-7.1-workspace
45442cc94740   workspace_php-7.3     "docker-php-entrypoi…"   44 hours ago        Up 57 seconds   0.0.0.0:9073->9000/tcp              php-7.3-workspace
02e2022098e3   mysql:8.0.21          "docker-entrypoint.s…"   45 hours ago        Up 57 seconds   33060/tcp, 0.0.0.0:4308->3306/tcp   mysql-8-workspace
d7fb387b7e0c   mysql:5.7             "docker-entrypoint.s…"   45 hours ago        Up 57 seconds   33060/tcp, 0.0.0.0:4307->3306/tcp   mysql-5.7-workspace

Подключение к БД

При работе с Docker для подключения к БД, необходимо знать особенность В качестве сервера необходимо указывать имя контейнера mysql-5.7 Пример в коде:

DB_CONNECTION=mysql
DB_HOST=mysql-5.7
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=secret

Пример подключения к Adminer: noifx.png


Пример работы phpinfo();

C8lxN.png

Оцените статью: