Докер — отличная, модная, трендовая технология. Первоначальная настройка docker очень проста, занимает порядка 5-10 минут. За что докер и любят: реализация, поддержка и простота использования контейнеров с приложениями выгодно отличается от голого lxc и openvz.
Несколько очевидных плюсов по сравнению с конкурентами:
- Присутствует центральный реестр (docker hub), где хранится и поддерживается большинство распространенных приложений таких как nginx, mysql, apache, php, logstash, elasticsearch, mongo. Билд образов происходит автоматически и так же автоматически прогоняются тесты.
- Чтобы запустить приложение не нужно знать что внутри контейнера, нужно лишь уметь управлять самим приложением. Достаточно прочитать на странице в docker hub где и какие конфигурационные файлы лежат, и как управлять контейнером в целом. Это на порядок проще настройки с нуля.
- В большинстве своем один контейнер-одно приложение, но это легко обойти и пользоваться докером как обычной системой виртуализации.
- Одна и та же сборка со всеми библиотеками и настройками может быть запущена где угодно. Отсутствием проблем с переносимостью.
- Простота развертывания собственного docker-registry. По сути это следствие п.1, образ docker-registry является официальным, он тестируется и своевременно обновляется.
- Шикарная документация и мощнейшее, хоть и молодое, сообщество.
В рунете статей на тему миграции в docker подозрително мало. Расскажу о своем опыте перевода этого сайта, т.е. простого lamp в докер. Кажется сложным, но по времени первая настройка голого lamp субъективно занимает времени больше чем то же хозяйство разворачивать в docker.
Системные требования весьма неприхотливые: https://docs.docker.com/engine/installation/binaries/. Основа — ядро 3.10 заведется и на более старых но работать с докером не так комфортно, изза отсутствия поддержки нескольких фич. Важнейшей из которой считаю возможность работы внутри контейнера для отладки. Пример такой работы будет показан ниже.
Обновление ядра описано в заметке:
Мастер класс по установке докера однострочником:
# curl -fsSL https://get.docker.com/ | sh
И не забываем что работать от root не круто, добавляем себя в групппу докера.
usermod -aG docker os
Теперь нужно определиться c образами контейнеров:
- Nginx — входящий балансировщик
- php — понятно что без тебя вордпрессу никуда. Мы будем использовать apache, ибо я не извращенец вордпрес на fpm держать. Пробовал плювался =)
- mysql — база
- sftp и фтп — для доступа к файлам. Установку этого софта рассмотрю в другой статье вместе с docker-compose.
Поскольку мы все это будем запускать хоть на одной машине но в изолированных контейнерах — необходимо контейнеры слинковать. Процесс это простой — линк, в нашем случае — это запись в /etc/hosts. Элементарно. Все что относится к докеру но не должно находиться внутри контейнеров — логи, исходники, базы данных и хомяки пользователей мы будем класть в папочку /srv/docker.
Итак поехали:
mkdir -p /srv/docker/casp.ru/old/var/www/casp.ru/old/ mkdir -p /srv/docker/casp.ru/old/var/log mkdir -p /srv/docker/casp.ru/old/home/sftpwordpress mkdir -p /srv/docker/mysql/db mkdir -p /srv/docker/nginx_in/etc mkdir -p /srv/docker/nginx_in/log
Итак запускаем в правильной последовательности и с правильными ключами.
Начинаем с базы данных. Запуск производится первый раз, нужно создать базы и задать рутовый пароль:
docker run -d -h mysql_local --name mysql_local \ -e MYSQL_ROOT_PASSWORD=SuperPass1 \ -v /srv/docker/mysql/db/:/var/lib/mysql \ mysql/mysql-server:latest
Если все сделали правильно то докер скачает образ, запустит контейнер без ошибок, кроме того в папке базы данных появятся файлы самой базы. После этого строку с паролем можно из скрипта запуска убрать.
Детально про ключи.
-d - запустить в виде демона, освободить консоль после запуска -h - имя хоста внутри контейнера --name имя контейнера, которое будет отображаться в docker ps -e environment, в частном случае с рутовыйм паролем. -v volume, грубо говоря прокидывание хостовой папки в контейнер mysql/mysql-server:latest - официальный последний образ mysql https://hub.docker.com/_/mysql/
С php-fpm немного длиннее, но тоже не очень сложно. Нужно взять за основу официальную сборку php-fpm и на основании ее собрать свой собственный, с включенными модулями. Для этого нужно создать папку в которую положим файл описания контейнера Dockerfile и собственно собрать контейнер.
mkdir php-caspru ; cd php-caspru cat << EOF > Dockerfile from php:5-apache #from php:5.5-apache RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \ && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ && docker-php-ext-install gd mysqli opcache RUN { \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.interned_strings_buffer=8'; \ echo 'opcache.max_accelerated_files=4000'; \ echo 'opcache.revalidate_freq=60'; \ echo 'opcache.fast_shutdown=1'; \ echo 'opcache.enable_cli=1'; \ } > /usr/local/etc/php/conf.d/opcache-recommended.ini RUN a2enmod rewrite #; a2ensite 000-default.conf VOLUME /var/www/html EOF docker build -t php:caspru .
Если все сделали правильно — сборка пройдет удачно. Обратите внимание что если нужно переключиться на другую ветку пхп достаточно только поменять строку в начале файла. Здесь используется последняя стабильная сборка php-5.6.
Запускаем и линкуем. Этому контейнеру нужен доступ к базе данных.
docker run -d -h php_caspru --name php_caspru \ --link mysql_local \ -v /srv/docker/casp.ru/old/var/www/casp.ru/old:/var/www/html \ php:caspru
Далее запускаем nginx (для проверки на порту с единицей на конце).
docker run -d --name nginx_in -h nginx_in \ -v /srv/docker/casp.ru/old/var/www/casp.ru/old:/var/www/casp.ru/old:ro \ -v /srv/docker/nginx_in/log:/var/log/nginx:rw \ -v /srv/docker/nginx_in/etc/nginx:/etc/nginx/:ro \ --link php_caspru:php_caspru \ -p 801:80 \ -p 4431:443 \ nginx
После чего помещаем файлы вордпреса в папку.
/srv/docker/casp.ru/old/var/www/casp.ru/old
Идем на наш сайт по 81 порту. Если не видим желаемого — ищем ошибку.
Если все в порядке, перезапускаем контейнер уже на 80м и 443м портах и гордимся освоением новой технологии.
Для nginx нужно так же предусмотреть ротацию логов. Тут никаких особых заморочек не ожидается:
cat /etc/logrotate.d/nginx_in /srv/docker/nginx_*/log/*.log { daily missingok rotate 52 compress delaycompress notifempty sharedscripts postrotate docker exec -it nginx_in nginx -s reopen endscript }
Ну и напоследок — зачем мы апгрейдили ядро? Если есть какие-то вопросы к тому что имеем в контейнере, нет четкого понимания что там происходит и как работает или просто нужно протестировать конфиг nginx — нет проблем, идем внутрь контейнера и работаем как привыкли:
docker exec -it nginx_in bash
Поддержка этой фичи появилась только в новых ядрах.