Как стать автором
Обновить

Настройка рабочего окружения Yii2 Framework с помощью Docker Toolbox на Windows

Добрый день, пользователи Хабра.
Данная статья предназначена, в первую очередь, для начинающих, тех, кто только начинает изучать Yii и Docker.
Большинство инструкций, которые мне предоставил Гугл, описывают установку окружения на машинах с установленным docker'ом (linux, mac). Мне повезло меньше, у меня Windows7, и на нее нужно ставить, как указано на сайте разработчика, устаревшее решение (legacy desktop solution) — Docker Toolbox.
К сожалению при использовании Docker Toolbox, появился не совсем очевидный нюанс. О нём — чуть позже. Конечно, может он оказался не очевидным только для меня, но в общем если вдруг: «не я такой один», эта инструкция для вас.

Итак, задача: развернуть Ubuntu с apache, php и mysql.
Будем считать, что Docker Toolbox уже установлен. Если вдруг — нет, то скачайте его и установите)

Устанавливаем Yii через Composer
composer create-project --prefer-dist yiisoft/yii2-app-basic yii2-project

В моем примере папка с проектом называется — yii2-project.
В проекте создаем папку docker, и в ней файл — Dockerfile.
Dockerfile
#указываем основной образ для контейнера
FROM ubuntu:latest

#обновим
RUN apt-get update

#устанавливаем апач
RUN apt-get install -y apache2 apache2-utils curl gnupg wget
RUN a2enmod rewrite

#установим переменные окружения
ENV TZ=Europe/Moscow

#указываем зону для нашего образа
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

#устанавливаем php и расширения
RUN apt-get install -y git python3 perl \
    php nano

RUN apt-get install -y \
    php-pdo php-pdo-mysql \
    php-mbstring php-tokenizer \
    php-xml php-simplexml php-zip \
    php-opcache php-iconv php-intl \
    php-json php-gd php-ctype php-oauth \
    php-apcu php-imagick php-xdebug \
    php-memcached php-ftp php-imap \
    php-curl iputils-ping

RUN apt-get update

#откроем 80 порт
EXPOSE 80

#добавим в контейнер конфигурационный файл php.ini
ADD ./docker/conf/php/php.ini /etc/php/7.2/apache2/php.ini

#добавим конфигурацию xdebug
ADD ./docker/conf/php/xdebug.ini /etc/php/7.2/mods-available/xdebug.ini

#добавим конфигурационный файл для apache
ADD ./docker/conf/apache/apache2.conf /etc/apache2/apache2.conf

#очистим папки
RUN rm -R /etc/apache2/sites-enabled/* /etc/apache2/sites-available/* /var/www/*

#укажем директорию /var/www как рабочую
WORKDIR /var/www

#запускаем процесс apache2
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]


Далее, создадим в папке docker папку conf, в ней две папки: apache и php, в них положим файлы конфигурации, соответственно для apache и php.
apache2.conf
Mutex file:${APACHE_LOCK_DIR} default
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

HostnameLookups Off
ServerName localhost
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn

Listen 80
AccessFileName .htaccess

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
IncludeOptional conf-enabled/*.conf

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

<Directory />
	Options -FollowSymLinks
	AllowOverride None
	Require all denied
	Options -Indexes
</Directory>

<Directory /var/www/>
	Options FollowSymLinks
	AllowOverride None
	Require all granted
	Options -Indexes
</Directory>

<FilesMatch "^\.ht">
	Require all denied
</FilesMatch>

<VirtualHost *:80>
	ServerName yii2-project
	ServerAdmin admin@localhost

	DocumentRoot /var/www/web
	<Directory "/var/www/web">
	        RewriteEngine on
	
	        RewriteCond %{REQUEST_FILENAME} !-f
	        RewriteCond %{REQUEST_FILENAME} !-d
	
	        RewriteRule . index.php
    	</Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>


php.ini
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1

disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = Off
max_execution_time = 30
max_input_time = 60
memory_limit = 128M

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On

log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 64M
post_max_size = 128M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60


;extension=php_mbstring.dll
;extension=php_bz2.dll
;extension=php_com_dotnet.dll
;extension=php_curl.dll
;extension=php_dba.dll
;extension=php_enchant.dll
;extension=php_exif.dll
;extension=php_fileinfo.dll
;extension=php_ftp.dll
;extension=php_gd2.dll
;extension=php_gettext.dll
;extension=php_gmp.dll
;extension=php_igbinary.dll
;extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_intl.dll
;extension=php_ldap.dll
;extension=php_mongodb.dll
;extension=php_mysqli.dll
;extension=php_oci8_12c.dll
;extension=php_odbc.dll
;extension=php_openssl.dll
;extension=php_pdflib.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
;extension=php_pgsql.dll
;extension=php_phpdbg_webhelper.dll
;extension=php_redis.dll
;extension=php_shmop.dll
; The MIBS data available in the PHP distribution must be installed.
; See http://www.php.net/manual/en/snmp.installation.php
;extension=php_snmp.dll
;extension=php_soap.dll
;extension=php_sockets.dll
;extension=php_sodium.dll
;extension=php_sqlite3.dll
;extension=php_sysvshm.dll
;extension=php_tidy.dll
;extension=php_timezonedb.dll
;extension=php_xmlrpc.dll
;extension=php_xsl.dll

[CLI Server]
cli_server.color = On

[Pdo_mysql]
pdo_mysql.default_socket=

[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off

[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"

[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off

[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off

[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

[bcmath]
bcmath.scale = 0

[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_length = 26
session.sid_bits_per_character = 5

[Assertion]
zend.assertions = -1

[Date]
date.timezone = "Europe/Moscow"

[Tidy]
tidy.clean_output = Off

[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5

[ldap]
ldap.max_links = -1


xdebug.ini
zend_extension=xdebug.so

xdebug.cli_color = 1
xdebug.show_local_vars = 1
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_connect_back = 0


В корне проекта создадим файл docker-compose.yml
docker-compose.yml
version: '3'
services:
  web:
    container_name: web
    build:
      context: ./
      dockerfile: ./docker/Dockerfile
    environment:
      XDEBUG_CONFIG: remote_host=host.docker.internal
      PHP_IDE_CONFIG: serverName=localhost
    ports:
      - 80:80
    volumes:
      - /yii2-project:/var/www
    links:
      - db
    depends_on:
      - db

  db:
    container_name: mysql
    image: 'mysql:latest'
    command: --default-authentication-plugin=mysql_native_password --innodb-use-native-aio=0
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: yii2_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - /yii2-project/docker/database:/var/lib/mysql


И вот здесь появляются нюансы.
В случае, если мы будем запускать окружение на локальной машине с установленным docker'ом, левая часть (слева от двоеточия) в этих установках будет относится к локальной машине:
# настройки для web
   ports:
      - 80:80
    volumes:
      - /yii2-project:/var/www

# настройки для db
    ports:
      - 3306:3306
    volumes:
      - /yii2-project/docker/database:/var/lib/mysql

Однако, Toolbox создает виртуальную машину в VirtualBox с установленным docker'ом и эти порты и пути будут относится к ней.
Поэтому, чтобы у нас всё завелось, необходимо расшарить для нашей виртуальной машины (по умолчанию default) нашу папку с проектом (yii2-project), а также сделать проброс портов:
image

Здесь указываем папку с проектом, имя папки (как в файле docker-compose.yml, в нашем примере — yii2-project), ставим галочки «авто-подключение», «создать постоянную папку»:
image

пробрасываем порты:
image

image

Дальше, по желанию, можно внести в файл hosts запись:
127.0.0.1 yii2-project

Еще важное замечание: для работы xdebug в файле docker-compose.yml в переменной XDEBUG_CONFIG: remote_host=host.docker.internal вместо 'host.docker.internal' необходимо установить ip-адрес вашей локальной машины. (Спасибо: Денис Бондарь) IP-адрес легко узнать в Центре управления сетями Windows.
Теперь всё готово для разворачивания окружения.
Запускаем машину:
docker-machine start

Если запуск прошел успешно, далее переходим в папку с нашим проектом и собираем:
docker-compose build

После сборки:
docker-compose up -d

Перейдем в контейнер:
docker-compose exec webserver bash

Поздравляю, Вы настроили рабочее окружение. Теперь проект доступен по ссылке (если внесли запись в hosts)
http://yii2-project:8080
или
http://localhost:8080

PS: если вдруг сервис mysql с первого раза не запустится — удалите папку database из папки docker проекта.
PS2: Не забудьте в конфиге базы данных Yii установить правильный host. В нашем случае это сервис 'db'.
'dsn' => 'mysql:host=db;dbname=yii2_db',
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.