Рубрики
Без рубрики

Докерейте приложение для колбы

Простая статья, чтобы объяснить, насколько приложена приложение Flask. Теги с докером, колбой, Python.

На прошлой неделе мне было брошено вызов, чтобы начать простое «Hello World» приложение для колбы, но это необходимо для запуска в контейнер докера. В этой статье я покажу вам, как был мой подход, чтобы решить эту проблему!

Хотя простой «Hello World», который я работал с лучшими практиками архитектуры. У меня была следующая структура каталога:

.
├── backend
│   ├── app.py
│   ├── blueprints
│   │   ├── core
│   │   │   ├── bp.py
│   │   │   ├── __init__.py
│   │   │   ├── routes.py
│   │   │   └── tests
│   │   │       └── test_bp_core.py
│   │   └── __init__.py
│   └── __init__.py
├── conftest.py
├── Dockerfile
├── .dockerignore
├── .gitignore
├── Pipfile
├── Pipfile.lock
├── pytest.ini
└── README.md
from flask import Flask


def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'My_Top_Secert_Key'

    # Blueprint

    from backend.blueprints.core import bp as bp_core
    bp_core.config(app)

    return app
from flask import Blueprint


bp = Blueprint('core', __name__)


def config(app):
    from backend.blueprints.core import routes # noqa
    app.register_blueprint(bp)
from backend.blueprints.core.bp import bp


@bp.route('/')
def home():
    return "Hello World"
import pytest

from flask import url_for


@pytest.fixture
def resp(client):
    return client.get(url_for('core.home'))


def test_bp_home_status_code_ok(resp):
    assert resp.status_code == 200

Опять же, в центре внимания этой статьи не следует объяснять подробную информацию о приложении Flask, поэтому, если у вас есть вопросы о том, как тестировать приложения Flask, пожалуйста, смотрите Документация Отказ

Вернуться к корню приложения, у меня есть некоторые файлы, которые интересны!

Один из них Conftest.py Отказ Этот файл отвечает за настройки pteest Чтобы запустить все тесты в приложении. Его код:

import pytest

from backend.app import create_app


@pytest.fixture
def app():
    app = create_app()
    return app


@pytest.fixture
def client(app):
    with app.test_client() as c:
        yield c

Другое – это Pytest.ini Простой файл, который сообщает pteest Шаблон файлов проверяет имена, в нашем случае Pytest.ini код:

[pytest]
python_files=test*.py *tests.py

Две другие файлы – Pipfile и Pipfile.lock.lock.lock . Эти файлы создаются или обновлены командой Pipenv Установите [Пакет] Отказ Как мы увидим позже, самым важным в нашем случае является Pipfile.lock Поскольку он блокирует версию всех зависимостей и позволяет определять детерминированную установку этих зависимостей в нашей среде.

И у нас есть Dockerfile , слишком. Этот файл отвечает за создание докера изображения. Это изображение будет использоваться для поднятия контейнера с приложением колба. Его код:

FROM python:3.7.1

LABEL Author="Vicente Marçal"
LABEL E-mail="vicente.marcal@gmail.com"
LABEL version="0.0.1b"

ENV PYTHONDONTWRITEBYTECODE 1
ENV FLASK_APP "backend/app.py"
ENV FLASK_ENV "development"
ENV FLASK_DEBUG True

RUN mkdir /app
WORKDIR /app

COPY Pip* /app/

RUN pip install --upgrade pip && \
    pip install pipenv && \
    pipenv install --dev --system --deploy --ignore-pipfile

ADD . /app

EXPOSE 5000

CMD flask run --host=0.0.0.0

Краткий объяснение об этом:

