如何在端口80上运行Spring Boot应用程序

45

我无法在80端口上启动应用程序。

我已经尝试在我的本地计算机上(使用我的IDE和本地服务器),但没有成功。

我已检查其他类似的帖子,并确保我以root身份在服务器上运行jar。

这是错误:

 till here all ok
...
java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:338)
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:760)
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:472)
at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.addConnector(StandardService.java:237)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:186)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:149)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)
...
...
...
Exception in thread "main" java.lang.IllegalStateException: Tomcat connector in failed state
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:157)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)

在哪个平台上?另请参阅此答案 - Elliott Frisch
6个回答

85
在Linux上,只有root用户才能打开低于1024的端口,因此默认情况下限制了80端口。如果你想在80端口上发布应用程序,你需要将请求重定向到你要运行Spring应用程序的端口(例如8080端口)。
解决方案1:HTTP代理服务器。你可以使用Apache2服务器,默认允许在80端口上工作,并且可以为你转发请求到Tomcat。以下是Debian的示例配置。
sudo apt-get install apache2

a2enmod proxy
a2enmod proxy_http   

cd /etc/apache2/sites-enabled
sudo nano 000-default.conf

编辑文件:

<VIRTUALHOST *:80>

    ProxyPreserveHost On

    # ...

    ProxyPass / http://localhost:8080/
</VIRTUALHOST>

保存文件: Ctrl+O, ENTER, Ctrl+X

注意:要了解有关虚拟主机配置的更多信息,可以点击此处查看详细的Apache手册。

重启Apache2以应用更改:

sudo service apache2 restart

或者

sudo systemctl restart apache2

解决方案2:端口转发

使用iptables进行重定向

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

如果你需要使用本地主机,也需要添加这个

iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

5
感谢提供 iptables 的解决方案。 - heroin
对于Mac,以下命令将起作用:echo“rdr pass inet proto tcp from any to any port 80-> 127.0.0.1 port 8080”| sudo pfctl -ef - - Awesome
1
感谢 Apache2 的解决方案!我编辑了你的答案,为这个解决方案添加了更多细节。 - naXa stands with Ukraine
以 root 用户身份运行该进程,然后我就可以使用 80 和 443 端口了。谢谢。 - sam
1
如果Apache可以做到,为什么我不能呢?他们所有的文件都是由apache/http用户拥有的,但他们可以很好地打开80端口。为什么我不能呢? - Derek White
我发现IP表不仅更容易使用,而且对于SSL(433到8443)连接也更方便,因为您不需要指定证书和密钥或以任何方式处理HTTP。 - Carlos López Marí

15

在Linux上使用sudo

我在Ubuntu上运行Spring Boot应用程序,执行java -jar app.jar --server.port=80也出现了相同的错误。由于低于1024的端口只能通过根访问打开,因此请使用"sudo": sudo java -jar app.jar --server.port=80

出于安全考虑,此部署方式仅建议用于本地测试。有关详细信息,请参见注释。


6
从安全角度来看,这不是一个好主意:现在您的Java应用程序以超级用户权限运行。使用“iptables”解决方案可以很好地避免这种情况。 - dirkjot
2
@dirkjot 是的,没错,谢谢你指出来。在我写我的解决方案时,被接受的答案中的 iptables 部分还不存在,所以我只是提供了一个快速的本地测试解决方案。这绝对不适用于生产部署。 - PhoenixPan
1
虽然不适合生产环境,但对于测试和调查目的来说,这是一个快速解决方案... - Rafael

6

以下是我在CentOS上执行的步骤。

步骤 1(可选):设置端口号

Spring Boot 应用默认使用 8080 端口运行,如果您希望更改端口号,可以在 src/main/resources/application.properties 文件中进行更改。

server.port = 8082 // any port above than 1024

步骤2:如果还没有安装,请安装Apache

在Centos 7上

sudo yum install httpd

步骤3:编辑您的虚拟主机

在这一步中,您需要编辑您的虚拟主机。
/etc/httpd/conf.d/vhost.conf

你的配置应该像这样:

你的配置应该长成这个样子


<VirtualHost *:80>
   ServerName yourdomin.com
   #DocumentRoot /var/www/html

   ProxyPreserveHost On
   ProxyPass / http://localhost:8082/
   ProxyPassReverse / http://localhost:8082/
</VirtualHost>

并且重新启动Apache服务器

sudo service httpd restart

2
在使用MacOS的情况下,现在可以在端口80上运行而不需要在MacOS Mojave版本10.14上进行任何更改。"Original Answer"被翻译为"最初的答案"。

0

如果你正在使用 Docker 运行 Spring Boot。

Dockerfile:

FROM adoptopenjdk/openjdk13 AS server
ADD /target/AppServer-1.0.jar AppServer-1.0.jar
ENTRYPOINT ["java", "-jar" , "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9000", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.local.only=false", "-Dcom.sun.management.jmxremote.port=1099", "-Dcom.sun.management.jmxremote.rmi.port=1099", "-Djava.rmi.server.hostname=127.0.0.1", "-Dlog4j.configurationFile=log4j2-docker.xml", "AppServer-1.0.jar", "--server.port=80"]

(*) 向右滚动直到看到 jar 名称后的 --server.port=80
构建镜像并运行:
docker run -it -p 8080:80 --cap-drop all --cap-add net_bind_service <image-name>:<tag>

(!) 请注意,我已删除此进程/容器的所有功能,并仅添加了相关功能 - net_bind_service,该功能将套接字绑定到特权端口(端口号小于1024)。


-2

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