Здрасти. Еще один частый вопрос с проекта Linux Factory:

Я собрал докер имейдж, а контейнер вечно в ребуте либо вообще не запускается, чо делать и как отлаживать?

Давай симулируем ситуацию и попробуем что-то с этим сделать.

Для начала соберем имейдж, это будет простой nginx + свой конфиг, который будет копироваться с локальной машины в имейдж.

Создаем на хостовой машине пару файлов:

Dockerfile:

FROM nginx:latest
WORKDIR /etc/nginx
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx.conf

user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        listen 80;
        server_name localhost;

        location / {
            return 200 'Hello, Docker!'
            add_header Content-Type text/plain;
        }
    }
}

Собираем имейдж:

docker build -t my-nginx .

Ждем, на экране бежит куча всякого непотребства. Это нормально. Ждем…

Проверяем:

docker images

Ага, все ок, выплюнуло что-то вроде:

REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
my-nginx     latest    b844ef77daa3   33 seconds ago   188MB

Запускаем:

docker run -d -p 80:80 my-nginx

Проверяем:

docker ps

Хуй там плавал. Ничо не стартануло… ошибок нет, куда смотреть?

Если контейнер вообще не запускается, то для начала смотрим логи:

1. Узнаем состояние контейнера:

docker ps -a

Видим хуй с маслом: Exited (1) 4 minutes ago

2. Смотрим логи:

docker logs --follow <id or name>

В <id or name> подставляем айдишник либо имя контейнера:

В логах видим ошибку:

invalid number of arguments in "return" directive in /etc/nginx/nginx.conf:15

Вот! С ней уже можно работать.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Получается мы посмотрели логи, даже для незапущенного контейнера.

Пиздуем в nginx конфиг и видим, что в 14й строке проебали точку с запятой.

Дополнительно можно посмотреть коды выхода:

docker inspect <id or name>

Например, если код выхода ExitCode = 137, значит не хватило ресурсов, подкинь памяти и все взлетит. Наверное…

Это основные моменты отладки.

Ну а если контейнер все же запустился, но что-то не работает, сначала повторяем все вышенаписанное. Ну и дополнительно можешь подключиться к нему в интерактивном режиме:

docker exec -it <id or name> bash/sh

Подставляешь id/name контейнера и выбираешь шелл, частенько bash из коробки не установлен, поэтому как вариант запускаешь sh.

А для визуализации слоев используем утилиту dive.

Установка dive:

DIVE_VERSION=$(curl -sL "https://api.github.com/repos/wagoodman/dive/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
curl -OL https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.deb
sudo apt install ./dive_${DIVE_VERSION}_linux_amd64.deb

Открываем имейдж на анализ:

dive <id or imagename>

Подставляем id или имя — ИМЕЙДЖА (не контейнера)

Смотрим, охуеваем, закрываем.

Еще можно глянуть конкретный файл в контейнере:

docker exec -it <id or name> cat /etc/nginx/nginx.conf

Либо скопировать его себе на локальную машину:

docker cp <id or name>:/etc/nginx/nginx.conf /tmp

Поправить и скопировать обратно в контейнер:

docker cp /tmp/nginx.conf <id or name>:/etc/nginx/nginx.conf

Перезапускаем контейнер с новым конфигом:

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

docker exec <id or name> nginx -s reload

Такие дела! Если знаешь еще хаки и способы отладки контейнеров/имейджей, пиши в комменты, будет полезно!