Описание инструкций Dockerfile
Инструкция | Описание | Пример |
---|---|---|
FROM | Указывает, какой базовый образ нужно использовать. Обязательная инструкция для Dockerfile | FROM ubuntu:16.04 |
MAINTAINER | Автор образа. | MAINTAINER DMosk <master@dmosk.ru> |
RUN | Выполняет команду в новом слое при построении образа. | RUN apt-get install python |
CMD | Запускает команду каждый раз при запуске контейнера. Может быть вызвана только один раз. Если в Dockerfile указать несколько таких инструкций, то выполнена будет последняя. | CMD |
LABEL | Добавляет метаданные. | LABEL version=»2″ |
EXPOSE | Указывает, какой порт должно использовать приложение внутри контейнера. | EXPOSE 8080 |
ENV | Задает переменные окружения в образе. | ENV PGPASSWORD pass |
ADD | Добавляет файлы/папки из текущего окружения в образ. Если в качестве копируемого файла указать архив, то он будет добавлен в образ в распакованном виде. Также в качестве источника принимает URL. | ADD /root/.ssh/{id_rsa,id_rsa.pub} /root/.ssh/ |
COPY | Также как и ADD добавляет файлы в образ, но обладает меньшими функциями — не принимает URL и не распаковывает архивы. Рекомендован для использования в случаях, где не требуются возможности ADD или когда нужно перенести архив, как архив. | COPY ./mypasswd /root/ |
ENTRYPOINT | Указывает команду, которой будет передаваться параметр при запуске контейнера. | ENTRYPOINT [«/sbin/apache2»] |
VOLUME | Добавляет том в контейнер. | VOLUME [«/opt/myapp»] |
USER | Задает пользователя, от которого будет запущен образ. | USER user:group |
WORKDIR | Можно задать каталог, откуда будут запускаться команды ENTRYPOINT и CMD. | WORKDIR /opt/apps |
ARG | Создает переменную, которую может использовать сборщик. | ARG folder=/opt/apps WORKDIR $folder |
ONBUILD | Действия, которые выполняются, если наш образ используется как базовый для другой сборки. | ONBUILD ADD . /app/src |
STOPSIGNAL | Переопределяет сигнал SIGTERM для завершения контейнера. | STOPSIGNAL SIGINT |
HEALTHCHECK | Команда, которая будет проверять работоспособность контейнера. | HEALTHCHECK —interval=5m —timeout=3s CMD curl -f http://localhost/ || exit 1 |
SHELL | Позволяет заменить стандартную оболочку для выполнения команд на пользовательскую. | SHELL [«/bin/sh», «-c»] |
Удалить все контейнеры Docker
Нужно сделать то же самое, но вместо stop выполнить rm
Разберём для
Linux
docker rm $(docker ps -aq)
Альтернативный способ это system prune
docker system prune
WARNING! This will remove:
— all stopped containers
— all networks not used by at least one container
— all dangling images
— all dangling build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
60136dcc356d794d23aee10d3e6440fd53204ed88ad1c45f9bb70d0f66dd1cc4
85375f0f0e5e3d196ec7b11b4f7834aadee167de6c489ce4bf90b940ddec5ea8
33efc448ad6c67ee7e61336482dd7110a059e0c78d8b0a321f0f192ee26a048e
Deleted Images:
deleted: sha256:409d2b2d3c0b20cfb9556bb1e8c69c6e8e8b6120c3883396a5015f109f3f25cb
deleted: sha256:c26bbf7dc2369c5a9e316dbf6c8c0f79fd81b1dd92d5a4ee343060c96cabebf2
deleted: sha256:fcf59b2324beadaf9fc689bb205bc28915a78da42aee860bbb17bded2c54be13
deleted: sha256:c9952ac8387d7dc94e779d2663120f3e93a61a615b710fd7680f0dde63d0c411
deleted: sha256:7b5a2e67a82fb2512681822bfb4fae0b61c135b55ecc55b8fe0bc41ee7d60b40
deleted: sha256:bbdc7e06675baa525c1a65fbedcc3145f3271d49cf828ecd0f77aed5e31e740d
deleted: sha256:08908b45bd8a5b6340e89d9a401e39a04d4c81c66a75b4fc31528c042632bdf9
deleted: sha256:75ed22a7abbe9c23df78263501d5236b7a1dd9649fba94da3aee59ba277fc2c7
deleted: sha256:30f928cfbca4c67e9c284907b304b73a0804fa19b9d8ff22896c6afb79440638
deleted: sha256:b0573c5f42fec17a41f9633532e4f0c1ce77fc111aaec5fa9293bf3975459396
deleted: sha256:a1b7d51ce64b376af6d3e24f10689f04903f7f6174c07f8515127819c4d464f0
deleted: sha256:28115231ced77eebf1e319aacf77c7373f4845f13aa4fd21864cea5b79b5998f
deleted: sha256:954454106831e933798549935ed4bebb0683ccb0807cb4a0ce69537242418d4f
deleted: sha256:043dfc7ae5ae1671626dc1aa082f66791f8579bdcda25c1ccd9d7938c3a352b1
deleted: sha256:32083ac1bbb41043358d3bdf20d2cf6a2b95ddd583fc5f000e723f9ae508cf46
deleted: sha256:f5578f194936295078b78ff2ba8b14807da8b7df240627f3fb85be07bc69f74d
deleted: sha256:1fb565177c22d167b2f0271608e7c2e5a5868e19b36d30fd707604b4f23f0505
deleted: sha256:a1e12e8d24f2e61e9c73c7c29c23b09130fb119cd9672df7f9a03602c0beac84
deleted: sha256:ea493968f3d604b29a929813490d123a8171f2f8a23c67047866b4ee81d4df0c
deleted: sha256:285e528ab55c765304d41679ae7f9b69265bf954762f51b84379212d532ad6bd
deleted: sha256:b11f4e5c2b7fd12935b558f1c6361def6545574703eda262ca1c812c9e60680c
deleted: sha256:af0157c41f52fcf54e4ca265fb5e121b110b66309cebc8ebab09a44eeca21ad0
deleted: sha256:77a594b76fb550d04d4b5a8c2f82bfb7f3cd5b6ac14ac8ab7550de75eb9b86f1
deleted: sha256:1e11339a7869cee0f3b2dd099dd28e1f1f5f987a01639d3e5866efc1f3879cc5
deleted: sha256:dbfcd0b2c04a3ed04f4d99a2b1e65366b43421207230efb9fc30dac37c677fa8
Total reclaimed space: 177.4MB
Подключение к базе из веб-сервера
По отдельности, наши серверы готовы к работе. Теперь настроим их таким образом, чтобы из веб-сервера можно было подключиться к СУБД.
Зайдем в контейнер с базой данных:
docker exec -it maria_db /bin/bash
Подключимся к mariadb:
:/# mysql -p
Создадим базу данных, если таковой еще нет:
> CREATE DATABASE docker_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
* в данном примере мы создаем базу docker_db.
Создаем пользователя для доступа к нашей базе данных:
> GRANT ALL PRIVILEGES ON docker_db.* TO ‘docker_db_user’@’%’ IDENTIFIED BY ‘docker_db_password’;
* и так, мы дали полные права на базу docker_db пользователю docker_db_user, который может подключаться от любого хоста (%). Пароль для данного пользователя — docker_db_password.
Отключаемся от СУБД:
> quit
Выходим из контейнера:
:/# exit
Теперь перезапустим наши контейнеры с новым параметром, который будет объединять наши контейнеры по внутренней сети.
Останавливаем работающие контейнеры и удаляем их:
docker stop maria_db web_server
docker rm maria_db web_server
Создаем docker-сеть:
docker network create net1
* мы создали сеть net1.
Создаем новые контейнеры из наших образов и добавляем опцию —net, которая указывает, какую сеть будет использовать контейнер:
docker run —name maria_db —net net1 -d -v mariadb:/var/lib/mysql mariadb
docker run —name web_server —net net1 -d -p 80:80 dmosk/webapp:v1
* указав опцию —net, наши контейнеры начинают видеть друг друга по своим именам, которые мы задаем опцией —name.
Готово. Для проверки соединения с базой данных в php мы можем использовать такой скрипт:
<?php
ini_set(«display_startup_errors», 1);
ini_set(«display_errors», 1);
ini_set(«html_errors», 1);
ini_set(«log_errors», 1);
error_reporting(E_ERROR | E_PARSE | E_WARNING);
$con = mysqli_connect(‘maria_db’, ‘docker_db_user’, ‘docker_db_password’, ‘docker_db’);
?>
* в данном примере мы подключаемся к базе docker_db на сервере maria_db с использованием учетной записи docker_db_user и паролем docker_db_password.
После его запуска, мы увидим либо пустой вывод (если подключение выполнено успешно), либо ошибку.
Код приложения
В открывшемся проекте рядом с главным классом, содержащим метод main, создаём ещё один класс — контроллер с методом hello ().
Класс помечен аннотацией @RestController, означающей, что он предназначен для обработки web-запросов. А метод помечен аннотацией @GetMapping c адресом «/» — перейдя по нему (выполнив get-запрос к http://localhost:8080/), мы получим сообщение «Hello Docker!»
Теперь открываем терминал и вводим команду:
Она упакует приложение в jar-файл и запустит его. Чтобы убедиться в корректности работы приложения — перейдём на http://localhost:8080/ в браузере и увидим заветное сообщение.
Теперь создаём файл с именем Dockerfile в корне проекта, который содержит инструкции для сборки образа со следующим текстом:
Вот что происходит, когда мы вводим этот код:
Команда | Описание |
---|---|
FROM adoptopenjdk/openjdk11:alpine-jre | Oбраз создаётся на основе alpine linux с установленной openjdk11 |
ARG JAR_FILE=target/spring-docker-simple-0.0.1-SNAPSHOT.jar | Переменной JAR_FILE присваивается путь к jar- архиву |
WORKDIR /opt/app | Назначаем рабочую директорию, в которой будут выполняться дальнейшие команды (перемещаемся в папку app) |
COPY ${JAR_FILE} app.jar | Наш jar-файл, указанный в JAR_FILE, копируется в папку app, и копии задаётся имя app.jar |
ENTRYPOINT | jar-файл запускается, собирается команда java -jar app.jar из заданной рабочей директории |
После этого в терминале вводим команду, с помощью которой собираем образ и запускаем контейнер.
Точка в конце важна, она указывает на расположение Dockerfile (символ «точка» означает текущую директорию. Проверьте, что образ создан командой docker images. Вывод должен быть таким:
Запускаем контейнер командой:
Опция -d означает старт процесса в фоновом режиме. Опция -p тоже важна — дело в том, что контейнер собирается в полностью изолированном окружении. Тот факт, что приложение внутри контейнера запущено на порту 8080, не означает, что оно доступно вне контейнера на этом порту.
Требуется явно указать, что порту 8080 в контейнере (здесь второе значение — это порт, на котором работает наше приложение в контейнере) соответствует порт 8080 на локальной машине, который будет использоваться при обращении к контейнеру. Поэтому пишем через двоеточие -p 8080:8080.
Теперь введём в терминале команду:
Пример упаковки приложения
Упаковка приложения на flask в контейнер.
Подразумеваем, что мы создали небольшое приложение на flask и разместили его код, в файле app.py.
Далее мы создали файл с зависимостями requirements.txt
Соответсвенно в dockerfile необходимо прописать команду для установки всех зависимостей из requirements.txt в образ
Созлаем dockerfile:
FROM python:3.6 RUN mkdir -p /usr/src/app/ WORKDIR /usr/src/app/ COPY . /usr/src/app/ RUN pip install --no-cache-dir -r requirements.txt CMD
Соберем образ из текущего каталога:docker build -t web-hello
Запустим образ с упакованным flask приложением в контейнере:docker run —rm —name web web-hello
Проброска портов
При выполнении этой команды, мы не сможем достучаться до web приложения т.к. не проброшены порты.
По умолчанию flask запускается на порту 8080.
По этому в dockerfile добавим команду:EXPOSE 8080которая говорит о том, что при запуске контейнера, у нас есть возможность(разрешение) пробросить порт 8080.
Запускаем контейнер еще раз с флагом —p
который принимает 2 параметра:1-ый порт на нашей машине2-ой порт в самом контейнере
docker run —rm —name web —p 8080:8080 web-hello
Установка Docker
Рассмотрим примеры установки на базе операционных систем Red Hat/CentOS и Debian/Ubuntu.
Red Hat/CentOS
Устанавливаем репозиторий — для этого загружаем файл с настройками репозитория:
wget https://download.docker.com/linux/centos/docker-ce.repo
* если система вернет ошибку, устанавливаем wget командой yum install wget.
… и переносим его в каталог yum.repos.d:
mv docker-ce.repo /etc/yum.repos.d/
Устанавливаем docker:
yum install docker-ce docker-ce-cli containerd.io
Если система вернет ошибку Необходимо: container-selinux >= …, переходим на страницу пакетов CentOS, находим нужную версию container-selinux и копируем на него ссылку:
… с помощью данной ссылки выполняем установку:
yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.99-1.el7_6.noarch.rpm
После повторяем команду на установку докера:
yum install docker-ce docker-ce-cli containerd.io
В deb-системе ставится командой:
apt-get install docker docker.io
После установки
Разрешаем запуск сервиса docker:
systemctl enable docker
… и запускаем его:
systemctl start docker
После проверяем:
docker run hello-world
… мы должны увидеть:
…
Hello from Docker!
This message shows that your installation appears to be working correctly.
…
Резюме
Правильный способ отсоединения от контейнера Docker — это довольно непонятная последовательность клавиш, которая возвращает вас в оболочку. Вы можете настроить эту последовательность, чтобы улучшить запоминаемость и избежать конфликтов с клавиатурой вашего контейнера.
Последовательности отсоединения клавиатуры могут быть неэффективными в некоторых случаях. По-прежнему можно отсоединиться от контейнера, определив и прервав процесс, поддерживающий вложение. В этом сценарии следует использовать обычные команды Unix, такие как ps и kill.
Наконец, если вы хотите, чтобы ваш контейнер был постоянно отключен, запустите его с флагом -d (docker run -d my-image: latest). Это отправит контейнер прямо в фоновый режим и не будет выводить данные в вашу оболочку. Отсоединенные контейнеры всегда видны с помощью команды docker ps и могут быть остановлены с помощью docker stop my-container.
Использование диска томами
Тома используются для хранения данных вне файловой системы контейнера. Например, когда контейнер запускает приложение с сохранением состояния, данные должны оставаться за его пределами и быть отделены от его жизненного цикла. Тома также используются потому, что тяжелые операции файловой системы внутри контейнера плохо влияют на производительность.
Допустим, мы запускаем контейнер на основе MongoDB, а затем используем его для тестирования бэкапа, который мы сделали ранее (он доступен локально в файле bck.json):
# Запуск контейнера mongo$ docker run --name db -v $PWD:/tmp -p 27017:27017 -d mongo:4.0# Импорт существующего бэкапа (из огромного файла bck.json)$ docker exec -ti db mongoimport \ --db 'test' \ --collection 'demo' \ --file /tmp/bck.json \ --jsonArray
Данные в файле бэкапа будут храниться на хосте в папке . Почему эти данные не сохраняются в слое контейнера? Причина в том, что в Dockerfile образа mongo расположение (где mongo хранит свои данные по умолчанию) определяется как том.
Извлечение Dockerfile, используемого для сборки образа контейнера MongoDB
Примечание: многие образы, часто связанные с приложениями с сохранением состояния, определяют тома для управления данными за пределами слоя контейнера.
Окончив тестирование бэкапа, мы останавливаем или удаляем контейнер. Однако том не удаляется, если мы не сделаем этого явно — он остается, потребляя дисковое пространство. Тогда мы можем пойти долгим путем:
$ docker volume rm $(docker volume ls -q)
Или использовать :
$ docker volume pruneWARNING! This will remove all local volumes not used by at least one container.Are you sure you want to continue? [y/N] yDeleted Volumes:d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d58f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f...732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094daTotal reclaimed space: 25.82GBluc@saturn:~$
Удаление изображений докеров
Удаление одного или нескольких изображений
Чтобы удалить один или несколько изображений Docker, используйте команду , чтобы найти идентификатор изображений, которые вы хотите удалить.
Результат должен выглядеть примерно так:
После того как вы расположены изображения , которые вы хотите удалить, передать их в команду . Например, чтобы удалить первые два изображения, перечисленные в приведенном выше выводе, выполните:
Если вы получили ошибку, аналогичную приведенной ниже, это означает, что изображение используется существующим контейнером. Чтобы удалить изображение, вам нужно сначала удалить контейнер.
Удалить оборванные и неиспользуемые изображения
Docker предоставляет команду , которая может использоваться для удаления оборванных и неиспользуемых изображений.
Оборванное изображение – это изображение, которое не помечено и не используется никаким контейнером. Чтобы удалить висячие изображения, введите:
Вам будет предложено продолжить, используйте флаг или для обхода запроса.
При удалении оборванных изображений, если созданные вами изображения не помечены, они также будут удалены.
Чтобы удалить все изображения, на которые не ссылается какой-либо существующий контейнер, а не только свисающие, используйте флаг :
Удаление изображений с использованием фильтров
С помощью команды вы можете удалить изображения на основе условия, используя флаг фильтрации . На момент написания этой статьи в настоящее время поддерживаются фильтры являются и . Вы можете использовать несколько фильтров, передавая несколько флагов .
Например, чтобы удалить все изображения, созданные более 12 часов назад, выполните:
Основы ENTRYPOINT && CMD
Перед началом нужно кратко вспомнить, что это такое и чем отличается. Эти две директивы в Dockerfile наверняка всем известны – обе запускают процессы в контейнере. Как правило, в entrypoint используется какой-либо скрипт или команда для запуска процесса внутри контейнера, а в cmd – параметры, которые передаются в entrypoint.
Если указывать параметры в квадратных скобках, т.е. в формате exec, то внутри контейнера будет выполняться лишь процесс, который указан для запуска, и никаких оболочек запущено не будет. Это значит, что замена (substitution) переменных и их обработка невозможны – это также предпочтительный вариант для простого запуска какого-либо процесса. О более сложных моментах будет рассказано далее.
Если же указать команду для запуска без фигурных скобок, то внутри контейнера можно будет увидеть, что процесс запущен через форму shell и процесс внутри будет вида sh -c “ping ya.ru”.
Грубый пример Dockerfile для демонстрации работы exec формы:
После сборки образа с именем “ping” и дальнейшего запуска контейнера из него будет выполняться команда “/bin/ping it-lux.ru”. Домен можно переопределить, указав его при запуске контейнера, например:
Тем самым выполняется переопределение значения из параметра CMD в Dockerfile, что очень удобно – из одного образа можно запускать команды с различными аргументами. Такой способ я использовал для выполнения крон-задач в отдельном докер-контейнере, указывая на хосте в crontab через аргументы путь к скриптам при запуске docker run, которые принимал для выполнения php.
Удаление контейнеров
Удаление одного или более определённых контейнеров
Используйте команду docker ps с флагом -a для определения имён или ID контейнеров, которые вы хотите удалить:
Получение списка:
docker ps -a
Удаление:
docker rm ID_or_Name ID_or_Name
Удаление контейнера при выходе
Если во время создания контейнера вы знаете, что вы не хотите сохранять его после завершения работы с ним, вы можете запустить docker run —rm для автоматического его удаления при выходе.
Запуск и удаление:
docker run --rm image_name
Удаление всех существующих контейнеров
Вы можете найти все контейнеры используя docker ps -a и отфильтровывая по их статусу: created, restarting, running, paused или exited. Для просмотра списка exited (из которых вышли) контейнеров, используйте флаг -f для фильтрации на основе статуса. Когда убедитесь, что хотите удалить эти контейнеры, используйте -q для передачи ID в команду docker rm.
Получение списка:
docker ps -a -f status=exited
Удаление:
docker rm $(docker ps -a -f status=exited -q)
Удаление контейнеров используя более чем один фильтр
Фильтры Docker могут быть скомбинированы повторением тэга фильтра с дополнительным значением. Этот результаты, которые соответствуют хотя бы одному из условий. Например, вы хотите удалить все контейнеры отмеченые как Created (состояние, которое может возникнуть в результате запуска контейнера с неверной командой) или Exited вы можете использовать два фильтра:
Получение списка:
docker ps -a -f status=exited -f status=created
Удаление:
docker rm $(docker ps -a -f status=exited -f status=created -q)
Удаление контейнеров в соответствии с образцом
Вы можете найти все контейнеры, которые соответствуют образцу, используя комбинацию docker ps и grep. Когда вам удалось составить список, удовлетворяющий вашим желаниям для удаления, вы можете использовать awk и xargs для передачи ID в docker rmi. Помните, что эти утилиты не поставляются с Docker и не обязательно присутствуют в вашей системе:
Получение списка:
docker ps -a | grep "pattern”
Удаление:
docker ps -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
Остановить и удалить все контейнеры
Просмотреть все контейнеры на вашей системе вы можете с docker ps. Добавление флаг -a покажет все контейнеры. Когда вы уверены, что вы хотите удалить их, добавьте флаг -q для передачи ID в команды docker stop и docker rm:
Получение списка:
docker ps -a
Удаление:
docker stop $(docker ps -a -q) docker rm $(docker ps -a -q)
Изменение последовательности для каждого контейнера
Помимо изменения вашей глобальной конфигурации, Docker принимает переопределения detachKeys для каждого контейнера и каждого вложения. Добавьте флаг —detach-keys к командам, которые могут присоединяться к процессам контейнера, чтобы установить определенную последовательность.
Команды, которые это поддерживают:
- докер запустить
- докер старт
- docker exec
- докер прикрепить
Вот как присоединиться к контейнеру, а затем использовать Ctrl-d с последующим подчеркиванием для отсоединения:
docker attach my-container —detach-keys = «Ctrl-d, _»
Флаг —detach-keys использует тот же формат последовательности клавиш, что и параметр конфигурации detachKeys. Флаг отменяет настройку docker.json; это, в свою очередь, отменяет последовательность Docker по умолчанию Ctrl-P / Ctrl-Q.
Выполнение контейнера Windows
В этом простом примере будет создан и развернут образ контейнера «Hello World». Для вашего удобства лучше выполнять эти команды в окне командной строки с повышенными привилегиями. Не используйте интегрированную среду сценариев Windows PowerShell, так как она не работает для интерактивных сеансов с контейнерами и в результате контейнеры перестают отвечать на запросы.
-
Запустите контейнер с интерактивным сеансом из образа . Для этого введите следующую команду в окне командной строки:
-
После запуска контейнера окно командной строки переходит в контекст контейнера. Внутри контейнера мы создадим простой текстовый файл «Hello World», а затем выйдем из контейнера с помощью следующих команд:
-
Получите идентификатор контейнера, из которого вы только что вышли, выполнив команду docker ps:
-
Создайте новый образ HelloWorld с учетом тех изменений, которые внесли в первом запущенном контейнере. Для этого выполните команду docker commit, заменив идентификатором реального контейнера:
После завершения вы получите пользовательский образ, содержащий скрипт «Привет мир». Это можно проверить с помощью команды docker images.
Ниже приведен пример выходных данных.
-
Наконец, запустите новый контейнер с помощью команды docker run с параметром , который позволяет автоматически удалить контейнер по завершении работы командной оболочки (cmd.exe).
В результате Docker создает контейнер на основе образа HelloWorld. В этом контейнере Docker запускает экземпляр командной строки cmd.exe, которая считывает указанный файл и выводит его содержимое в оболочку. В конце Docker приостанавливает работу контейнера и удаляет его.
Отсоединение без остановки
Docker поддерживает комбинацию клавиш для изящного отсоединения от контейнера. Нажмите Ctrl-P, а затем Ctrl-Q, чтобы отключить соединение.
Вы вернетесь в свою оболочку, но ранее присоединенный процесс останется живым, поддерживая работу вашего контейнера. Вы можете проверить это, используя docker ps, чтобы получить список запущенных контейнеров.
Нажатие Ctrl-C или запуск команды выхода обычно завершает процесс переднего плана контейнера, если он не был специально настроен. Контейнер Docker должен иметь работающий процесс переднего плана; контейнер без него перейдет в остановленное состояние.
Остановка, запуск и перезапуск контейнеров
Вы можете остановить запуск контейнеров и запустить остановленный контейнер. Существует несколько различий между запуском остановленного контейнера и запуском нового экземпляра того же образа:
- Вы используете одни и те же переменные среды, тома, порты и другие аргументы исходной команды запуска.
- Вам не нужно создавать еще один контейнер.
- Если остановленный экземпляр изменил свою файловую систему, запущенный контейнер будет использовать то же самое.
Давайте остановим контейнер nginx, а затем запустим его. Когда вы ссылаетесь на контейнер, вы можете использовать его имя или однозначный префикс своего идентификатора. Обычно я называю свои контейнеры долгожители, поэтому у меня есть значащий дескриптор и не нужно иметь дело с автогенерируемыми именами Docker или префиксами идентификаторов контейнеров.
ОК. Nginx остановлен (статус « Exited»). Давайте начнем:
Перезапуск работающего контейнера — это еще один вариант, который эквивалентен , за которым следует .
Общее потребление
Docker великолепен, и в этом нет сомнений. Пару лет назад он представил новый способ сборки, доставки и запуска любых рабочих нагрузок, демократизируя использование контейнеров и чрезвычайно упрощая управление их жизненным циклом.
Такой подход предоставил разработчику возможность запускать любые приложения, не загрязняя локальную машину. Однако, когда мы запускаем контейнеры, развертываем сложные стеки приложений, создаем собственные образы и извлекаем их, потребление памяти в файловой системе хоста может значительно увеличиться.
Если мы не очищали локальную машину в течение некоторого времени, то результаты этой команды могут удивить:
$ docker system df
Пример потребления памяти Docker в файловой системе хоста
Эта команда показывает использование диска Docker в нескольких категориях:
- Образы (Images): размер образов, извлеченных из реестра и созданных локально.
- Контейнеры (Containers): дисковое пространство, занимаемое слоями чтения-записи каждого из контейнеров, работающих в системе.
- Локальные тома (Local Volumes): в случае, если хранение осуществляется на хосте, но вне файловой системы контейнера.
- Кэш сборки (Build Cache): кэш, сгенерированный процессом сборки образа (касается BuildKit в Docker 18.09).
Из вывода выше видно, что большое количество дискового пространства можно восстановить. Поскольку оно не используется Docker, его можно вернуть хост-машине.
Удаление образов Docker
Когда вы загружаете образ Docker, он сохраняется на сервере, пока вы не удалите его вручную.
Удаление одного или нескольких изображений
Чтобы удалить один или несколько образов Docker, сначала вам нужно найти идентификаторы образов:
Результат должен выглядеть примерно так:
После того, как вы найдете изображения, которые хотите удалить, передайте их команде . Например, чтобы удалить первые два изображения, перечисленные в выходных данных выше, вы должны запустить:
Если вы получили сообщение об ошибке, подобное приведенному ниже, это означает, что существующий контейнер использует изображение. Чтобы удалить изображение, вам сначала нужно удалить контейнер.
Удаление болтающихся изображений
Docker предоставляет команду удаления которую можно использовать для удаления оборванных и неиспользуемых образов.
Оборванное изображение — это изображение, которое не помечено и не используется никаким контейнером. Чтобы удалить болтающиеся изображения, введите:
Будьте осторожны при выполнении этой команды. Если вы построили изображение без тега, оно будет удалено.
Удаление всех неиспользуемых изображений
Чтобы удалить все изображения, на которые не ссылается какой-либо существующий контейнер, а не только висячие, используйте команду с параметром :
Удаление изображений с помощью фильтров
С помощью команды вы также можете удалять изображения в зависимости от определенного условия с параметром .
Например, чтобы удалить все изображения, созданные более семи дней (168 часов) назад, вы должны запустить:
Запуск образа в контейнере
docker run my-supper-image — Запускает образ в контейнере, после run передаем имя приложения.
Если вывести все контейнеры:docker ps -a
Мы увидим таблицу, где в графе name нашему контейнеру присвоилось имя blablabla_lala.Если мы хотим задать собственное имя для контейнера, то при запуске нужно указать, директиву —name:docker run —name my-new-name my-supper-image
Если после этого выполнить команду:docker ps -a
В таблице в поле name мы увидим:blablabla_lala — имя контейнера запущенного в 1-ый разmy-new-name — имя контейнера запущенного с директивой name
т.е. по факту мы уже имеем уже 2 контейнера на основании 1-го образа.
Запуск
На этом этапе команды на выполнение даются “как есть” без объяснения деталей. Подробнее о том, как их формировать и
что в них входит разбирается позже.
Начнем с самого простого варианта:
При первом вызове данная команда начнет скачивать образ (image) nginx, поэтому придется немного подождать. После того, как образ скачается, запустится bash, и вы окажетесь внутри контейнера (container).
Побродите по файловой системе, посмотрите директорию /etc/nginx. Как видите, её содержимое не совпадает с тем, что находится у вас на компьютере. Эта файловая система появилась из образа nginx. Всё, что вы сделаете здесь внутри, никак не затронет вашу основную файловую систему. Вернуться в родные скрепы можно командой .
Теперь посмотрим вариант вызова команды , выполненной уже в другом контейнере, но тоже запущенном из образа nginx:
Команда выполняется практически мгновенно, так как образ уже загружен. В отличие от предыдущего старта, где запускается баш и начинается интерактивная сессия внутри контейнера, запуск команды для образа nginx выведет на экран содержимое указанного файла (взяв его из файловой системы запущенного контейнера) и вернет управление в то место, где вы были. Вы не окажетесь внутри контейнера.
Последний вариант запуска будет таким:
Данная команда не возвращает управление, потому что стартует nginx. Откройте браузер и наберите . Вы увидите как загрузилась страница Welcome to nginx!. Если в этот момент снова посмотреть в консоль, где был запущен контейнер, то можно увидеть, что туда выводится лог запросов к . Остановить nginx можно командой Ctrl + C.
Несмотря на то, что все запуски выполнялись по-разному и приводили к разным результатам, общая схема их работы — одна. Докер при необходимости автоматически скачивает образ (первый аргумент после ) и на основе него стартует контейнер с указанной командой.
Образ — самостоятельная файловая система. Пока мы используем готовые образы, но потом научимся создавать их самостоятельно.
Контейнер — запущенный процесс операционной системы в изолированном окружении с подключенной файловой системой из образа.
Повторюсь, что контейнер — всего лишь обычный процесс вашей операционной системы. Разница лишь в том, что благодаря возможностям ядра (о них в конце) Докер стартует процесс в изолированном окружении. Контейнер видит свой собственный список процессов, свою собственную сеть, свою собственную файловую систему и так далее. Пока ему не укажут явно, он не может взаимодействовать с вашей основной операционной системой и всем, что в ней хранится или запущено.
Попробуйте выполнить команду и наберите внутри запущенного контейнера. Вывод будет таким:
Как видно, процесса всего два, и у Bash PID равен 1. Заодно можно посмотреть в директорию /home командой и убедиться, что она пустая
Также обратите внимание, что внутри контейнера по умолчанию используется пользователь