Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка веб-приложений с использованием фреймворка Flask. В 2 частях. Ч.2. Учебное пособие-1.pdf
Скачиваний:
2
Добавлен:
06.09.2026
Размер:
421 Кб
Скачать
☆

'message': 'pong!'

})

1.2. ИСПОЛЬЗОВАНИЕ КОНТЕЙНЕРОВ DOCKER

Для начала необходимо убедиться, что в окружении установлены пакеты

Docker, Docker Compose и Docker Machine:

$ docker -v

Docker version 17.12.0-ce, build c97c6d6 $ docker-compose -v

docker-compose version 1.18.0, build 8dd22a9 $ docker-machine -v

docker-machine version 0.13.0, build 9ba6da9

Перейдём к задаче создания нового хоста Docker с помощью Docker

Machine и связыванию его с клиентом Docker:

$ docker-machine create -d virtualbox testdriven-dev $ docker-machine env testdriven-dev

$ eval "$(docker-machine env testdriven-dev)"

Добавим файл Dockerfile-dev следующего содержания в каталог users:

FROM python:3.6.4

# определение рабочего каталога

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

# добавление файла с требованиями

COPY ./requirements.txt /usr/src/app/requirements.txt

# установка зависимостей

RUN pip install -r requirements.txt

# добавление приложения

COPY . /usr/src/app

# запуск сервера

CMD python manage.py run -h 0.0.0.0

Также добавим файл .dockerignore в каталог users:

env

.dockerignore Dockerfile-dev Dockerfile-prod

7

Как и файл. gitignore, файл .dockerignore позволяет исключить определён-

ные файлы и каталоги из списка копируемых объектов в образ. Затем добавим в корень файл docker-compose-dev.yml со следующим содержимым:

version: '3.4'

services:

users:

container_name: users build:

context: ./services/users dockerfile: Dockerfile-dev

volumes:

-'./services/users:/usr/src/app'

ports:

-5001:5000

environment:

-FLASK_APP=project/__init__.py

-FLASK_DEBUG=1

Эта конфигурация служит для создания контейнера с именем users из файла Dockerfile. Том volume используется для монтирования кода в контейнер.

Это необходимо для среды разработки, чтобы контейнер обновлялся при каж-

дом изменении исходного кода. Без этого пришлось бы пересобирать образ по-

сле каждого изменения, внесённого в исходный код.

Обратите внимание на используемую версию файла сборки Docker – 3.4.

Имейте в виду, что это не связано напрямую с установленной версией Docker Compose – версия определяет формат файла, который мы используем.

Создадим образ:

$ docker-compose -f docker-compose-dev.yml build

При первом запуске процесс займёт несколько минут. Последующие сборки будут выполнять намного быстрее, поскольку Docker кеширует резуль-

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

$ docker-compose -f docker-compose-dev.yml up -d

Флаг -d используется для запуска контейнеров в фоновом режиме.

Для получения IP-адреса, связанного с контейнером, выполним следую-

щую команду:

docker-machine ip testdriven-dev

Перейдём по адресу http://DOCKER_MACHINE_IP:5001/users/ping. Мы убедимся, что видим тот же JSON-ответ, что и раньше. Затем добавим пере-

8

менную среды в файл docker-compose-dev.yml, чтобы загрузить конфигурацию

приложения для среды разработки:

version: '3.4'

services:

users: container_name: users build:

context: ./services/users dockerfile: Dockerfile-dev

volumes:

-'./services/users:/usr/src/app'

ports:

-5001:5000

environment:

-FLASK_APP=project/__init__.py

-FLASK_DEBUG=1

-APP_SETTINGS=project.config.DevelopmentConfig

Затем обновим файл project/__init__.py, чтобы получить переменные среды:

#services/users/project/__init__.py

#инстанционирование приложения

app = Flask(__name__)

# подключение конфигурации

app_settings = os.getenv('APP_SETTINGS') app.config.from_object(app_settings)

@app.route('/users/ping', methods=['GET']) def ping_pong():

return jsonify({ 'status': 'success', 'message': 'pong!' })

Обновим контейнер:

$ docker-compose -f docker-compose-dev.yml up -d

Чтобы убедиться в том, что загружена правильная конфигурация, необ-

ходимо добавить оператор print в файл __init__.py перед обработчиком мар-

шрута:

import sys

9

print(app.config, file=sys.stderr)

После этого просмотрим записи в журнале:

$ docker-compose -f docker-compose-dev.yml logs

