Глава 4. Декларативное описание нашего прикладного приложения с помощью Docker Compose

Мы уже видели как запускать контейнеры при помощи соответствующей команды docker run. Однако это ограничивает нас запуском одного отдельного контейнера за раз. Хотя это и великолепно для единичных задач, у нас, разработчиков, наши приложения обычно создаются из множества компонентов, или, в терминологии Docker, служб. Например, дополнительно к нашему серверу Rails нам обычно требуется по крайней мере некая база данных.

Раз уж мы думаем о неком приложении в целом, запуск контейнеров при помощи docker run становится слишком громоздким. Нам понадобится некий иной инструмент верхнего уровня, который позволит нам координировать контейнеры и управлять ими для различных имеющихся служб, составляющих наше приложение.

Введём Docker Compose.

Приступая к работе с Compose

Docker Compose - или для краткости просто Compose (Компоновщик) - является инструментом для управления неким приложением, которому требуется какое- то количество работающих совместно различных контейнеров. Compose является объявлениями: вы определяете каждую часть своего приложения - именуемую как служба - и Compose обрабатывает работу по предоставлению гарантий того что правильные контейнеры исполняются когда и как вам это требуется. Он также управляет созданием и удалением ресурсов, необходимых данному прикладному приложению. Например, он создаёт некую обособленную частную сетевую среду для вашего приложения, снабжая вас некоторой предсказуемой изолированной средой. Как мы увидим в Части 2, Вперёд в производство, он также играет некую ключевую роль в том как мы развёртываем и масштабируем приложения с помощью Docker.

Compose разработан с целью вооружения разработчиков на уме. Он позволяет нам масштабировать свои приложения в терминах знакомых нам понятий - например "запускаем свою веб службу" или "останавливаем базу данных". Всё это сильно контрастирует с командами docker run нижнего уровня, которые мы уже видели, где сложнее обнаружить тот контекст, который мы пытаемся достичь.

Однако, прежде чем мы сможем заставить Compose делать наши ставки, нам вначале требуется описать своё приложение, создав некий файл docker-compose.yml. Он не подменяет необходимость в Dockerfile - чертежах для создания контейнеров - но описывает какие образы требуются нашему приложению и как они согласованно запускаются.

Вот некий первоначальный docker-compose.yml:


​1: 	version: ​'​​3'​                                      
​2: 	
​3: 	services:                                         
​4: 	
​5: 	  web:                                            
​6: 	    build: ​.​                                      
​7: 	    ports:                                        
​8: 	      - ​"​​3000:3000"​
 	   

Некий файл Компоновки всегда начинается с какого- то номера версии (строка 1), которая определяет тот формат файла, который будет применяться. Это помогает гарантировать что данное прикладное приложение продолжит исполняться ожидаемым образом по мере добавления в Compose новых свойств, или же при прерывающих изменениях. Мы используем версию 3 - самую последнюю основную версию на момент написания.

Далее у нас имеется некая коллекция с названием services (строка 3), которая применяется для группирования составных частей некоторой отдельной службы - которую мы выбрали именуемой как web - для её представления (строка 5). Мы увидим добавление иной службы в Главе 5, За рамками прикладного приложения: добавляем Redis.

Под web встраиваются его различные параметры настройки (строки 6-8).

Самая первая из них:


​ 	build: ​.​
 	   

сообщает Compose где обнаруживать тот Dockerfile, который следует применять для построения нашего образа. Определяемый нами путь является относительным для самого файла docker-compose.yml. В данном случае он расположен в том же самом каталоге.

Далее мы переходим к строкам 7-8:


​ 	ports:                                        
​ 	  - ​"​​3000:3000"​
 	   

Это эквивалентно значению параметра -p 3000:3000, который мы определяли в своей команде docker run. Если вы вспомните, он применялся для установления соответствия порта 3000 порту 3000 в нашей локальной машине. Он требуется для того чтобы сделать наше приложение Rails доступным из нашей локальной машины.

Запуск нашего прикладного приложения

Вооружившись docker-compose.yml , Compose теперь настроен на управление нашим приложением. Однако прежде чем мы запустим своё приложение, вначале слегка слегка настроим своё домашнее хозяйство. По умолчанию Ruby выполняет буферизацию вывода в stdout, что недостаточно хорошо играет с Compose. Давайте исправим это отключив буферизацию вывода Ruby.

В самом верху вашего файла config/boot.rb добавьте следующую строку:


​ 	$stdout.​sync​ = ​true​
		

Теперь мы готовы к запуску нашего приложения. Вместо длинной команды docker run теперь мы можем использовать:


​ 	​$ ​​docker-compose​​ ​​up​
		

Прежде чем мы пройдёмчя по получаемому выводу, давайте обсудим что делает эта команда.

Когда вы запускаете docker-compose up, Compose проверяет что все необходимые ресурсы были настроены, создавая те, которые отсутствуют, перед тем как запустить контейнер для каждой службы.

В частности, он:

  1. Создаёт некую обособленную сеть только для данного приложения

  2. Создаёт все не локальные монтируемые тома определённые для данного приложения (у нас их пока нет - дополнительно об этом в Главе 6, Глава 6. Добавляем базу данных: Postgres)

  3. Собирает некий образ для всех служб при помощи директивы build

  4. Создаёт некий контейнер для каждой службы

  5. Запускает по контейнеру для сдужбы

Достаточно впечатляюще для отдельной команды.

Если мы вернёмся к выводу данной команды, то мы увидим многое из того что происходит. Сначала создаётся сеть:


​ 	Creating network "myapp_default" with the default driver
		

По соглашению Compose устанавливает название для данной сети <appname>_default, где appname где имя приложения по умолчанию берётся из того каталога, в котором он находится.

Далее мы строим необходимый образ для своей службы web:


​ 	Building web
​ 	Step 1/8 : FROM ruby:2.6
​ 	​ --->​​ ​​f28a9e1d0449​
​ 	Step 2/8 : LABEL maintainer="rob@DockerForRailsDevelopers.com"
​ 	​ --->​​ ​​Using​​ ​​cache​
​ 	​ --->​​ ​​d69ea7d90f89​
​ 	Step 3/8 : RUN apt-get update -yqq && apt-get install -yqq --no-install-
​ 	recommends   nodejs
​ 	​ --->​​ ​​Using​​ ​​cache​
​ 	​ --->​​ ​​463750079bef​
​ 	...
​ 	Step 8/8 : CMD ["bin/rails", "s", "-b", "0.0.0.0"]
​ 	​ --->​​ ​​Running​​ ​​in​​ ​​b11e989011fc​
​ 	Removing intermediate container b11e989011fc
​ 	​ --->​​ ​​a18b3079c84b​
​ 	Successfully built a18b3079c84b
		

Compose определяет название и версию для данного образа устанавливая его тег:


​ 	Successfully tagged myapp_web:latest
		

применяя соглашение <appname>_<service_name>:latest, вновь ссылаясь на appname из содержащего её каталога. В нашем случае это превращается в myapp_web:latest.

Вы можете убедиться что был создан образ myapp_web исполнив следующее в отдельном терминальном окне:


​ 	​$ ​​docker​​ ​​images​
		

Вы должны квидеть его в одной из строк получаемого вывода:


​ 	REPOSITORY      TAG         IMAGE ID          CREATED                 SIZE
​ 	myapp_web       latest      a18b3079c84b      About a minute ago      1.01GB
​ 	​...​
		

Compose будет строить образы только если их нет, что может быть по причине того что это первый раз когда вы запускаете docker-compose up, либо потому что вы удалили его. Это важный момент: именно вы отвечает за построение своих образов по мере необходимости (смотрите Повторное построение наших образов); на самом деле, Compose напоминает нам об этом в своём выводе:


​ 	WARNING: Image for service web was built because it did not already exist.
​ 	To rebuild this image you must use `docker-compose build` or `docker-compose
​ 	up --build`.
 	Предупреждение: Образ для веб службы был построен потому что его ещё не было.
 	Для повторного его построения вам следует применить `docker-compose build` или `docker-compose up --build`.
		

Затем Compose создаёт и запускает некий обособленный контейнер для нашей службы web на основе того образа, что мы только что создали. Он будет именовать контейнеры применяя формат <appname>_<service name>_<n>:


​ 	Creating myapp_web_1 ... done
		

В процессе, называемом присоединением (attaching), Compose далее подключает наши локальные потоки ввода/ вывода (stdin, stdout и stderr) к данному запускаемому контейнеру, поэтому мы можем видеть его вывод:


​ 	Attaching to myapp_web_1
		

В качестве результата мы наблюдаем запуск своего сервера Rails внутри данного контейнера:


 ​ 	web_1  | => Booting Puma
​ 	web_1  | => Rails 5.2.2 application starting in development
​ 	web_1  | => Run `rails server -h` for more startup options
​ 	web_1  | Puma starting in single mode...
​ 	web_1  | * Version 3.12.0 (ruby 2.6.0-p0), codename: Llamas in Pajamas
​ 	web_1  | * Min threads: 5, max threads: 5
​ 	web_1  | * Environment: development
​ 	web_1  | * Listening on tcp://0.0.0.0:3000
​ 	web_1  | Use Ctrl-C to stop
		

Наш сервер Rails запускается благодаря той инструкции CMD по умолчанию, которую мы установили в разделе Команда по умолчанию. Мы можем иметь установленной соответствующую команду непосредственно в docker-compose.yml за счёт настройки параметра command для web - это приведёт к перекрытию действия той инструкции CMD, которая определена в его Dockerfile.

Проследуте вперёд и убедитесь что ваше приложение запущено: посетите в своём браузере http://localhost:3000. Вы должны увидеть вновь знакомую вам страницу приветствия Rails.

Великолепно! Наш docker-compose.yml работает и всё первоклассно.

После этого вы можете прекратить Compose нажав Ctrl-C; вы должны увидеть что ваши контейнеры будут остановлены.

[Замечание]Контейнеры не останавливаются аккуратно

К сожалению у Compose периодически возникает проблема, за проявлением которой вам следует наблюдать. Порой при прекращении Compose с помощью Ctrl-C вы можете обнаруживать ^CERROR: Aborting видеть что соответствующие контейнеры не остановлены. К сожалению, если это происходит, вам придётся остановить эти контейнеры вручную при помощи docker-compose stop. Относительно дополнительных подробностей обратитесь к Главе 9.

В исполнении этого сейчас нет необходимости, но если вы не желаете заботиться о просмотре вывода своего контейнера, мы можем запускать свои контейнеры в режиме отключённых (detached) определяя соответствующий параметр -d. Это запускает данное приложение в фоновом режиме {Прим. пер.: в качестве демона} и возвращает вам приглашение вашей оболочки.


​ 	​$ ​​docker-compose​​ ​​up​​ ​​-d​
​ 	Starting myapp_web_46768de21d89 ... done
		

Следует заметить, тем не менее, что Rails может потребоваться некоторое время для запуска вашего приложения и установки его доступности.

[Замечание]Проблемы с запуском Rails?

Если вы столкнулись с некой ошибкой своего сревера, который сообщает нечто подобное "A server is already running" (Сервер уже запущен), вы столкнулись с некой ошибкой в Compose. На данный момент просто удалите имеющийся tmp/pids/server.pid в своей локальной машине. Для получения лучшего решения обратитесь к Главе 9.

Монтирование локального тома

Прежде чем мы покинем свой docker-compose.yml, давайте выполним некое небольшое добавление.

Мы уже видели как монтировать некий локальный каталог внутри некого контейнера при помощи docker run с применением параметра -v - мы это делали в разделе Генерация нового прикладного приложения Rails без установленного Ruby с тем, чтобы необходимые вырабатываемые внутри этого контейнера файлы проекта Rails были доступными в нашей локальной машине.

Некий монтируемый том представляет какую- то файловую систему, которая совместно используется вашей локальной машиной и самим контейнером. Файлы в таком монтируемом томе синхронизуются в обоих направлениях между вашей локальной машиной и самим контейнером. По этой причине некое монтирование локального тома может делать для вас возможной локальную разработку и при этом иметь данный сервер Rails исполняемым в самом контейнере и автоматически подхватывающим такие изменения файлов без перезапуска - в точности как мы и привыкли это делать.

На этот раз мы собираемся настроить такой локально монтироуемый том при помощи Compose без применения docker run. В своей команде docker run для монтирования своего текущего локального каталога внутри соответствующего контейнера по /usr/src/app, мы применяли -v $PWD:/usr/src/app. Того же самомого с помощью Compose мы можем достичь добавляя в свой docker-compose.ymlследующее:


​ 	version: ​'​​3'​
​ 	
​ 	services:
​ 	
​ 	  web:
​ 	    build: ​.​
​ 	    ports:
​ 	      - ​"​​3000:3000"​
»	    volumes:
»	      - ​.:/usr/src/app​
 	   

Здесь мы определили соответствие своего тома в том свойстве volumes, которое мы добавили для своей службы web. Хотя такая установка соответствия тома очень похожа на применяемый нами параметр docker run, имеется одно небольшое отличие. Мы имеем возможность ссылаться на текущий каталог просто применяя некую точку (.) вместо применявшейся ранее переменной среды $PWD. Compose делает возможной относительную адресацию подобную указанной на основе того где находится соответствующий docker-compose.yml - небольшой чудесный бонус.

Перезапуская своё приложение на этот раз с помощью этого изменения:


​ 	​$ ​​docker-compose​​ ​​up​​ ​​-d​
		

мы теперь имеем возможность следовать обычному потоку разработки по изменению файлов локально и немедленно наблюдать изменения просто перегружая страницу браузера.

[Замечание]Проблемы с запуском Rails?

Если вы столкнулись с некой ошибкой своего сревера, который сообщает нечто подобное "A server is already running" (Сервер уже запущен), вы столкнулись с некой ошибкой в Compose. На данный момент просто удалите имеющийся tmp/pids/server.pid в своей локальной машине. Для получения лучшего решения обратитесь к Главе 9.

Запуск и останов служб

Достаточно распространённой вещью, которую мы вынуждены делать пока разрабатываем своё приложение, являются останов или запуск различных служб, которые мы создаём. На ммоент мы окунёмся в тонкости контроля, которые Compose предоставляет нам для этого. Прежде чем мы следаем это, однако, будет полезно иметь представление того путешествия, которое совершают контейнеры, от момента создания до того момента когда они более не требуются.

Следующая схема отображает нам некую упрощённую версию жизненного цикла контейнера:

 

Рисунок 4-1



Контейнер вступает в строй с соответствующим состоянием created (созданный). Он не исполняет никакого кода; он просто сидит и дожидается своего вызова. Когда этот контейнер запускается, он переходит в состояние running (исполняемого), где он активно выполняет код. Та команда docker run, которую мы уже наблюдали, создаёт некий новый контейнер, а заетм запускает его.

Пребывая в состоянии исполняемого некий контейнер может быть restarted (перезапущен), stopped (остановлен), killed (уничтожен) или paused (приостановлен). Приостановка контейнера подвешивает все исполняемые процессы с тем, чтобы они смогли продолжить исполнение (resumed) через какое- то время позднее. Останов контейнера пытается аккуратно остановить посредством отправки сигнала прекращения (SIGTERM) в основной процесс внутри этого контейнера - в случае отказа возвращаясь назад к некому принудительному завершению при помощи сигнала kill (уничтожения, SIGKILL). Уничтожение контейнера сразу перескакивает к принудительному прекращению.

В случае своего останова контейнер переходит в состояние stopped (остановленного) если он останавливается или уничтожается, либо если прекращается сам исполняемый внутри основной процесс. Данное состояние остановленного аналогично состоянию созданного: такой контейнер сидит в нём до тех пор пока не будет вызван снова. Отсюда данный контейнер может быть либо перезапущен, либо если вам более не придётся его применять, удалён из вашей системы. Имея всё это ввиду, давайте рассмотрим как это работает на практике при помощи Compose.

Прежде всего давайте проверим какие контейнеры исполняются в данный момент. Для этого мы воспользуемся командой ps:


