Короткий ответ
Docker-образ — неизменяемый «шаблон» с файловой системой и метаданными приложения, а контейнер — запущенный экземпляр этого образа с собственным изолированным процессом; это похоже на отношение класса и объекта — образ — класс, контейнер — конкретный объект.
Как это работает подробнее
образ состоит из read-only слоёв, объединённых union-filesystem; при docker run Docker добавляет сверху записываемый слой и создаёт изолированный процесс с собственными namespace и cgroups.
Пример кода
Команды терминала
docker build -t myapp:1.0 .
docker run -d --name app1 myapp:1.0
docker run -d --name app2 myapp:1.0
docker ps # два независимых процесса на базе одного образаЧто использовать на практике
- Рекомендация. из одного образа можно запустить сколько угодно независимых контейнеров; изменения внутри контейнера не влияют на образ и теряются при удалении контейнера, если не вынесены в volume. Образ хранится в registry, контейнер — эфемерная рантайм-единица.
Подводные камни
- Риск. хранить важные данные только в писаемом слое контейнера — при пересоздании они пропадают; путать
docker build(создание образа) иdocker run(создание и запуск контейнера).