使用 nginx 在不同的外部端口上公开两个应用程序 - nginx:[emerg] bind() 到 0.0.0.0:8000 失败(98:地址已在使用中)

使用 nginx 在不同的外部端口上公开两个应用程序 - nginx:[emerg] bind() 到 0.0.0.0:8000 失败(98:地址已在使用中)

我正在尝试使两个应用程序可在我的 LAN 服务器(raspberry pi)上访问。

  • 实验室应用:这是一个非常简单的应用程序,使用第三方的 flask 制作,使用 sqlite3 数据库,结果是我的应用程序文件夹中的一个文件。它位于路径上/var/www/lab_app/,在内部端口 8080 和外部端口 80 上运行。

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)
  • aqi_气象数据:一个更复杂的应用程序,由我使用 django 制作,使用 postgresql 数据库。它位于路径/var/www/aqi_luftdaten/并在内部端口 8000 上运行 - 我已通过命令手动启动它:

python manage.py runserver 0.0.0.0:8000

目前,只有以下lab_app可用且可访问:

它的Web服务器是nginx,其应用程序服务器是uWSGI。

nginx配置如下:

目录中有一个/var/www/lab_app/lab_app_nginx.conf由符号链接指向的配置文件/etc/nginx/conf.d

ln -s /var/www/lab_app/lab_app_nginx.conf /etc/nginx/conf.d/

其内容是

server {
    listen      80;
    server_name localhost;
    charset     utf-8;
    client_max_body_size 75M;

    location /static {
        root /var/www/lab_app/;
    }

    location / { try_files $uri @labapp; }
    location @labapp {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/lab_app/lab_app_uwsgi.sock;
    }
}

通过按照教程,我删除了默认的 nginx sites-enabled 配置文件,因此该目录/etc/nginx/sites-enabled无效。

目录内/etc/nginx/sites-available/只有默认文件/etc/nginx/sites-available/default

其内容是

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }

}

uWSGI配置如下:

有一个文件,/var/www/lab_app/lab_app_uwsgi.ini其内容为:

[uwsgi]
#application's base folder
base = /var/www/lab_app

#python module to import
app = lab_app
module = %(app)

home = %(base)
pythonpath = %(base)

#socket file's location
socket = /var/www/lab_app/%n.sock

#permissions for the socket file
chmod-socket    = 666

#the variable that holds a flask application inside the module imported at line #6
callable = app

#location of log files
logto = /var/log/uwsgi/%n.log

我已使用以下命令将其信息加载到 uWSGI

bin/uwsgi --ini /var/www/lab_app/lab_app_uwsgi.ini

然后有一个文件/etc/systemd/system/emperor.uwsgi.service包含内容

[Unit]
Description=uWSGI Emperor
After=syslog.target

[Service]
ExecStart=/var/www/lab_app/bin/uwsgi --ini /var/www/lab_app/lab_app_uwsgi.ini
# Requires systemd version 211 or newer
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

该应用程序在我的 LAN 上运行良好,并且可以通过外部设备浏览器通过我的服务器的 IP 访问。

现在我想aqi_luftdaten在外部端口 80 上公开应用程序。

所以我要做的第一件事就是为这个应用程序配置 nginx。

因此我创建了一个 nginx 配置文件/var/www/aqi_luftdaten/nginx/aqi_luftdaten_nginx.conf,其中包含内容

server {
    listen      3000;
    server_name localhost;
    charset     utf-8;
    client_max_body_size 75M;

    location /static/ {
        root /var/www/aqi_luftdaten/static/;
    }

    location / { 
    proxy_pass http://localhost:8000;
    }
}

/etc/nginx/conf.d/并通过simbollicaly 将其链接到目录

ln -s /var/www/aqi_luftdaten/nginx/aqi_luftdaten_nginx.conf /etc/nginx/conf.d/

然后重启 nginx

/etc/init.d/nginx restart

但我收到此错误:

[....] Restarting nginx (via systemctl): nginx.serviceJob for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.
 failed!

通过跑步systemctl status nginx.service我得到了

nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2024-04-01 12:04:18 BST; 10s ago
     Docs: man:nginx(8)
  Process: 26704 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 26705 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)

Apr 01 12:04:15 Raspberry100 systemd[1]: Starting A high performance web server and a reverse proxy server...
Apr 01 12:04:15 Raspberry100 nginx[26705]: nginx: [emerg] bind() to 0.0.0.0:8000 failed (98: Address already in use)
Apr 01 12:04:16 Raspberry100 nginx[26705]: nginx: [emerg] bind() to 0.0.0.0:8000 failed (98: Address already in use)
Apr 01 12:04:16 Raspberry100 nginx[26705]: nginx: [emerg] bind() to 0.0.0.0:8000 failed (98: Address already in use)
Apr 01 12:04:17 Raspberry100 nginx[26705]: nginx: [emerg] bind() to 0.0.0.0:8000 failed (98: Address already in use)
Apr 01 12:04:17 Raspberry100 nginx[26705]: nginx: [emerg] bind() to 0.0.0.0:8000 failed (98: Address already in use)
Apr 01 12:04:18 Raspberry100 nginx[26705]: nginx: [emerg] still could not bind()
Apr 01 12:04:18 Raspberry100 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Apr 01 12:04:18 Raspberry100 systemd[1]: nginx.service: Failed with result 'exit-code'.
Apr 01 12:04:18 Raspberry100 systemd[1]: Failed to start A high performance web server and a reverse proxy server.

因此看起来端口 8000 已被使用,但我不明白为什么,因为其他应用程序暴露在端口 8080:80 上

答案1

问题实际上是 aqi_luftdaten 应用程序已手动启动并在端口 8000 上运行,因此 nginx 发现该端口已被使用。

我通过使用 ctrl+C 停止服务器运行然后再次运行来修复该问题

/etc/init.d/nginx restart

这次我得到了

[ ok ] Restarting nginx (via systemctl): nginx.service.

如果我尝试在另一台设备的浏览器中访问 aqi_luftdaten 应用程序,http://<raspberrypi_IP>:3000/我会成功

<html><head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>

因为 uWSGI 尚未配置。

相关内容