​ 	​$ ​​docker-compose​​ ​​ps​
​ 	   Name              Command           State           Ports
​ 	---------------------------------------------------------------------
​ 	myapp_web_1   bin/rails s -b 0.0.0.0   Up      0.0.0.0:3000->3000/tcp
		

Данное перечисление содержит соответствующее название контейнера, ту команду, которая была применена для его запуска, его текущее состояние и соответствие его портов. Здесь вы можете видеть контейнер нашего сервера Rails; он всё ещё запущен с того момента когда мы его исполнили в предыдущий раз docker-compose up -d (Up означает что он исполняется).

Если мы теперь намерены остановить свой сервер Rails, нам придётся сделать это при помощи команды ​stop. По умолчанию, эта команда будет применена ко всем процессам, перечисленным в нашем файле docker-compose.yml​. Например, для останова всех контейнеров во всём данном приложении нам бы пришлось исполнить:


​ 	​​$ ​docker-compose​ ​stop​
		

Чтобы указать целью некий определённый процесс, нам придётся определить соответствующее название процесса после предпринимаемого нами действия:


​ 	$ ​docker-compose​ ​stop​ ​<service_name>
		

Это может казаться неким спорным вопросом, поскольку в настоящее время web является единственной определённой нами службой. Однако вскорости мы добавим ещё службы, начиная с Главе 5, За рамками прикладного приложения: добавляем Redis. Это обычное явление когда вы желаете указывать целью команды конкретную службу, следовательно будет очень полезно запомнить данный шаблон - в частности потому что все имеющиеся команды docker-compose следуют ему.

Давайте двинемся далее и остановим свою службу web:


​ 	​$ ​docker-compose​ ​stop​ ​web​
​ 	​Stopping myapp_web_1 ... done
		

Загрузка localhost:3000 в вашем браузере теперь завершится неудачей, а перечисление всех контейнеров сообщит что ваш сервер Rails был прекращён:


​ 	​$ ​​docker-compose​​ ​​ps​
​ 	   Name              Command           State    Ports
​ 	-----------------------------------------------------
​ 	myapp_web_1   bin/rails s -b 0.0.0.0   Exit 1
		

Имея некий контейнер остановленным, мы имеем возможность запустить его снова при помощи команды start:


​​ 	​$ ​​docker-compose​​ ​​start​​ ​​web​
​ 	Starting web ... done
		

Имеется также команда restart, которая будет удобной когда, например, вы провели некие изменения настроек и желаете чтобы ваш сервер Rails подхватил бы их:


​​​ 	​$ ​​docker-compose​​ ​​restart​​ ​​web​
​ 	Restarting myapp_web_1 ... done
		

Все рассмотренные нами команды Compose полагаются на лежащие в основе команды docker. Однако мы бы не хотели рассматривать их подробно, так как теперь мы будем применять Compose. Compose предоставляет нам всю мощность команд нижнего уровня docker, но в более простых, сосредоточенных на приложении командах.

Прочие общие задачи

Помимо запуска и останова наших служб, имеется ряд дополнительных моментов, которые часто выступают частью нашей повседневной разработки. Мы намерены предпринять тур с небольшими остановками для их отображения, так как они потребуются нам в последующих главах.

  Просмотр журналов контейнера

Мы уже видели, что docker-compose up без параметра -d подключается к запускаемому им контейнеру и впоследствии отображает его вывод.Однако существует также некая выделенная команда для просмотра выода контейнера, которая намного удобнее.

Давайте просмотрим журнал регистраций определённого контейнера:


​ 	​$ ​​docker-compose​​ ​​logs​​ ​​-f​​ ​​web​
		

Вы должны обнаружить некие записи, показывающие что наш сервер Rails был запущен, аналогичные таким:


 web_1 | => Booting Puma
​ web_1 | => Rails 5.2.2 application starting in development
​ web_1 | => Run `rails server -h` for more startup options
​ web_1 | Puma starting in single mode...
​ web_1 | * Version 3.12.0 (ruby 2.6.0-p0), codename: Llamas in Pajamas
​ web_1 | * Min threads: 5, max threads: 5
​ web_1 | * Environment: development
​ web_1 | * Listening on tcp://0.0.0.0:3000
​ web_1 | Use Ctrl-C to stop
		

