我目前正在AWS ElasticBeanstalk中使用single container docker environment部署Django + uWSGI应用。这个环境已经附带了nginx,我目前正在尝试配置它。
我正在努力实现以下目标:
环境信息:
这是我目前的配置:
.ebxtensions / 00-负载均衡器-terminatehttps.config
option_settings:
aws:elb:listener:443:
ListenerEnabled: true
ListenerProtocol: HTTPS
SSLCertificateId: <resource-id-here>
InstancePort: 443
InstanceProtocol: HTTP
aws:elb:listener:80:
ListenerEnabled: true
ListenerProtocol: HTTP
InstancePort: 80
InstanceProtocol: HTTP
.ebextensions / 01-nginx的-proxy.config
files:
"/etc/nginx/sites-available/test.domain.com.conf":
mode: "000644"
owner: root
group: root
content: |
server {
listen 80;
server_name test.domain.com;
access_log /var/log/nginx/$server_name.access.log;
location / {
return 301 https://$server_name$request_uri;
}
location = /status/ {
access_log /var/log/nginx/$server_name.healthd.log healthd;
include uwsgi_params;
uwsgi_pass docker;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
}
}
server {
listen 443;
server_name test.domain.com;
access_log /var/log/nginx/$server_name.access.log;
location / {
include uwsgi_params;
uwsgi_pass docker;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
client_max_body_size 100m;
}
location /static {
alias /var/www/static;
}
}
commands:
00_enable_site:
command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/test.domain.com.conf /etc/nginx/sites-enabled/test.domain.com.conf'
.ebextensions / 02-healthcheckurl.config
option_settings:
- namespace: aws:elasticbeanstalk:application
option_name: Application Healthcheck URL
value: /status/
application.ini(uwsgi config)
[uwsgi]
master = true
socket = :3031
processes = 4
enable-threads = true
threads = 2
chdir = /opt/app/
wsgi-file = test/wsgi.py
logto2 = /var/log/uwsgi.log
callable = application
py-autoreload = 3
现在,在测试配置时:
检查http://test.domain.com/status/正常
$ wget http://test.domain.com/status/
--2017-01-14 23:00:18-- http://test.domain.com/status/
Resolving test.domain.com... 52.xx.xx.xx, 52.xx.xx.xy
Connecting to test.domain.com|52.xx.xx.xx|:80... connected.
HTTP request sent, awaiting response... 200 OK
检查http://test.domain.com/hello/没有按预期工作。它重定向很好,但它会挂起,直到请求超时。
$ wget http://test.domain.com/hello/
--2017-01-14 22:59:13-- http://test.domain.com/hello/
Resolving test.domain.com... 52.xx.xx.xx, 52.xx.xx.xy
Connecting to test.domain.com|52.xx.xx.xx|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://test.domain.com/hello/ [following]
--2017-01-14 22:59:15-- https://test.domain.com/hello/
Connecting to test.domain.com|52.xx.xx.xx|:443... connected.
HTTP request sent, awaiting response... 408 REQUEST_TIMEOUT
2017-01-14 23:00:17 ERROR 408: REQUEST_TIMEOUT.
答案 0 :(得分:4)
按照@ deviavir的建议,我需要允许来自负载均衡器的流量进入EC2实例。
这是我的最终配置:
.ebextensions
|-- 00-resources.config
|-- 01-nginx-proxy.config
<强> .ebextensions / 00-resources.config 强>:
Resources:
AWSEBSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Allow traffic to ports 80 and 443 from the load balancer. Restrict SSH access."
AWSEBLoadBalancer:
Type: "AWS::ElasticLoadBalancing::LoadBalancer"
Properties:
Listeners:
- {LoadBalancerPort: 80,
Protocol: 'HTTP',
InstancePort: 80,
InstanceProtocol: 'HTTP'}
- {LoadBalancerPort: 443,
Protocol: 'HTTPS',
InstancePort: 443,
InstanceProtocol: 'HTTP',
SSLCertificateId: 'arn:aws:acm:us-east-1:xxxx:certificate/yyyy'}
HealthCheck:
Target: HTTP:80/status/
HealthyThreshold: '3'
UnhealthyThreshold: '5'
Interval: '30'
Timeout: '5'
Port80SecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 80
FromPort: 80
SourceSecurityGroupName: {"Fn::GetAtt" : ["AWSEBLoadBalancer" , "SourceSecurityGroup.GroupName"]}
Port443SecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
SourceSecurityGroupName: {"Fn::GetAtt" : ["AWSEBLoadBalancer" , "SourceSecurityGroup.GroupName"]}
SSHSecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 22
FromPort: 22
CidrIp: xx.xx.xx.xx/yy
<强> .ebextensions / 01-nginx的-proxy.config 强>:
files:
"/etc/nginx/sites-available/test.domain.com.conf":
mode: "000644"
owner: root
group: root
content: |
server {
listen 80;
server_name test.domain.com;
access_log /var/log/nginx/$server_name.access.log;
location / {
return 301 https://$server_name$request_uri;
}
location = /status/ {
access_log /var/log/nginx/$server_name.status.log;
uwsgi_pass docker;
include uwsgi_params;
}
}
server {
listen 443;
server_name test.domain.com;
access_log /var/log/nginx/$server_name.access.log;
location / {
uwsgi_pass docker;
include uwsgi_params;
client_max_body_size 100m;
}
location /static/ {
root /var/www;
}
}
commands:
00_enable_site:
command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/test.domain.com.conf /etc/nginx/sites-enabled/test.domain.com.conf'
答案 1 :(得分:1)
修改强>
OP的问题已经解决Configuring nginx in a single docker container environment (AWS ElasticBeanstalk),我将留下以下信息以保证完整性。
从nginx配置中删除端口443的“server”块,并在.ebxtensions/00-loadbalancer-terminatehttps.config
中将aws:elb:listener:443:
的{{1}}设置为80,并使用nginx'$ http_x_forwarded_proto检查HTTPS ”。
InstancePort
为什么呢?目前看来你的nginx + elb试图一起终止HTTPS,但你的nginx没有回复任何。如果您不打算使用内部HTTPS,那么只需坚持一个nginx服务器块并在那里完成所有逻辑就更有意义了。
我建议使用以下配置文件:
<强> .ebxtensions / 00-负载均衡器-terminatehttps.config 强>
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
<强> .ebextensions / 01-nginx的-proxy.config 强>
option_settings:
aws:elb:listener:443:
ListenerEnabled: true
ListenerProtocol: HTTPS
SSLCertificateId: <resource-id-here>
InstancePort: 80
InstanceProtocol: HTTP
aws:elb:listener:80:
ListenerEnabled: true
ListenerProtocol: HTTP
InstancePort: 80
InstanceProtocol: HTTP
请注意,我绝不会声称这是解决您问题的最佳解决方案(甚至根本就没有解决方案),408似乎表明了一个有点奇怪的问题 - 但是,这应该会让您更简单的配置调试,希望能让你马上上去。