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

NGINX文件服务器仅能解压.gz文件,bash脚本未运行求排查

NGINX文件服务器仅.gz可自动解压的问题分析与解决

搭建NGINX文件服务器时,期望点击.gz、.zip、.7z、.tar压缩文件自动解压,但仅.gz生效,其他格式未触发脚本执行,核心原因及解决方案如下:

问题根源

  1. NGINX未传递文件参数到脚本
    当前@execute_script仅重写路径到脚本,未将请求的文件路径作为参数传入,脚本中$1为空,无法处理非.gz文件。

  2. 缺少脚本执行的NGINX配置
    NGINX本身无法直接执行bash脚本,需通过fcgiwrap等工具桥接,现有配置仅重写路径,未触发脚本执行逻辑。

  3. 正则匹配未覆盖所有目标格式
    location ~ ^/files/(.*\.(gz|zip))$仅匹配gz、zip,7z、tar格式的请求不会进入该规则,自然无法触发解压。

  4. 脚本依赖缺失且逻辑不完整
    Dockerfile仅安装zip,未安装7z、tar的解压工具;脚本也未添加7z、tar的处理分支。


解决方案

1. 更新NGINX配置,支持脚本执行与参数传递

修改nginx.conf,使用fcgiwrap执行脚本并传递文件路径:

worker_processes auto;

events {
    worker_connections 1024;
}

http {
    gzip on;
    gzip_types text/plain text/css
               application/json
               application/javascript
               text/xml
               application/xml
               application/xml+rss
               text/javascript;
    
    server {
        listen 7756;
        server_name 127.0.0.1;

        location /files {
            alias /usr/share/nginx/html/;
            autoindex on;
            autoindex_exact_size on;
            autoindex_localtime on; 
        }

        # 匹配所有需要解压的格式
        location ~ ^/files/(.*\.(gz|zip|7z|tar))$ {
            alias /usr/share/nginx/html/$1;
            add_header Content-Disposition 'attachment; filename="$1"';
            types { application/octet-stream .gz .zip .7z .tar; }
            gzip off;
            try_files $uri @decompress;
        }

        location @decompress {
            internal;
            fastcgi_pass unix:/var/run/fcgiwrap.socket;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/decompress.sh;
            fastcgi_param QUERY_STRING file=$1;
        }
    }
}

2. 完善Dockerfile,安装必要依赖

添加fcgiwrap、p7zip-full、tar等工具:

FROM nginx:latest

RUN apt-get update && \
    apt-get install -y zip p7zip-full tar fcgiwrap && \
    rm -rf /var/lib/apt/lists/*

RUN rm /etc/nginx/nginx.conf

COPY scripts/decompress.sh /usr/share/nginx/html/
RUN chmod +x /usr/share/nginx/html/decompress.sh

COPY nginx.conf /etc/nginx

3. 修改解压脚本,支持全格式处理

脚本从QUERY_STRING获取文件路径,完善各格式解压逻辑:

#!/bin/bash

# 提取并解码请求的文件路径
FILE=$(echo "$QUERY_STRING" | grep -o 'file=[^&]*' | cut -d'=' -f2)
FILE=$(echo "$FILE" | sed 's/%20/ /g')

if [ ! -f "$FILE" ]; then
    echo "File not found: $FILE"
    exit 1
fi

# 根据后缀执行解压
if [[ "$FILE" =~ \.gz$ ]]; then
    echo "Decompressing .gz file: $FILE"
    gzip -d "$FILE"
elif [[ "$FILE" =~ \.zip$ ]]; then
    echo "Extracting .zip file: $FILE"
    unzip "$FILE" -d "$(dirname "$FILE")"
elif [[ "$FILE" =~ \.7z$ ]]; then
    echo "Extracting .7z file: $FILE"
    7z x "$FILE" -o"$(dirname "$FILE")"
elif [[ "$FILE" =~ \.tar$ ]]; then
    echo "Extracting .tar file: $FILE"
    tar -xf "$FILE" -C "$(dirname "$FILE")"
else
    echo "Unsupported file format: $FILE"
    exit 1
fi

# 返回解压后的内容(单文件则输出,目录可自定义返回逻辑)
TARGET="${FILE%.*}"
if [ -f "$TARGET" ]; then
    cat "$TARGET"
elif [ -d "$TARGET" ]; then
    echo "Extracted directory: $TARGET"
fi

4. 调整docker-compose.yml,确保服务启动

添加启动命令,保证fcgiwrap与NGINX同时运行:

version: '3.9'

networks:
  nginx-file-server-network:
    name: nginx-file-server-network
    driver: bridge

services:
  nginx-file-server-service:
    container_name: nginx-file-server-service
    image: nginx-file-server-image:1.0
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./files:/usr/share/nginx/html
    ports:
      - 7756:7756
    networks:
      - nginx-file-server-network
    command: bash -c "service fcgiwrap start && nginx -g 'daemon off;'"

内容的提问来源于stack exchange,提问作者Jesus Fragoso Jimenez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:24