{‘dt’: {‘pre’: ”}}
{‘dd’: [‘То’, {‘code’: ‘ОТ’}, ‘Определите базовое изображение, которое будет использоваться для создания моего изображения. В этом случае я использую базовое изображение’, {‘code’: ‘Python: 3.7.1’}, ‘.’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘То’, {‘code’: ‘МЕТКА’}, ‘- это способ поставить некоторую информацию, как имя автора, электронная почта для контакта и версия DockerFile’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘То’, {‘code’: ‘БЕЖАТЬ’}, ‘отвечает за выполнение команд, в этом случае то’, {‘code’: ‘mkdir/app.’}, ‘которые создают каталог, называемое приложением в корне.’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘То’, {‘code’: ‘Рабочий’}, ‘Определяет рабочий каталог, в этом случае мой’, {‘code’: ‘/приложение’}, ‘создан предыдущий в’, {‘code’: ‘БЕЖАТЬ’}, ‘пункт.’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘То’, {‘code’: ‘Скопировать’}, ‘зависит от копирования файлов с хоста в контейнер, в этом случае с’, {‘code’: ‘*’}, ‘сообщить Docker, чтобы скопировать все файлы начать с’, {‘code’: ‘Пипс’}, ‘к’, {‘code’: ‘/приложение/’}, ‘. Обратите внимание: очень важно доработать путь директора с’, {‘code’: ‘/’}]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘Этот’, {‘code’: ‘БЕЖАТЬ’}, ‘пункт делает модернизацию’, {‘code’: ‘пипс’}, ‘, установить’, {‘code’: ‘пиронв’}, ‘и установите сквозные приложенные зависимости. Для установки колбежных зависимостей использовался’, {‘code’: ‘Установка Pipenv’}, ‘С некоторыми флагами:’]}
{‘dt’: {‘code’: ‘–dev.’}}
{‘dd’: ‘это также указывает на установку зависимостей разработки;’}
{‘dt’: {‘code’: ‘–система’}}
{‘dd’: [‘Это очень важно, потому что в докер контейнер у нас есть изолированная среда, и не нужно создавать виртуальнв, Этот флаг сообщает’, {‘code’: ‘пиронв’}, ‘именно это;’]}
{‘dt’: [{‘code’: ‘–развертывать’}, ‘с’, {‘code’: ‘- свет-Pipfile’}]}
{‘dd’: [‘сообщить’, {‘code’: ‘пиронв’}, ‘использовать’, {‘code’: ‘Pipfile.lock.lock.lock’}, ‘Чтобы установить все зависимости. в’, {‘code’: ‘Pipfile.lock.lock.lock’}, ‘У нас есть все зависимости с вашими версиями заблокирован’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘После установки всех зависимостей с предложением’, {‘code’: ‘ДОБАВЛЯТЬ’}, ‘Добавлены все файлы одного каталога, где находится DockerFile на хосте’, {‘code’: ‘/приложение’}, ‘на контейнере.’]}
{‘dt’: ‘ABS:’}
{‘dd’: [‘В том же каталоге есть файл называется’, {‘code’: ‘.dockerignore.’}, ‘что вроде’, {‘code’: ‘.gitignore.’}, ‘Inform Docker, чтобы игнорировать файлы и каталоги в своем содержании.’]}
{‘dt’: {‘pre’: ”}}
{‘dd’: ‘Этот пункт обнажает порт 5000 контейнера к внешнему миру.’}
{‘dt’: {‘pre’: ”}}
{‘dd’: [‘Окончательно, оговорка’, {‘code’: ‘CMD’}, ‘Выполните команды после сборки и вверх контейнера. В этом случае команда является’, {‘code’: ‘Flask Run.0.0.0.’}, ‘которые выполняют сервер Flask в Host 0.0.0.0 и серверы нашего приложения Flask.’]}
{‘dt’: ‘ABS:’}
{‘dd’: ‘Очевидно, это небольшой тест. Если вам нужно использовать это в производстве, рекомендуется запустить сервер WSGI, как UWSGI или Gunicorn вместо сервера Flask, который используется только в среде разработки.’}

Некоторые слова о использовании Скопировать и Добавить :

