You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将.htaccess规则转Nginx指令,Taskly CRM部署遇重定向循环

Taskly CRM部署:.htaccess转Nginx配置遇重定向循环问题

环境与默认Nginx配置

在自有VPS上使用Cloudpanel部署Taskly CRM,添加网站时Cloudpanel自动生成以下预配置的虚拟主机文件:

server {
  listen 8080;
  listen [::]:8080;
  server_name crm.mydomain.it;
  {{root}}

  try_files $uri $uri/ /index.php?$args;
  index index.php index.html;

  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }

  if (-f $request_filename) {
    break;
  }
}

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name crm.mydomain.it;
  {{root}}

  {{nginx_access_log}}
  {{nginx_error_log}}

  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  {{settings}}

  location / {
    {{varnish_proxy_pass}}
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    proxy_connect_timeout      720;
    proxy_send_timeout         720;
    proxy_read_timeout         720;
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_temp_file_write_size 256k;
  }

  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }

  if (-f $request_filename) {
    break;
  }
} 

需要转换的.htaccess规则

原Taskly CRM的Apache重写规则如下:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.jpeg|\.gif|robots\.txt|\.ico|\.woff|\.woff2|.ttf|\.svg)$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(css|assets|landing|storage|installer|js|custom)/(.*)$ public/$1/$2 [L,NC]
</IfModule>

尝试的转换及问题

使用在线工具转换后的Nginx配置如下,保存后访问域名出现重定向循环:

# nginx configuration by winginx.com

autoindex off;

location ~* (\.css|\.js|\.png|\.jpg|\.jpeg|\.gif|robots\.txt|\.ico|\.woff|\.woff2|.ttf|\.svg)$ {
}

location ~ /public/ {
}

location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /%1 redirect;
  }
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.php break;
  }
  if (!-e $request_filename){
    rewrite ^/(css|assets|landing|storage|installer|js|custom)/(.*)$ /public/$1/$2 break;
  }
}

正确的Nginx配置修正方案

在线工具生成的配置存在逻辑错误(如无效的/%1重写、顺序错误的规则),需替换为以下正确配置,整合到Cloudpanel的虚拟主机文件中:

修改8080端口的server块(处理PHP和核心重写)

替换原8080 server块的内容为:

server {
  listen 8080;
  listen [::]:8080;
  server_name crm.mydomain.it;
  {{root}}

  # 禁用目录索引(对应.htaccess的 -Indexes)
  autoindex off;
  # 禁用MultiViews(对应.htaccess的 -MultiViews)
  types_hash_max_size 2048;

  # 处理Authorization头
  fastcgi_param HTTP_AUTHORIZATION $http_authorization;

  # 移除尾部斜杠重定向
  if (!-d $request_filename) {
    rewrite ^/(.*)/$ /$1 permanent;
  }

  # 重写静态资源到public目录
  location ~ ^/(css|assets|landing|storage|installer|js|custom)/ {
    rewrite ^/(.*)$ /public/$1 last;
  }

  # 前端控制器:所有非静态资源请求转发到index.php
  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  # PHP处理规则
  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
    # 确保Authorization头传递到PHP
    fastcgi_param HTTP_AUTHORIZATION $http_authorization;
  }
}

修改443/80端口的server块(处理SSL和Varnish)

保留原SSL重定向和静态资源缓存规则,仅调整location /块,移除多余的if判断:

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name crm.mydomain.it;
  {{root}}

  {{nginx_access_log}}
  {{nginx_error_log}}

  # HTTP转HTTPS重定向
  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  {{settings}}

  # 反向代理到Varnish(8080端口)
  location / {
    {{varnish_proxy_pass}}
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    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 $scheme;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    proxy_connect_timeout      720;
    proxy_send_timeout         720;
    proxy_read_timeout         720;
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_temp_file_write_size 256k;
  }

  # 静态资源缓存规则(保留Cloudpanel默认,已覆盖.htaccess中的静态资源类型)
  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }
}

关键修正点

  1. 移除在线工具生成的无效if判断,改用Nginx原生的try_files和location匹配,避免重定向循环
  2. 调整静态资源重写顺序:先把指定目录的请求转发到public,再处理前端控制器
  3. 确保Authorization头正确传递到PHP,解决API授权问题
  4. 保留Cloudpanel的Varnish代理和SSL配置,不破坏原有环境

内容的提问来源于stack exchange,提问作者johnnydeppa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:40:52