Docker — это популярная платформа для создания, запуска и управления контейнерами. Она помогает разработчикам и системным администраторам быстро развертывать приложения в изолированном и переносимом окружении.
Подробнее о самом Docker и его установке мы говорили в отдельных статьях. Сегодня мы рассмотрим основные шаги для создания контейнеров и управления ими.
Создание и запуск контейнера
- Пример 1: Явное скачивание образа и запуск контейнера
- Пример 2: Запуск контейнера без предварительного скачивания
Пример 1: Явное скачивание образа и запуск контейнера
Допустим, вы хотите запустить в контейнере веб-сервер NGINX. Сначала вручную, с помощью pull, скачиваем образ:
[root@waky ~]# docker pull nginx
Using default tag: latest
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
[root@waky ~]# systemctl start docker
[root@waky ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
38513bd72563: Pull complete
10d18f46ee87: Pull complete
a8d825a0683a: Pull complete
a131bc1d4bd5: Pull complete
3818929ac19f: Pull complete
1498b1cfda15: Pull complete
c50c84d0ed4d: Pull complete
Digest: sha256:029d4461bd98f124e531380505ceea2072418fdf28752aa73b7b273ba3048903
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@waky ~]#
Эта команда ищет образ nginx в локальной системе. Если он там есть, Docker использует его. Если нет — автоматически скачает его из Docker Hub и сохранит у вас локально. Если не указывать версию образа будет скачан последний (latest).
Затем запускаете контейнер командой run:
[root@waky ~]# docker run -d --name nginx_container -p 8080:80 nginx
398af1888e7dc4717f55a744235b0a86f0e3e4866c8db43020d77075ef104f23
[root@waky ~]#
Использованные параметры запуска:
–d, —detach – запуск контейнера в фоновом режиме
—name – имя контейнера
–p, —publish list – привязка портов контейнера к портам хоста, в данном случае 80 порт контейнера к 8080 сервера, на котором работает Docker
Docker находит образ nginx в локальном хранилище и создает из него контейнер. На вывод подается ID созданного контейнера.
Мы можем проверить работу контейнера с помощью curl, обратимся к 8080 порту сервера, на который транслируется 80 (дефолтный) порт на котором работает веб сервер NGINX в контейнере.
[root@waky ~]# curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@waky ~]#
В ответ получили приветственную страницу NGINX.
Это классический сценарий: сначала pull, затем run.
Пример 2: Запуск контейнера без предварительного скачивания
Теперь попробуем запустить контейнер с другим образом — например, alpine. Это один из часто используемых образов, он содержит минимальную Linux-систему, и является отличной базой для создания собственных образов и контейнеров.
У нас еще нет образа alpine, но мы сразу используем run:
[root@waky ~]# docker run -it --name alpine_shell alpine /bin/sh
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
2d35ebdb57d9: Pull complete
Digest: sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
Status: Downloaded newer image for alpine:latest
/ #
Использованные параметры запуска:
–i, —interactive – держит STDIN контейнера открытым
–t, —tty – дает доступ до псевдо терминала
—name – имя контейнера
Docker ищет образ alpine у себя. Не находит и автоматически скачивает с Docker Hub, сохраняя его локально. После этого запускает контейнер, и выполняет переданную команду – /bin/sh. В итоге мы оказываемся в интерактивной оболочке внутри контейнера.
Для проверки выполним простейшую команду и выйдем из этой консоли:
/ # ping -c 3 google.com
PING google.com (74.125.131.113): 56 data bytes
64 bytes from 74.125.131.113: seq=0 ttl=105 time=121.833 ms
64 bytes from 74.125.131.113: seq=1 ttl=105 time=122.183 ms
64 bytes from 74.125.131.113: seq=2 ttl=105 time=122.364 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 121.833/122.126/122.364 ms
/ # exit
[root@waky ~]#
Управление контейнерами
После запуска контейнера, важно уметь управлять ими:
| Команда | Описание |
docker ps | Просмотр запущенных контейнеров |
docker ps -a | Просмотр всех контейнеров (в т.ч. остановленных) |
docker stop <имя/ID> | Остановка контейнера |
docker start <имя/ID> | Запуск остановленного контейнера |
docker restart <имя/ID> | Перезапуск контейнера |
docker rm <имя/ID> | Удаление остановленного контейнера |
docker images | Просмотр скачанных образов |
docker rmi | Удаление образа |
Просмотр запущенных контейнеров
Команда ps выводит список работающих контейнеров с указанием их ID, имени, образа из которого создан контейнер и прочей полезной информации:
[root@waky ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
398af1888e7d nginx "/docker-entrypoint.…" 50 minutes ago Up 50 minutes 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp nginx_container
[root@waky ~]#
Мы видим только один контейнер nginx_container, так как alpine_shell завершил свою работу после выхода из консоли.
Просмотр всех контейнеров
Для вывода всех контейнеров, в том числе и остановленных, используется аргумент -a:
[root@waky ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31085b7910c5 alpine "/bin/sh" 22 minutes ago Exited (0) 18 minutes ago alpine_shell
398af1888e7d nginx "/docker-entrypoint.…" 50 minutes ago Up 50 minutes 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp nginx_container
[root@waky ~]#
В данном выводе содержаться уже оба использованных контейнера.
Остановка контейнера
Работая с отдельными контейнерами можно использовать как их идентификатор (ID)так и имя (имена контейнеров уникальны).
Чтобы остановить контейнер используйте stop:
[root@waky ~]# docker stop nginx_container
nginx_container
[root@waky ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@waky ~]#
Список работающих контейнеров пуст.
Запуск остановленного контейнера
С помощью start запустим обратно этот же контейнер, но вместо имени используем ID:
[root@waky ~]# docker start 398af1888e7d
398af1888e7d
[root@waky ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
398af1888e7d nginx "/docker-entrypoint.…" 4 hours ago Up 5 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp nginx_container
[root@waky ~]#
Наш контейнер снова в списке активных.
Перезапуск контейнера
При необходимости перезапустить контейнер используется команда restart:
[root@waky ~]# docker restart nginx_container
nginx_container
[root@waky ~]#
Удаление остановленного контейнера
Удалим второй контейнер используя rm:
[root@waky ~]# docker rm alpine_shell
alpine_shell
[root@waky ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
398af1888e7d nginx "/docker-entrypoint.…" 4 hours ago Up 8 minutes 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp nginx_container
[root@waky ~]#
Контейнера с alpine не осталось в списке существующих контейнеров. Удаление контейнера не удаляет образ, из которого был создан этот контейнер.
Попробуем удалить первый контейнер:
[root@waky ~]# docker rm nginx_container
Error response from daemon: cannot remove container "nginx_container": container is running: stop the container before removing or force remove
[root@waky ~]# docker stop nginx_container
nginx_container
[root@waky ~]# docker rm nginx_container
nginx_container
[root@waky ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@waky ~]#
При первой попытке мы получили ошибку – нельзя удалить работающий контейнер. Поэтому сначала останавливаем, потом удаляем.
Просмотр скачанных образов
Осталось разобраться с образами. Получим список локальных образов:
[root@waky ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 706db57fb206 2 weeks ago 8.32MB
nginx latest 657fdcd1c365 2 weeks ago 152MB
[root@waky ~]#
Удаление образа
Удалим оставшиеся образы командой rmi:
[root@waky ~]# docker rmi alpine nginx
Untagged: alpine:latest
Untagged: alpine@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
Deleted: sha256:706db57fb2063f39f69632c5b5c9c439633fda35110e65587c5d85553fd1cc38
Deleted: sha256:256f393e029fa2063d8c93720da36a74a032bed3355a2bc3e313ad12f8bde9d1
Untagged: nginx:latest
Untagged: nginx@sha256:029d4461bd98f124e531380505ceea2072418fdf28752aa73b7b273ba3048903
Deleted: sha256:657fdcd1c3659cf57cfaa13f40842e0a26b49ec9654d48fdefee9fc8259b4aab
Deleted: sha256:80a172d7673c2438064e08c7891798ae736b9f65b24b33ee849aa519d660d0be
Deleted: sha256:d0437576e6e1ca87b75c0fc237b8afc322ddfb3ae0327a177503571a2f4bb20c
Deleted: sha256:eb5bda0607e6f7ae16c240a351645078a0249891a3a44d0d6a9ac41d55e2b446
Deleted: sha256:4ab1e8afb5f1c3249d9d243e1b4cd6abcedd20cd16693893852e97c1fc3a97f4
Deleted: sha256:0b7735a9234f3aff06db222061ecc411841f3b82ad205d3166618ea9fbf0ae80
Deleted: sha256:5ba3270e2400d2ade941f6ffe0e69696b3b47261239347f2fea5b74a39508a07
Deleted: sha256:d7c97cb6f1fe7cae982649e9f55efe201212e8acaa64bd668c083b204e4efd4c
[root@waky ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@waky ~]#
Тут тоже есть очевидное ограничение – нельзя удалить образ, если он используется каким либо контейнером.
Заключение
Мы разобрались, как создавать и удалять контейнеры, а так же управлять ими. Попробуйте повторить весь цикл команд самостоятельно. Знание основных команд сильно упрощает и ускоряет повседневную работу с Docker.