37

From reading the AWS documentation, it appears that when using Docker as the platform on Elastic Beanstalk (EB) (as opposed to Tomcat, etc.), only a single port can be exposed. I'm trying to understand why Amazon created this restriction -- seems that you now can't even serve both HTTP and HTTPS.

I'd like to use Docker as the container since it allows me to run several interconnected server processes within the same container, some of which require multiple ports (e.g. RTSP). Are there any workarounds for this kind of application, where say an RTSP and HTTP server can both be running within the same Docker container on EB?

thinkski
  • 1,306
  • 1
  • 15
  • 25

3 Answers3

23

Even though none of the documentation explains it, Single Container Docker Environment does support mapping multiple ports

{
    "AWSEBDockerrunVersion": "1",
    "Ports": [
        {
            "ContainerPort": "8080"
        },
        {
            "HostPort": "9000",
            "ContainerPort": "8090"
        }
    ]
}

With above configuration, port 8080 of docker will get mapped to host machines port 80 and port 8090 of docker will get mapped to host machine's port 9000.

To be more clear always the first port in the list will get mapped to host machine's port 80 and remaining will get mapped to specified hostPort (or) the same as container port in absence of host port.

Prabu
  • 2,436
  • 1
  • 15
  • 9
  • 3
    That is the correct answer! The answer marked as "correct" only deals with providing the necessary infrastructure changes (security group rules, listener) to ensure accessibility of any additional ports. – user2124712 Jan 10 '18 at 11:52
  • Thank you! Locally, how to use `eb local run` with multiple ports? – DiegoRBaquero May 29 '18 at 17:01
  • So I followed the above, but the second port is not exposed. Do I need to do the load balancer as well? Instead of the above? – Robert Moskal Jun 06 '19 at 21:39
  • 1
    @robert-moskal This will only map the docker port to host machine's port. To expose the host machine's port to external world, you need to follow security group configuration – Prabu Jun 10 '19 at 07:19
  • @Prabu thank you so much for your answer and comment. I stumbled upon this answer after hours of searching and the solution was actually quite simple. – jens1101 Sep 02 '19 at 11:45
  • Note this does not seem to work anymore (March 2021). In current version of ElasticBeanstalk the second port does not get exposed from the container. – jso Mar 19 '21 at 19:05
  • @jso It's still working without any issue – Prabu Mar 26 '21 at 14:50
  • @Prabu may depends on platform version then? Tested with current Docker on AL2, the port configuration in Dockerrun.aws.json was clearly ignored. It worked with ports specified in docker-compose.yml though. – jso Mar 28 '21 at 10:58
  • @jso - Effectively this did not work for AL2 (Docker 64 on AL2 3.4.8). Did you eventually found a solution ? – mikethe Dec 01 '21 at 00:50
4

In its current form, the Docker support in Elastic Beanstalk is marginal at best. FWIW I wrote a blog post evaluating EB that touched on this. I found that in addition to your observation about ports, it's not possible to run multiple containers, nor to even customize the docker run command. Hopefully they'll extend support in a future update.

Ben Whaley
  • 32,811
  • 7
  • 87
  • 85
  • Is there a recommended way to find out about this if/when its added? – thinkski Oct 14 '14 at 01:50
  • I like to follow [Jeff Barr's blog](http://aws.amazon.com/blogs/aws/) for AWS updates. – Ben Whaley Oct 14 '14 at 04:27
  • Is this still the case? – DkM Dec 11 '14 at 08:39
  • 3
    Per the [docs](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_image.html): "You can specify multiple container ports, but AWS Elastic Beanstalk uses only the first one to connect your container to the host's reverse proxy and route requests from the public Internet." – Ben Whaley Dec 11 '14 at 17:09
  • 2
    Is this now side-stepped by deploying multiple docker containers and using the port mapping? – Vinay Feb 25 '16 at 03:21
  • 1
    @Vinay I can confirm that the multiple docker container configuration and the port mapping in the Dockerrun.aws.json file works. – daxiang28 May 25 '17 at 18:34
4

You could write an on-start config file for Elastic Beanstalk's LoadBalancer/ReversProxy to forward the additional ports to its EC2 instance(s). an example from Ben Delarre :

"Resources" : {
  "AWSEBLoadBalancerSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Enable 80 inbound and 8080 outbound",
      "VpcId": "vpc-un1que1d",
      "SecurityGroupIngress" : [ {
        "IpProtocol" : "tcp",
        "FromPort" : "80",
        "ToPort" : "80",
        "CidrIp" : "0.0.0.0/0"
      }],
      "SecurityGroupEgress": [ {
        "IpProtocol" : "tcp",
        "FromPort" : "8080",
        "ToPort" : "8080",
        "CidrIp" : "0.0.0.0/0"
      } ]
    }
  },
  "AWSEBLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
      "Subnets": ["subnet-un1que1d2"],
      "Listeners" : [ {
        "LoadBalancerPort" : "80",
        "InstancePort" : "8080",
        "Protocol" : "HTTP"
      } ]
    }
  }
}

Ref:

Nasser Al-Wohaibi
  • 4,562
  • 2
  • 36
  • 28
  • 2
    This example opens port 80 on the load balancer and proxies to port 8080 on the instance. It does not expose multiple instance ports. And even if it did, the reverse proxy on the instance that forwards requests to docker cannot listen on multiple ports. – Ben Whaley Dec 31 '14 at 15:10
  • This is just an example on how to configure the load balancer on init of Elastic Beanstalk instance. The reverse proxy can listen and forward multiple ports, at least according to aws docs and aws console. What you need after exposing multiple ports in docker, is to build upon the example and allow the reverse proxy to listen and forward whatever port needed. – Nasser Al-Wohaibi Dec 31 '14 at 15:45
  • simply EXPOSE PORT(s) in docker then create config file containing load balancer settings in .ebextensions – Nasser Al-Wohaibi Dec 31 '14 at 15:53
  • 2
    But it is not just the load balancer. For docker, beanstalk also sets up a local proxy on the instance that forwards traffic to the docker container. Have you successfully configured a docker container with multiple ports on beanstalk? – Ben Whaley Dec 31 '14 at 16:34
  • The EC2 instance(the host) and the docker image are open for the developer to tinker with. Either on container start and after, you can setup everything with the app by utilizing **`.ebextensions`**. – Nasser Al-Wohaibi Jan 01 '15 at 11:42
  • 2
    I dont find this example particularly clear. It would have been better to illustrate what the OP asked for, that is showing how to setup a 443 and 80 in that config file. Hence the low votes on this answer, but high votes on question. – Houman Aug 19 '15 at 17:17