Мы должны увидеть результат похожий на следующий вывод:

<Config {

'DEBUG': True, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'USE_X_SENDFILE': False, 'LOGGER_NAME': 'project', 'LOGGER_HANDLER_POLICY': 'always', 'SERVER_NAME': None, 'APPLICATION_ROOT': None, 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': False, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': True, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None}

>

Обязательно удалите оператор print перед тем, как продолжить разработ-

ку приложения дальше.

1.3. НАСТРОЙКА СУБД POSTGRESQL

Перейдём к настройке сервиса PostgreSQL. Запустим его, развернём в контейнере и свяжем с контейнером users. Добавим пакеты Flask-SQLAlchemy

и psycopg2 в файл requirements.txt:

Flask-SQLAlchemy==2.3.2

psycopg2==2.7.3.2

Обновим файл config.py:

# services/users/project/config.py import os

class BaseConfig:

"""Базовая конфигурация"""

TESTING = False SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(BaseConfig):

10

"""Конфигурация для разработки"""

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')

class TestingConfig(BaseConfig):

"""Конфигурация для тестирования"""

TESTING = True

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_TEST_URL')

class ProductionConfig(BaseConfig):

"""Конфигурация для производственной среды"""

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')

Обновим файл __init__.py, чтобы создать новый экземпляр SQLAlchemy и

определим модель базы данных:

# services/users/project/__init__.py import os

import datetime

from flask import Flask, jsonify

from flask_sqlalchemy import SQLAlchemy

# инстанционирование приложения app = Flask(__name__)

# подключение конфигурации

app_settings = os.getenv('APP_SETTINGS') app.config.from_object(app_settings)

# инстанционирование базы данных db = SQLAlchemy(app)

# модель

class User(db.Model): __tablename__ = "users"

id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(128), nullable=False)

email = db.Column(db.String(128), nullable=False)

active = db.Column(db.Boolean(), default=True, nullable=False)

def __init__(self, username, email): self.username = username self.email = email

# маршруты

@app.route('/users/ping', methods=['GET']) def ping_pong():

11

return jsonify({

'status': 'success',

'message': 'pong!'

})

Добавим каталог db в структуру project и добавим файл create.sql в этот новый каталог:

CREATE DATABASE users_prod;

CREATE DATABASE users_dev;

CREATE DATABASE users_test;

Затем добавим файл Dockerfile в тот же каталог:

FROM postgres

# запуск скрипта create.sql при инициализации

ADD create.sql /docker-entrypoint-initdb.d

Мы расширяем официальный образ PostgreSQL, добавляя файл формата

SQL в каталог docker-entrypoint-initdb.d контейнера, который будет выполнять-

ся при инициализации.

Обновим содержимое файла docker-compose.yml-dev:

version: '3.4' services:

users: container_name: users build:

сontext: ./services/users dockerfile: Dockerfile-dev

volumes:

- './services/users:/usr/src/app' ports:

-5001:5000

environment:

-FLASK_APP=project/__init__.py

-FLASK_DEBUG=1

-APP_SETTINGS=project.config.DevelopmentConfig

-DATABASE_URL=postgres://postgres:postgres@usersdb:5432/users_dev

-DATABASE_TEST_URL=postgres://postgres:postgres@usersdb:5432/users_test

depends_on:

-users-db

links:

- users-db

12

users-db:

container_name: users-db build:

context: ./services/users/project/db dockerfile: Dockerfile

ports:

-5435:5432

environment:

-POSTGRES_USER=postgres

-POSTGRES_PASSWORD=postgres

После запуска СУБД PostgreSQL будет доступна на порту 5435 на хост-

машине и на порту 5432 для служб, работающих в других контейнерах. По-

скольку служба users зависит не только от того, что контейнер запущен и вы-

полняется, но и от того, что фактический экземпляр PostgreSQL также запущен и выполняется, добавим файл-скрипт entrypoint.sh в контейнер users:

#!/bin/sh

echo "Waiting for postgres..." while ! nc -z users-db 5432;

do sleep 0.1 done

echo "PostgreSQL started"

python manage.py run -h 0.0.0.0

Обновим файл Dockerfile-dev:

FROM python:3.6.4

# установка зависимостей среды

RUN apt-get update -yqq \

&&apt-get install -yqq --no-install-recommends \ netcat \

&&apt-get -q clean

# определение рабочего каталога

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

# добавление файла с требованиями

COPY ./requirements.txt /usr/src/app/requirements.txt

13

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]