Удаление образов Docker
Удаление одного или нескольких конкретных образов
Используйте команду с флагом , чтобы найти идентификатор удаляемых образов. Эта команда покажет вам все образы, включая промежуточные слои образов. Когда вы определитесь с составом удаляемых образов, вы можете передать их идентификаторы или теги в :
Список:
Удаление:
Удаление образов, не привязанных к контейнеру
Образы Docker состоят из нескольких слоев. Несвязанные образы — это слои, не имеющие связей с каким-либо образами с тегами. У них нет никакого назначения, и они просто занимают место на диске. Их можно найти, добавив флаг фильтра со значением в команду . Если вы уверены, что хотите удалить их, вы можете использовать команду :
Примечание. Если вы создали образ и не пометили его тегами, он будет отображаться в списке несвязанных образов, поскольку он не привязан к образу с тегом. Этого можно избежать, при сборке образа. Также вы можете помечать тегами уже существующие образы с помощью комнады docker tag.
Список:
Удаление:
Удаление образов по шаблону
Вы можете найти все образы, соответствующие определенному шаблону, используя комбинацию команд и . Когда вы будете довольны, вы можете удалить их, используя для передачи идентификаторов в . Эти утилиты не предоставляются Docker и могут быть доступны не во всех системах:
Список:
Удаление:
Удаление всех образов
Для вывода всех образов Docker в системе нужно добавить флаг в команду . Если вы уверены, что хотите удалить их все, добавьте флаг для передачи идентификатора образа в :
Список:
Удаление:
Тома Docker
Тома Docker — это способ создания постоянного хранилища для контейнеров Docker. Тома Docker не привязаны к времени жизни контейнера, поэтому сделанные в них записи не исчезнут, как это произойдет с контейнером. Они также могут быть повторно подключены к одному или к нескольким контейнерам, чтобы можно было обмениваться данными и подключать новые контейнеры к существующему хранилищу. Тома Docker работают путем создания каталога на главной машине и последующего монтирования этого каталога в контейнер (или в несколько контейнеров). Этот каталог существует вне многослойного образа, который обычно содержит контейнер Docker, поэтому он не подчиняется тем же правилам (только для чтения и т. д.).
Давайте создадим том Docker и посмотрим его в действии:
Простой вызов docker volume create позволит создать новый том. Если мы проверим этот том, мы можем увидеть, где он живет на хост-файловой системе:
С вызовом inspect приходит много информации ,но все, что нас действительно беспокоит прямо сейчас, это Mountpoint
Обратите внимание, что здесь указан путь, начианющийся с /var/lib/docker…. Если вы откроете этот путь на своем компьютере, на котором работает Docker, вы можете просмотреть данные, хранящиеся внутри этого тома
Метод, который мы только что использовали для создания тома, не является единственным способом. При запуске контейнера вы можете указать -v, чтобы создать новый том на лету:
Как вы можете видеть, мы добавили новый аргумент к нашей docker run команде: -v. Существует специальный синтаксис для этого аргумента, с полями, разделенными двоеточиями. Первое поле — это название тома, в данном случае, testdata. Второе поле — это путь в контейнере, куда том будет примонтирован, в нашем случае, /data. Давайте запишем данные на том из контейнера:
Эти данные видны снаружи контейнера, в пути монтирования тома на хосте:
Вы должны были заметить, что в пути название тома больше не является случайной строкой — это теперь имя тома, которое мы указали при использовании -v аргумента. Тома Docker могут иметь либо рандомизированные имена, инициализированные Docker Engine, или имена, назначенные пользователем самостоятельно. Имена должны быть уникальными для каждого хоста. Созданный во время выполнения том Docker теперь становится доступным в команде docker volume ls :
Это означает, что мы можем использовать этот том снова с другим контейнером или даже несколькими контейнерами. Давайте проверим это прямо сейчас. Во-первых, подключите том к busybox контейнеру:
Внутри контейнера давайте напечатаем информацию о системе, а затем запишем на том:
Теперь запустите второй busybox контейнер, работающий одновременно с первым:
Нам доступны данные, которые были записаны в первом контейнере:
Это подчеркивает еще одно из преимуществ томов Docker: совместное использование данных между контейнерами.
Удаление томов
Удаление одного или нескольких томов — Docker 1.9 и выше
Используйте команду для определения названий томов, которые вы хотите удалить. Затем вы можете удалить один или несколько томов с помощью команды :
Список:
Удаление:
Удаление несвязанных томов — Docker 1.9 и выше
Поскольку тома существуют независимо от контейнеров, при удалении контейнера тома не удаляются автоматически. Если том существует, но не связан ни с какими контейнерами, он называется несвязанным томом. Чтобы найти такие тома и убедиться в необходимости их удаления, вы можете использовать команду с фильтром, чтобы в результатах выводились только несвязанные тома. Если список вас устроит, вы можете удалить все тома с помощью команды :
Список:
Удаление:
Удаление контейнера и его тома
Если вы создали том без имени, его можно удалить одовременно с контейнером, используя флаг
Обратите внимание, что это работает только с томами без имени. При успешном удалении контейнера отображается его идентификатор
Обратите внимание на отсутствие указания на удаление тома. Если у тома нет имени, он удаляется из системы незаметно. Если у тома есть имя, он сохраняется в системе без уведомлений.
Удаление:
Удаление образов Docker
Удаление конкретного образа
Команда docker images с флагом –a позволяет узнать ID образа, который нужно удалить. Она отображает все образы, включая промежуточные уровни. Определив образы, которые нужно удалить, вы можете передать их ID команде docker rmi:
Удаление недействительных образов
Образы Docker состоят из нескольких уровней. Недействительные образы – это уровень образов, которые больше не имеют никакого отношения к образам с метками. Они впустую потребляют дисковое пространство. Чтобы найти такие образы, используйте команду docker images и флаг –f (filter) со значением dangling=true. Если вы уверены, что хотите удалить все эти образы, добавьте в команду docker rmi флаг –q и укажите ID образов через пробел.
Чтобы найти и удалить образы:
Примечание: Если при создании образа не были добавлены метки, такой образ также окажется в списке недействительных образов, так как у него нет никакой связи с метками. Чтобы избежать этого, добавляйте метки при сборке образа. Команда docker tag позволяет добавить метку после сборки образа.
Удаление образов по шаблону
С помощью команд docker images и grep можно найти все образы, соответствующие шаблону. Чтобы удалить все совпадающие с шаблоном образы, можно передать команде docker rmi ID всех образов с помощью команды awk. Имейте в виду: эти утилиты не предоставляются платформой Docker и не всегда доступны в системе по умолчанию.
чтобы удалить образы:
Удаление всех образов
Чтобы просмотреть все доступные образы Docker, добавьте флаг -a в команду docker images.
Чтобы удалить все образы, добавьте флаг –q и передайте образы команде docker rmi:
Minitutorial: указание томов
Учитывая этот Dockerfile:
(Для результата этого урока не имеет значения, если мы укажем или — не спрашивайте меня, почему)
Построить это:
Бежать:
Внутри контейнера запустите в командной строке, и вы заметите, что существуют два каталога; и .
Запуск контейнера также создает две директории, или «тома», на стороне хоста.
Во время работы контейнера выполните на хост-машине, и вы увидите что-то вроде этого (для краткости я заменил среднюю часть имени тремя точками):
Вернувшись в контейнер, выполните (создает пустой файл в указанном месте).
Этот файл теперь доступен на хост-машине, на одном из безымянных томов lol. Мне потребовалось две попытки, потому что я впервые попробовал первый из перечисленных томов, но в итоге я нашел свой файл во втором указанном томе, используя эту команду на хост-компьютере:
Точно так же вы можете попытаться удалить этот файл на хосте, и он также будет удален в контейнере.
Примечание. Папка также называется «точкой монтирования».
Выйдите из контейнера и перечислите тома на хосте. Они ушли. Мы использовали флаг при запуске контейнера, и эта опция эффективно уничтожает не только контейнер при выходе, но и тома.
Запустите новый контейнер, но укажите том с помощью :
Это добавляет третий том, и вся система имеет три безымянных тома. Команда вылетела бы, если бы мы указали только . Аргумент должен быть абсолютный путь внутри контейнер. На стороне хоста новый третий том является анонимным и находится вместе с двумя другими томами в .
Ранее было заявлено, что не может сопоставить путь к хосту, что создает проблему для нас при попытке доставить файлы с хоста в контейнер во время выполнения. Другой синтаксис решает эту проблему.
Представьте, что у меня есть подпапка в каталоге проекта , которую я хочу синхронизировать с внутри контейнера. Эта команда делает свое дело:
Обе стороны символа ожидают абсолютного пути. Левая сторона — это абсолютный путь на хост-машине, а правая сторона — это абсолютный путь внутри контейнера. — это команда, которая «печатает текущий/рабочий каталог». Помещение команды в принимает команду в скобках, запускает ее в подоболочке и возвращает абсолютный путь к каталогу нашего проекта.
Собирая все это вместе, предположим, что у нас есть в папке нашего проекта на хост-машине со следующим содержимым:
Мы создаем этот Dockerfile:
Мы запускаем эту команду:
Это печатает «Привет, мир!».
Самое приятное то, что мы можем совершенно свободно изменять файл .Java новым сообщением для другого вывода при втором запуске — без необходимости перестраивать образ =)
Заключительные замечания
Я довольно новичок в Docker, и вышеупомянутый «учебник» отражает информацию, которую я собрал из 3-х дневного хакатона командной строки. Мне почти стыдно, что я не смог предоставить ссылки на понятную англоязычную документацию, подкрепляющую мои заявления, но я искренне считаю, что это связано с отсутствием документации, а не с личными усилиями. Я знаю, что примеры работают так, как рекламируется, используя мою текущую настройку, которая называется «Windows 10 -> Vagrant 2.0.0 -> Docker 17.09.0-ce».
Учебное пособие не решает проблему «как мы указываем путь контейнера в Dockerfile и позволяем команде run только указывать путь к хосту». Там может быть способ, я просто не нашел его.
Наконец, у меня есть ощущение, что указание в Dockerfile не просто необычно, но, вероятно, лучше никогда не использовать . По двум причинам. Первая причина, которую мы уже определили: мы не можем указать путь к хосту — это хорошо, потому что файлы Docker должны быть очень независимы от особенностей хост-машины. Но вторая причина — люди могут забыть использовать опцию при запуске контейнера. Можно не забыть удалить контейнер, но забыть удалить объем. Кроме того, даже при наличии наилучшей человеческой памяти может оказаться сложной задачей выяснить, какие из всех анонимных томов можно безопасно удалить.
Возможные проблемы
Рассмотрим некоторые проблемы, которые могут возникнуть в процессе настройки.
1. Errors during downloading metadata for repository ‘AppStream’
Ошибка возникает при попытке собрать имидж на Linux CentOS 8. Полный текст ошибки может быть такой:
Errors during downloading metadata for repository ‘AppStream’:
— Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=container
Error: Failed to download metadata for repo ‘AppStream’: Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=container
Причина: система внутри контейнера не может разрешить dns-имена в IP-адрес.
Решение: в CentOS 8 запросы DNS могут блокироваться брандмауэром, когда в качестве серверной части (backend) стоит nftables. Переключение на iptables решает проблему. Открываем файл:
vi /etc/firewalld/firewalld.conf
Находим строку:
FirewallBackend=nftables
… и меняем ее на:
FirewallBackend=iptables
Перезапускаем сервис firewalld:
systemctl restart firewalld
Другие Типы Монтирования
Есть два других типа томов Docker, которые мы еще не обсуждали: bind mount и tempfs mount.
Bind Mount
Bind mount используются для монтирования существующего пути на хосте в контейнер. Используя —mount совместно с <host path>:<container path>, вы можете указать существующие каталоги, которые будут монтироваться в контейнер. Это очень удобно при использовании информации о конфигурации, такой как каталоги внутри /etc. Это также полезно, когда у вас есть информация, которую вы хотите использовать в контейнере, например, существующие наборы данных или статические файлы веб-сайта.
Tempfs Mount
Задача tempfs монтирования состоит в том, чтобы обеспечить доступное для записи расположение, которое специально не сохраняет информацию после окончания срока службы контейнера. Возможно, вы думаете: «зачем это нужно?” В контейнере, который не имеет подключенного тома, все записи идут в тонкий слой R/W, вставленный во время выполнения. Любая запись, направленная на этот слой, влияет на файловую систему, поскольку эти записи выполняются на базовом хосте. Обычно это не является проблемой, если вы не пишете значительные объемы одноразовых данных (таких как журналы). В этом случае вы можете наблюдать снижение производительности, так как файловая система должна обрабатывать все эти вызовы write. tempfs монтирование было создано для предоставления контейнерам временного пути записи, который не влияет на операции файловой системы. В частности, tempfs это эфемерное монтирование, которое записывается непосредственно в память. Этот том можно создать с помощью —tempfs аргумента.
Драйвера Томов
По умолчанию тома хранят информацию о базовой хост-системе. Docker также имеет концепцию, называемую драйверами томов, которая позволяет указать, как и где хранить тома. Например, вы можете хранить том Docker внутри корзины Amazon S3. Это может быть удобно, если вы хотите, чтобы информация сохранялась не только за пределами срока службы контейнера, но и за пределами срока службы хоста.
Полезные советы по Docker
Введение
Docker позволяет легко помещать приложения и службы в контейнеры, чтобы их можно было запускать где угодно. Однако при работе с Docker можно легко накопить чрезмерное количество неиспользуемых образов, контейнеров и томов данных, замедляющих работу и потребляющих место на диске.
Docker предоставляет все необходимые инструменты для очистки системы из командной строки. В этом руководстве с полезными советами кратко описываются полезные команды для освобождения места на диске и организации системы посредством удаления неиспользуемых образов, контейнеров и томов Docker.
Использование этого руководства:
- Это руководство в формате полезных советов содержит автономные сниппеты для командной строки
- Вы можете перейти к любому разделу, актуальному для задачи, которую вы пытаетесь выполнить.
Синтаксис замены команды , используемый в командах, доступен во многих популярных оболочках, включая bash, zsh и Windows Powershell.
Usage of the Volume API
The volume API introduced in Docker 1.9 enables to perform operations on volume very easily.
First have a look at the commands available in the volume API.
We will start with the create command, and create a volume named html.
If we list the existing volume, our html volume should be the only one.
The output should be something like
In the volume API, like for almost all the other Docker’s API, there is an inspect command. Let’s use it against the html volume.
The output should be the following one.
The Mountpoint defined here is the path on the Docker host where the volume can be accessed. We can note that this path uses the name of the volume instead of the auto-generated ID we saw in the example above.
We can now use this volume and mount it on a specific path of a container. We will use a Nginx image and mount the html volume onto /usr/share/nginx/html folder within the container.
Note: /usr/share/nginx/html is the default folder served by nginx. It contains 2 files: index.html and 50x.html
Note: we use the -p option to map the nginx default port (80) to a port on the host (8080). We will come back to this in the lesson dedicated to the networking.
From the host, let’s have a look at the content of the volume.
The content of the /usr/share/nginx/html folder of the www container has been copied into the /var/lib/docker/volumes/html/_data folder on the host.
Let’s have a look at the nginx’s welcome page
From our host, we can now modify the index.html file and verify the changes are taken into account within the container.
Let’s have a look at the nginx’s welcome page. We can see the changes we have done in the index.html.
Note: please reload the page if you cannot see the changes.
Удаление томов
Удаление конкретного тома (Docker 1.9 +)
Чтобы узнать имя тома (или томов), используйте команду:
Чтобы удалить том, укажите его имя в команде docker volume rm. Чтобы удалить несколько томов, укажите их имена через пробел.
Удаление недействительных томов (Docker 1.9 +)
Том должен существовать независимо от контейнера. Следовательно, когда контейнер удаляется, том не удаляется автоматически. Он остаётся в системе, хотя больше не обслуживает ни один контейнер. Такие тома считаются недействительными и просто занимают место на диске.
Чтобы найти такие тома, используйте команду:
Чтобы удалить недействительные тома, используйте:
Удаление тома вместе с контейнером
Если вы создали безымянный том, вы можете удалить его вместе с контейнером с помощью флага –v.
Примечание: Это работает только с безымянными контейнерами!
Когда контейнер успешно удалён, на экране отображается его ID. При этом в команде никак не обозначается удаление контейнера. Если том не имеет имени, он будет просто удалён из системы. Если у тома есть имя, он останется в системе.
Mount host’s folder into a container
The last item we will talk about is named bind-mount and consist of mounting a host’s folder into a container’s folder. This is done using the -v option of the docker container run command. Instead of specifying one single path (as we did when defining volumes) we will specified 2 paths separated by a column.
Note: HOST_PATH and CONTAINER_PATH can be a folder or file. None of the Paths have to exist before starting the Container as they will be created automatically during the start.
1st case
Let’s run an alpine container bind mounting the local /tmp folder inside the container /data folder.
We end up in a shell inside our container. By default, there is no /data folder in an alpine distribution. What is the impact of the bind-mount ?
The /data folder has been created inside the container and it contains the content of the /tmp folder of the host. We can now, from the container, change files on the host and the other way round.
2nd case
Let’s run a nginx container bind mounting the local /tmp folder inside the /usr/share/nginx/html folder of the container.
Are the default index.html and 50x.html files still there in the container’s /usr/share/nginx/html folder ?
No ! The content of the container’s folder has been overridden with the content of the host folder.
Bind-mounting is very usefull in development as it enables, for instance, to share source code on the host with the container.
Data persistency without a volume ?
We will first illustrate how data is not persisted outside of a container by default.
Let’s run an interactive shell within an alpine container named c1.
We will create the /data folder and a dummy hello.txt file in it.
We will then check how the read-write layer (container layer) is accessible from the host.
Let exit the container first.
Let’s inspect our container in order to get the location of the container’s layer.
We can use the command and then scroll into the output until the GraphDriver key, like the following.
Or we can directly use the Go template notation and get the content of the GraphDriver keys right away.
You should then get an output like the following (the ID will not be the same though)
From our host, if we inspect the folder which path is specified in UpperDir, we can see our /data and the hello.txt file we created are there.
Try the below command, to see the contents of the /data folder:
What happen if we remove our c1 container now ? Let’s try.
It seems the folder defined in the UpperDir above does not exist anymore. Do you confirm that ? Try running the command again and see the results.
This shows that data created in a container is not persisted. It’s removed with the container’s layer when the container is deleted.
Удаление контейнеров
Удаление конкретного контейнера
Команда docker ps с флагом –a отображает все доступные контейнеры (их имена или ID).
Чтобы удалить контейнер (или несколько контейнеров), передайте имя или ID команде docker rm:
Удаление контейнера при остановке
Если при сборке контейнера вы точно знаете, что после выполнения задачи он станет ненужным, вы можете автоматически удалить его с помощью docker run –rm. Как только контейнер выполнит свою задачу и остановится, он будет удалён.
Удаление всех остановленных контейнеров
С помощью команды docker ps –a, флага –f и параметра status вы можете найти все доступные контейнеры, которые находятся в определённом состоянии: created, restarting, running, paused и exited. Например:
Чтобы удалить все остановленные контейнеры, используйте флаг –q в команде docker rm и передайте ей ID контейнеров, которые нужно удалить:
Удаление контейнера с помощью нескольких фильтров
Фильтры Docker можно комбинировать. Для этого нужно просто повторно добавить флаг –f. К примеру, чтобы вывести все контейнеры со статусом created (контейнер был создан, но запущен с помощью неправильной команды) и exited, можно использовать команду:
Чтобы удалить эти контейнеры, нужно ввести:
Удаление контейнеров по шаблону
Поиск контейнеров по шаблону можно выполнить с помощью команд docker ps и grep.
Найдя все контейнеры, которые соответствуют заданному шаблону, вы можете удалить их с помощью команд docker rmi, awk и xargs.
Примечание: Эти утилиты не всегда поставляются системой по умолчанию.
Остановка и удаление контейнера
Чтобы просмотреть все контейнеры в системе, введите:
Чтобы удалить контейнеры, передайте их ID командам docker stop и docker rm с помощью флага –q:
Использование docker-compose
В отличие от docker, с помощью docker-compose можно разворачивать проекты, состоящие из нескольких контейнеров, одной командой.
И так, автоматизируем запуск наших контейнеров с использованием docker-compose. Необходимо, чтобы он был .
Сначала удалим контейнеры, которые создали на предыдущих этапах:
docker rm -f web_server maria_db
Переходим в каталог для наших сборок:
cd /opt/docker/
Создаем yml-файл с инструкциями сборки контейнеров через docker-compose:
vi docker-compose.yml
—
version: «3.8»
services:
web_server:
build:
context: ./web-server/
args:
buildno: 1
container_name: web_server
restart: always
environment:
TZ: «Europe/Moscow»
ports:
— 80:80
maria_db:
image: mariadb
container_name: maria_db
restart: always
environment:
TZ: «Europe/Moscow»
volumes:
— /var/lib/docker/volumes/mariadb/_data/:/var/lib/mysql
* в формате yml очень важное значение имеют отступы. Если сделать лишний пробел, то мы получим ошибку.
* где:
- version — версия файла yml. На странице docs.docker.com представлена таблица, позволяющая понять, какую версию лучше использовать, в зависимости от версии docker (docker -v).
- services — docker-compose оперирует сервисами, где для каждого создается свой блок описания. Все эти блоки входят в раздел services.
- build — опции сборки. В нашем примере для веб-сервера мы должны собрать имидж.
- context — указываем путь до Dockerfile.
- args — позволяет задать аргументы, которые доступны только в процессе сборки. В данном примере мы используем только аргумент с указанием номера сборки.
- container_name — задаем имя, которое будет задано контейнеру после его запуска.
- restart — режим перезапуска. В нашем случае всегда, таким образом, после перезагрузки сервера, наши контейнеры запустятся.
- ports — при необходимости, указываем порт, который будет наш сервер пробрасывать запрос внутрь контейнера.
- environment — задает системные переменные. В данном примере, временную зону.
- volumes — позволяет внутрь контейнера прокинуть каталог сервера. Таким образом, важные данные не будут являться частью контейнера и не будут удалены после его остановки.
Запускаем сборку наших контейнеров с помощью docker-compose:
docker-compose build
Запускаем контейнеры в режиме демона:
docker-compose up -d
Проверяем, какие контейнеры запущены:
docker ps
При внесении изменений можно перезапускать контейнеры командой:
docker-compose up —force-recreate —build -d
Просто пересоздать контейнеры:
docker-compose restart
или только для одного из сервисов:
docker-compose restart web_server
* где web_server — название сервиса в файле docker-compose.
Defining a volume at runtime
We have seen volume defined in a Dockerfile, we will see they can also be defined at runtime using the -v flag of the docker container run command.
Let’s create a container from the alpine image, we’ll use the -d option so it runs in background and also define a volume on /data as we’ve done previously.
In order the PID 1 process remains active, we use the following command that pings Google DNS and log the output in a file within the /data folder.
The container is ran that way:
Let’s inspect the container and get the Mounts key using the Go template notation.
We have pretty much the same output as we had when we defined the volume in the Dockerfile.
If we use the folder defined in the Source key, and check the content of the ping.txt within the /data folder, we get something similar to the following.
The ping.txt file is updated regularly by the command running in the c3 container.
Stopping and removing the container will obviously stop the ping command but the /data/ping.txt file will still be there. Give it a try
NGINX + PHP + PHP-FPM
Рекомендуется каждый микросервис помещать в свой отдельный контейнер, но мы (для отдельного примера) веб-сервер с интерпретатором PHP поместим в один и тот же имидж, на основе которого будут создаваться контейнеры.
Создание образа
Создадим каталог, в котором будут находиться файлы для сборки образа веб-сервера:
mkdir -p /opt/docker/web-server
Переходим в созданный каталог:
cd /opt/docker/web-server/
Создаем докер-файл:
vi Dockerfile
- FROM centos:8
- MAINTAINER Dmitriy Mosk <[email protected]>
- ENV TZ=Europe/Moscow
- RUN dnf update -y
- RUN dnf install -y nginx php php-fpm php-mysqli
- RUN dnf clean all
- RUN echo «daemon off;» >> /etc/nginx/nginx.conf
- RUN mkdir /run/php-fpm
- COPY ./html/ /usr/share/nginx/html/
- CMD php-fpm -D ; nginx
- EXPOSE 80
* где:
1) указываем, какой берем базовый образ. В нашем случае, CentOS 8.
3) задаем для информации того, кто создал образ. Указываем свое имя и адрес электронной почты.
5) создаем переменную окружения TZ с указанием временной зоны (в нашем примере, московское время).
7) запускаем обновление системы.
устанавливаем пакеты: веб-сервер nginx, интерпретатор php, сервис php-fpm для обработки скриптов, модуль php-mysqli для работы php с СУБД MySQL/MariaDB.
9) удаляем скачанные пакеты и временные файлы, образовавшиеся во время установки.
10) добавляем в конфигурационный файл nginx строку daemon off, которая запретит веб-серверу автоматически запуститься в качестве демона.
11) создаем каталог /run/php-fpm — без него не сможет запуститься php-fpm.
13) копируем содержимое каталога html, который находится в том же каталоге, что и dockerfile, в каталог /usr/share/nginx/html/ внутри контейнера. В данной папке должен быть наше веб-приложение.
15) запускаем php-fpm и nginx. Команда CMD в dockerfile может быть только одна.
17) открываем порт 80 для работы веб-сервера.
В рабочем каталоге создаем папку html:
mkdir html
… а в ней — файл index.php:
vi html/index.php
<?php
phpinfo();
?>
* мы создали скрипт, который будет выводить информацию о php в браузере для примера. По идее, в данную папку мы должны положить сайт (веб-приложение).
Создаем первый билд для нашего образа:
docker build -t dmosk/webapp:v1 .
Новый образ должен появиться в системе:
docker images
При желании, его можно отправить на Docker Hub следующими командами:
docker login —username dmosk
docker tag dmosk/webapp:v1 dmosk/web:nginx_php7
docker push dmosk/web:nginx_php7
* первой командой мы прошли аутентификацию на портале докер-хаба (в качестве id/login мы используем dmosk — это учетная запись, которую мы зарегистрировали в Docker Hub). Вторая команда создает тег для нашего образа, где dmosk — учетная запись на dockerhub; web — имя репозитория; nginx_php7 — сам тег. Последняя команда заливает образ в репозиторий.
* подробнее про докера.
Запуск контейнера и проверка работы
Запускаем веб-сервер из созданного образа:
docker run —name web_server -d -p 80:80 dmosk/webapp:v1
Открываем браузер и переходим по адресу http://<IP-адрес сервера с docker> — откроется страница phpinfo:
Наш веб-сервер из Docker работает.