Контейнер-докер не запускается, поскольку существующий файл pid

Когда я запускаю контейнер докера, он терпит неудачу, потому что существующий файл pid:

[[email protected] sergio]# docker logs sharp_shockley 
httpd (pid 1) already running
httpd (pid 1) already running
httpd (pid 1) already running
httpd (pid 1) already running

Как удалить такой файл, потому что я его не нахожу.

[[email protected] sergio]# docker version
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8/1.4.1
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8/1.4.1

[[email protected] sergio]# find / -name "httpd.pid"
find: ‘/run/user/1000/gvfs’: Permiso denegado

Ответ 1

После слишком большого разочарования я решил это в своем сломанном контейнере фабрикатора:

Вы должны знать, что такое имя/путь к файлу http pid. В приведенном ниже примере в /run/apache2/apache2.pid внутри контейнера. После этого вы выполните следующее:

docker start [container_id]; docker exec [container_id] rm /run/apache2/apache2.pid

Что это значит, это запустить контейнер, а затем сразу же попытаться запустить команду для удаления файла PID - мы надеемся, прежде чем какой-либо процесс, который должен запускаться док-станция, имеет время для отказа. Если процесс контейнера не удается быстро, это может не сработать для вас. Попробуйте запустить его несколько раз, и вы можете побить его на удар.

Чтобы найти местоположение моего PID файла, я сделал что-то похожее на @sebelk, но вместо того, чтобы расширять tar файл, я сэкономил некоторое время, просто указав его содержимое и искав правильное имя файла... например:

docker export [container_id] > /tmp/brokecontainercontents.tar
tar -tf /tmp/brokecontainercontents.tar | less 

Это глупо, и, вероятно, гораздо лучший способ просмотреть содержимое контейнера. В идеале вы можете узнать имя файла PID каким-либо другим способом (комментарии приветствуются!).

Богоявление

Ответ выше полезен, но теперь я понимаю, что я и многие другие здесь неправильно поняли Докера на фундаментальном уровне. На самом деле, @styonsk downvoted ответ ниже правильный. И, @avijendr критический комментарий тоже верен: это уничтожит данные в контейнере, но это не имеет значения. Я объясню.

Мне изначально сказали, что Докер был "как chroot, но лучше". Это правдиво, но вводит в заблуждение. В тюрьме chroot ваши данные живут в тюрьме (конечно, как это сделать, как еще это может произойти в тюрьме)? Поэтому, когда я начал использовать Docker, я подумал, что функция Volumes - это способ получить данные в контейнере - чтобы вы могли подключить Volume к вашей локальной системе и посмотреть, что в ней было. Когда я попробовал это, я действительно пометился, потому что это было так, как будто контейнер потерял все мои данные - контейнерное приложение действовало именно так, и ничего не было в локальном месте установки! Неправильно неправильно.

Объемы в Docker монтируют ваши локальные данные/файлы в контейнер, а не наоборот. Поэтому, когда я монтировал том в пустой локальный каталог (ожидая появления файлов в контейнере), вместо этого пустой контейнер был установлен в контейнер, скрывая файлы, которые существовали в контейнере, и при этом приложение выглядело так, как будто потерял свои данные (ну, потому что это было). На самом деле тот факт, что контейнер Docker даже работает без установленного тома, является побочным эффектом и, возможно, вредным. Это не то, как оно предназначено для работы. Любые данные, которые записываются в расположение тома в контейнере, как ожидается, будут одноразовыми!

(Кстати, я начал использовать Docker через Kitematic, который будет тянуть, создавать и запускать контейнер за один шаг, не спрашивая, где вы хотите смонтировать свои тома, что является частью того, что мне показалось неправильной идеей..I теперь лично считаю, что он не должен запускать контейнер до тех пор, пока вы не смонтировали тома где-то или явно не решили сделать это.)

Таким образом, предполагаемое использование контейнера Docker обычно (и должно быть) для запуска приложения внутри контейнера, которое действует на данные вне контейнера, то есть в томах, которые монтируются в вашу локальную систему. Это означает, что вы должны просто уничтожить контейнер, если с ним что-то пойдет не так, и запустите другую копию, смонтированную в одни и те же объемы - вы получите все свои данные, потому что они не были в контейнере в первую очередь.

Следовательно, ответ @styonsk - правильный ответ: если вы правильно используете Docker, вы должны просто уничтожить контейнер и запустить новый. С одной стороны, это звучит как излишний, но, с другой стороны, точка контейнерного приложения заключается в том, что вам не нужно знать, что происходит внутри него, и, возможно, вы этого не знаете... как вы знаете единственное вещь, сломанная после нечистого выключения, заключается в том, что файл httpd.pid все еще существует? Там может быть намного больше проблем, о которых вы не знаете! Возможно, это абстракция.

Если эта модель не работает для вашего случая использования - или вам просто не нравится - ответ, вероятно, заключается в том, что вы не должны использовать контейнер Docker. Это тоже нехорошо, просто вы можете попытаться вставить плоский винт с помощью драйвера Phillips. Вместо этого вам может понадобиться только легкая, но полностью статическая виртуальная среда.

Ответ 2

Try:

docker-compose down

Чтобы уничтожить все среды, которые уже запущены.

Ответ 3

Может возникнуть необходимость в восстановлении/воссоздании. docker-compose up --build --force-recreate <service-name>

Кроме того, хост (физический сервер) может не иметь места на диске.

Ответ 4

Основываясь на комментариях Paul и документации докеров, я нашел решение:

docker export sharp_shockley > /tmp/sharp_shockley.tar
mkdir /tmp/sharp_shockley
cd /tmp/sharp_shockley/
tar xvf sharp_shockley.tar
rm run/httpd/httpd.pid
rm sharp_shockley.tar
tar -c . | sudo docker import - apache3

Затем мне нужно выполнить некоторые незначительные исправления, удалить временные файлы в /var/run/httpd, зафиксировать изменения, а затем я могу начать снова мой контейнер.

Дополнительная информация на https://docs.docker.com/reference/commandline/cli/#import Командная строка докеров