Простое приложение с Docker: определение контейнера с помощью Dockerfile

Пришло время приступить к созданию приложения в стиле Docker. Мы начинаем с нижней части иерархии такого приложения, контейнера (container), который описывает этот пост. Над этим уровнем находится служба (service), которая определяет поведение контейнеров в процессе эксплуатации. Наконец, на верхнем уровне находится стек (stack), определяющий взаимодействия всех служб.

Stack
Services
Container

Ваша новая среда разработки

Раньше, если бы вы начали писать приложение на Python, первым делом вам нужно было установить среду исполнения Python на ваш компьютер. Но это создает ситуацию, когда среда на вашем компьютере должна быть идеальной для того, чтобы ваше приложение работало должным образом, а также должна соответствовать вашей производственной среде.

С помощью Docker вы можете просто взять переносимую среду выполнения Python как образ, без необходимости установки. Затем ваша сборка может включать в себя базовый образ Python вместе с кодом приложения, обеспечивая совместное перемещение вашего приложения, его зависимостей и среды выполнения.

Эти переносимые образы определяются чем-то, называемым Dockerfile.

Определите контейнер с помощью Dockerfile

Dockerfile определяет, что происходит в среде внутри вашего контейнера. Доступ к таким ресурсам, как сетевые интерфейсы и дисковые накопители, виртуализирован в этой среде, которая изолирована от остальной части вашей системы, поэтому вам необходимо сопоставить порты с внешним миром и точно определить, какие файлы вы хотите "скопировать" в эту среду. Однако после этого вы можете ожидать, что сборка вашего приложения, определенная в этом Dockerfile, ведет себя точно так же, где бы она ни работала.

Dockerfile

Создайте пустой каталог на вашем локальном компьютере. Измените каталоги (cd) на новый каталог, создайте файл с именем Dockerfile, скопируйте и вставьте следующее содержимое в этот файл и сохраните его. Обратите внимание на комментарии, которые объясняют каждое утверждение в вашем новом Dockerfile.

# Использовать официальную среду исполнения Python в качестве родительского образа
FROM python:2.7-slim

# Установить рабочий каталог в /app
WORKDIR /app

# Скопируйте содержимое текущего каталога в контейнер в /app
COPY . /app

# Установите все необходимые пакеты, 
# указанные в файле requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Сделать порт 80 доступным 
# для мира за пределами этого контейнера
EXPOSE 80

# Определить переменную среды
ENV NAME World

# Запустить app.py при запуске контейнера
CMD ["python", "app.py"]

Этот Dockerfile ссылается на пару файлов, которые мы еще не создали, а именно на app.py и requirements.txt. Давайте создадим их дальше.

Само приложение

Создайте еще два файла, requirements.txt и app.py, и поместите их в одну папку с Dockerfile. Это завершает наше приложение, которое, как вы можете видеть, довольно просто. Когда вышеупомянутый Dockerfile встроен в образ, из-за команды COPY этого Dockerfile присутствуют app.py и requirements.txt, а вывод из app.py доступен через HTTP благодаря команде EXPOSE.

requirements.txt

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Теперь мы видим, что pip install -r requirements.txt устанавливает библиотеки Flask и Redis для Python, и приложение выводит переменную среды NAME, а также вывод вызова socket.gethostname(). Наконец, поскольку Redis не работает (поскольку мы установили только Python библиотеку для работы с Redis, а не сам Redis), следует ожидать, что попытка использовать ее здесь не удастся и приведет к сообщению об ошибке.

Примечание. При обращении к имени хоста, находящегося внутри контейнера, выдается идентификатор контейнера, который похож на идентификатор процесса для исполняемого файла.

Обратите внимание: Вам не нужен Python или что-либо в файле requirements.txt в вашей системе, а также сборка или запуск этого образа не устанавливают их в вашей системе. Вы действительно не настраивали среду с Python и Flask в своей операционной системе, но они есть у вас в контейнере.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Язык поисковых запросов в Graylog

Хэш-таблица: разрешение коллизий

Нормальные формы, пример нормализации в базе данных