Reputation: 12007
I have a Tomcat 7.0 webapp running inside a docker container on AWS Elastic Beanstalk (EB) (I followed the tutorial here).
When I browse to my EB url myapplication.elasticbeanstalk.com, I get a 502 Bad Gateway
by served by nginx. So its immediately clear that my port 80 is not forwarding to my container. When I browse to myapplication.elasticbeanstalk.com:8888 (another port I exposed in my Dockerfile) the connection is refused (ERR_CONNECTION_REFUSED
). So I SSH'ed into the AWS instance and checked the docker logs, which show that my Tomcat server has started successfully, yet obviously hasn't processed any requests.
Does anyone have any idea my port 8888 appears not to be forwarding to my container?
Executing the command (on the AWS instance):
sudo docker ps -a
gives:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c353e236da7a aws_beanstalk/current-app:latest "catalina.sh run" 28 minutes ago Up 13 minutes 80/tcp, 8080/tcp, 8888/tcp sharp_leakey
which shows port 80, 8080, and 8888 as being open on the docker container.
My Dockerfile is fairly simple:
FROM tomcat:7.0
EXPOSE 8080
EXPOSE 8888
EXPOSE 80
and my Dockerrun.aws.json file is:
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "myusername/mycontainer-repo"
},
"Authentication": {
"Bucket": "mybucket",
"Key": "docker/.dockercfg"
},
"Ports": [
{
"ContainerPort": "8888"
}
]
}
Does anyone see where I could be going wrong? I'm not even sure where to look at this point.
Also, my AWS security group for the instance is open on port 80, 8080, and 8888. Any advice would be greatly appreciated! I'm at a loss here.
Update 1:
Minor update, although I am still having trouble. After SSH'ing into my AWS EB instance, I inspected the Docker container to grab the IP of the container:
sudo docker inspect c353e236da7a
which gave me the IP as 172.17.0.6
.
Then, again from the AWS instance, I ran a curl
command:
curl 172.17.0.6:8080/homepage
which works, and returns the HTML of homepage! However, curl 172.17.0.6:8888/homepage
does not work (so I'm not sure what the "ContainerPort" : "8888"
means in the Dockerrun.aws.json
file then).
However, I still have the question, why aren't my :8080
requests being forwarded to the container Tomcat webserver? As above, myapplication.elasticbeanstalk.com:8080/homepage still receives a connection refused (ERR_CONNECTION_REFUSED
).
Upvotes: 2
Views: 3679
Reputation: 1732
I'm done this using fixing of nginx's listen ports. So, you have to add .ebextensions directory into root of your app and put your config file here (in my example it's 00-bypass-nginx-proxy.config):
files:
"/tmp/change_nginx_port.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/sh
# change listen port from 80 to 8761
sed -i '7s/.*/ listen 8761;/' /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf
# restart nginx
service nginx restart
container_commands:
00setup-nginx:
command: "/tmp/change_nginx_port.sh"
Your service now will be available on port 8761. Pay attention to sed
part of script, there is hardcoded line number which could be differ on your environment.
Upvotes: 0
Reputation: 15755
myapplication.elasticbeanstalk.com
Is a load balancer, not your instance. Elastic beanstalk launches a load balancer to autoscale your instances. Therefore when you are connecting to myapplication.elasticbeanstalk.com:8888
You are actually connecting to an instance that has only port 80 open. The load balancer then fowards traffic to an instance listening on port 8080.
You should be able to access your web application by just using the url without a port: myapplication.elasticbeanstalk.com
The reason this doesn't work is because you told your docker container to use port 8080, but told Beanstalk to forward to port 8888. Sure, all your ports are open, but tomcat is only running on port 8080.
The ports section in the dockerrun.aws.json
doesnt tell your app which port to run on, it tells the load balancer which port to forward to.
Ports – (required when you specify the Image key) Lists the ports to expose on the Docker container. AWS Elastic Beanstalk uses ContainerPort value to connect the Docker container to the reverse proxy running on the host.
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.
as seen here.
Or, in other words, the 8888 that you told beanstalk to forward to is working correctly, but your app is actually running on port 8080. You should change the dockerrun.aws.json to use the port 8080
instead.
Upvotes: 4