Реф.: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Это все, что нам нужно подключить наше приложение для колбы. Теперь нам нужно построить и запустить наш документ докера.

Чтобы построить мы используем эту команду Docker CLI:

docker build -t vm_docker_flask .

Команда Docker Build построит наш образ, с флагом -t Это положил тег vm_docker_flask На нашем образе и, наконец, последняя часть CLI – Отказ (DOT), который сообщает Docker, что DockerFile находится в текущем каталоге.

Эта команда показывает нам этот результат в нашем терминале:

Sending build context to Docker daemon  29.18kB
Step 1/15 : FROM python:3.7.1
 ---> 1e80caffd59e
Step 2/15 : LABEL Author="Vicente Marçal"
 ---> Running in a7975e93672a
Removing intermediate container a7975e93672a
 ---> 448662ef63d8
Step 3/15 : LABEL E-mail="vicente.marcal@gmail.com"
 ---> Running in 75f6319066de
Removing intermediate container 75f6319066de
 ---> 0898192a03f7
Step 4/15 : LABEL version="0.0.1b"
 ---> Running in defb5aee2083
Removing intermediate container defb5aee2083
 ---> 02042247ded0
Step 5/15 : ENV PYTHONDONTWRITEBYTECODE 1
 ---> Running in 5e9124dfa05c
Removing intermediate container 5e9124dfa05c
 ---> c35cd3ecc42f
Step 6/15 : ENV FLASK_APP "backend/app.py"
 ---> Running in ea58e08644ad
Removing intermediate container ea58e08644ad
 ---> f2fb780d29fc
Step 7/15 : ENV FLASK_ENV "development"
 ---> Running in f72976410ba2
Removing intermediate container f72976410ba2
 ---> bb444664e3b0
Step 8/15 : ENV FLASK_DEBUG True
 ---> Running in e18257443538
Removing intermediate container e18257443538
 ---> a2bbca32f540
Step 9/15 : RUN mkdir /app
 ---> Running in ebbcc284fe40
Removing intermediate container ebbcc284fe40
 ---> 7fb8c7fac9f8
Step 10/15 : WORKDIR /app
 ---> Running in c76604d10578
Removing intermediate container c76604d10578
 ---> 074aa15fee4c
Step 11/15 : COPY Pip* /app/
 ---> 554f403d7b11
Step 12/15 : RUN pip install --upgrade pip && pip install pipenv && pipenv install --dev --system --deploy --ignore-pipfile
 ---> Running in 08faec42b7d5
Collecting pip
  Downloading https://files.pythonhosted.org/packages/d8/f3/413bab4ff08e1fc4828dfc59996d721917df8e8583ea85385d51125dceff/pip-19.0.3-py2.py3-none-any.whl (1.4MB)
Installing collected packages: pip
  Found existing installation: pip 18.1
    Uninstalling pip-18.1:
      Successfully uninstalled pip-18.1
Successfully installed pip-19.0.3
Collecting pipenv
  Downloading https://files.pythonhosted.org/packages/13/b4/3ffa55f77161cff9a5220f162670f7c5eb00df52e00939e203f601b0f579/pipenv-2018.11.26-py3-none-any.whl (5.2MB)
Requirement already satisfied: pip>=9.0.1 in /usr/local/lib/python3.7/site-packages (from pipenv) (19.0.3)
Collecting virtualenv-clone>=0.2.5 (from pipenv)
  Downloading https://files.pythonhosted.org/packages/e3/d9/d9c56deb483c4d3289a00b12046e41428be64e8236fa210111a1f57cc42d/virtualenv_clone-0.5.1-py2.py3-none-any.whl
Collecting virtualenv (from pipenv)
  Downloading https://files.pythonhosted.org/packages/33/5d/314c760d4204f64e4a968275182b7751bd5c3249094757b39ba987dcfb5a/virtualenv-16.4.3-py2.py3-none-any.whl (2.0MB)
