Задать вопрос
@kzk8888

Как настроить nginx + php-fpm Битрикс24 для корректной работы с websocket?

Всех приветствую, столкнулся с такой проблемой, потребовалось собрать в контейнерах nginx + php-fpm + mysql + memcached + push&pull v2.0

Все развернулся и все прекрасно работает, но, есть проблема с работой вебсокетов.

в nginx.conf добавил эти строки

upstream push-upstream {
        server push:9099;
    }

    map $http_upgrade $connection_upgrade {
      default upgrade;
      '' 'close';
    }

    map $http_upgrade  $replace_upgrade {
      default $http_upgrade;
      ''      "websocket";
    }


а сам файл шаблон конфигурации для сайта такой

server {
    listen 80;
    server_name #SITE_NAME#;

    charset utf-8;
    root /var/www/bitrix;
    index index.php index.html bitrixsetup.php restore.php;

    access_log /var/log/nginx/#SITE_NAME#-access.log;
    error_log /var/log/nginx/#SITE_NAME#-error.log;

    # bitrix recommendation, respect server's mime-type and don't try to guess it
    add_header X-Content-Type-Options nosniff;

    location ~* ^/bitrix/subws/ {
        proxy_pass http://push-upstream;
        # http://blog.martinfjordvald.com/2013/02/websockets-in-nginx/
        # 12h+0.5
        proxy_max_temp_file_size 0;
        proxy_read_timeout  43800;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $replace_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location ~* ^/bitrix/sub/ {
        rewrite ^/bitrix/sub/(.*)$ /bitrix/subws/$1 break;
        proxy_pass http://push-upstream;
        proxy_max_temp_file_size 0;
        proxy_read_timeout  43800;
    }

    location ~* ^/bitrix/rest/ {
        proxy_pass http://push-upstream;
        proxy_max_temp_file_size 0;
        proxy_read_timeout  43800;
    }

    if (!-e $request_filename) {
       rewrite  ^(.*)$  /bitrix/urlrewrite.php last;
    }

    # remove multiple slashes
    # duplicated slashes sometimes will work and won't be rewritten, fixing it in this configuration is tricky
    rewrite ^([^.]*?\/)\/+(.*)$ $1$2 permanent;

    # redirect index.php to page without it
    if ($request_uri ~* "^(.*/)index\.php$") {
        return 301 $1;
    }

    location / {
        if (-f /var/www/bitrix/index.php) {
            root /var/www/bitrix;
            break;
        }
        if (-f /var/www/bitrix/bitrixsetup.php) {
            root /var/www/bitrix;
            break;
        }
        if (-f /var/www/bitrix/restore.php) {
            root /var/www/bitrix;
            break;
        }
        try_files $uri $uri/ @bitrix;
        root  /var/www/bitrix;
    }

    location /.well-known {
        root /var/www/bitrix;
    }

    location @bitrix {
        fastcgi_pass php-upstream;
        include fastcgi_params;
        # make SERVER_NAME behave same as HTTP_HOST
        fastcgi_param SERVER_NAME $host;
        fastcgi_param SCRIPT_FILENAME $document_root/bitrix/urlrewrite.php;
    }

    location = /restore.php {
        include fastcgi_params;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_send_timeout 21600;
        fastcgi_read_timeout 21600;
        # make SERVER_NAME behave same as HTTP_HOST
        fastcgi_param SERVER_NAME $host;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        client_body_buffer_size 1024m;
        client_max_body_size 1024m;
    }

    location = /favicon.png {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        log_not_found off;
        access_log off;
    }

    location ~ (/\.ht|/\.git|/\.gitignore|/vendor/|/composer|/bitrix/updates|/bitrix/modules|/upload/support/not_image|/upload/1c_exchange|/bitrix/php_interface|/logs/) {
        deny all;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|eot|otf|ttf|woff|woff2)$ {
        log_not_found off;
        access_log off;
        expires 30d;
        add_header Cache-Control public;
        # re-add security header
        add_header X-Content-Type-Options nosniff;
    }

    location ~ /upload/ {
        client_body_buffer_size 1024m;
        client_max_body_size 1024m;
    }

    location ~ \.php$ {
        if (!-f $request_filename) {
          rewrite  ^(.*)/index.php$  $1/ redirect;
        }
        include fastcgi_params;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_send_timeout 21600;
        fastcgi_read_timeout 21600;
        # make SERVER_NAME behave same as HTTP_HOST
        fastcgi_param SERVER_NAME $host;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    error_page 404 /var/www/bitrix/404.html;

    location /404.html {}
}


через lets encrypt получаю сертификат и все на 443 порт становится без проблем.

Но, основная проблема в том что коннект к вебсокету и запросы на wss:// и на ws:// возвращает 404 ошибку. Методом тыка нашел причину, причина в этих строках

if (!-e $request_filename) {
       rewrite  ^(.*)$  /bitrix/urlrewrite.php last;
    }


если их закоментировать, то, есть коннект с вебсокет и запросы идут а сайт не работает, а если раскоментировать их, то сайт работает, но запросы на вебсокет 404 ошибка. Все облазил, не могу придумать как решить. Можете ли помочь с решением данной проблемы?
  • Вопрос задан
  • 317 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
@dodo512
https://nginx.org/ru/docs/http/ngx_http_rewrite_mo...

Директивы break, if, return, rewrite и set обрабатываются в следующем порядке:

последовательно выполняются директивы этого модуля, описанные на уровне server;
в цикле:
ищется location по URI запроса;
последовательно выполняются директивы этого модуля, описанные в найденном location;
цикл повторяется, если URI запроса изменялся, но не более 10 раз.


server {

    if (!-e $request_filename) {
       rewrite  ^(.*)$  /bitrix/urlrewrite.php last;
    }

    location ~* ^/bitrix/subws/ {
        proxy_pass http://push-upstream;
        ...
    }

Тут первыми выполняются if и rewrite, описанные на уровне server.
URI запроса меняется на /bitrix/urlrewrite.php и только потом начинается поиск подходящего location.
Так что в location ~* ^/bitrix/subws/ { запрос уже никогда не попадёт.

If is Evil... when used in location context
Сочетание if + try_files работает криво.
location / {
    if (-f /var/www/bitrix/index.php) {
        root /var/www/bitrix;
        break;
    }
    if (-f /var/www/bitrix/bitrixsetup.php) {
        root /var/www/bitrix;
        break;
    }
    if (-f /var/www/bitrix/restore.php) {
        root /var/www/bitrix;
        break;
    }
    try_files $uri $uri/ @bitrix;
    root  /var/www/bitrix;
}

location @bitrix {
    fastcgi_pass php-upstream;

Так как не работает try_files, то запрос не может попасть в location @bitrix. В итоге ошибка 404.

Нужно убрать:
if (-f /var/www/bitrix/index.php) {
    root /var/www/bitrix;
    break;
}
if (-f /var/www/bitrix/bitrixsetup.php) {
    root /var/www/bitrix;
    break;
}
if (-f /var/www/bitrix/restore.php) {
    root /var/www/bitrix;
    break;
}


if (!-e $request_filename) {
   rewrite  ^(.*)$  /bitrix/urlrewrite.php last;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы