CloudFoundry application opening two ports - cloud-foundry

I have a CF application that opens two ports. AFAIK CF can create routing on only for one of them - to the one that is located in VCAP_APP_PORT or PORT. How can I create some route to the second port? I don't mind having separate name directing to other port.

As stated in some other comments it is now possible in CF to use multiple ports for your application. There is a chapter in the CF documentation which describes how to do it.
I followed the instructions and still had some trouble to fully understand it, that's why I provide a step by step guide here with some explanations (replace all variables in [] with the actual values):
Configure your application to listen on multiple ports. In my case I configured a spring boot app to listen on port 8080 for HTTPS requests and on port 8081 for HTTP requests (used for calls to actuator endpoints like health/prometheus as described here). This means that I have configured one TCP route and one HTTP route in CF and mapped those routes to the CF app.
Get the [APP_GUID] of the CF app which should be reachable on multiple ports:
cf app [APP_NAME] --guid
Add the ports (e.g. 8080, 8081) to the CF app: cf curl /v2/apps/[APP_GUID] -X PUT -d '{"ports": [8080, 8081]}'
Now the route (e.g. in this case the HTTP route) which points to the CF app must also be adjusted so that it points to the correct CF app port. First you need to get the route information, you can do it with
cf curl /v2/routes?q=host:[HOST_NAME] or with cf curl /v2/apps/[APP_GUID]/routes and save the guid of the route that points to your app ([ROUTE_GUID]).
For this particular route you have to adjust the route mappings. Each CF route can have multiple route mappings. You can show current route mappings for a route with this command: cf curl /v2/routes/[ROUTE_GUID]/route_mappings. With cf curl /v2/route_mappings -X POST -d '{"app_guid": "[APP_GUID]", "route_guid": "[ROUTE_GUID]", "app_port": 8081}' you add a mapping to a route (e.g. here to 8081).
The route has now two mappings, one pointing to 8080 and one pointing to 8081. If you want the route to only point to one of the ports (e.g. 8081) you have to delete the mapping with the port you do not want to have. Run cf curl /v2/routes/[ROUTE_GUID]/route_mappings to show all route mappings. Then extract the guid of the route mapping that should be deleted (e.g. the one to port 8080). Finally, run cf curl /v2/route_mappings/[GUID_ROUTE_MAPPING] -X DELETE to delete the route mapping you do not need.
Now your CF app should be reachable on another port than 8080 when the newly configured route is used.

Currently an application on Cloud Foundry is not able to have two ports mapped into its container environment. As part of the new Diego runtime, multiple port mappings has been exposed, but is not currently available through the API.
Depending on what you need, you could take a look at Lattice, which uses the Diego runtime. Some documentation can be found here.

Cloud Foundry will route TCP/WebSocket traffic coming from 80/443 to the one assigned port. Your application can not listen to any other port.
https://docs.cloudfoundry.org/devguide/deploy-apps/prepare-to-deploy.html#ports
You can either create multiple url mappings, or have two applications that communicate with each other using a messaging or database service.

Resurrecting an old question, but this is supported in Cloud Foundry now. Support was added around April 2019. Check your version to see if it supports this.
The general process is:
Use cf cli to update your app to list all the ports it listens on
Update each route to the app with the specific port that the route should use. If you have two ports, you'll need two or more routes one port per route.
Restart the app
Right now you have to use cf curl to manually update these records. Instructions can be found here: https://docs.cloudfoundry.org/devguide/custom-ports.html. Hopefully future cf cli versions make this easier.

Related

AWS multiple sites, one instance, multiple ports

I have one Wordpress on Apache already deployed on port 80 and configured through Route 53. This is obviously on port 80. Now, I have created a new project in react.js that is listening to different port, port 3000. Both sites are on the same EC2 Ubuntu instance. I would like to attach to the second site (node.js) different domain name and configure this to work, however, I don't know how to do it. Can you please help?
Point the two domains to your EC2 elastic IP(A records).
On apache, configure virtual host which enable you to run two web site on a single machine. see this link: Apache Virtual Host documentation - Apache HTTP Server Version 2.2

Cloud Foundry: How to remap an exposed port in Docker image?

