Работа с 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 образа, либо же можно задать имя образа

Создание своего образа

  1. Создаём сначала контейнер:
    		docker run -it --name [myapp] --hostname [hostname] ubuntu bash
    где [myapp] - это название контейнера, а [hostname] - название хоста. Например:
    		docker run -it --name myapp --hostname myapp ubuntu bash
  2. Далее внутри контейнера выполняются нужные команды, производятся необходимые настройки, создаются символьные ссылки на нужные бинарники.
  3. Превращаем контейнер в образ:
    		docker commit [containter_name] [user_name]/[app_name]
    где [containter_name] - это название контейнера, которое мы указывал при создании контейнера, передавая через опцию --name, [user_name] - это имя пользователя на https://hub.docker.com, а [app_name] - название приложения. В примере приведённом выше [containter_name] является myapp.
  4. Перед тем как отправлять образ на https://hub.docker.com необходимо произвести авторизацию с помощью команды:
    		docker login -u "[user_name]" -p "[password]" docker.io
    где [user_name] это имя пользователя на hub.docker.com, а [password] это пароль.
  5. Отправляем образ на 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 понадобится следующее:

Файловая структура проекта:

  • каталог 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/

Laradock

Шпаргалка про Laradock

Тэги:

Тэг в списке: