
Docker-контейнер: как создавать образы и развёртывать приложения
Есть проект? Напишите нам
Обсудим задачу и подберём оборудование
Docker помогает упаковать приложение вместе с библиотеками, настройками среды и системными зависимостями, а затем запустить ту же сборку на другом компьютере или сервере. Вместо ручной установки Python, PostgreSQL, CUDA и десятка пакетов сервер получает заранее подготовленный образ.
В этом гайде пройдём всю цепочку: напишем Dockerfile, соберём Docker-образ, запустим Docker-контейнер, подключим постоянное хранилище, объединим несколько сервисов через Docker Compose и развернём приложение на сервере. Отдельно разберём GPU в Docker: NVIDIA Container Toolkit, CUDA-образы и несколько изолированных ИИ-окружений на одном GPU-сервере.
Что такое Docker и зачем он нужен
Представим Python-приложение, которому нужны определённая версия интерпретатора, библиотеки из requirements.txt, системные пакеты и PostgreSQL. На компьютере разработчика всё работает. На сервере установлена другая версия Python, одной библиотеки нет, а другая обновилась и сломала совместимость.
Docker переносит окружение вместе с приложением. Разработчик описывает его в Dockerfile, собирает образ и запускает из него один или несколько контейнеров. Такой подход упрощает перенос между рабочей машиной, тестовым стендом и продакшеном.
- Одинаковая среда разработки, тестирования и продакшена;
- Быстрый запуск приложения на новом сервере;
- Изоляция разных версий библиотек и системных пакетов;
- Микросервисная архитектура и CI/CD;
- Локальный запуск баз данных и вспомогательных сервисов;
- ИИ-разработка с разными версиями CUDA, PyTorch или TensorFlow.
Изоляция окружений не означает, что каждый контейнер получает собственную полноценную операционную систему. Linux-контейнеры используют ядро среды, в которой работает Docker Engine. При нативной установке в Linux это обычно ядро хоста, а Docker Desktop в Windows и macOS запускает Linux-контейнеры внутри служебной виртуальной машины.
Docker и виртуальная машина: в чём разница
Виртуализация и контейнеризация решают похожую задачу — отделяют приложения друг от друга, — но делают это на разных уровнях.
| Параметр | Docker-контейнер | Виртуальная машина |
|---|---|---|
| ОС | Использует ядро среды Docker Engine | Имеет отдельную гостевую ОС |
| Запуск | Обычно быстрый | Требуется загрузка гостевой ОС |
| Накладные расходы | Относительно небольшие | Выше из-за виртуального оборудования и ОС |
| Типичный сценарий | Приложения, сервисы, CI/CD | Отдельные ОС, жёсткая изоляция, legacy-системы |
Виртуальная машина остаётся полезной, когда нужна отдельная ОС или более жёсткая граница между средами. Docker удобнее, когда требуется быстро переносить и масштабировать приложения. Эти подходы не исключают друг друга: Docker часто работает внутри виртуальной машины в облаке или на VDS.
Ключевые понятия: образ, контейнер, Dockerfile, реестр
У Docker несколько сущностей, которые начинающие пользователи часто смешивают.
- Dockerfile — текстовый файл с инструкциями сборки.
- Docker-образ — готовый шаблон файловой системы и параметров запуска.
- Docker-контейнер — запущенный экземпляр образа.
- Registry — серверное хранилище образов, например Docker Hub.
Вся цепочка выглядит так: исходный код и Dockerfile передаются команде docker build, после чего появляется Docker-образ. Его можно сохранить в registry через docker push, получить на сервере через docker pull и затем запустить как контейнер.
Чем образ отличается от контейнера
Образ сам по себе не является работающим приложением. Это неизменяемый шаблон, из которого Docker создаёт экземпляры. Если есть образ myapp:1.0, из него можно запустить несколько независимых контейнеров с разными именами, портами и переменными окружения.
Во время работы контейнер получает собственный записываемый слой. Критичные постоянные данные лучше не хранить только там. При удалении контейнера этот слой исчезнет, поэтому базы данных, пользовательские файлы и другие постоянные данные выносят в volumes или внешнее хранилище.
Docker Hub и другие реестры образов
Registry нужен, чтобы хранить образы вне локального компьютера. После сборки docker build -t myapp:1.0 . можно создать тег для репозитория командой docker tag myapp:1.0 username/myapp:1.0, а затем отправить образ через docker push username/myapp:1.0. На сервере тот же Docker-образ получают командой docker pull username/myapp:1.0.
Docker Hub подходит для публичных проектов и частных репозиториев. В корпоративной инфраструктуре часто используют приватный реестр образов. Версии лучше фиксировать тегами вроде app:1.0, app:1.1 или app:2026-09-01. Тег latest не гарантирует, что на сервере находится именно та версия, которую ожидает команда.
Как Docker связывает client, daemon и registry
Когда выполняется docker run nginx, команда docker выступает клиентом и обращается к Docker daemon. Daemon управляет локальными образами, контейнерами, сетями и томами. Если образа nginx на машине нет, daemon скачивает его из registry, после чего создаёт контейнер.
Docker daemon обладает широкими правами на хосте. Поэтому доступ к Docker API и сокету /var/run/docker.sock нельзя без необходимости передавать приложениям или неизвестным контейнерам.
Как создать Docker-образ: пошагово
Для практического примера возьмём небольшое Python-приложение. В каталоге проекта будут app.py, requirements.txt, Dockerfile, .dockerignore и compose.yaml. Предположим, приложение слушает порт 8000 и запускается через Gunicorn.
Структура Dockerfile (FROM, COPY, RUN, CMD/ENTRYPOINT)
Простой Dockerfile можно разобрать по основным инструкциям:
| Инструкция | Пример | Что делает |
|---|---|---|
| FROM | python:3.13-slim | Задаёт базовый образ |
| WORKDIR | /app | Выбирает рабочий каталог внутри образа |
| COPY | requirements.txt . | Копирует файл зависимостей |
| RUN | pip install --no-cache-dir -r requirements.txt | Устанавливает зависимости во время сборки |
| COPY | . . | Копирует исходный код проекта |
| CMD | gunicorn --bind 0.0.0.0:8000 app:app | Задаёт команду запуска по умолчанию |
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Инструкция EXPOSE 8000 документирует порт приложения, но сама по себе не открывает его на хосте. Для публикации порта нужен параметр -p в docker run или раздел ports в Compose.
RUN выполняется во время сборки образа, а CMD — при запуске контейнера. ENTRYPOINT тоже задаёт исполняемую команду, но обычно используется, когда образ должен вести себя как отдельная программа и дополнительные аргументы передаются к фиксированной точке входа. Для небольшого сервиса достаточно CMD.
Команда docker build и кэширование слоёв
Сборка запускается командой docker build -t myapp:1.0 . Точка в конце обозначает build context — набор файлов, доступных сборщику. Современный Docker использует BuildKit и старается повторно применять уже готовые слои из build cache.
Порядок инструкций влияет на скорость повторной сборки. Если сначала выполнить COPY . ., а затем устанавливать зависимости, изменение одного файла исходного кода может сбросить кэш и заставить Docker заново выполнять установку пакетов. Поэтому удобнее сначала копировать requirements.txt, затем выполнять RUN pip install ..., а исходники добавлять позже.
После сборки список образов можно проверить командой docker image ls. Для тестового запуска подойдёт docker run --rm -d --name myapp -p 8000:8000 myapp:1.0.
Тегирование образов и версионирование
Тег можно присвоить сразу при сборке через docker build -t myapp:1.0 . или позднее командой docker tag myapp:1.0 username/myapp:1.0. Для новой версии меняется тег, например на myapp:1.1, после чего образ отправляется в registry.
На рабочем сервере лучше явно указывать конкретный тег. Тогда понятно, какая версия сейчас запущена, а при ошибке можно вернуть предыдущую. Использовать один latest как единственный способ версионирования неудобно: он скрывает, какая именно сборка реально работает.
.dockerignore и контекст сборки
Команда docker build . передаёт сборщику содержимое текущего каталога как build context. Туда не нужно включать всё подряд. В .dockerignore обычно исключают .git, локальное виртуальное окружение .venv, __pycache__, временные файлы, журналы, тестовые артефакты и секреты вроде .env.
Это ускоряет сборку и снижает риск случайно добавить в образ ненужные или чувствительные файлы. Особенно опасно копировать приватные ключи и токены: секрет, попавший в слой Docker-образа, нельзя считать безопасно удалённым простым rm в следующей инструкции.
Запуск и управление контейнерами
После сборки Docker-образ можно использовать многократно. Повторный docker build нужен только тогда, когда меняется сам образ, а не при каждом запуске контейнера.
Для разработки и тестирования контейнерных ИИ-приложений необязательно сразу брать сервер на четыре–шесть GPU. Если достаточно одной-двух GPU, можно использовать компактную систему для локального инференса, RAG и экспериментов.
docker run: основные флаги
Базовый запуск выглядит как docker run myapp:1.0. На сервере часто нужны дополнительные параметры. Например, -d запускает процесс в фоне, --name myapp задаёт имя, -p 8000:8000 публикует порт, -e APP_ENV=production передаёт переменную окружения, а --restart unless-stopped задаёт автоматический перезапуск.
Без указания IP Docker публикует порт на всех интерфейсах хоста. Если сервис нужен только локально, безопаснее использовать -p 127.0.0.1:8000:8000.
Для временного теста удобно использовать --rm: после остановки контейнер автоматически удалится. Когда флагов становится слишком много, а вместе с приложением запускаются база данных, Redis или фоновые воркеры, лучше перейти на Docker Compose.
Логи, остановка, удаление контейнеров
Работающие контейнеры показывает docker ps, а вместе с остановленными — docker ps -a. Логи доступны через docker logs myapp, а режим наблюдения за новыми строками — через docker logs -f myapp. Остановить экземпляр можно командой docker stop myapp, запустить снова — docker start myapp, удалить остановленный — docker rm myapp.
Для диагностики внутри уже работающего контейнера используют docker exec -it myapp sh. Но ручное изменение файлов через docker exec не должно превращаться в способ обновления приложения: новый контейнер всё равно будет создан из исходного образа и не унаследует такие исправления.
Volumes и сети Docker
Контейнеры лучше считать заменяемыми, а постоянные данные хранить отдельно. Именованный том можно создать командой docker volume create app-data и подключить при запуске через --mount type=volume,src=app-data,dst=/data. Удаление контейнера не удаляет такой том автоматически.
Для связи сервисов используется сеть Docker. Команда docker network create app-net создаёт пользовательскую сеть, а подключённые к ней контейнеры могут обращаться друг к другу по именам. В Compose такая сеть обычно создаётся автоматически, поэтому веб-приложение может обращаться к базе по имени сервиса, например db, без публикации базы в интернет.
Docker Compose: запуск многоконтейнерных приложений
Один docker run удобен. Пять длинных команд для веб-приложения, базы данных, Redis и фонового воркера — уже нет. Docker Compose описывает весь набор сервисов в YAML-файле и позволяет управлять им как единым проектом.
В старых гайдах часто встречается команда docker-compose. Современный вариант — docker compose. Старое написание с дефисом относится к standalone Compose и сохраняется в legacy-сценариях, поэтому при чтении старых инструкций важно не смешивать два варианта CLI.
Структура docker-compose.yml
Название docker-compose.yml по-прежнему поддерживается, но для нового проекта лучше использовать compose.yaml. Верхнеуровневый параметр version: в современном Compose не требуется.
| Элемент | Пример | Назначение |
|---|---|---|
| services | web, db | Описывает контейнеры приложения |
| image / build | username/myapp:1.0 или build: . | Выбирает готовый образ или локальную сборку |
| ports | 8000:8000 | Публикует порт сервиса |
| environment | DATABASE_HOST=db | Передаёт переменные окружения |
| volumes | postgres-data:/var/lib/postgresql/data | Сохраняет постоянные данные |
| healthcheck | pg_isready ... | Проверяет готовность сервиса |
services:
web:
build: .
ports:
- "127.0.0.1:8000:8000"
environment:
DATABASE_HOST: db
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres-data:
Значение POSTGRES_PASSWORD можно положить в локальный файл .env, но этот файл нельзя добавлять в репозиторий. Названия переменных приложения нужно адаптировать под его конфигурацию.
Запускается проект командой docker compose up -d. Состояние показывает docker compose ps, логи — docker compose logs -f, а остановка и удаление контейнеров проекта выполняются через docker compose down.
Типичный сценарий: веб-приложение и база данных
Для связки веб-приложения и PostgreSQL достаточно двух сервисов в compose.yaml. Сервис web использует образ приложения, публикует порт 8000 и получает параметры подключения через переменные окружения. Сервис db использует официальный образ PostgreSQL, хранит данные в named volume и имеет healthcheck.
Веб-приложение обращается к базе по имени db внутри внутренней сети Compose. Порт PostgreSQL наружу можно вообще не публиковать. Если требуется дождаться готовности БД, а не только запуска её процесса, в depends_on используют условие service_healthy, а у базы задают healthcheck через pg_isready.
Пароль удобно передавать через переменную окружения, например ${POSTGRES_PASSWORD}, но реальный production-секрет нельзя хранить в Git. Для локальной разработки допустим .env, если файл исключён из репозитория и .dockerignore.
Оптимизация образов
Неоптимизированный образ легко разрастается до гигабайтов. Проблема не только в диске: большие слои дольше скачиваются из registry, замедляют обновления и могут содержать лишние пакеты.
Multi-stage build
Multi-stage build разбивает сборку на несколько стадий. Каждая начинается со своего FROM, а в финальный образ переносятся только необходимые артефакты. Например, первая стадия на Python может собрать wheel-пакеты, а вторая — установить уже готовые пакеты и добавить приложение, не сохраняя лишние build-инструменты.
В Go и C++ эффект ещё заметнее: компилятор, заголовочные файлы и исходники остаются в builder-стадии, а production-образ получает только готовый бинарник и необходимые библиотеки среды выполнения.
Уменьшение размера образа
Универсального «самого маленького» базового образа нет. Alpine иногда полезен, но его нельзя автоматически считать лучшим выбором для Python, научных библиотек или программ, которые ожидают glibc.
- Использовать подходящий минимальный runtime-образ;
- Исключать ненужные файлы через
.dockerignore; - Не оставлять компиляторы и build-инструменты в production-стадии;
- Применять multi-stage build;
- Не копировать локальные виртуальные окружения;
- Удалять временные файлы в том же слое, где они появились;
- Не включать секреты и локальные данные;
- Располагать редко меняющиеся слои раньше часто меняющихся.
Сначала стоит смотреть на состав образа, воспроизводимость сборки и время обновления, а уже потом на минимальное число мегабайт.
Docker и GPU: контейнеры для ИИ-нагрузок
Docker особенно полезен в ИИ-разработке. Один проект требует PyTorch и одну CUDA-среду, второй — другую версию библиотек, третий запускает TensorRT или vLLM. Устанавливать всё глобально на одном Linux-сервере неудобно, а контейнеризация позволяет разделить пользовательские окружения.
Важная граница проходит по драйверу: NVIDIA-драйвер работает на хосте. Контейнер получает пользовательские CUDA-библиотеки, фреймворк и зависимости, но не приносит с собой независимый драйвер ядра для видеокарты.
Если Docker используется для локального инференса, обучения или нескольких ИИ-окружений, сервер стоит подбирать не только по числу GPU, но и по объёму VRAM, памяти и характеру нагрузки.
Выберите GPU-сервер под свои задачи
Готовые конфигурации для инференса, машинного обучения и вычислений
NVIDIA Container Toolkit: зачем нужен и как установить
Для корректного доступа Docker к NVIDIA GPU используется NVIDIA Container Toolkit. Сначала на хосте должен нормально работать драйвер — это проверяют командой nvidia-smi. Затем устанавливают Toolkit, настраивают Docker через sudo nvidia-ctk runtime configure --runtime=docker и перезапускают Docker daemon командой sudo systemctl restart docker.
Для новых установок ставят nvidia-container-toolkit и настраивают Docker через nvidia-ctk. Отдельно устанавливать nvidia-docker2 или nvidia-container-runtime обычно не требуется: необходимая функциональность входит в Toolkit.
Запуск контейнера с GPU: docker run --gpus all
После настройки можно выполнить тестовый запуск контейнера с GPU. Общая форма команды выглядит как docker run --rm --gpus all nvidia/cuda:<подходящий-тег> nvidia-smi. Если всё работает, внутри контейнера появится информация о доступных ускорителях.
Не обязательно выдавать приложению все карты. Например, параметр --gpus '"device=1,2"' позволяет предоставить контейнеру конкретные GPU. На сервере с четырьмя ускорителями инференс-сервис можно закрепить за GPU 0–1, а экспериментальное окружение — за GPU 2–3.
Готовые CUDA-образы для обучения и инференса
В официальном репозитории nvidia/cuda публикуются разные CUDA-образы. Выбирать их лучше по назначению, а не только по номеру версии.
| Тип | Содержимое | Когда выбирать |
|---|---|---|
| base | Минимальный набор CUDA runtime | Самое компактное базовое окружение |
| runtime | CUDA runtime и дополнительные библиотеки | Инференс и запуск готовых приложений |
| devel | Runtime плюс инструменты разработки и заголовки | Компиляция CUDA-кода и сборка расширений |
CUDA-образ нужно выбирать с учётом совместимости с драйвером хоста. Для продакшен-среды полезно фиксировать полный тег вместо неопределённой версии, чтобы обновление образа не изменило CUDA-окружение неожиданно.
Изоляция окружений на одном GPU-сервере: разные версии CUDA и фреймворков без конфликтов
На одном GPU-сервере можно держать разные окружения: контейнер A — PyTorch и CUDA-среда A, контейнер B — другая версия PyTorch и CUDA-среда B, контейнер C — vLLM для инференса. Обновление библиотек в одном окружении не должно ломать остальные.
Но Docker не превращает один ускоритель в несколько автоматически изолированных физических GPU. Если два контейнера используют одну карту, они делят вычислительные ресурсы и VRAM. На совместимых дата-центровых ускорителях для аппаратного разделения можно применять MIG, но это функция конкретной GPU и инфраструктуры.
Если контейнеры постоянно обслуживают модели, полезно отдельно оценить серверную платформу. Общие сценарии разобраны в материале DigitalRazor «Для чего нужен GPU-сервер».
Для компактного локального инференса, RAG, разработки и тестирования можно использовать RackStation AI с одной-двумя GPU. Для нескольких параллельных R&D-окружений и более тяжёлых ИИ-нагрузок подойдёт масштабируемый DevBox AI на нескольких ускорителях.
Деплой Docker-приложений на сервер
Локальный запуск — только половина задачи. Следующий этап — доставить проверенную версию на сервер и обновлять её без ручной установки зависимостей.
Если сам сервер ещё не подготовлен, SSH, базовую безопасность, домен, HTTPS и Nginx отдельно разбираем в гайде «Как развернуть VDS/VPS-сервер».
Для постоянного контейнеризованного инференса сервер должен выдерживать не только саму модель, но и параллельные сервисы, базы данных, RAG и фоновые задачи.
Нужна помощь с выбором сервера?
Специалисты помогут подобрать оборудование под нагрузку, бюджет и задачи
Подготовка сервера
- Linux-сервер и SSH-доступ;
- Docker Engine;
- Compose plugin, если используется Compose;
- Доступ к registry;
- Место под образы и volumes;
- Открытые только необходимые порты.
Публично выставлять Docker daemon в интернет без правильно настроенной защиты не нужно. Для GPU-сервера дополнительно устанавливаются NVIDIA-драйвер и NVIDIA Container Toolkit.
От локального образа до registry и сервера
Рабочая последовательность состоит из нескольких коротких команд. Локально выполняется docker build -t myapp:1.2 ., затем docker tag myapp:1.2 username/myapp:1.2 и docker push username/myapp:1.2. На сервере нужную версию получают через docker pull username/myapp:1.2.
Сервер получает версию образа, на которую в момент загрузки указывает тег 1.2. Если нужна строгая воспроизводимость развёртывания, образ можно закрепить по digest sha256. Серверу не нужно отдельно ставить Python-пакеты или вручную воспроизводить окружение. Та же схема хорошо ложится на CI/CD: Git → тесты → docker build → registry → сервер.
Развёртывание через Docker Compose
На сервере в compose.yaml указывают образ нужной версии, например username/myapp:1.2, публикуют необходимые порты и задают restart policy. Затем выполняют docker compose pull и docker compose up -d. Состояние проверяют через docker compose ps, а логи — через docker compose logs -f.
Для одного сервера этого достаточно во многих проектах. Когда приложение нужно распределять по кластеру машин, автоматически масштабировать и управлять десятками сервисов, начинается полноценная оркестрация контейнеров — например, через Kubernetes. Compose не заменяет кластерный оркестратор.
Когда на одном сервере одновременно работают инференс, RAG, API и несколько экспериментальных окружений, важны уже не только Docker и Compose, но и количество GPU, VRAM, оперативная память и возможность расширения системы.
Обновление приложения и откат версии
Готовый Docker-образ не редактируют на сервере вручную. Для новой версии собирается новый образ, например username/myapp:1.3, и отправляется в registry. Затем в compose.yaml меняется тег с 1.2 на 1.3, после чего выполняются docker compose pull и docker compose up -d.
Build cache позволяет не пересобирать неизменившиеся слои. Если проблема обнаружилась уже после релиза, для отката достаточно вернуть в Compose предыдущий тег образа и снова запустить обновление проекта. Такой подход надёжнее попытки «починить» контейнер вручную через docker exec.
Healthcheck и автоматический перезапуск
Restart policy и healthcheck решают разные задачи. Параметр restart: unless-stopped определяет, нужно ли перезапустить завершившийся процесс. Healthcheck проверяет, способен ли сервис реально выполнять работу.
Процесс может оставаться запущенным, но база ещё не принимать подключения, а веб-сервис — зависнуть. Поэтому состояние running не равно healthy. Ни healthcheck, ни restart policy при этом не обеспечивают полноценную высокую доступность сами по себе: для отказоустойчивости нужны резервирование, балансировщик и инфраструктура уровнем выше одного контейнера.
Важно
Статус unhealthy сам по себе не заставляет обычный Docker Engine перезапустить контейнер. Restart policy срабатывает при остановке процесса. Для автоматической реакции на healthcheck нужен дополнительный механизм или оркестратор.
Частые ошибки при работе с Docker
Docker позволяет быстро получить рабочий результат, поэтому часть проблем проявляется уже после переноса приложения на сервер.
- Данные базы хранятся только во внутреннем слое контейнера;
- Все версии помечены единственным тегом
latest; - Секреты попадают в Dockerfile или Git;
- Build context содержит гигабайты ненужных файлов;
- Ранний
COPY . .постоянно сбрасывает build cache; - Production-образ содержит компилятор и build-инструменты;
- Наружу опубликованы лишние порты;
- Нет healthcheck и restart policy;
- Контейнер получает лишние привилегии;
- Сторонний образ используется без проверки происхождения.
Если сервер собирается под несколько контейнеров и разные рабочие нагрузки, конфигурацию лучше сразу рассчитывать с запасом по GPU, VRAM, оперативной памяти и накопителям.
Выберите решение для работы
Найдите готовый компьютер под вашу профессию
Безопасность контейнеров
Контейнеризация улучшает изоляцию приложений, но контейнер нельзя считать непроницаемой песочницей. Особенно опасно без необходимости использовать --privileged: такой режим выдаёт контейнеру существенно больше возможностей на хосте.
Не следует подключать неизвестному приложению /var/run/docker.sock, хранить пароль через инструкцию ENV DATABASE_PASSWORD=... в Dockerfile или копировать приватные ключи в образ. Приложение по возможности запускают не от root, bind mounts дают только туда, где они нужны, а запись отключают, если достаточно чтения.
Для сторонних CUDA-образов действуют те же правила. Наличие CUDA в названии не делает образ безопасным: нужно проверять registry, издателя, содержимое, права и то, какие каталоги и устройства контейнер получает от хоста.
Частые вопросы (FAQ)
Заключение
Рабочая схема Docker довольно проста: Dockerfile описывает окружение, docker build создаёт версионированный образ, registry хранит его, а Docker или Compose запускает тот же пакет на сервере. Volumes отделяют постоянные данные от заменяемых контейнеров, сети связывают сервисы, а healthcheck и restart policy помогают контролировать их состояние.
Для GPU в Docker к этой цепочке добавляются совместимый NVIDIA-драйвер на хосте и NVIDIA Container Toolkit. После настройки разные CUDA-образы и версии фреймворков можно держать в отдельных окружениях, не превращая сервер в набор конфликтующих системных зависимостей.
Если приложение выросло от экспериментального контейнера до постоянного инференса, RAG или нескольких ИИ-сервисов, оборудование стоит подбирать под число GPU, объём VRAM и характер нагрузки. Подробнее о локальных моделях читайте в материале DigitalRazor «Какие модели ИИ можно развернуть на своём ПК или сервере».
Мы поможем подобрать GPU-сервер под количество контейнеров, размер модели и требуемый объём видеопамяти — без лишнего запаса по компонентам.


















