Контейнер Nginx Docker постоянно перезапускается.

Вопрос или проблема

Мой текущий docker-compose.yml выглядит так:

version: '3'

services:

    testsite-nginx:
        image: nginx:alpine
        container_name: test_site_nginx
        restart: unless-stopped
        tty: true
        volumes:
            - ./nginx.conf:/etc/nginx/nginx.conf
            - ./example.co.uk:/var/www
        ports:
            # Я действительно хочу сопоставить его с портом 8080 на моем локальном компьютере, а не 80
            - 8080:80
        networks:
            - app-network

    testsite-mysql:
        image: mysql:5.7.22
        container_name: test_site_mysql
        restart: unless-stopped
        tty: true
        ports:
            # Я действительно хочу сопоставить его с портом 3309 на моем локальном компьютере, а не 3306
            - 3309:3306
        environment:
            MYSQL_DATABASE: laravel
            MYSQL_ROOT_PASSWORD: somethingreallysecure
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
        volumes:
            - dbdata:/var/lib/mysql/
            - ./example.co.uk/mysql/my.cnf:/etc/mysql/my.cnf
        networks:
            - app-network

    testsite-app:
        build:
            context: .
        image: example.co.uk/app
        container_name: test_site_app
        restart: unless-stopped
        tty: true
        environment:
            SERVICE_NAME: app
            SERVICE_TAGS: dev
        working_dir: /var/www
        volumes:
            - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
            - ./example.co.uk:/var/www
        depends_on:
            - testsite-nginx
            - testsite-mysql
        networks:
            - app-network

networks:
    app-network:
        driver: bridge

volumes:
    dbdata:
        driver: local

Однако, когда я запускаю docker-compose up --build -d, а затем запускаю docker-compose ps, я вижу, что мой контейнер nginx постоянно перезапускается:

$ docker-compose ps
     Name                    Command                 State              Ports
--------------------------------------------------------------------------------------
test_site_app     docker-php-entrypoint php-fpm    Up           9000/tcp
test_site_mysql   docker-entrypoint.sh mysqld      Up           0.0.0.0:3309->3306/tcp
test_site_nginx   /docker-entrypoint.sh ngin ...   Restarting

Я пробовал использовать tty: true, как упоминалось в предыдущих вопросах на ServerFault, но это не решило проблему, как видно выше. Есть ли какие-либо решения?

При выполнении docker compose logs test_site_nginx благодаря пользователю на Reddit, я увидел эту ошибку:

2021/01/20 12:37:18 [emerg] 1#1: invalid number of arguments in "user" directive in /etc/nginx/nginx.conf:2
nginx: [emerg] invalid number of arguments in "user" directive in /etc/nginx/nginx.conf:2

Оказалось, что я пропустил точку с запятой в конце строки конфигурации при объявлении

user www-data; # <-- я не добавил ;

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

У меня возникла похожая проблема после перезагрузки моего хоста. Когда хост снова запустился, мой контейнер nginx застрял в цикле перезапуска.

Попытка проверить журналы для контейнера с помощью sudo docker logs <*container_id*> -f не показывала никаких новых сообщений.

Мне пришлось сделать следующее:

  1. отключить перезапуск sudo docker update --restart=no <*nginx-container-id*>
  2. остановить контейнер sudo docker stop <*nginx-container-id*>
  3. удалить контейнер sudo docker rm <*nginx-container-id*>

При попытке заново собрать контейнер он выдал ошибку “failed to bind host port for 0.0.0.0:80:container_ip:80/tcp address already in use”

sudo lsof -i :80 показал, что nginx использует порт.

Оказалось, что я также имел службу nginx, запущенную на локальном хосте. Не уверен, как и почему. Я остановил её с помощью sudo systemctl stop nginx и отключил её с помощью sudo systemctl disable nginx. После этого я смог заново собрать контейнер sudo docker compose up -d. Всё запустилось и работало как и до перезагрузки.

.

Ответ или решение

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

Теория

Контейнеры Docker могут входить в состояние перезагрузки по нескольким причинам. Один из частых случаев — это неверная конфигурация приложения или конфигурационного файла. В контексте Nginx это может быть вызвано ошибкой в nginx.conf. Неправильные или некорректные директивы могут приводить к вынужденной перезагрузке контейнера до тех пор, пока ошибка не будет исправлена.

Docker при этом позволяет указывать политику перезапуска, например, restart: unless-stopped, что означает, что контейнер будет автоматически пытаться перезапуститься после завершения работы, если его не остановить вручную. Таким образом, контейнер с ошибкой в конфигурации может бесконечно перезагружаться, не начиная корректную работу.

Пример

В предоставленной конфигурации Docker Compose у вас три сервиса: Nginx, MySQL и веб-приложение. Проблема возникает с контейнером Nginx, который находится в состоянии "Restarting". Из логов мы видим ошибку на второй строке файла nginx.conf:

2021/01/20 12:37:18 [emerg] 1#1: invalid number of arguments in "user" directive in /etc/nginx/nginx.conf:2
nginx: [emerg] invalid number of arguments in "user" directive in /etc/nginx/nginx.conf:2

Эта ошибка указывает на неверную директиву user, которая была исправлена добавлением необходимой точки с запятой:

user www-data;

Другое замечание касается конфликта портов, который может возникнуть, если другой процесс уже использует необходимый порт. В вашем случае, на порту 80 уже работала другая инстанция Nginx, не связанная с Docker. Это привело к ошибке привязки порта при перезапуске контейнера. Эту проблему удалось разрешить остановкой и отключением локального сервиса Nginx.

Применение

Рассмотрев возможные причины и решение этой проблемы, можно сделать несколько выводов и рекомендаций:

  1. Проверка конфигурационных файлов: Всегда проверяйте на синтаксические ошибки все конфигурационные файлы сервисов, работающих в контейнерах. Вы можете использовать команду nginx -t для проверки конфигурации Nginx.

  2. Анализ логов: Используйте логи для диагностики проблем. Команда docker logs <container_id> предоставит информацию о том, какие именно ошибки происходят при запуске.

  3. Отсутствие конфликтов портов: Перед запуском контейнеров убедитесь, что порты, требуемые для их работы, свободны. Это можно сделать командами lsof -i :port_number для проверки, какие процессы используют данный порт.

  4. Правильная настройка политики рестарта: Политика unless-stopped может иногда запутывать диагностику, так как контейнер будет постоянно перезапускаться. Используйте no во время диагностики, чтобы контейнер не пытался перезагрузиться самостоятельно.

  5. Контроль за внешними сервисами: Убедитесь, что версии приложений, установленные на главной машине, не конфликтуют с контейнеризированными версиями тех же сервисов.

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

Оцените материал
Добавить комментарий

Капча загружается...