Назад | Перейти на главную страницу

Php + Nginx + Varnish на docker-compose, ubuntu18

!Важный. РЕШЕНИЕ НАЙДЕНО. У меня все ниже работает нормально. И это почти единственный случай, когда можно скопировать решение вопроса. Для этого прочтите раздел «Моя конфигурация».

Главный вопрос

При попытке открыть домашнюю страницу (через https 443 или http 80 не имеет значения) я вижу ошибку 503 Varnish. Похоже, Varnish не может получить доступ к Nginx обратно.

Журнал запросов на лак

*   << Request  >> 20        
-   Begin          req 19 rxreq
-   Timestamp      Start: 1587133057.263443 0.000000 0.000000
-   Timestamp      Req: 1587133057.263443 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.168.112.7 46616 a0
-   ReqMethod      GET
-   ReqURL         /
-   ReqProtocol    HTTP/1.0
-   ReqHeader      X-Real-IP: 192.168.112.1
-   ReqHeader      X-Forwarded-For: 192.168.112.1
-   ReqHeader      X-Forwarded-Proto: https
-   ReqHeader      X-Forwarded-Port: 443
-   ReqHeader      Host: magento2.docker
-   ReqHeader      Connection: close
-   ReqHeader      Cache-Control: max-age=0
-   ReqHeader      Upgrade-Insecure-Requests: 1
-   ReqHeader      User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
-   ReqHeader      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
-   ReqHeader      Sec-Fetch-Site: none
-   ReqHeader      Sec-Fetch-Mode: navigate
-   ReqHeader      Sec-Fetch-User: ?1
-   ReqHeader      Sec-Fetch-Dest: document
-   ReqHeader      Accept-Encoding: gzip, deflate, br
-   ReqHeader      Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,be;q=0.6
-   ReqHeader      Cookie: mage-banners-cache-storage=%7B%7D; _ga=GA1.2.164324136.1586263205; private_content_version=b9dd22e11f7865017754892a623f70f0; mage-cache-storage=%7B%7D; mage-cache-storage-section-invalidation=%7B%7D; mage-messages=; recently_viewed_product=%7B%7D
-   ReqUnset       X-Forwarded-For: 192.168.112.1
-   ReqHeader      X-Forwarded-For: 192.168.112.1, 192.168.112.7
-   VCL_call       RECV
-   VCL_return     pass
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       PASS
-   VCL_return     fetch
-   Link           bereq 21 pass
-   Timestamp      Fetch: 1587133057.263600 0.000157 0.000157
-   RespProtocol   HTTP/1.1
-   RespStatus     503
-   RespReason     Backend fetch failed
-   RespHeader     Date: Fri, 17 Apr 2020 14:17:37 GMT
-   RespHeader     Server: Varnish
-   RespHeader     Content-Type: text/html; charset=utf-8
-   RespHeader     Retry-After: 5
-   RespHeader     X-Varnish: 20
-   RespHeader     Age: 0
-   RespHeader     Via: 1.1 varnish (Varnish/6.2)
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1587133057.263609 0.000166 0.000009
-   Filters        
-   RespHeader     Content-Length: 279
-   RespHeader     Connection: close
-   Timestamp      Resp: 1587133057.263640 0.000197 0.000031
-   ReqAcct        1164 0 1164 242 279 521
-   End  

