Деплой проекта на php/python с помощью Docker. Часть 2
Создание контейнера для python-приложения
В случае с python'ом всё гораздо проще - в данном случае не надо обслуживать статику, настраивать nginx, копировать файлы настроек и т.п. Dockerfile выглядит так:
FROM python:2.7.9
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN pip install \
tornado \
mongoalchemy \
apscheduler \
redis \
boto
EXPOSE 8080
CMD python server.py & > /dev/null && /bin/bash
Конейнер создаём на основе официального, с уже установленным python'ом 2.7 (FROM python:2.7.9). Далее всё просто - создаём рабочую директорию, указываем, что нам надо пробросить на хост машину порт 8080, на котором будет работать наше приложение, устанавливаем необходимые библиотеки и задаём команду запуска. Думаю, тут всё предельно просто и понятно
Скрипт запуска контейнера:
#! /bin/bash
sudo docker build -t example/python-app .
sudo docker stop python-app
sudo docker rm python-app
sudo docker run -d -i -t \
--name python-app \
-v $PWD:/usr/src/app \
-h python-app \
--link mongo:mongo \
--link redis:redis \
-p 8080:8080 \
example/python-app
Всё так же, как и в скрипте запуска контейнера для php-приложения. Вместо монтирования директории проекта (-v $PWD:/usr/src/app) можно было бы скопировать всё необходимое в контейнер ("ADD . /usr/src/app" в Dockerfile), так как здесь, в отличие от php, для обновления проекта одного git pull недостаточно и надо перезапускать контейнер. Но моё приложение пишет логи в текущую директорию и мне хотелось бы просматривать их там же.
Для деплоя приложения на продакшн-сервер я использую простой скрипт:
#! /bin/bash
git checkout master
git pull origin master
sudo docker restart python-app
Установка и настройка
Итак, у нас есть всё необходимое, чтобы развернуть проект на удалённом сервере. Далее - пошаговая инструкция, нагло скопированная из внутренней wiki :)
В первую очередь, на сервере нужен git
sudo apt-get install git
Копируем ключ
ssh-keygen
cat ~/.ssh/id_rsa.pub
и даём этому серверу доступ к репозиториям в bitbucket/github.
Ставим docker. Для ubuntu server это делатся скриптом
curl -sSL https://get.docker.com/ubuntu/ | sudo sh
Клонируем репозитории:
git clone url-репозитория app
git clone url-репозитория python-app
Скрипт для запуска бд хранится в моём случае в репозитории с php-приложением. Запускаем его, потом - скрипты для создания контейнеров приложений.
Набираем команду
sudo docker ps
И ожидаем увидеть примерно следующее:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ffcaf6c186f example/python-app:latest "/bin/sh -c 'python 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp python-app
d364fac3517d example/app:latest "/bin/sh -c 'service 13 minutes ago Up 13 minutes 0.0.0.0:80->80/tcp app
7682066be8c9 redis:latest "/entrypoint.sh redi 16 minutes ago Up 16 minutes 0.0.0.0:6379->6379/tcp redis
0959a6da8db9 mongo:2.4 "/entrypoint.sh mong 16 minutes ago Up 16 minutes 0.0.0.0:27017->27017/tcp mongo
И, наконец, устанавливаем клиенты для работы с mongodb и redis:
sudo apt-get install mongodb-clients
sudo apt-get install redis-tools
Так как контейнеры работают на стандартных портах, работа с ними ничем не отличается от "обычной" работы с mongo и redis с помощью утилит mongo, mongodump, redis-cli и др.
Работа с контейнерами
Список запущенных контейнеров:
sudo docker ps
Запуск/остановка/перезапуск контейнера:
sudo docker start/stop/restart название-контейнера
Логи контейнера:
sudo docker logs название-контейнера
top процессов контейнера:
sudo docker top название-контейнера
Переменные окружения
Docker позволяет задавать переменные окружения linux, но я пошёл другим, на мой взгляд, более простым путём - в корневой директории проекта создаётся файл .env с информацией о текущем окружении (конечно же, он должен быть добавлен в .gitignore), который используется при инициализации конфига приложения. То есть, чтобы указать окружение проекта, например, на продакшн сервере, я пишу в консоли:
echo "prod" > .env
Заключение
Итак, в этой статье я показал пример "контейнеризации" веб-приложения с помощью docker'а и разворачивания его на сервере. Пример довольно простой, но вполне пригодный для дальнейшего усовершенствования.
Чем больше я работаю с Docker, тем больше нахожу в нём плюсов - как для локальной разработки, так и для использования в продакшене. Окружение проекта, не зависящее от того, где он запускается, возможность создавать отдельные окружения для разных проектов на PC разработчика, или, например, возможность развернуть копию инфраструктуры приложения для тестов, и многое другое.
На этом всё, надеюсь, информация окажется для кого-то полезной, жду советов, отзывов, вопросов в комментариях.