Флаг -f указывает данной команде следовать имеющемуся выводу - то есть оставлять соединение подключённым и продолжать добавлять в конец вывода экрана всего что поступает в данный журнал аналогично команде Unix

tail.

Для прекращения потока вывода регистрационных записей нажмите Ctrl - C.

Важно сознавать, что данная команда отображает регистрационный записи самого вывода контейнера вместо регистрационных записей вашего сервера Rails, которые, по умолчанию, сохраняются в соответствующем каталоге log/. Однако, как мы позднее увидим в Части 2, Вперёд в производство, при использовании Docker принято настраивать Rails на вывод регистрационных записей в stdout.

Относительно дополнительных параметров

docker logs отсылаем вас к документации Docker.

  Исполнение одноразовых команд

До сих пор мы запускали свой контейнер web только применяя установленный в образе по умолчанию CMD. Что если нам требуется запустить некую иную команду? Например, часто мы желаем выполнять такие вещи как миграцию своей базы данных с помощью db:migrate, запускать свои проверки, обновлять наши gems или выполнять те многие команду Rails, которые мы применяем как часть своей разработки. Как нам это делать?

В действительности имеются два различных способа достижения этого, которые мы покажем на неком тривиальном примере: вывод echo чего бы то ни было на ваш экран. Не дайте обмануть вас этому простому примеру; данный подход использует тот же самый механизм, кторый мы будем применять для своих любимых команд в последующих главах.

Прежде всего мы можем воспользоваться docker run для запуска некого нового контейнера для своих одноразовых команд. Мы предоставляем такую команду после названия соответствующей службы, как это показано ниже, что перекрывает все определённые по умолчанию команды как в нашем файле docker-compose.yml, так и в самом Dockerfile:


​ 	​$ ​​docker-compose​​ ​​run​​ ​​--rm​​ ​​web​​ ​​echo​​ ​​'ran a different command'​
​ 	ran a different command
		

Данная команда echo исполнена успешно. Стоит отметить, что когда мы запускаем свой сервер Rails, наш контейнер прекращается немедленно после исполнения данной команды. Это происходит потому, что данная команда echo завершается и возвращает своё состояние выхода, в то время как наш сервер Rails выполняется в цикле сохраняя своё исполнение пока вы не попросите его остановиться (или если он рухнет). Кроме того, так как это одноразовая команда, мы воспользовались соответствующим параметром --rm для удаления этого контейнера по его завершению - в противном случае мы бы заканчивали с кучей дополнительных контейнеров лежащими там.

Второй способ исполнения одноразовых команд избегает вовсе запуска некого нового контейнера. Вместо этого он полагается на уже исполняемый контейнер и выполняет соответствующую команду в нём. Это выполняется при помощи соответствующей команды docker-compose exec.

Допустим, что наш сервер Rails исполняется, тогда мы можем запустить свой пример echo следующим манером:


​​ 	​$ ​​docker-compose​​ ​​exec​​ ​​web​​ ​​echo​​ ​​'ran a different command'​
​ 	ran a different command
		

Хотя это работает только при уже исполняемом контейнере, поскольку новый контейнер не запускается, нам не приходится помнить об очистке от дополнительных контейнеров или применении соответствующего параметра --rm.

  Повторное построение наших образов

Мы можем запросить для себя Compose собрать наши образы вместо применения лежащих в основе команд docker build. Это полезно для того чтобы избегать переключения между командами docker и docker-compose, но также и происходит по той причине, что ваше приложение может содержать множество Dockerfile для более чем одной службы; наш файл docker-compose.yml будет отслеживать какой Dockerfile для какой службы применяется.

Для перестроения образа сервера своего приложения Rails, известного Compose в качестве службы web вам следует вызвать такую команду:


​ 	​$ ​​docker-compose​​ ​​build​​ ​​web​
		

Имеется несколько различных причин почему вам может понадобиться выполнить перестроение своего образа. Зачастую это обусловлено тем что вы обновляете свой Gemfile и вам требуется переустановить свои gems (сам Dockerfile содержит соответствующую командуbundle install). Более редко это происходит потому что вам приходится изменять свой Dockerfile для установки дополнительных зависимостей. А ещё порой вы пожелаете совместно использовать свой образ и вам потребуется включать самые последние изменения кода (благодаря соответствующей инструкции Dockerfile COPY), как мы это увидим в Части 2, Вперёд в производство.

  Убираем за собой

Как вы можете помнить, когда мы впервые вызвали для своего проекта docker-compose up, она создала некую сетевую среду, необходимые тома и все контейнеры, требующиеся для данного приложения. Соответствующая ей команда docker-compose down останавливает все запущенные контейнеры и удаляет их вместе с соответствующими выделенными сетями и томами этого приложения.

Это полезно когда вы работает с неким проектом и желает высвободить пространство, применяемое его ресурсами. Если вы желаете удалить соответствующие контейнеры этого приложения, также имеется соответствующая этой цели команда docker-compose up.

[Замечание]Прдрезка: освобождение от неиспользуемых ресурсов

Поскольку мы говорим о высвобождаемых ресурсах, имеются также некоторые другие команды, которые помогут нам с этой целью.

Раз мы изменили свой Dockerfile и перестроили образы, некие образы неминуемо больше не требуются или не применяются, всё ещё присутствуя здесь и занимая драгоценное дисковое пространство. Также существуют образы, именуемые как подвисшие (dangling); всё это можно удалить при помощи команды docker image prune.

Существует целое семейство команд prune для высвобождения прочих неиспользуемых ресурсов (например, docker container prune). Для высвобождения всех ресурсов за один проход даже имеется отдельная команда:

Беглый обзор

Мы представили мощный инструментарий для своего арсенала: Docker Compose. Это действительно команда всё- в- одном для разработки наших прикладных приложений с помощью Docker.

Давайте напомним что мы изучили. В этой главе:

  1. Мы представили docker-compose.yml и его формат.

  2. Мы создали свой собственный docker-compose.yml для нашего приложения Rails, включая локально монтируемый том, который позволяет нам вживую изменять локальные файлы.

  3. Мы увидели как раскрутить наше приложение целиком и запустить свой сервер Rails при помощи следующей команды:

    
    ​ 	​$ ​​docker-compose​​ ​​up​
    		
  4. Мы изучили различные команды для управления своим приложением с помощью Compose:

    • Перечисление исполняемых контейнеров

      
      ​ 	​$ ​​docker-compose​​ ​​ps​
      		
    • Управление жизненным циклом контейнера

      
      ​ 	​$ ​​docker-compose​​ ​​[start|stop|kill|restart|pause|unpause|rm]​​ ​​\​
      ​ 	​                 ​​<service​​ ​​name>
      		
    • Просмотр регистрационных записей

      
      ​ 	​$ ​​docker-compose​​ ​​logs​​ ​​[-f]​​ ​​<service​​ ​​name>
      		
    • Запуск одноразовых команд в неком новом проходящем контейнере

      
      ​ 	​$ ​​docker-compose​​ ​​run​​ ​​--rm​​ ​​<service​​ ​​name> ​​<some​​ ​​command>
      		
    • Исполнение одноразовых команд в неком имеющемся контейнере

      
      ​ 	​$ ​​docker-compose​​ ​​exec​​ ​​<service​​ ​​name>​​ ​​<some​​ ​​command>
      		
    • Перестроение некого образа

      
      ​ 	​$ ​​docker-compose​​ ​​build​​ ​​<service​​ ​​name> 
      		

Применяя все эти чудеса Compose мы заменяем большинство своих сложных команд docker run чем- то более чистым, ясным для понимания и управляемым. Теперь мы можем запустить своё приложение целиком с нуля всего лишь одной командой:


​ 	​$ ​​docker-compose​​ ​​up​
		

Ура!

Теперь самое время начать применять Compose для расширения имеющихся возможностей нашего прикладного приложения путём добавления служб.