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

Dockerfile

Чтоб в последствии легко разворачивать подобные контейнеры нужно создать Dockerfile для создания снимка системы которым мы будем пользоваться в будущем. Пример создание php окружение с нужными расширениями уже внутри этого контейнера:

#Dir for extensions config /usr/local/etc/php/conf.d/

FROM php:5.6-fpm

RUN apt-get update
RUN apt-get install -y php5-dev php-pear php5-common

# curl уже входит в образ 5.6-fpm но на всякие пожарные попробуем установить
RUN apt-get install -y curl libcurl4-openssl-dev
RUN docker-php-ext-install curl
RUN docker-php-ext-enable curl

# Устанавливаем все расширения
RUN docker-php-ext-install json
RUN docker-php-ext-enable json

RUN apt-get install -y libpng-dev
RUN apt-get install -y libjpeg-dev
RUN docker-php-ext-install gd
RUN docker-php-ext-enable gd

RUN apt-get install -y libxml2-dev
RUN docker-php-ext-install xml
RUN docker-php-ext-enable xml

RUN docker-php-ext-install opcache
RUN docker-php-ext-enable opcache

RUN docker-php-ext-install session
RUN docker-php-ext-enable session

RUN docker-php-ext-install mbstring
RUN docker-php-ext-enable mbstring

RUN docker-php-ext-install mysqli
RUN docker-php-ext-enable mysqli

RUN docker-php-ext-install pdo
RUN docker-php-ext-enable pdo

RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-enable pdo_mysql

RUN apt-get install -y libpq-dev
RUN docker-php-ext-install pdo_pgsql
RUN docker-php-ext-enable pdo_pgsql

RUN apt-get install -y php5-memcached

RUN pecl install redis
RUN docker-php-ext-enable redis

RUN docker-php-ext-install pcntl
RUN docker-php-ext-enable pcntl

# Настройка xDebug (КЭП)
RUN pecl install xdebug-2.3.2
RUN docker-php-ext-enable xdebug
RUN touch /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_autostart=true >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_mode=req >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_handler=dbgp >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_connect_back=1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_port=9000 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
# RUN echo xdebug.remote_host=127.0.0.1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.idekey=PHPSTORM >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.remote_enable=1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.profiler_append=0 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.profiler_enable=0 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.profiler_enable_trigger=1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.profiler_output_dir=/var/debug >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.profiler_output_name=cachegrind.out.%s.%u >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.var_display_max_data=-1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.var_display_max_children=-1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.var_display_max_depth=-1 >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

RUN apt-get install -y geoip-bin geoip-database libgeoip-dev
RUN apt-get install -y php5-geoip

RUN apt-get install -y wget
RUN wget https://phar.phpunit.de/phpunit.phar
RUN chmod +x phpunit.phar
RUN mv phpunit.phar /usr/local/bin/phpunit

WORKDIR /var/www

CMD ["php-fpm"]

Собрать образ описаный в Dockerfile нужно при помощи команды docker build. Также можно легко эспортировать контейнер в сжатый архив и перенести руками готовую стстему без необходимости выкачивания ее из сети и сборки модулей. Для этого помогут команды save и load Для хранения данных в разных проектах мы используем MySQL, memcached, redis и PGSQL, поднимем их в разных контейнерах. Бляго все они имеют официальные образы в Docker Hub и если нужно их расширить, то есть хорошая документация на страницах их образов. Для модификации конфигов и переобъявления к примеру пароля root пользователя для MySQL можно прописать это в Dockerfile ссылаясь на образ источник при помощи директивы FROM, так же как мы сделали для PHP. Имейте в виду что все что в нутри контейнера, при его падении/отключении пропадает безвозвратно, для того чтоб не терялись конфиги, и сами данные лучше пробрасывать файлы в хост через параметр для команды run -v, через Dockerfile это не получится сделать, или прописать через оркестрацию.

Оркестрация

Скачав и развернув все необходимые образы нам нужно объединить их при помощи параметра —link или сконфигурировать docker-compose.yml для удобного хранения конфига и последующего легкого модифицирования нашей связки. Чтоб постоянно не отправлять в контейнер файлы и сохранять данные из БД на хосте, конфиги для nginx, php, … тянуть с хоста. Если вы хотите обновлять ПО то лучше использовать Docker data container, а для разработки пробрасывать в хост то, что нужно. Для примера свяжем Nginx+PHP-FPM+MySQL+Memcached.

fpm:
  image: php-fpm-dev #наш контейнер со всеми необходимыми расширениями
  links:
    - mysql
    - memcached
  volumes:
    - ./:/var/www # подключаем проект к php-fpm
mysql:
  image: mysql
  volumes:
    - ./data-mysql:/var/lib/mysql # сохранение файлов БД на хосте
  environment:
    MYSQL_ROOT_PASSWORD: 12345
  ports:
    - 3306:3306
memcached:
  image: memcached
  ports:
    - 8080:1080
nginx:
  image: nginx
  links:
    - fpm
  ports:
    - 80:80
    - 443:443
  volumes:
    - ./:/var/www # подключаем проект к php-fpm, также можно использовать volumes_from для подключения разелов из других контейнеров
    - ./nginx:/etc/nginx/ # тянем настройки nginx из проекта

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