Collecting certifi (from pipenv)
  Downloading https://files.pythonhosted.org/packages/9f/e0/accfc1b56b57e9750eba272e24c4dddeac86852c2bebd1236674d7887e8a/certifi-2018.11.29-py2.py3-none-any.whl (154kB)
Requirement already satisfied: setuptools>=36.2.1 in /usr/local/lib/python3.7/site-packages (from pipenv) (40.6.2)
Installing collected packages: virtualenv-clone, virtualenv, certifi, pipenv
Successfully installed certifi-2018.11.29 pipenv-2018.11.26 virtualenv-16.4.3 virtualenv-clone-0.5.1
Installing dependencies from Pipfile.lock (9a5a3a)…
Removing intermediate container 08faec42b7d5
 ---> 740ed1329305
Step 13/15 : ADD . /app
 ---> 3551608282e2
Step 14/15 : EXPOSE 5000
 ---> Running in 07b57fe6a5e7
Removing intermediate container 07b57fe6a5e7
 ---> 2e07658bbae8
Step 15/15 : CMD flask run --host=0.0.0.0
 ---> Running in bdf7404770f6
Removing intermediate container bdf7404770f6
 ---> cf7d3ee68072
Successfully built cf7d3ee68072
Successfully tagged vm_docker_flask:latest

После этого нам нужно запустить наш контейнер. Последующее команду Docker CLI делает магию:

 docker run -d --name my_container_flask -p 5000:5000 vm_docker_flask

Команда Docker Run Запускает наш контейнер, флаг -d сообщить Docker, который работает в фоновом режиме, флаг --name поставить my_container_flask в наш контейнер, флаг Свяжите порт 5000 контейнера к порту 5000 хоста и, в конце, это название нашего изображения, встроенного в Docker Build команда.

Эта команда показывает нам этот результат в нашем терминале (или аналогично, потому что эта команда возвращает идентификатор контейнера):

33169f573b7bdf078ef8d55741ec037f2914aa78343ad96c8277854c3bcdf6b2

Теперь мы можем сделать наш первый тест, посмотреть, работает ли наш контейнер, для этого мы выполняем команду Docker CLI так:

pythonprojects/docker_flask_app [ docker container ps        ] 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
880a5b59f2aa        vm_docker_flask     "/bin/sh -c 'flask r…"   15 minutes ago      Up 15 minutes       0.0.0.0:5000->5000/tcp   my_container_flask

Эта команда Docker CLI показывает нам, если наши контейнеры работают и их информация, как идентификатор контейнера, изображение, команда и так далее. В нашем случае только my_container_flask Как вы можете увидеть выше.

Еще один тест, который мы можем сделать, это простой HTTP-запрос. Я использую httpie-приложение В этом тесте. Смотрите результат терминала:

pythonprojects/docker_flask_app [ http 0.0.0.0:5000         ]
HTTP/1.0 200 OK
Content-Length: 11
Content-Type: text/html; charset=utf-8
Date: Tue, 05 Mar 2019 18:17:24 GMT
Server: Werkzeug/0.14.1 Python/3.7.1

Hello World

Теперь самый важный тест. Мы выполняем Pтойцу в наш контейнер, чтобы запустить тесты против нашей колбы. Тест просто прост только утверждение, если код состояния, возвращаемый приложением Flask, это 200 ОК!

Для этого мы выполняем команду Follow Docker CLI:

 docker exec my_container_flask pytest 

Эта команда Docker CLI работает в Pteest против my_container_flask, и если все в порядке, у нас есть этот клеммный результат:

=========================== test session starts ============================
platform linux -- Python 3.7.1, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
rootdir: /app, inifile: pytest.ini
plugins: sugar-0.9.2, flask-0.14.0
collected 1 item

backend/blueprints/core/tests/test_bp_core.py .                      [100%]

========================= 1 passed in 0.06 seconds =========================

Это все люди !!

Оригинал: “https://dev.to/riverfount/dockerize-a-flask-app-17ag”