*   << BeReq    >> 21        
-   Begin          bereq 20 pass
-   VCL_use        boot
-   Timestamp      Start: 1587133057.263477 0.000000 0.000000
-   BereqMethod    GET
-   BereqURL       /
-   BereqProtocol  HTTP/1.0
-   BereqHeader    X-Real-IP: 192.168.112.1
-   BereqHeader    X-Forwarded-Proto: https
-   BereqHeader    X-Forwarded-Port: 443
-   BereqHeader    Host: magento2.docker
-   BereqHeader    Cache-Control: max-age=0
-   BereqHeader    Upgrade-Insecure-Requests: 1
-   BereqHeader    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
-   BereqHeader    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
-   BereqHeader    Sec-Fetch-Site: none
-   BereqHeader    Sec-Fetch-Mode: navigate
-   BereqHeader    Sec-Fetch-User: ?1
-   BereqHeader    Sec-Fetch-Dest: document
-   BereqHeader    Accept-Encoding: gzip, deflate, br
-   BereqHeader    Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,be;q=0.6
-   BereqHeader    Cookie: mage-banners-cache-storage=%7B%7D; _ga=GA1.2.164324136.1586263205; private_content_version=b9dd22e11f7865017754892a623f70f0; mage-cache-storage=%7B%7D; mage-cache-storage-section-invalidation=%7B%7D; mage-messages=; recently_viewed_product=%7B%7D
-   BereqHeader    X-Forwarded-For: 192.168.112.1, 192.168.112.7
-   BereqProtocol  HTTP/1.1
-   BereqHeader    X-Varnish: 21
-   VCL_call       BACKEND_FETCH
-   VCL_return     fetch
-   FetchError     backend default: fail errno 111 (Connection refused)
-   Timestamp      Beresp: 1587133057.263561 0.000084 0.000084
-   Timestamp      Error: 1587133057.263564 0.000087 0.000002
-   BerespProtocol HTTP/1.1
-   BerespStatus   503
-   BerespReason   Service Unavailable
-   BerespReason   Backend fetch failed
-   BerespHeader   Date: Fri, 17 Apr 2020 14:17:37 GMT
-   BerespHeader   Server: Varnish
-   VCL_call       BACKEND_ERROR
-   BerespHeader   Content-Type: text/html; charset=utf-8
-   BerespHeader   Retry-After: 5
-   VCL_return     deliver
-   Storage        malloc Transient
-   Length         279
-   BereqAcct      0 0 0 0 0 0
-   End    

Моя конфигурация

Исходный код можно найти здесь: https://github.com/zhartaunik/magento2-docker

Вот несколько необходимых для истории моментов:

docker-compose.yml

version: "3"
services:
  varnish:
    container_name: varnish
    build:
      context: varnish/
    ports:
      - 6081:6081

  nginx:
    container_name: nginx
    build:
      context: nginx/
    working_dir: /etc/nginx
    ports:
      # {internal_in_docker}:{external_from_browser}
      - 80:80
      - 443:443
      - 8001:8001
    volumes:
      - ./magento:/var/www/magento
    env_file:
      - ./.env
...

nginx / и т.д. / vhost.conf

upstream fastcgi_backend {
  server magento:9000;
}

server {
    listen 80;
    listen 443 ssl;

    server_name _;
    ssl on;
    ssl_certificate /etc/nginx/ssl/magento.crt;
    ssl_certificate_key /etc/nginx/ssl/magento.key;
    keepalive_timeout 300s;

    location / {
        proxy_pass http://varnish:6081;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Port 443;
        proxy_set_header Host $host;
        proxy_read_timeout 600s;
    }
}

