配置Apache httpd绑定域名部署应用并解决端口冲突
问题背景
我在AWS Amazon Linux 2023 EC2实例上,使用Apache(httpd)服务器将运行在3001端口的React(前端)/Python(后端)应用部署到GoDaddy预留域名www.demo.com,并配置了TLS。应用通过Docker Compose运行,使用静态弹性IP;未配置httpd和TLS时,访问elasticIP:3001可正常运行。但配置之后,访问https://www.demo.com仅显示Apache默认的"It works!"页面(说明TLS已生效)。
我了解到需修改/etc/httpd/conf/httpd.conf中的Listen属性或配置VirtualHost指令,但存在困惑:若添加Listen 3001,启动应用时会出现端口冲突,因为该配置让Apache监听3001端口,与应用端口冲突。
针对VirtualHost,我尝试了以下配置,但访问https://www.demo.com仍显示Apache默认页面:
<VirtualHost *:3001> ServerName www.demo.com </VirtualHost>
问题
- 如何配置Apache,让
https://www.demo.com连接到应用的3001端口且无端口冲突?或者将应用改为运行在80端口,该如何配置? - VirtualHost是否需要DocumentRoot或其他属性?Apache文档示例中的
DocumentRoot "/www/docs/host.example.com"路径来源是什么?VirtualHost应配置在httpd.conf中吗?
附TLS/SSL配置步骤(手动执行):
# 启动EC2、安装docker、compose及拉取git仓库后执行: sudo service httpd start sudo service httpd status sudo yum update -y sudo yum install -y mod_ssl sudo service httpd restart # 在/etc/pki/tls/private生成自定义密钥 cd /etc/pki/tls/private sudo openssl genrsa -out custom.key sudo chown root.root custom.key sudo chmod 600 custom.key cd /etc/pki/tls/private sudo openssl req -new -key custom.key -out csr.pem # ------------------------ # 将CSR提交给GoDaddy,用新CSR重新生成证书,审核后下载新crt文件 # 下载证书文件 # ------------------------ # 将CA签发的证书及中间证书放入/etc/pki/tls/certs cd /etc/pki/tls/certs sudo vi custom.crt # 粘贴从GoDaddy下载的crt文件内容 sudo chown root.root custom.crt sudo chmod 600 custom.crt cd /etc/pki/tls/private sudo rm /etc/pki/tls/private/localhost.key # ------------------------ # 编辑/etc/httpd/conf.d/ssl.conf指定新证书和密钥文件 # 在Apache的SSLCertificateFile指令中指定CA签发的主机证书路径及文件名: SSLCertificateFile /etc/pki/tls/certs/custom.crt # 从GoDaddy收到crt和pem(内容相同),以及abc-bundle.crt(未使用) # 若收到中间证书文件,需配置: # SSLCACertificateFile /etc/pki/tls/certs/intermediate.crt # 在Apache的SSLCertificateKeyFile指令中指定私钥路径及文件名: SSLCertificateKeyFile /etc/pki/tls/private/custom.key # ------------------------ # 保存/etc/httpd/conf.d/ssl.conf并重启Apache sudo service httpd restart # 通过https访问域名
解决方案
问题1:无端口冲突的Apache配置(反向代理)
不需要让Apache监听3001端口,而是用反向代理将Apache收到的HTTPS请求转发到本地3001端口的应用,这样就不会产生端口冲突。
配置步骤:
- 启用Apache代理模块:
sudo yum install -y mod_proxy mod_proxy_http sudo service httpd restart
- 修改SSL虚拟主机配置(推荐在
/etc/httpd/conf.d/ssl.conf的<VirtualHost *:443>块中添加,或单独新建/etc/httpd/conf.d/demo-proxy.conf文件):
<VirtualHost *:443> ServerName www.demo.com # 保留你已配置的TLS证书路径 SSLCertificateFile /etc/pki/tls/certs/custom.crt SSLCertificateKeyFile /etc/pki/tls/private/custom.key # 若有GoDaddy的中间证书,添加此行 SSLCACertificateFile /etc/pki/tls/certs/abc-bundle.crt # 反向代理核心配置 ProxyPass / http://127.0.0.1:3001/ ProxyPassReverse / http://127.0.0.1:3001/ # 可选:修复应用获取请求协议/端口的问题 RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" </VirtualHost>
- 重启Apache生效:
sudo service httpd restart
备选:将应用改到80端口运行
修改Docker Compose配置,把应用的端口映射从3001:3001改为80:3001(假设容器内应用监听3001端口):
# docker-compose.yml示例片段 services: your-app: ports: - "80:3001" # 其他原有配置...
修改后需停止Apache(80端口会被应用占用),但这种方式不如反向代理灵活——HTTPS默认用443端口,仍需要Apache/Nginx处理证书,因此更推荐反向代理方案。
问题2:VirtualHost的DocumentRoot及配置位置
- DocumentRoot:使用反向代理时不需要配置DocumentRoot,因为所有请求都会被转发到应用;如果是托管静态文件,DocumentRoot是静态文件的存放目录,Apache文档示例中的路径仅为演示,需替换为你自己的文件路径。
- VirtualHost配置位置:不建议直接修改
httpd.conf,最好在/etc/httpd/conf.d/目录下新建独立的.conf文件(比如demo-proxy.conf),Apache会自动加载该目录下的配置,更便于管理和排查问题。 - 你之前的错误在于将VirtualHost配置为监听3001端口,但Apache默认监听80(HTTP)和443(HTTPS)端口,HTTPS请求需配置
<VirtualHost *:443>来处理。
内容的提问来源于stack exchange,提问作者chocalaca

