Belov Solutions

Традиционное приветствие миру: Создание простого веб-сервера

Введение в традиционное приветствие

Приветствие «Hello World!» — это первый шаг для многих разработчиков, изучающих программирование или веб-разработку. Эта простая фраза стала символом начала пути в создании приложений. В этой статье мы подробно разберем, как создать веб-сервер, возвращающий «Hello World!», используя Python, фреймворк Flask и технологию контейнеризации Docker. Мы начнем с базовой настройки, а затем улучшим проект для разработки и эксплуатации, добавив продвинутые инструменты, такие как uWSGI и скрипты управления. Это руководство подходит как для новичков, так и для опытных разработчиков, желающих углубить свои знания.

Подготовка проекта

Для начала создадим новый каталог identidock, который будет служить корневой директорией нашего проекта. Внутри него создадим подкаталог app для хранения исходного кода на Python. В подкаталоге app создадим файл identidock.py. Структура проекта будет выглядеть следующим образом:

$ tree identidock/
identidock/
├── app
│   └── identidock.py
1 directory, 1 file

Создание базового веб-сервера

Откроем файл identidock.py и добавим следующий код, который создает минимальный веб-сервер на Flask:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

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

Этот код импортирует Flask, создает экземпляр приложения и определяет маршрут /, возвращающий «Hello World!». Метод app.run() запускает сервер на порту 5000, а параметр host='0.0.0.0' позволяет обращаться к серверу из вне контейнера. Это базовая реализация, которую мы позже улучшим.

Настройка Docker для запуска

Для контейнеризации используем Docker, который позволяет запускать приложение в изолированной среде. Создадим файл Dockerfile в корневом каталоге identidock со следующим содержимым:

FROM python:3.4
WORKDIR /app
COPY app /app
CMD ["python", "identidock.py"]

Инструкция FROM python:3.4 указывает базовый образ Python версии 3.4. WORKDIR задает рабочую директорию, COPY копирует наш код, а CMD запускает сервер. Построим и запустим образ:

$ cd identidock
$ docker build -t identidock .
...
$ docker run -d -p 5000:5000 identidock
0c75444e8f5f16dfe5aceb0aae074cc33dfc06f2d2fb6adb773ac51f20605aa4

Флаг -d запускает контейнер в фоновом режиме, а -p 5000:5000 перенаправляет порт 5000 контейнера на порт 5000 хоста. Проверим работу сервера:

$ curl localhost:5000
Hello World!

Если вы используете Docker Machine (например, на macOS или Windows через Docker Toolbox), замените localhost на IP-адрес виртуальной машины, полученный командой $(docker-machine ip default):5000.

Улучшение рабочего процесса с монтированием

Текущая настройка требует пересоздания образа при каждом изменении кода, что неудобно для разработки. Для упрощения процесса смонтируем каталог хоста в контейнер с помощью bind mount. Остановим и удалим предыдущий контейнер, затем запустим новый:

$ docker stop $(docker ps -lq)
$ docker rm $(docker ps -lq)
$ docker run -d -p 5000:5000 -v "$(pwd)"/app:/app identidock

Аргумент -v "$(pwd)"/app:/app монтирует подкаталог app хоста в /app контейнера, заменяя его содержимое. Теперь изменения в коде сразу отражаются. Например, заменим «World» на «Docker»:

$ sed -i '' s/World/Docker/ app/identidock.py
$ curl localhost:5000
Hello Docker!

Если sed недоступен, отредактируйте файл в текстовом редакторе, заменив «World» на «Docker». Это значительно ускоряет разработку, устраняя необходимость повторной сборки.

Переход к продвинутому серверу uWSGI

Flask-сервер по умолчанию подходит только для разработки, так как он не оптимизирован и небезопасен для эксплуатации. Перейдем к uWSGI — серверу приложений, готовому к производственной среде. Обновим Dockerfile:

FROM python:3.4
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app
EXPOSE 9090 9191
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
USER uwsgi
CMD ["uwsgi", "--http", "0.0.0.0:9090", "--wsgi-file", "/app/identidock.py", "--callable", "app", "--stats", "0.0.0.0:9191"]

Здесь добавлены uWSGI и Flask, определены порты 9090 (HTTP) и 9191 (статистика), создан пользователь uwsgi для безопасности. Построим и запустим образ:

$ docker build -t identidock .
...
$ docker run -d -p 9090:9090 -p 9191:9191 identidock
$ curl localhost:9090
Hello Docker!

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

Гибкость с помощью скрипта управления

Для объединения сред разработки и эксплуатации добавим скрипт cmd.sh в корневой каталог identidock:

#!/bin/bash
set -e
if [ "$ENV" = 'DEV' ]; then
    echo "Running Development Server"
    exec python "identidock.py"
else
    echo "Running Production Server"
    exec uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191

Этот скрипт переключает режим в зависимости от переменной окружения ENV. Обновим Dockerfile для использования скрипта:

FROM python:3.4
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app
COPY cmd.sh /
EXPOSE 9090 9191
RUN chmod +x /cmd.sh
USER uwsgi
CMD ["/cmd.sh"]

Сделайте скрипт исполняемым и протестируйте:

$ chmod +x cmd.sh
$ docker build -t identidock .
...
$ docker run -e "ENV=DEV" -p 5000:5000 identidock
Running Development Server
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Без -e "ENV=DEV" запустится uWSGI. Это позволяет использовать один образ для разных сценариев.

Дополнительные оптимизации и безопасность

Для повышения безопасности добавим файл requirements.txt с зависимостями:

Flask==0.10.1
uWSGI==2.0.8

Обновим Dockerfile, заменив RUN pip install на:

COPY requirements.txt .
RUN pip install -r requirements.txt

Это улучшает читаемость и управление зависимостями. Также можно добавить файл конфигурации uWSGI (uwsgi.ini):

[uwsgi]
http = 0.0.0.0:9090
wsgi-file = /app/identidock.py
callable = app
stats = 0.0.0.0:9191

Обновите CMD в Dockerfile на CMD ["uwsgi", "--ini", "/uwsgi.ini"] и скопируйте файл в контейнер с COPY uwsgi.ini /.

Мониторинг и отладка

Для мониторинга состояния uWSGI используйте порт 9191. Пример запроса:

$ curl localhost:9191

Это вернет JSON с статистикой сервера. Для отладки добавьте в identidock.py логирование:

import logging
logging.basicConfig(level=logging.DEBUG)
app.logger.debug('Server started')

Просмотрите логи с docker logs для диагностики проблем.

Заключение

Мы создали веб-сервер с «Hello World!», адаптировали его для разработки и эксплуатации с помощью Docker, Flask и uWSGI, добавили скрипты и оптимизации. Этот подход демонстрирует основы контейнеризации и веб-разработки.

Отзывы

Оставить отзыв

Ваша эл. почта не будет опубликована