server {
    listen 8001;

    server_name localhost;

    set $MAGE_ROOT /var/www/magento;
    set $MAGE_MODE developer;

Я столкнулся с проблемой, потому что я не использовал желаемый varnish.vcl. Если вы используете этот, у вас все должно работать нормально

лак / etc / varnish.vcl

vcl 4.0;

import std;
# The minimal Varnish version is 4.0
# For SSL offloading, pass the following header in your proxy server or load balancer: 'SSL-OFFLOADED: https'

backend default {
    .host = "nginx";
    .port = "8001";
}
...

Как в моем понимании это должно работать

Что я ищу здесь

Обновление №1 (Решение найдено)

Я протестировал вашу настройку Docker, и главное, что я заметил, это то, что определение бэкэнда /etc/varnish/default.vcl в вашем контейнере varnish выглядит следующим образом: backend default {.host = "127.0.0.1"; .port = "8080"; }

Я обнаружил ошибку в DockerFile. Я использовал конфигурацию по умолчанию с неправильными настройками хоста / порта. Я изменил это значение, и все стало нормально работать.

Вот источники (все их можно найти на https://github.com/zhartaunik/magento2-docker):

лак / Dockerfile

FROM varnish:6.2

COPY etc/varnish.vcl /etc/varnish/
COPY bin/docker-entrypoint.sh /docker-entrypoint.sh

RUN chmod +x /docker-entrypoint.sh

ENV VARNISH_CONFIG  /etc/varnish/varnish.vcl
ENV VARNISH_STORAGE malloc,2048m
ENV VARNISH_LISTEN  :6081
ENV VARNISH_MANAGEMENT_LISTEN 127.0.0.1:6082
EXPOSE 6081
EXPOSE 6082

ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"]

лак / bin / docker-entrypoint.sh

#!/bin/bash

set -e

exec varnishd \
    -j unix,user=vcache \
    -F \
    -f ${VARNISH_CONFIG} \
    -s ${VARNISH_STORAGE} \
    -a ${VARNISH_LISTEN} \
    -T ${VARNISH_MANAGEMENT_LISTEN} \
    -p feature=+esi_ignore_https \
    ${VARNISH_DAEMON_OPTS}

Я также удалил depends_on раздел.

Я протестировал вашу настройку Docker, и главное, что я заметил, это то, что определение серверной части /etc/varnish/default.vcl в твоем varnish контейнер следующий:

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

Это, конечно, приводит к В соединении отказано ошибка.

Когда я меняю его на следующее, он работает

backend default {
    .host = "nginx";
    .port = "8001";
}

Непосредственно перед отправкой 1-го запроса в Varnish я выполнил следующую команду, чтобы проверить, какой бэкэнд будет использоваться:

Отладка

root@a5ddd5873f9a:/etc/varnish# varnishlog -i backendopen
*   << BeReq    >> 17
-   BackendOpen    25 default 172.31.0.9 8001 172.31.0.2 58070

*   << Request  >> 16

*   << Session  >> 15

Как только соединение открыто, BackendOpen тег не появится в вашем varnishlog вывод.

В твоем случае BackendOpen никогда не появлялся в журналах, потому что вы никогда успешно не открывали бэкэнд-соединение.

Простой способ постоянно контролировать состояние ваших внутренних серверов в Varnish - это связать probes как показано ниже:

backend default {
    .host = "nginx";
    .port = "8001";
    .probe = {
        .url = "/";
        .timeout = 1s;
        .interval = 5s;
        .window = 5;
        .threshold = 3;
    }
}

Следить за здоровьем можно, запустив varnishlog -g raw как показано ниже:

root@a5ddd5873f9a:/etc/varnish# varnishlog -g raw
  0 Backend_health - default Still sick 4---X-R- 0 3 5 0.001804 0.000000 HTTP/1.1 404 Not Found

В этом случае серверная часть sick поскольку / URL возвращает HTTP/1.1 404 Not Found. Если вы убедитесь, что это HTTP/1.1 200 OK, проверка работоспособности пройдет, и вы не узнаете, к какому серверу Varnish пытается подключиться.

Возможные проблемы с зависимостью

Однако могут быть и некоторые depends_on проблемы в вашем docker-compose.yml файл:

  • Лак зависит от Nginx. Если Nginx не запущен вовремя, Varnish не сможет решить проблему. nginx имя хоста, которое он использует в качестве бэкэнда.
  • Nginx зависит от Varnish. Если Varnish не запущен вовремя, Nginx не сможет решить проблему. varnish имя хоста, через которое ему нужно проксировать свой трафик.

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

Чтобы ваша установка работала, мне нужно было убедиться, что Nginx зависит от Varnish, иначе контейнер Nginx не запустится. Но мне пришлось удалить зависимость Nginx от Варниса, иначе я застрял в цикле циклических зависимостей.

Вывод

В твоем docker-compose setup, ваш файл VCL не указывает на правильный серверный модуль Nginx.

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