Примечение: В этой статье мы пошагово создадим рабочее окружение, для Web разработки, с помощью Docker. Статья будет дополняться, весь проект будет размещен на GitHub и обновляться. Все вопросы можно будет оставить, через сервис GitHub https://github.com/LukaS0lncev/workspace
Установка Docker на Windows
Примечание: Подробно рассматривать установку Docker и Docker compose на Windows мы не будем, просто укажем ссылки на нужный софт.
Нам необходим будет:
- Docker под Windows, все можно скачать по ссылке и установить https://docs.docker.com/docker-for-windows/install/
- Docker Compose под Windows, все можно скачать по ссылке и установить https://docs.docker.com/compose/install/
Быстрый старт
Примечание: Если вам нужен быстрый старт, скачал, запустил и работаешь, то ниже команды для быстрого запуска проекта:
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
В каждый файл скопируйте содержимое из этих файлов:
- для 5.6 https://github.com/LukaS0lncev/workspace/blob/main/php/5.6/workspace/Dockerfile
- для 7.1 https://github.com/LukaS0lncev/workspace/blob/main/php/7.1/workspace/Dockerfile
- для 7.2 https://github.com/LukaS0lncev/workspace/blob/main/php/7.2/workspace/Dockerfile
- для 7.3 https://github.com/LukaS0lncev/workspace/blob/main/php/7.3/workspace/Dockerfile
Пример файла для версии 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
-
Создайте файл nginx\conf.d\default.conf и скопируйте туда https://github.com/LukaS0lncev/workspace/blob/main/nginx/conf.d/default.conf
-
Создайте файл nginx\conf.d\vhost.conf и скопируйте туда https://github.com/LukaS0lncev/workspace/blob/main/nginx/conf.d/vhost.conf
Скопируйте свой проект
Теперь ваши проекты можете расположить по пути 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: