Шпаргалка docker
Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Информация и регистрация
- docker info - Информация обо всём в установленном Docker
- docker history - История образа
- docker tag - Дать тег образу локально или в registry
- docker login - Залогиниться в registry
- docker search - Поиск образа в registry
- docker pull - Загрузить образ из Registry себе на хост
- docker push - Отправить локальный образ в registry
Управление контейнерами (Container Management)
- docker ps -а - Посмотреть все контейнеры
- docker start container-name - Запустить контейнер
- docker kill/stop container-name - Убить (SIGKILL) /Остановить (SIGTERM) контейнер
- docker logs --tail 100 container-name - Вывести логи контейнера, последние 100 строк
- docker inspect container-name - Вся инфа о контейнере + IP
- docker rm container-name- Удалить контейнер (поле каждой сборки Dockerfile)
- docker rm -f $(docker ps -aq) - Удалить все запущенные и остановленные контейнеры
- docker events container-name - Получения событий с контейнера в реальном времени.
- docker port container-name - Показать публичный порт контейнера
- docker top container-name - Отобразить процессы в контейнере
- docker stats container-name - Статистика использования ресурсов в контейнере
- docker diff container-name - Изменения в ФС контейнера
Управление образами (Images Management)
- docker build -t my_app . - Билд контейнера в текущей папке, Скачивает все слои для запуска образа
- docker images / docker image ls - Показать все образы в системе
- docker image rm / docker rmi image - Удалить image
- docker commit
lepkov/debian11slim:version3 - Создает образ из контейнера - docker insert URL - вставляет файл из URL в контейнер
- docker save -o backup.tar - Сохранить образ в backup.tar в STDOUT с тегами, версиями, слоями
- docker load -i backup.tar - Загрузить образ в .tar в STDIN с тегами, версиями, слоями
- docker import - Создать образ из .tar
- docker image history --no-trunc - Посмотреть историю слоёв образа
- docker system prune -f - Удалит все, кроме используемого (лучше не использовать на проде, ещё кстати из-за старого кеша может собираться cтарая версия контейнера)
Отличия Save, Load от Export, Import
Docker поддерживает команды export
и import
, которые часто могут быть перепутаны с save
, load
. Ключевое отличие данных команд в том, для чего они предназначены:
- save/load выгружают и загружают образы контейнеров, которые будут использоваться для создания контейнеров;
- export выгружает файловую систему созданного контейнера (не образ контейнера, а изменения, которые внес контейнер в образ);
- import позволяет создать образ тома файловой системы из архива, созданного с помощью export, который может использоваться, например, при запуске контейнера с помощью
—volumes-from
.
В целом, разница заключается, что save/load
относятся к данным образов, а export/import
к данным контейнеров.
Запуск docker (Run)
-
docker run -d -p 80:80 -p 22:22 debian:11.1-slim sleep infinity (
--rm
удалит после закрытия контейнера,--restart unless-stopped
добавит автозапуск контейнера) - Запуск контейнера интерактивно или как демона/detached (-d
), Порты: слева хостовая система, справа в контейнере, пробрасывается сразу 2 порта 80 и 22, используется легкий образ Debian 11 и команда бесконечный сон -
docker update --restart unless-stopped redis - добавит к контейнеру правило перезапускаться при закрытии, за исключением команды стоп, автозапуск по-сути
-
docker exec -it container-name /bin/bash (ash для alpine) - Интерактивно подключиться к контейнеру для управления, exit чтобы выйти
-
docker attach container-name - Подключиться к контейнеру чтоб мониторить ошибки логи в реалтайме
Хранилище (Volumes)
Скопировать в корень контейнера file
docker cp file <containerID>:/
Скопировать file из корня контейнера в текущую директорию командной строки
docker cp <containerID>:/file .
Создать volume для постоянного хранения файлов
docker volume create todo-db
Добавить named volumу todo-db к контейнеру (они ok когда мы не заморачиваемся где конкретно хранить данные)
docker run -dp 3000:3000 --name=dev -v todo-db:/etc/todos container-name
docker run -dp 3000:3000 --name=dev --mount source=todo-db,target=/etc/todos container-name
# тоже самое что команда сверху
Отобразить список всех volume’ов
docker volume ls
Инспекция volume’ов
docker volume inspect
Удалить volume
docker volume rm
Сеть (Network)
Создать сеть
docker network create todo-app
Удалить сеть
docker network rm
Отразить все сеть
docker network ls
Вся информация о сети
docker network inspect
Соединиться с сетью
docker network connect
Отсоединиться от сети
docker network disconnect
Пробросить текущую папку в контейнер и работать на хосте, -w
working dir, sh
shell
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
node:12-alpine \
sh -c "yarn install && yarn run dev"
Запуск контейнера с присоединением к сети и заведение переменных окружения
docker run -d \
--network todo-app --network-alias mysql \ # (алиас потом сможет резолвить докер для других контейнеров)
-v todo-mysql-data:/var/lib/mysql \ # (автоматом создает named volume)
-e MYSQL_ROOT_PASSWORD=secret \ # (в проде нельзя использовать, небезопасно)
-e MYSQL_DATABASE=todos \ # (в проде юзают файлы внутри конейнера с логинами паролями)
mysql:5.7
Запуск контейнера с приложением
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:12-alpine \
sh -c "yarn install && yarn run dev"
CMD VS ENTRYPOINT
Разница в том, что CMD
выполняется из под /bin/sh
по дефолту, а ENTRYPOINT
без него. В случае с CMD, команда и параметры к ней захардкожены в образ, пример запуска с переопределением команды CMD ["sleep","10"]
docker run ubuntu sleep 5
Контейнер проспит 5 секунд вместо 10.
В случае с ENTRYPOINT, только команда захардкожена в образ, пример запуска с переопределением команды ENTRYPOINT ["sleep"] CMD ["10"] (Есл используются обе директивы, то в энтрипоинте команда, а в cmd параметры к ней)
docker run ubuntu 5
Контейнер проспит 5 секунд вместо 10.
Чтобы переопределить ENTRYPOINT:
docker run --entrypoint another-command ubuntu 20
Обычно практика такая, всегда используй CMD, если только не требуется каждый раз запускать контейнер с разным параметром (экономия времени, чтоб каждый раз не вводить строчку с командой)
Лучшая практика(Best Practice)
Следуй принципу минимальных привилегий, процессы в контейнере никогда не должны выполняться из под рута
, кроме редких случаев, нужно добавлять команду user
и менять юзера на non-root
.
Не привязываться к UID
, он динамичен, можно записать во временную папку UID.
Сделать все исполняемые файлы владельцем рута, чтобы никто не изменил исполняемые файлы, а пользователю достаточно только права на выполнение.
Чем меньше компонентов и открытых портов, тем меньше поверхность для атак.
Использовать multistage
для промежуточного контейнера для компиляции всего, зависимостей, временных файлов, образ может весить на треть меньше.
Distroless
с чистого листа, использовать минимальный набор пакетов, например избавиться от образа Ubuntuи выбрать Debian-base, наши контейнеры содержат уязвимости изначального образа, чекать это.
Нужно обновлять всё до того, как выйдет из под поддержки.
Оставлять только те порты, которые реально нужны, избегать 22 и 21 3389 (ssh & ftp & rdp).
Никогда не помещайте логины/пароли в команде, в докерфайлах, переменных, docker secret или любой другой менеджер секретов ok.
Не использовать ADD
, только COPY
(когда используем точку - это воркдир где лежит докерфайл).
При сборке используйте .dockerignore
чтобы убрать сенситив дату, это как .gitignore
.
При сборке вначале команд лучше кешировать команду ран, а потом скопировать исходные данные.
Метадату записать.
Использовать тесты типа Linter и сканеры образов для CI.
Время от времени делать prune, докер любит много места жрать