Elastic Beanstalk不支持来自单个Docker容器的多个端口,因此您需要按照建议在代理级别进行处理。但是,您的EC2实例不需要了解您的证书,因为您可以在负载均衡器处终止SSL连接。
在您的.ebextensions目录中,为nginx代理创建一个配置,其中包含两个服务器配置。一个代理http://docker(默认配置,端口80),另一个重定向到https(我选择端口8080)。
.ebextensions/01-nginx-proxy.config:
files:
  "/etc/nginx/sites-available/000-default.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      map $http_upgrade $connection_upgrade {
          default        "upgrade";
          ""            "";
      }
      server {
          listen 80;
          gzip on;
          gzip_comp_level 4;
          gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
          access_log    /var/log/nginx/access.log;
          location / {
              proxy_pass            http://docker;
              proxy_http_version    1.1;
              proxy_set_header    Connection            $connection_upgrade;
              proxy_set_header    Upgrade                $http_upgrade;
              proxy_set_header    Host                $host;
              proxy_set_header    X-Real-IP            $remote_addr;
              proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
          }
      }
      server {
          listen 8080;
          location / {
              return 301 https://$host$request_uri;
          }
      }
commands:
   00_enable_site:
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/000-default.conf /etc/nginx/sites-enabled/000-default.conf'
为EB负载均衡器和安全组创建第二个配置,将其设置如下:
- EC2实例:
- 允许负载均衡器在端口80/8080上进行通信
- 允许从任何地方在端口22上进行通信(用于ssh访问,可选)
 
- 负载均衡器:
- 将端口443 HTTPS转发到端口80 HTTP
- 将端口80 HTTP转发到端口8080 HTTP
 
.ebextensions/02-load-balancer.config:
"Resources" : {
  "AWSEBSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Instance security group (22/80/8080 in)",
      "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "8080",
          "ToPort" : "8080",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "22",
          "ToPort" : "22",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancerSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Load balancer security group (80/443 in, 80/8080 out)",
      "VpcId" : "<vpc_id>",
      "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "CidrIp" : "0.0.0.0/0"
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "443",
          "ToPort" : "443",
          "CidrIp" : "0.0.0.0/0"
        } ],
      "SecurityGroupEgress": [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "CidrIp" : "0.0.0.0/0"
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "8080",
          "ToPort" : "8080",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
      "Listeners" : [ {
          "LoadBalancerPort" : "80",
          "InstancePort" : "8080",
          "Protocol" : "HTTP"
        }, {
          "LoadBalancerPort" : "443",
          "InstancePort" : "80",
          "Protocol" : "HTTPS",
          "SSLCertificateId" : "arn:aws:iam::<certificate_id>:<certificate_path>"
        } ]
    }
  }
}
(注意:不要忘记用您的值替换SSLCertificateId和VpcId)。
负载平衡器(HTTP)的端口80上的任何流量都将到达EC2实例上的端口8080,该端口将重定向到HTTPS。负载平衡器(HTTPS)上端口443上的流量最终将由EC2实例(即Docker代理)上的端口80提供服务。