Как сохранить образ docker
С помощью команды docker save «image» > «path».tar образ сохраняется, но весит очень много, около 2Гб, а также не открывается с ошибкой «Файл имеет неверный формат или поврежден» Мой Dockerfile:
FROM node:18-alpine WORKDIR /usr/src/app EXPOSE 3000 COPY package.json ./ RUN npm install COPY . . CMD ["npm", "run", "start"]
docker-compose.yml:
version: '3.8' services: app: build: context: ./APP container_name: front ports: - '3000:3000' volumes: - .:/APP
Возможно ли, что образ выгружается вместе со всеми зависимостями в виде ОС и тд, если да, то как выгрузить образ без этих зависимостей?
Отслеживать
задан 12 апр 2023 в 16:08
43 7 7 бронзовых знаков
а зачем? и как вы пытаетесь его открыть, что получаете ошибку «Файл имеет неверный формат или поврежден»?
12 апр 2023 в 18:06
Образ нужно развернуть на другой системе, а открыть я его пытался винраром и 7zip
12 апр 2023 в 21:49
для этих целей обычно используют docker registry, например docker hub или любой другой, но даже если вы хотите использовать docker save, то на другой машине нужно просто использовать docker load и все, а уменьшить образ можно с помощью multistage build
12 апр 2023 в 21:51
2 gb — это как-то очень много. Я собрал небольшое приложение в докере на образе node:18-alpine , и получил всего 172 мб, а после сжатия gzip и вовсе 50 мб. Вы уверены, что ничего лишнего не тащите в образ инструкцией COPY . . ?
13 апр 2023 в 2:49
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Да, image save выгружает образ целиком, включая базовый образ. Восстановить образ из архива командой image load
У вас получается архив размером 2 Гб? Это очень странно. Базовый образ всего 174 мб, сжатием gzip получается 50 мб.
Я сделал маленький образ
FROM node:18-alpine WORKDIR /usr/src/app EXPOSE 8081 COPY ./src . CMD ["node", "hello.js"]
В ./src лежит единственный файл hello.js
var http = require("http"); http.createServer(function (request, response) < response.writeHead(200, < 'Content-Type': 'text/plain' >); response.end('Hello World\n'); >).listen(8081); console.log('Server started at http://localhost:8081/');
docker build . -t try-node
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE try-node latest 4445087d824e 13 minutes ago 175MB
docker image save try-node | gzip > image.tar.gz du -sm image.tar.gz
50 image.tar.gz
Итого — выгруженный сжатый образ размером 50 мегабайт.
$ docker image rm try-node $ cat image.tar.gz | gzip -d | docker image load f1417ff83b31: Loading layer [==================================================>] 7.338MB/7.338MB 8f90faa0eb99: Loading layer [==================================================>] 164.2MB/164.2MB e2ed77d8fead: Loading layer [==================================================>] 7.819MB/7.819MB 1e9663a5b8eb: Loading layer [==================================================>] 3.584kB/3.584kB 03429486714c: Loading layer [==================================================>] 3.072kB/3.072kB 242deab87f84: Loading layer [==================================================>] 3.584kB/3.584kB Loaded image: try-node:latest
Образ загружен и добавлен в список образов:
docker image ls try-node REPOSITORY TAG IMAGE ID CREATED SIZE try-node latest 4445087d824e 25 minutes ago 175MB
Docker. Перенос образа на другой хост.
Имеем docker контейнер который нужно перенести на другой хост. По сути наша задача сводится с переносу образа на новый хост и запуску контейнера из этого образа.
Смотрим на контейнер
user@host:/# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 262202e83aeb priv/container "bash" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:443->443/tcp ACME
Посмотреть какие тома присоединены к контейнеру можно в разделе «Mounts» в выводе команды:
docker inspect %ID_контейнера%
Сохранение образа. На первом месте куда сохранять, на втором что сохранять.
docker save -o /%путь%/image.tar priv/container
Копируем тома(volumes). По умолчанию лежат «/var/lib/docker/volumes/». На первом месте указываем куда копировать, на втором что:
tar -cvf ./data_vol.tar /var/lib/docker/volumes/data_vol/
Переносим образ и тома на новый хост, можно сделать при помощи «scp». Если порт SSH не стандартный, нужно его указать ключом «-P». Ключ «-P» должен быть на первом месте. Далее указываем что копировать, потом хост куда копировать в формате %имя_пользователя%@%адрес_хоста%:%путь_куда_копировать%. При указании «~» в пути файл скопируется в домашнюю папку пользователя.
scp -P 123 ./image.tar user@123.123.123.2:~
По завершении копирования тома нужно разархивировать и закинуть на место(по умолчанию «/var/lib/docker/volumes/»):
tar -xvf /home/user/data_vol.tar
Кормим докер нашим образом:
docker load -i /home/user/image.tar
После всех этих процедур докер увидит образ и позволит создать из него контейнер.
Выгрузка, загрузка и распространение образов контейнеров Docker в виде архива
Стандартный способ распространения образов Docker — использование репозиториев Docker, которые позволяют как опубликовать вновь созданные образы, так и скачать их для локального использования. Развернуть локальный реестр Docker можно за 1 минуту, однако, для полноценного использования требуется больше действий, например, установка SSL-сертификата и поддержка авторизации.
Бывают случаи, когда серверы, на которых планируется выполнять контейнеры, созданные из образов, полностью изолированы от сегмента сети и не могут скачать себе образ из реестра. В этом случае у разработчиков возникает необходимость каким-то образом сформировать образ контейнера на сервере. Команда docker build тоже часто не подходит, поскольку большинство образов при сборке скачивает зависимости и необходимые слои из сети. Если хост не имеет подключения к сети, то и скачать ничего не сможет.
К счастью, Docker предоставляет стандартный механизм для распространения образов без использования реестров с помощью импорта и экспорта. Далее в статье мы рассмотрим как воспользоваться этими возможностями для того, чтобы эффективно распространять образы на серверы, где подключение к интернет невозможно.
Вообще, данный подход можно применять и в ряде других случаев, часть из которых мы перечислим ниже:
- обеспечение развертывания без сети;
- гарантированное развертывание с твердого носителя (USB, DVD);
- поставка в форме готового к использовании дистрибутива;
- минимизация инфраструктуры за счет исключения лишних элементов (registry).
Сохранение образа в архив
Для начала рассмотрим как можно выполнить сохранение образа контейнера из среды. Для выполнения данной операции используется команда docker save (man docker-save):
docker pull ubuntu:18.04 docker save -o ubuntu-1804.tar ubuntu:18.04
После выполнения данной команды образ со всеми слоями будет выгружен из пространства образов демона Docker в файловую систему в виде архива tar.
Интересно, что таким образом можно выгрузить более одного образа:
docker pull ubuntu:16.04 docker save -o ubuntu-16+18.tar ubuntu:18.04 ubuntu:16.04
Таким образом, вы можете за одну команду выгрузить все необходимые для распространения контейнеры в один tar-архив.
Загрузка образа в среду Docker
Для выполнения загрузки ипользуется обратная операция docker load:
# удалим образы docker rmi ubuntu:18.04 ubuntu:16.04 # убедимся, что нет доступных образов docker images | grep ubuntu | wc -l # загрузим образы из архива в среду Docker docker load -i ubuntu-16+18.tar aa54c2bc1229: Loading layer [==================================================>] 121.6MB/121.6MB 7dd604ffa87f: Loading layer [==================================================>] 15.87kB/15.87kB 2f0d1e8214b2: Loading layer [==================================================>] 11.78kB/11.78kB 297fd071ca2f: Loading layer [==================================================>] 3.072kB/3.072kB Loaded image: ubuntu:16.04 Loaded image: ubuntu:18.04 # проверим доступное количество образов docker images | grep ubuntu | wc -l 2
Таким образом вы можете распространять образы контейнеров Docker между узлами без использования реестра и даже сети, например, на DVD или накопителе USB.
Отличия Save, Load от Export, Import
Docker поддерживает команды export и import, которые часто могут быть перепутаны с save, load. Ключевое отличие данных команд в том, для чего они предназначены:
- save/load выгружают и загружают образы контейнеров, которые будут использоваться для создания контейнеров;
- export выгружает файловую систему созданного контейнера (не образ контейнера, а изменения, которые внес контейнер в образ);
- import позволяет создать образ тома файловой системы из архива, созданного с помощью export, который может использоваться, например, при запуске контейнера с помощью —volumes-from.
В целом, разница заключается, что save/load относятся к данным образов, а export/import к данным контейнеров.
dnncomp / Docker. Работа с образами.md
После того, как вы зарегистрировались, необходимо создать репозиторий (прямо как на GitHub).
На странице вы увидите плашку Create a Repository. Нажмите на неё.
После нажатия вы попадете на страницу создания репозитория. Создайте там свой репозиторий.
Отлично! Теперь у вас есть свой репозиторий, где можно хранить свои образы.
Команды для работы с репозиторием
После того, как у вас появился репозиторий, попробуйте загрузить в него свой образ.
Чтобы это сделать, необходимо локально авторизоваться, при необходимости сменить имя и тег образа и сделать пуш на Docker Hub.
- Для локальной авторизации используется команда docker login. В таком случае у вас попросит username (как раз Docker ID) и пароль.
- Чтобы сменить название образа и тег, нужно воспользоваться командой docker tag . В названии результирующего образа будет присутствовать ваш username, слеш (/), название репозитория.
- Чтобы отправить образ на Docker Hub, нужно ввести команду docker push Чтобы локально разлогиниться, нужно ввести команду docker logout.
- После того, как вы загрузили образ на Docker Hub, вы можете его скачать. Как вы уже знаете, делается это командой docker pull 🙂
Работа с файлами
docker volume ls — вывести список вольюмов
docker volume create — создать вольюм
docker volume rm — удалить вольюм
docker volume prune — удалить вольюмы, которые не используются контейнерами
Переменные окружения, логи и порты
Важный момент про порты
При поднятии контейнера можно прокинуть несколько портов.
Для этого нужно просто задать опцию -p несколько раз:
Например, можно сделать вот так:
docker run -p 80:80 -p 81:80 -p 82:80 nginx
В результате на компьютере мы свяжем порты 80, 81 и 82 с портом 80 в контейнере.
Чаще это нужно, когда программа в контейнере способна слушать несколько портов.
То есть что-то в духе:
docker run -p 80:80 -p 443:443 some_web_image
ENV — инструкция в Dockerfile, которая позволяет задавать переменные окружения в контейнерах.
* Не задавайте через эту инструкцию секретные данные
docker run -e = — позволяет задать переменную окружения в конкретном контейнере.
docker logs — позволяет вытащить логи из контейнера
docker logs -f — не отключаемся от контейнера docker logs -t — добавляем время к логам
EXPOSE — инструкция в Dockerfile, которая позволяет сообщить пользователю, какой(ие) порт(ы) слушает приложение внутри контейнера. Не прокидывает порты на хост.
docker run -p : — связывает порт внутри контейнера с портом на хосте.
docker run -p :: — по умолчанию адрес на хосте задается 0.0.0.0 (про него узнаем в следующем уроке). При поднятии можно изменить этот адрес. Например: docker run -p 127.0.0.1:80:80 nginx
Введение в сети
docker network ls — список сетей
docker network create — создать сеть
docker network rm — удалить сеть
docker run —net= — подключаем контейнер к сети
docker inspect — получить информацию об объектах докера (контейнер, образ, вольюм, сеть)
Веб-приложение в контейнерах
Этапы задаются при помощи нескольких инструкций FROM .
Из одного этапа сборки в другой можно копировать артефакты при помощи COPY —from= .
FROM AS builder . . . FROM . . . COPY --from=builder . . .
YAML и docker-compose
docker-compose ps — список контейнеров
docker-compose up — поднять приложение
docker-compose up — поднять конкретный контейнер docker-compose up -d — поднять контейнеры в фоновом режиме docker-compose -f docker-compose.dev.yml up — указать docker-compose.yaml файл
docker-compose stop — остановить поднятые контейнеры
docker-compose start — запустить остановленные контейнеры
docker-compose down — остановить и удалить контейнеры и сеть
Веб-приложение в docker-compose
build — собираем образ, на основе которого поднимем сервис
image — образ, на основе которого поднимем сервис
container_name — название контейнера в сервисе
volumes — список вольюмов для сервиса
environment — переменные окружения в сервисе
networks — список сетей, к которым нужно подуключить сервис
ports — список портов, которые нужно прокинуть у сервиса
restart — указываем поведение сервиса при падении
deploy/replicas — указываем количество контейнеров у сервиса
depends_on — определяем зависимость между сервисами
healthcheck — задаем проверку для сервиса