django

Запускаем django-приложение в Docker на Vagrant под Windows

  • четверг, 14 декабря 2017 г. в 03:14:12
https://habrahabr.ru/post/344514/
  • Виртуализация
  • Django


Привет Хабр! Несколько лет я находился в readonly-режиме на сайте Хабрахабр, изредка оставляя комментарии к чужим публикациям, и за несколько недель до нового года, мне захотелось поменять это положение вещей. Этому послужило мое недавнее задание на работе. А когда начал искать информацию, понял, что ее, как всегда, много, написано запутанно и не то что мне хотелось бы найти. А как быть, если этот человек новичок в этом вопросе? Вот и решил попробовать себя на этом поприще. Сделать туториал, который был бы полезен мне в первую очередь.

Поехали.

Уже несколько лет Docker был на слуху у меня, но никак не доводилось с ним поработать. А тут как раз менеджменту захотелось поменять свой стек. Начали говорить такие слова как Docker, контейнеры и облака. Чем не повод изучить что-то новое? Я работаю DevOps инженером на радио. Мой список технологий очень прост: Octopus Deploy + TeamCity + и тележка самописных приложений. Работает безотказно.

В этой статье я хочу поделиться информацией в том виде, в котором мне самому лично хотелось бы ее найти. Цель запустить Docker на Vagrant, создать образ с Django проектом по умолчанию, инициализировать контейнер и достучаться к сайту с основной ОС.

На работе я работаю под Windows. Для начала нам понадобится Chocolatey, чтобы установить необходимые софт.

Установим удобный терминал (cmder), VirtualBox и Vagrant:

C:\> choco install cmder
C:\> choco install vagrant
C:\> choco install virtualbox

Если не хотите использовать Chocolatey, можно поставить все вручную.

Создадим папку для нашего проекта, и добавим в него Vagrantfile файл:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
  config.vm.network "forwarded_port", guest: 5000, host: 8080, host_ip: "127.0.0.1"
end

Обычно, этот файл можно сгенерировать одной командой vagrant init ubuntu/xenial64. Я добавил одну строчку для переадресации портов между основной и гостевой ОС на виртуальной машине. Это понадобится позже, когда мы захотим зайти на наш сайт, запущенный в контейнере.

Запустим виртуальную машину и подключимся к терминалу с помощью следующих двух Vagrant команд:

vagrant up
vagrant ssh

Мы должны успешно подключиться к терминалу виртуальной машине.

Перейдем к установке Docker:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce

Проверим, что Docker установлен успешно и сервис запущен. Выполним следующую команду:

sudo systemctl status docker

Создадим Dockerfile файл со следующим содержанием:

FROM python:latest

ENV PYTHONUNBUFFERED 1

RUN apt-get update
RUN mkdir /code

WORKDIR /code

RUN pip install django==1.11.8
RUN django-admin startproject mysite

RUN python mysite/manage.py migrate
RUN echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')" | python mysite/manage.py shell

ADD . /code/

CMD python mysite/manage.py runserver 0.0.0.0:5000

Мы создали описание будущего образа с Django приложением по умолчанию. В этом описании, мы используем Python образ, и добавляем наших приправ, а именно: установка Django, создание проекта по умолчанию, запуск скриптов для инициализации базы данных и создание админ пользователя.

Давайте соберем образ, выполнив:

sudo docker build -t my/app:latest .

Эта команда подтягивает все необходимые образы из Docker реестра, и добавляет нашу конфигурацию в итоговый с названием my/app.

Запустите команду, и вы увидите свой собранный образ локально:

sudo docker images

Это всего лишь навсего образ как класс, который нам необходимо инициализировать. При инициализации мы создаем контейнер (объект). Контейнер это запущенный образ в Docker.

Создаем контейнер на базе нашего образа:

sudo docker run -d -p 5000:5000 my/app

Docker вернет вам сгенерированный уникальный идентификатор (guid) запущенного контейнера. Только что мы запустили наше приложение в контейнере. В команде мы указали Docker произвести сопоставление портов внутри контейнера и внешнего у гостевой ос.

Сверните удаленный терминал, и запустите браузер в основной системе. Перейдите по адресу: http://localhost:8080/

Вы увидите заглавную страницу Django приложения. Вы можете перейти на admin страницу, и войти в контрольную панель с admin/pass данными.

Почему Vagrant? Для экспериментов я никогда не устанавливаю ничего на основную систему, и работаю с виртуальными машинами. Если что-то пошло не так, всегда можно удалить и начать все сначала. Лучшая документация для меня — код.

Вернемся к консоли. Чтобы просмотреть логи, выполните команду:

sudo docker logs <guid контейнера> | head

Команда выведет output консоли, запущенного Django внутреннего сервера. Все то же, что вы видите обычно запустив python manage.py runserver у себя локально.

Выключим контейнер следующей командой:

sudo docker stop <guid контейнера>

Опять возвращаемся к нашему запущенному браузеру в основной системе, и перегружаем вебсайт. Он недоступен.

Когда контейнер остановлен, воспринимайте это как выключенный сервер. Состояние контейнера сохранено, как если бы вы сделали хибейрнет на своем десктопе.

Эта команда выведет список всех инициализированных контейнеров:

sudo docker ps -a

Давайте запустим наш контейнер снова:

sudo docker start <guid контейнера>

Браузер возвращает нам все тот же вебсайт. Можете залогиниться в контрольную панель, создать пользователя, и потом выключить и включить контейнер. Вы увидите, что пользователь сохранен и доступен, когда контейнер снова запущен.

Я специально использовал старую версию Django, чтобы показать следующий момент. Откройте Dockerfile, и отредактируйте его. Уберите версию Django, когда мы его устанавливаем с помощью pip команды.

Соберите новый образ командой:

sudo docker build -t my/app:latest .

Заметьте, мы не останавливали запущенный контейнер. Командой выше мы обновили образ, который хранится локально.

Давайте удалим текущий контейнер командой:

sudo docker kill <guid>

И запустим новый контейнер:

sudo docker run -d -p 5000:5000 my/app

Каждый раз, когда вы запускаете новый контейнер на базе образа, Docker генерирует ему уникальный идентификатор, по которому вы можете с ним работать (выключать, включать, подключаться по терминалу и т.д.)

На этом все, давайте подчистим за собой и уберем все лишнее.

Выйдите из SSH сессии в терминале, набрав:

exit

И вы снова у себя в домашней директории основной системы. Vagrant все еще запущен, Docker и ваш контейнер соответственно. Проверить это можно опять же через браузер, убедиться, что сайт еще запущен.

Чтобы удалить запущенную виртуальную машину в Vagrant, запустите:

vagrant halt
vagrant destroy

Первая команда выключает виртуальную машину и сохраняет ее состояние, а вторая производит удаление виртуальной машины из VirtualBox.