Работа с Docker
В данный момент изучаю Docker по программе курса, ссылка на первое занятие которого находится под этим параграфом.
Описание часто используемых команд Docker
Основная команда это:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
она запускает команды в новом контейнере.
Оригинальный текст, доступный по ссылке на официальном сайте:
The docker run command first creates a writeable container layer over the specified image, and then starts it using the specified command. That is, docker run is equivalent to the API /containers/create then /containers/(id)/start. A stopped container can be restarted with all its previous changes intact using docker start. See docker ps -a to view a list of all containers.
Мой вольный перевод:
Командаdocker run
сначала создаёт доступный для записи слой контейнера поверх определённого образа, а затем запускает его используя определённые команды. Это можно трактовать как то, чтоdocker run
эквивалентно API/containers/create
, а затем/containers/(id)/start
. Остановленный контейнер может быть перезапущен вместе со всеми его предыдущими нетронутыми изменениями используяdocker start
. Вызовитеdocker ps -a
посмотреть список всех контейнеров.
Для начала рекомендую добавить текущего пользователя в группу docker для того, чтобы не приходилось каждый раз набирать sudo
.
sudo usermod -aG docker [username] sudo service docker restart
docker run -it ubuntu bash
Ключи -i
и -t
говорят о том, что необходимо создать сеанс интерактивной работы на подключаемом терминальном устройстве. ubuntu
в данном случае это название образа, а bash
инициализирует командную оболочку /bin/bash
. После загрузки и проверки образа docker помещает его в рабочий контейнер, который лежит на host-машине.
Вывод списка всех контейнеров, включая остановленные:
docker ps -a
Запуск контейнера по имени:
docker start [containter_name]
где [containter_name] - имя контейнера.
Остановка контейнера по имени:
docker stop [containter_name]
где [containter_name] - имя контейнера.
Инициализация контейнера со своим именем хоста:
docker run -h [host_name] -it ubuntu bash
где [host_name] - имя хоста.
Получить информацию о контейнере:
docker inspect [containter_name]
где [containter_name] - имя контейнера.
Задать имя для контейнера:
docker run --name [containter_name] -it ubuntu bash
где [containter_name] - имя контейнера..
Посмотреть список изменённых файлов в работающем контейнере:
docker diff [containter_name]
где [containter_name] - имя контейнера..
Посмотреть список событий, произошедших в заданном контейнере:
docker logs [containter_name]
где [containter_name] - имя контейнера.
Удалить контейнер:
docker rm [containter_name]
где [containter_name] - имя контейнера.
Вывести идентификаторы всех остановленных контейнеров:
docker ps -aq -f status=exited
Удалить все остановленные контейнеры:
docker rm -v $(docker ps -aq -f status=exited)
Запуск контейнера в фоновом режиме:
docker run -d bitnami/apache
Запуск контейнера с пробрасыванием порта:
docker run -d -p 8000:8080 bitnami/apache
где 8000 - это порт на хости-машине, а 8080 - это порт внутри контейнера
Список существующих образов, который мы получали ранее:
docker images
Удалить образ:
docker rmi [id_image]
где [id_image] - это id образа
Удалить образы с остановленными контейнерами:
docker rmi $(docker images -q) --force
Посмотреть историю образа:
docker history [id_image]
где [id_image] - это id образа, либо же можно задать имя образа
Создание своего образа
- Создаём сначала контейнер:
docker run -it --name [myapp] --hostname [hostname] ubuntu bash
где [myapp] - это название контейнера, а [hostname] - название хоста. Например:docker run -it --name myapp --hostname myapp ubuntu bash
- Далее внутри контейнера выполняются нужные команды, производятся необходимые настройки, создаются символьные ссылки на нужные бинарники.
- Превращаем контейнер в образ:
docker commit [containter_name] [user_name]/[app_name]
где [containter_name] - это название контейнера, которое мы указывал при создании контейнера, передавая через опцию--name
, [user_name] - это имя пользователя на https://hub.docker.com, а [app_name] - название приложения. В примере приведённом выше [containter_name] является myapp. - Перед тем как отправлять образ на https://hub.docker.com необходимо произвести авторизацию с помощью команды:
docker login -u "[user_name]" -p "[password]" docker.io
где [user_name] это имя пользователя на hub.docker.com, а [password] это пароль. - Отправляем образ на Hub:
docker push [user_name]/[app_name]
Создание своего образа с помощью Dockerfile
В нужной директории необходимо создать файл с названием Dockerfile и указать в нём необходимые инструкции. Пример содержимого такого файла:
FROM ubuntu RUN apt-get update && apt-get install -y cowsay && ln -s /usr/games/cowsay /usr/bin/cowsay
где конструкция FROM
отвечает за задание базового образа, а конструкция RUN
за выполнение определённых команд после загрузки базового образа. Далее в этой же директории выполняем команду:
docker build -t [user_name]/[app_name] .
где флаг -t
отвечает за имя образа, [user_name] это имя пользователя на hub.docker.com, [app_name] - название приложения. После этого можно запускать контейнер:
docker run [user_name]/[app_name] cowsay "Hello World!"
Также можно указать свою точку входа с помощью конструкции ETRYPOINT []
. Она выполнится при команде docker run
. Вот так:
FROM ubuntu RUN apt-get update && apt-get install -y cowsay && ln -s /usr/games/cowsay /usr/bin/cowsay ENTRYPOINT ["cowsay"]
После этого после выполнения команды
docker build -t [user_name]/[app_name] .
можно запустить контейнер уже вот так:
docker run [user_name]/[app_name] "TEST"
после чего команда cowsay
выполнится автоматически.
Итоговый файл:
FROM ubuntu MAINTAINER Ivan Ivanov <ivanov@gmail.com> RUN apt-get update && apt-get install -y cowsay && ln -s /usr/games/cowsay /usr/bin/cowsay ENTRYPOINT ["cowsay"]
где в конструкции MAINTAINER задаётся имя разработчика образа.
Соединение контейнеров между собой. Пример:
Берём следующие образы:
И выполняем следующие команду:
docker run --name mysqlserver -e MYSQL_ROOT_PASSWORD=123456 -d mariadb
то есть запускаем контейнер mysqlserver образа mariadb в фоновом режиме(опция -d
), и с помощью опции -e
передаём переменную окружения MYSQL_ROOT_PASSWORD со значением 123456
А также команду:
docker run --link mysqlserver:db -p 8080:8080 adminer
тут мы выполняем команду, в которой передаём информацию о том, что нам нужно установить соединение между новым контейнером, который будет создан на базе образа adminer и существующим контейнером mysqlserver. И в новом контейнере ссылка на существующий обозначается именем db. В файле /etc/hosts нового контейнера указывается запись на ip-адрес контейнера mysqlserver. Это позволяет нам пользоваться именем данного хоста. По сути в новом контейнере образа adminer создаётся DNS-запись имя и IP-адрес контейнера с базой MySQL. Для установления соединения между контейнерами в системе используется команда --link.
Запуск контейнеров с помощью docker-compose
Теперь можно рассмотреть пример аналогичной конфигурации запуска контейнеров, только с помощью docker-compose. Необходимо в директории проекта создать файл с названием docker-compose.yml
, либо же docker-compose.yaml
, в котором будут указаны все необходимые настройки.
Пример файла docker-compose.yml
:
version: '3.1' services: db: image: mariadb restart: always environment: MYSQL_ROOT_PASSWORD: 123456 adminer: image: adminer restart: always ports: - 6080:8080
По секциям:
version
- версия формата файла compose. Подробнее про описание можно посмотреть по ссыкле https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix . Также по ссылке https://github.com/docker/compose/releases можно посмотреть какие версии файлов доступны для текущих версий composer и docker-compose. https://sreeninet.wordpress.com/2017/03/28/comparing-docker-compose-versions - таблица с версиями docker и docker-compose- в секции
services
перечислены контейнеры. В данном примере это db и adminer. Не нужно путать с именами которые передаются в опции--name
в командеdocker run -it --name=myapp
!!! - в секции
image
передаётся название образа - В секции
restart
определяем будет ли перезапускать контейнер после неожиданного сбоя. - В секции
environment
мы определяем значения переменных среды в контейнере - В секции
port
мы указываем значения портов, которые будут использоваться на локальной машине(первым значением) и в контейнере(второе значение после двоеточия)
Запускаем контейнер следующим образом:
docker-compose up -d
опция -d
как и везде указывает, что запускаем в фоновом режиме.
Посмотреть запущенные с помощью docker-compose контейнеры можно также командой:
docker-compose ps
Совместный запуск контейнера с помощью docker-compose и Dockerfile
Первый вариант файла docker-compose.yml:
version: '3.1' services: db: build: ./db restart: always environment: MYSQL_ROOT_PASSWORD: 123456 adminer: build: ./adminer restart: always ports: - 6080:8080
Тут нужно обратить внимание на то, что в этом файле нет секции image
, но появилась секция build
, в которой указана папка, содержащая в себе Dockerfile, в котором описаны нужные конструкции.
Для секции db
содержимое файла Dockerfile:
FROM mariadb
Для секции adminer
содержимое файла Dockerfile:
FROM adminer
Далее перестраиваем проект следующей командой:
docker-compose build
и после этого уже можно запускать
docker-compose up
Остановка и удаление контейнеров с помощью docker-compose
Команда
docker-compose stop
остановит ваши запущенные docker-контейнеры, однако не удалит их. В отличии от нее, команда
docker-compose down
остановит запущенные docker-контейнеры и удалит их, а также все docker-сети (networks) созданные при запуске связки контейнеров из файла docker-compose.yml.
Подключение тома с помощью docker-compose
Файл docker-compose.yml будет выглядеть следующим образом:
version: '3.1' services: db: build: ./db restart: always environment: MYSQL_ROOT_PASSWORD: 123456 volumes: - ./databases:/var/lib/mysql adminer: build: ./adminer restart: always ports: - 6080:8080
где в секции volumes
мы как раз и инициализируем том.
Объяснение того, как можно уменьшить размер образа
Тут нужно просто смотреть:
Использование Docker на примере запуска laravel
Тут тоже лучше посмотр:
Текстовое описание
Итак нам для запуска примера одного проекта на Laravel понадобится следующее:
- Образ PHP: https://hub.docker.com/_/php
- Образ MySQL: https://hub.docker.com/_/mariadb/
- Образ Composer: https://hub.docker.com/_/composer/
- Ссылка на проект на GitHub: https://github.com/dka-develop/dka-blog
Файловая структура проекта:
- каталог
databases
- здесь будут храниться таблицы БД; - каталог
dka-blog
- папка с проектом, скачанная через Git; - каталог
web
- каталог, в котором хранится Dockerfile, содержащий настройки образа PHP; - файл
.env
- файл с наcтройками констант путей в файловой структуре хост-машины и контейнера - файл
docker-compose.yml
- основной файл с настройками образов и контейнеров
Содержимое файла .env
#PATH DB_PATH_HOST=./databases # путь к проекту на хост-машине, то есть вне контейнера APP_PATH_HOST=./dka-blog # путь к каталогу с проектом в контейнере, будет иметь расшаренную папку # внутри контейнера APP_PATH_CONTAINER=/var/www/html/
Содержимое файла docker-compose.yml
version: '3' services: web: build: ./web environment: - APACHE_RUN_USER=#1000 volumes: - ${APP_PATH_HOST}:${APP_PATH_CONTAINER} ports: - 8080:80 working_dir: ${APP_PATH_CONTAINER} db: image: mariadb restart: always environment: MYSQL_ROOT_PASSWORD: 123456 volumes: - ${DB_PATH_HOST}:/var/lib/mysql adminer: image: adminer restart: always ports: - 6080:8080 composer: image: composer:1.10.5 volumes: - ${APP_PATH_HOST}:${APP_PATH_CONTAINER} working_dir: ${APP_PATH_CONTAINER} command: composer install
Содержимое файла Dockerfile
из папки web
FROM php:7.2-apache RUN docker-php-ext-install \ pdo_mysql \ && a2enmod \ rewrite
Сборка и запуск проекта:
docker-compose up --build
после первой сборки проекта в последующие разы достаточно будет запускать командой docker-compose up
- если файл Dockerfile и docker-compose.yml не менялись.
Войти в контейнер веб-сервера в командной строке:
docker-compose exec web bash
где docker-compose exec
- это вход в контейнер, web
- название контейнера из секции services в файле docker-compose.yml, а bash
- запуск bash.
Дальше нужно просто сгенерировать ключ для приложения Laravel командой:
php artisan key:generate
в файле .env
приложения Laravel прописать настройки доступа к БД, где опция DB_HOST
будет равна названию секции в файле docker-compose.yml
в секции services
, отвечающему за хранение БД. В данном случае это db. То есть DB_HOST=db
, так как:
db: image: mariadb restart: always environment: MYSQL_ROOT_PASSWORD: 123456 volumes: - ${DB_PATH_HOST}:/var/lib/mysql
и после этого уже выполнить стандартные миграции начальные:
php artisan migrate
Ссылки на полезные шпаргалки по Docker
https://habr.com/ru/company/flant/blog/336654/