如何在Nginx上运行CGI脚本

33

我遇到了设置CGI脚本在Nginx上运行的问题,目前我找到了这个网址,但问题是我无法将Perl脚本作为服务运行,以便它能在后台运行,即使重新启动也会自动重新运行。

你有什么想法吗?我正在运行Centos 5。

我在这里找到了一些解决方案,但我无法将给出的代码与这个Perl脚本集成。 我对Perl完全不了解,请帮忙。


由于您是“Perl的零基础”,建议考虑使用C编写CGI。 Perl有一些严重的缺点,例如每次使用都需要编译,并且通常很难理解,除非您是Perl迷。 如果您的程序是编译的C,则stdin来自浏览器,stdout返回给浏览器,而且它还非常小和高效。 我为自己的一个程序打广告,请查看其中的jbe.c文件,这是编译为CGI程序jbe的内容。 https://sourceforge.net/projects/cgi-jukebox/ - Alan Corey
7个回答

25

Nginx没有原生的CGI支持(它支持fastCGI)。这种情况的典型解决方案是将Perl脚本作为fastCGI进程运行,并编辑nginx配置文件以重定向请求到fastCGI进程。如果您只想运行CGI脚本,那么这个解决方案相当复杂。

您一定要使用nginx来解决这个问题吗?如果您只想执行一些Perl CGI脚本,请考虑使用Apache或Lighttpd,因为它们带有CGI模块,可以原生地处理您的CGI脚本,而不需要将脚本作为单独的进程运行。为此,您需要安装Web服务器并编辑Web服务器配置文件以加载CGI模块。对于Lighttpd,您需要在配置文件中添加一行以启用CGI文件的处理,然后将CGI文件放入cgi-bin文件夹中。


谢谢你的评论,是的我需要使用Nginx,因为整个网站都在Nginx下运行,现在我有这个(http://www.forkosh.com/mimetex.html)CGI脚本在网站下运行,网站是数学测试,所以我需要Mimetex符号支持,但它只能作为CGI运行......到目前为止,我已经为PHP脚本配置了FastCGI,但对于简单的CGI没有起作用:(请帮帮忙... - Askhat
1
虽然Apache和Lighttpd都带有自己的CGI模块,但CGI脚本仍在单独的进程中运行,作为Web服务器的子进程。它们的CGI模块只负责解析URL、填充环境变量等工作。 - cifer
你是否曾经解决过如何在NGINX上运行CGI脚本的问题?我已经正确设置了FASTCGI,但是当我运行CGI脚本时,我只能看到脚本的代码。 - trynacode
谢谢!这个回答可能对楼主没有帮助,但是对我有帮助。顺便问一下,你有没有想过为什么NGINX甚至没有计划支持CGI呢?CGI对我来说似乎是一个不错的备选方案。 - Franklin Yu

17

安装另一个运行在不同端口上的Web服务器(Apache, Lighttpd),然后使用nginx代理你的CGI请求到该Web服务器。

只需要在安装了一个运行在8080端口的Web服务器之后,将以下内容添加到nginx配置中即可。

location /cgi-bin {
    proxy_pass http://127.0.0.1:8080;
}

请查看Nginx位置指令详解以获取更多细节信息。


我应该在不同的端口上创建另一个Web服务器实例吗?我的意思是,我需要安装新的Nginx实例吗?还是应该使用Apache? - Askhat
你应该在不同的端口上安装Apache或Lighthttpd,然后通过Nginx代理到cgi-bin文件夹。 - Burak Tamtürk
3
这种方式的好处是什么?为什么不只运行Apache?NGINX作为中间层提供了哪些好处? - Octopus
2
在提供某些cgi脚本的同时,您可能会提供静态文件或fastcgi。由于nginx的事件驱动设计,它比apache更快地提供静态文件和fastcgi相关内容。由于需要打开新线程或进程来处理cgi脚本,因此nginx不执行cgi脚本。 - Burak Tamtürk

13

Nginx是一种Web服务器。您需要使用一个应用服务器来完成您的任务,例如uWSGI。它可以使用其本地非常有效的二进制接口uwsgi与nginx通信。

(Nginx是一种Web服务器,需要使用应用服务器(如uWSGI)来完成任务,并通过其本地二进制接口uwsgi与Nginx通信。)

5
因为OP标记了perl,所以可能需要使用PSGI/Plack(Perl的WSGI + Rack)。 - Ashley
2
真是让人惊喜,我刚刚了解到uWSGI包括PSGI支持,太棒了! - Ashley
12
你是说Apache和Lighttpd以及许多其他服务器不算网络服务器,因为它们支持CGI吗?使用“应用程序服务器”来运行CGI脚本是一种过度设计。 - Alex K
2
Apache可以同时作为应用服务器和Web服务器。当它运行您的Web应用程序时,它充当应用服务器。Lighttpd本身不运行CGI。它使用FastCGI协议与应用程序通信,就像nginx一样。 - VBart
抱歉,但不需要应用服务器来运行CIG。普通的Web服务器可以运行CGI。 - daniel sp

6

6
我发现了这个链接:https://github.com/ruudud/cgi。它的内容如下:
===
On Ubuntu: apt-get install nginx fcgiwrap
On Arch: pacman -S nginx fcgiwrap

Example Nginx config (Ubuntu: /etc/nginx/sites-enabled/default):

server {
    listen   80;
    server_name  localhost;
    access_log  /var/log/nginx/access.log;

    location / {
        root /srv/static;
        autoindex on;
        index index.html index.htm;
    }

    location ~ ^/cgi {
        root /srv/my_cgi_app;
        rewrite ^/cgi/(.*) /$1 break;

        include fastcgi_params;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME /srv/my_cgi_app$fastcgi_script_name;
    }
}

将root和fastcgi_param行更改为包含CGI脚本的目录,例如此存储库中的cgi-bin/目录。
如果您是控制狂并手动运行fcgiwrap,请务必相应更改fastcgi_pass。示例中列出的路径是在Ubuntu中使用开箱即用的fcgiwrap设置时的默认路径。
===
我马上要试一下。

4
嗨,欢迎。也许在发布答案之前你应该尝试并确认解决方案? :) - Ali
1
我认为现在可以使用 include fastcgi.conf 并删除 fastcgi_param SCRIPT_FILENAME ... 这一行。 - gelonida

1
根据Brad的回答,简化和现代化,并提供Awstats的CGI示例。
location ~ ^/cgi-bin/awstats\.pl {

        root /usr/lib/cgi-bin;
        rewrite ^/cgi-bin/(.*) /$1 break;

        include fastcgi.conf;
        fastcgi_pass unix:/run/fcgiwrap.socket;
}

您需要安装 fcgiwrap 软件包。

0
如果您有一个专用的文件夹,使用fastcgi-wrap进行配置会变得更加简单。
sudo apt-get install fcgiwrap

location /cgi-bin {
    gzip off;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    include /etc/nginx/fastcgi_params;
}

然后例如

/var/www/html/cgi-bin/hello.sh

#!/bin/bash
echo -e "Content-type:text/html\n"
echo "<pre>"
env # Show available environment vars, including QUERY_STRING etc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接