I would like to run RabbitMQ service using my organization's Cloud Foundry Service. I checked the RabbitMQ docker image and saw that the following ports are exposed:
"ExposedPorts": {
"25672/tcp": {},
"4369/tcp": {},
"5671/tcp": {},
"5672/tcp": {}
},
I start the app by installing it in Cloud Foundry as follows: cf push -o rabbitmq RabbitMQ -u process.
The app gets installed and gets started. However, it is listening on port 5672. The CF service only allows me to have ports between 10000 and 10999. So I go into the CF portal, remove the HTTP route, and create a new TCP route on port 10123 for the rabbitmq app.
How do I go about mapping the port 10123 (external facing) to the port 5672 (RabbitMQ, internal facing) using the CF CLI?
There is functionality to map a route with specific external ports to specific internal app ports. It is described in the docs here.
https://docs.cloudfoundry.org/devguide/custom-ports.html#procedure
At the moment, the functionality isn't directly supported by the cf cli, so you need to use cf curl to manually send a few requests.
The general flow is this.
Get your app's guid.
Configure a list of ports for your app, cf curl /v2/apps/APP-GUID -X PUT -d '{"ports": [25672, 4369, 5671, 5672]}'
Map a TCP route to your app with cf map-route my-app example.com --port 10123.
Get the route guid of your TCP routee. Run cf curl /v2/routes?q=host:example.com.
Update the route mapping with cf curl /v2/route_mappings -X POST -d '{"app_guid": "APP-GUID from #1", "route_guid": "ROUTE-GUID from #4", "app_port": 5672}'
Optionally repeat 3-5 for additional ports.

AWS ec2 access local app via different hostname/domain name without Route 53

I have a web app running locally on my ec2. I can access it publicly via ec2 Public DNS (IPv4) - ec2-x-xxx-xxx-xxx.compute-1.amazonaws.com:8000
But this app has the functionality to trigger two different web apps based on the domain url.
localhost:8000 -> app 1
myapp.localhost:8000 -> app 2
I cannot add the string myapp to my ec2 Public DNS address and make the app to load due to the the domain name not resolving.
I don't want to go the Route 53 route.
Can this be done any other way ? Maybe by adding hostnames to the ec2 hosts config file ?
If so please point me to the right direction. Thanks.
From the description, I can see you have an app that checks the DNS name sent in the HTTP request to distinguish 2 different business logic in one application. Technically, there is only one application since you only have one process running which listens to port 8000. The app 1 and app 2 are just 2 different execution paths internally inside the application.
On your local machine (which is an EC2 instance in this case), by changing the /etc/hosts file, you can have both localhost and myapp.localhost pointing to 127.0.0.1, which is the IP on you default loopback network interface. With this, you can access the app locally by using these 2 locally resolved domain names. They will be resolved to the same IP and target the same running process on your machine.
As you can see how it works locally on your machine, in order to achieve your goal, you will need 2 DNS records pointing to the same IP. Since you cannot use Route 53 or other similar services to create more public DNS records to map to your EC2 instance's public IP, there is no way for you to have the second DNS name for your machine.
It's actually a bit weird to have your app's business logic relying on the DNS names which you cannot actually control. I would suggest you use the HTTP headers or query parameters to solve your problem.
One solution by using custom HTTP header can be done like:
(For App1)
HTTP GET ec2-x-xxx-xxx-xxx.compute-1.amazonaws.com:8000
Header: X-APP-NAM=app1
(For App2)
HTTP GET ec2-x-xxx-xxx-xxx.compute-1.amazonaws.com:8000
Header: X-APP-NAME=app2
In your app, at the place where you check the DNS name, you can change the logic to check X-APP-NAME HTTP header value instead, then proceed with different execution path (different apps as you said). Thus, you only need one DNS name to support 2 apps.
Hopefully, this helps you.

VM Instance group to configure to listen on port 80 and 8080

I have configure my VM in such a way that I have 2 application running on one VM.
First App listen on ip:80 port
Second App listen on ip:8080 port
I have enabled ports on VM instances group like this.
I have my Load Balancer configured with two front rules like this.
I want to map ip1:80 to my 80 port application and ip2:8080 to 8080 application
when I tried accessing my application using load balancers IP address it always show me 8080 port application.
I have two backend service running
help me here google team. I m newb
If you want to use IP addresses but not URLs/Domain(s) to reach to your web applications, then URL Maps cannot help to implement your design, as URL map forwards the request to the correct backend service using host values (example.com) and path values (/path) in the destination URL.
That being said, you can add one more Target Proxy to your LB resources to route incoming requests directly to the desired backend services. This will allow you to keep your minimum number of instances as one VM.
For more information, visit this article.
I had similar problem and I had to add second backend.
So I have two backends: one for 80 port, other for 8080. And I have on managed group.

Multiple dockers and multiple domains on elastic beanstalk

I have 10 low-traffic websites, all with different domains and I want to run all of them on one elastic beanstalk environment.
I'm a developer with zero experience with docker but from reading other answers I got the idea that a multicontainer docker environment could be what I need.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_ecs.html
Can someone who have done it before (multiple domains on an EB environment) confirm that I'm on the right direction? If so, is there somewhere a tutorial on doing a multi-domain environment for people who never used docker?
AWS EB doesn't handle routing based on domain names. You can expose multiple ports. 80 and 9000 are exposed in the graphic below. But the visitor must type to port into the url, that's very ugly.
In order to route traffic to a container based on the domain you need a proxy. Nginx Proxy can do that for you.