Это машинный перевод текста, который может содержать ошибки!
Создание образа с помощью Dockerfile
Здесь вы создаете образ из приложения на базе Flask и тестируете его с помощью docker run. Работа считается завершенной, когда приложение отвечает и вы убедились в том, что локальный файл .env не включен в новый образ. Для тестового приложения не требуются ни GitHub, ни внешний API.
Перед сборкой
Вам необходимо создать образ и убедиться, что контейнер из этого образа отвечает на запросы. Для этого требуется установленный Docker (см. раздел «Уровень 1 — Начало работы») и умение запускать и проверять контейнер, как показано в разделе «Запуск и проверка контейнера». Если у вас нет приложения на Flask, используйте тестовое приложение ниже. Работайте в каталоге проекта на виртуальной машине Linux, где находятся файлы app.py, а также любые шаблоны и другие проектные файлы.
Если проект находится в репозитории кода, то в разделе «Git в терминале: Уровень 1 — Клонирование, коммит и публикация» описано, как клонировать его на ВМ. Вы также можете создавать файлы с помощью текстового редактора на ВМ. Используйте команды pwd и ls, чтобы проверить, что вы находитесь в правильном каталоге. Не выполняйте сборку из пустой папки или из оболочки хоста Proxmox.
Сначала попробуйте с небольшим тестовым приложением
Если вы еще не перенесли свое приложение в ВМ, можете попрактиковаться с Dockerfile на минимальном приложении. Создайте папку командой mkdir min-app и перейдите в нее командой cd min-app, затем создайте файл app.py через nano:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Привет из контейнера!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Затем создайте файлы requirements.txt и Dockerfile так, как показано ниже. Когда сборка заработает, сделайте то же самое со своим собственным приложением.
Создайте файл requirements.txt в той же папке. В нем перечисляются пакеты Python, которые должны быть установлены в образе. Для простого приложения из раздела «Flask 1», использующего только Flask, содержимое следующее:
Flask
Если приложение использует сторонние библиотеки, они также должны быть перечислены с правильными именами пакетов, например requests. Файлы из .venv не копируются для установки пакетов; Docker устанавливает их заново на основе этого списка. Версии можно зафиксировать, например, используя имя_пакета==версия, если вы проверили, какие версии используются приложением.
Также создайте файл .dockerignore перед первой сборкой. Он предотвращает копирование локальных секретных данных, истории Git и локального окружения Python в образ:
.env
.git
__pycache__/
.venv/
app-data/
Также добавьте .env в .gitignore, если вы используете Git. Если файлы игнорирования уже содержат содержимое, добавляйте отсутствующие правила вместо замены файлов. Используйте [[Git in Terminal Level 5 - gitignore и секреты|.gitignore и секреты]], чтобы проверить отслеживание перед тем, как делиться кодом.
Создание образа с помощью Dockerfile
Команда docker build собирает пакет. Команда docker run создаёт и запускает контейнер на основе пакета. Сам процесс сборки не запускает приложение. См. раздел [[Docker Уровень 0 — Что такое Docker|Уровень 0]], если вам нужно снова различать образы и контейнеры.
Dockerfile описывает шаги, которые Docker использует для создания образа. Каждая строка выполняет определённое действие:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
Docker выполняет сборку поэтапно. Команды COPY и RUN могут добавлять слои файловой системы, в то время как, например, CMD описывает способ запуска контейнера. Docker может повторно использовать результаты предыдущих сборок из кэша сборки. Если этап необходимо пересобрать, последующие этапы также должны быть выполнены заново.
Поэтому мы копируем только requirements.txt, прежде чем выполнить COPY . .: длительная установка выполняется до копирования исходного кода, который часто изменяется:
flowchart TB
L1["Базовый образ: python:3.12-slim"] --> L2["Рабочая директория: /app"]
L2 --> L3["Копирование requirements.txt"]
L3 --> L4["Установка пакетов с помощью pip"]
L4 --> L5["Копирование исходного кода"] COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
Если файл requirements.txt изменяется, Docker должен повторно установить пакеты. Это желательное поведение: новый пакет действительно должен попасть в образ. Если меняется только исходный код, Docker может использовать готовый слой установки и продолжить сборку с команды COPY . ..
Когда Docker публикуют порт, он перенаправляет трафик на программу внутри контейнера. Поэтому программа должна слушать сетевой интерфейс контейнера, а не только адрес 127.0.0.1, который означает «этот контейнер». Если программа слушает только адрес 127.0.0.1, другие машины не смогут получить к ней доступ через опубликованный порт Docker.
Пример с Flask
При запуске в контейнере Flask должен слушать все сетевые интерфейсы (0.0.0.0). Это означает, что Flask принимает запросы на всех сетевых картах внутри контейнера. Замените существующий блок запуска в файле app.py следующим кодом:
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False)
Это учебная конфигурация с использованием сервера разработки Flask. Перед использованием решения в производственной среде его необходимо запускать на подходящем WSGI-сервере; см. Flask: настройка для продакшена.
Команда EXPOSE 5000 описывает порт, который использует приложение; она сама по себе не публикует этот порт. Публикацию порта выполняет параметр -p 127.0.0.1:5000:5000 в команде ниже. Сборка и запуск:
docker build -t min-app:latest .
docker run -d --name min-app -p 127.0.0.1:5000:5000 min-app:latest
docker logs -f min-app
Нажмите Ctrl+C, чтобы завершить просмотр журнала. Контейнер продолжает работать.
Тест из самой ВМ:
curl http://127.0.0.1:5000
Вы получите содержимое из основного маршрута приложения. В выражении -p 127.0.0.1:5000:5000 запись 127.0.0.1:5000 означает порт 5000 на сервере, но только для программ, работающих непосредственно на этом сервере. Последнее число указывает на порт внутри контейнера. Если это не работает, сначала проверьте результат команды docker ps, логи и корректность публикации порта.
При использовании префикса 127.0.0.1 порт закрыт от внешнего сетевого доступа, поэтому другие машины не могут получить доступ к приложению во время его разработки и тестирования. Это безопасная практика по умолчанию для приложений в стадии разработки. Без указания 127.0.0.1 (то есть с параметром -p 5000:5000) порт будет слушать все сетевые интерфейсы сервера. Такая конфигурация требуется лишь тогда, когда другой компьютер или прокси-сервер должен иметь возможность обратиться к приложению, что рассматривается в разделе Уровень 3.
Контрольная точка: Собственный образ работает
Команда curl http://127.0.0.1:5000 должна отображать главную страницу приложения. Для тестового приложения ответ будет Hei fra containeren!. Объясните, что создала команда docker build и какой процесс запустила команда docker run. При возникновении ошибок сначала прочитайте журнал перед переходом к следующему шагу.
Убедитесь, что .env находится вне контейнера
Вам не нужен реальный ключ для проверки этого. Если в проекте ещё нет файла .env, вы можете создать его с помощью PIGGY_TEST=безопасное_тестовое_значение. Сохраните существующий файл; не перезаписывайте свои значения.
- Убедитесь, что
.envуказан как исключение и в.dockerignore, и в.gitignore. - Если вы используете Git, выполните проверки из упражнения [[Git в терминале Уровень 5 - gitignore и секреты|упражнения по .gitignore]]. Игнорируемый файл также не должен отслеживаться ранее.
- Пересоберите образ и проверьте этот путь к файлу без вывода содержимого:
docker build -t min-app:latest .
docker run --rm --entrypoint sh min-app:latest -c 'test ! -e /app/.env && echo ".env отсутствует в /app"'
Ожидаемый результат — «файл .env отсутствует в /app». Если сообщение не появляется, проверьте файл игнорирования перед публикацией образа. Это проверяет путь к файлу в итоговой файловой системе нового образа. Это не обновляет старые образы, другие файлы с секретами или значения, указанные непосредственно в коде или Dockerfile. Сначала замените настоящий ключ, если предыдущий был раскрыт.
Если сборка или приложение не работают
При ошибке ModuleNotFoundError проверьте файл requirements.txt и выполните повторную сборку. При ошибках загрузки базового образа или пакетов Python протестируйте сеть с помощью метода [[Feilsokingsmetode Level 1 - Systematisk feilsøking|Метод устранения неполадок]]. В случае отсутствия ответа по HTTP прочитайте вывод команды docker logs min-app и проверьте адрес Flask и привязку портов.
Следующие шаги
Покажите ответ приложения и проверьте .env. Объясните, что описывает Dockerfile, что создаётся при сборке и что запускает docker run. Продолжите с Docker — Публикация приложения. Если вы хотите описать запуск и обновление в файле Compose, то Запуск и обновление приложения с помощью Compose является необязательным углублённым материалом.
Compose и обновления теперь находятся на странице Запуск и обновление приложения с помощью Compose.
Хранение данных объясняется на странице Сохранение данных вне контейнера; применение Compose находится на странице Запуск и обновление приложения с помощью Compose.
Инструкция по API теперь находится на странице Переменная окружения и ключ API и является необязательной.