Контейнеризация - абстракция вокруг группы процессов, позволяющая их изолировать и предоставляющая виртуализацию на уровне операционной системы. В отличии от полной виртуализации операционной системы, контейнеризация не загружают все ядро ОС целиком, а лишь использует механизмы ядра Linux - в частности для этого используются две фичи Linux: контрольные группы (cgroups) и пространства имен (namespaces)
Пространства имен - набор инструментов (функции ядра) для контроля того, что видит отдельный процесс и какие действия может выполнять как процесс, так и пользователь внутри пространства имен
Раньше процесс можно было ограничивать только по процессорному времени. С появлением контрольных групп стало возможным ограничивать использование ресурсов сетевых, памяти и так далее. Контрольные группы включают в себя контроллеры для учета и управления ресурсами
Самая популярная утилита для управления контейнерами - Docker.
Docker, помимо реализации пространства имен и контрольных групп, включает в себя управление образами, CLI для работы с контейнером и прочее
Образ (Image) - это по сути архив с предустановленными заранее программами и библиотеками для работы приложения.
Образ может определяться специальным файлом с названием Dockerfile
, например:
# Делаем форк на основе готового образа с установленным Python
FROM python:3.12
WORKDIR /usr/local/app
# Устанавливаем зависимости приложения
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Копируем исходники
COPY src ./src
EXPOSE 5000
# Создает нового пользователя, чтобы не запускать приложение от лица root
RUN useradd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
Каждая строчка в файле Dockerfile
называется слоем (layer). Чтобы собрать из Dockerfile
полноценный образ, воспользуемся командой
docker build -t my-python-app .
В Docker Desktop можно посмотреть на слои образа:
Также можно посмотреть публичные образы в Docker Hub.
Собранный образ теперь можно запустить в контейнере.
В файле docker-compose.yml
можно указать конфигурацию контейнера
# Версия параметров Compose
version: "2"
services:
postgres:
# Имя образа (в данном случае с готовым PostgreSQL 14)
image: postgres:14
# Имя контейнера
container_name: postgres_db
# Переназначение портов между контейнером и хостом
ports:
- "5432:5432"
# Привязка файловой системы контейнера с файловой системой хоста
volumes:
- ./scripts:/docker-entrypoint-initdb.d
- ./pgdata:/var/lib/postgresql/data
# Переменные среды: имя, пароль и название БД в PostgreSQL
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypass
POSTGRES_DB: mydb
Чтобы запустить контейнер, воспользуемся командой
docker compose up
в каталоге с docker-compose.yml
. Флаг -d
запустит контейнер в фоновом режиме. Команда
docker compose down
прервет выполнение в контейнере, а команда
docker compose stop
остановит контейнер с возможностью возобновления. При помощи
docker ps
можно посмотреть все запущенные контейнеры.
В примере выше мы связали локальную папку ./scripts
с /docker-entrypoint-initdb.d
. При запуске PostgreSQL выполнит все .sql
и .sh
-скрипты, находящиеся в ней, таким образом, можно задать начальную схему базы данных