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

Управление пакетами apt и запуск Python HTTP-сервиса в venv

Содержание курса

2. Изолированное виртуальное окружение venv

Если устанавливать библиотеки Python прямо в систему, со временем разные проекты начнут требовать конфликтующие версии одних и тех же файлов. Чтобы этого избежать, каждый проект запускают в изолированном виртуальном окружении — venv. Это отдельный каталог, куда копируется интерпретатор и куда устанавливаются только нужные текущему приложению зависимости.

Сначала создадим рабочую директорию проекта в домашнем каталоге и перейдём в неё:

mkdir ~/devops-demo
cd ~/devops-demo

Символ ~ обозначает домашний каталог текущего пользователя, поэтому путь указывает на /home/student/devops-demo независимо от того, где именно вы находились в терминале.

Теперь создадим внутри окружение с именем .venv:

python3 -m venv .venv

Флаг -m указывает Python выполнить стандартный модуль venv как программу, а аргумент .venv задаёт имя каталога. Точка в начале делает каталог скрытым для обычного вывода ls.

Проверим, что внутри каталога появились свои исполняемые файлы:

ls -l .venv/bin

В списке будет находиться отдельный исполняемый файл python. Чтобы использовать именно его, не нужно менять настройки оболочки — достаточно запустить его по точному относительному пути .venv/bin/python.

Создадим файл приложения app.py в редакторе nano:

nano app.py

Вставьте в него предоставленный готовый код сервиса:

import argparse
import json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/health":
            status, payload = 200, {"status": "ok"}
        elif self.path == "/":
            status, payload = 200, {"service": "devops-demo", "version": "v1"}
        else:
            status, payload = 404, {"error": "not found"}
        body = json.dumps(payload).encode()
        self.send_response(status)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        if self.command != "HEAD":
            self.wfile.write(body)

    def do_HEAD(self):
        self.do_GET()


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--host", default="127.0.0.1")
    parser.add_argument("--port", type=int, default=8000)
    args = parser.parse_args()
    server = ThreadingHTTPServer((args.host, args.port), Handler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass
    finally:
        server.server_close()

Сохраните файл комбинацией Ctrl+O, подтвердите имя клавишей Enter и выйдите через Ctrl+X.

Для запуска скрипта передадим его путь изолированному интерпретатору:

.venv/bin/python app.py

Такой вызов гарантирует, что программа запускается именно внутри подготовленного окружения .venv, не затрагивая системные пакеты операционной системы.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

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

Проверка решения остаётся отдельным действием.