Top.Mail.Ru

Деплой проекта на 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 разработчика, или, например, возможность развернуть копию инфраструктуры приложения для тестов, и многое другое.

На этом всё, надеюсь, информация окажется для кого-то полезной, жду советов, отзывов, вопросов в комментариях.