Run a Docker image as a Cloud Foundry App on IBM Cloud

In that blog post I want to point out an awesome topic: “Run a Docker container image as a Cloud Foundry App on IBM Cloud”

Rainer Hochecker, Simon Moser and I had an interesting exchange about running a Docker image as a Cloud Foundry App on IBM Cloud.

The advantage with that approach is: you don’t need to instantiate a Kubernetes or OpenShift cluster. You can just run a single Docker image with your single application on IBM Cloud. That can be useful in different situations where you need to control the contents of your application, and the cloud foundry build-pack mechanism maybe restricts you.

IBM offers to run Cloud Foundry Apps on IBM Cloud and supports a set of build packsBut, by the fact IBM uses Cloud Foundry, you can also upload a Docker image as a Cloud Foundry application, it’s an officially supported feature. Yes there is no documentation related to that topic in the IBM Cloud documentation, but you can apply the Cloud Foundry documentation.

One impact of that situation is, you don’t see the VCAP variables and you can’t use the out of the box binding for IBM Cloud services. You have to manage the bindings to your IBM Cloud services by yourself.  

Let’s start with a short guide: How to setup a Cloud Foundry application using a Docker image.

When you follow the steps, you need to replace the name for the domain, port or hostname with your own settings. We will use in that example the IBM Cloud Shell on IBM Cloud and Node-RED as our Docker image.

The following images shows a simplified overview.

  1. We push the Docker image and run it as a container in a Cloud Foundry app
  2. We define a route with a port mapping to access the application from the internet.

cloudfoundry ibmcloud container simplified-overview


Step 1: Logon to IBM Cloud and open the IBM Cloud Shell.

The gif shows how to access the IBM Cloud Shell from the IBM Cloud UI.

cloudfoundry ibmcloud container open-ibmcloud-shell


Step 2: Change to the IBM Cloud UI to create a Cloud Foundry space in your region, if you don’t have one.

The gif shows how to create a new space dev, in the existing organization thomas.suedbroecker , in the region Germany.

cloudfoundry ibmcloud container create-cloud-foundry-space


Step 3: Go back to the IBM Cloud Shell and set the Cloud Foundry endpoint, organization and space. I my case I used following values.

  • Endpoint: api.eu-de.cf.cloud.ibm.com

  • Organization: thomas.suedbroecker

  • Space: dev

  • Resource group: Default
ibmcloud target --cf-api api.eu-de.cf.cloud.ibm.com -o thomas.suedbroecker -s dev -g Default

Step 4: Verify your Cloud Foundry settings on IBM Cloud (IBM Cloud documentation)

ibmcloud target

Step 5: Push a Docker image from a container registry.

  • Application name: node-red
  • Image: node-red-docker:v10

In the IBM Cloud Shell you need to install the Cloud Foundry API with ibmcloud cf install and verify the API version ibmcloud cf -v.

ibmcloud cf push node-red --docker-image=docker.io/nodered/node-red-docker:v10 --no-start --no-route

Note: Of course you can also use a private container image registry like the IBM Cloud Image Container Registry , if you want.

In this case, you’d need understand the Cloud Foundry documentation:

CF_DOCKER_PASSWORD=YOUR-PASSWORD cf push APP-NAME --docker-image REPO/IMAGE:TAG --docker-username USER

The IBM Cloud Image Container Registry also contains the documentation how to do this for Cloud Foundry, here is the command.

export CF_DOCKER_PASSWORD=<apikey>
ibmcloud cf push appname -o <region>.icr.io/<namespace>/<image_repo> --docker-username iamapikey

Step 6: Get the GUID from the Cloud Foundry App instance. A_GUID=Application GUID

A_GUID=$(ibmcloud cf app node-red --guid|awk '/[0-9]/{print $1}') 
echo $A_GUID

Step 7:  Set the port to access the application inside the Docker container of the Cloud Foundry application.

> The port information you get from your Docker image description. In this example we find the port on Docker hub for the Node-RED image.

  • PORT: 1880
ibmcloud cf curl /v2/apps/$A_GUID -X PUT -d '{"ports": [1880]}'

Step 8: In this step we create a route to the Cloud Foundry App, to access later the running application from the internet.

The Domain name eu-de.mybluemix.net depends on the region you create the Cloud Foundry App. In that sample we using eu-de. (see IBM Cloud documentation )

  • Domain: eu-de.mybluemix.net
  • Hostname: node-red-tsuedbroecker
ibmcloud cf create-route dev eu-de.mybluemix.net --hostname node-red-tsuedbroecker

Step 9: We need to map the route to the Cloud Foundry App , to access the running application from the internet.

  • Application name: node-red
  • Domain: eu-de.mybluemix.net
  • Hostname: node-red-tsuedbroecker
ibmcloud cf map-route node-red eu-de.mybluemix.net --hostname node-red-tsuedbroecker

Step 10: Now we extract the GUID for the newly created route. (R_GUID=route GUID)

R_GUID=$(ibmcloud cf curl "/v2/routes?q=host:node-red-tsuedbroecker" | sed -n 's|.*"guid": "\([^"]*\)".*|\1|p') 
echo $R_GUID

Step 11: We need to update the route mappings with our GUID’s. (

R_GUID and A_GUID)

ibmcloud cf curl /v2/route_mappings -X POST -d '{"app_guid": "'"$A_GUID"'", "route_guid": "'"$R_GUID"'", "app_port": 1880}'

Step 12: Start the Cloud Foundry application.

ibmcloud cf start node-red

Step 13: Visit the Cloud Foundry App in the IBM Cloud UI and inspect the possibilities.

In the gif you see, there is no build pack information and there are no environment variables.

cloudfoundry ibmcloud buildpack


Step 14: Now open the application URL and use the running Node-RED instance.

The gif shows, how to access the application URL inside the Cloud Foundry App.

cloudfoundry ibmcloud container

Understanding the given “out-of-the-box” HTTPS route to our application

The internal port of our container is in our example 1880 as described on Docker hub for the Node-RED image.  But when we invoke our application from the internet on IBM Cloud, we will use the unique route we defined for application. We created and mapped an external route with HTTPS (Port 443) to our application.

Example for the structure: HTTPS://[YOUR_HOSTNAME].[IBM PROVIDED DOMAIN] with SSL provided by IBM 

The creation of that rout has happen in step 11 and step 12. It is a root with HTTPS is secured with an SSL certificate provided out-of-the-box for us as you see in the gif:

cf-https-route

We also can add an additional route protected with SSL as you see in the gif below. We can choose in my case two out-of-the-box provided domains for our appliction.

cf-https-route-02

To use custom SSL and domains you have to visit the IBM Cloud documentation .


I hope this was useful for you and let’s see what’s next?

Greetings,

Thomas

PS:  You can try out Cloud Foundry Apps or Kubernetes on IBM Cloud. By the way, you can use the IBM Cloud for free, if you simply create an IBM Lite account. Here you only need an e-mail address.

#IBMCloud, #CloudFoundry, #IBMDeveloper, #Docker

11 thoughts on “Run a Docker image as a Cloud Foundry App on IBM Cloud

Add yours

    1. Hi Carmine,

      I didn’t tested that port 443 because this is the default HTTPS port, as you see here https://en.wikipedia.org/wiki/HTTPS .

      In the Cloud Foundry documentation here https://docs.cloudfoundry.org/devguide/custom-ports.html they only talking about HTTP and not HTTPS.

      From my perspective you could find out does your Docker image has a configuration option for HTTP and a port?

      Keep in mind you will invoke your app from the internet with the route provided by the IBM Cloud Foundry app. In my example it is: https://node-red-tsuedbroecker.eu-de.mybluemix.net, so user will use HTTPS from external.

      I hope this helps a bit and greetings Thomas

      Liked by 1 person

  1. There are VNC application and VPN application. External port will occupy port 443. I can temporary change the internal port to other port, but for external port, i hope it can be port 443, so it can firewall friendly. Otherwise I need to set an website just for forward port to 443, which mean I need two application.

    Like

    1. Hi Carmie, I added for you the section to the blog post “UNDERSTANDING THE GIVEN “OUT-OF-THE-BOX” HTTPS ROUTE TO OUR APPLICATION”. Maybe that helps to understand, that you don’t need to manage the external access to your application from the internet. This task is done from the IBM Cloud. You have already an HTTPS port with SSL. If you need to add your own domain and SSL certificate you need to follow the steps in the IBM Cloud documentation. https://cloud.ibm.com/docs/cloud-foundry-public?topic=cloud-foundry-public-custom-domains I hope that helps. Greetings Thomas

      Like

  2. Receive few times the link, but still do not get it.
    1) ibmcloud target -cf
    2) ibmcloud cf push node-red –docker-image=docker.io/nodered/myapp –no-start –no-route
    3) following the “Adding the route with the custom domain to an app” and add an my.dynu.net DNS domain.
    3) following the “Mapping the custom domain to the system domain”, in dynu.net add cname custom-domain.us-south.cf.cloud.ibm.com.
    e.g. CNAME custom-domain.us-south.cf.cloud.ibm.com
    then I try to access app by my.dynu.net. but fail.
    ping is resolved 169.62.254.80 which is an US south IP address.

    Like

    1. Hmm, we need to separate the problem.

      1. Does the upload of your custom image work?
      2. How did you add your custom domain?

      Your problem is the custom domain, right?

      “To use a custom domain, you must register the custom domain on a public DNS server, and then configure the custom domain in IBM Cloud.”
      https://cloud.ibm.com/docs/cloud-foundry-public?topic=cloud-foundry-public-custom-domains

      I thinks this video helps to understand the background how to map in that video for an old mapping.:

      “As an example, you can use *.mycompany.com to associate the route http://www.mybluemix.net to your app. You can also use example.mycompany.com to associate the route http://www.example.bluemix.net to your app.”

      I have no free domain on my site to check it, but I think you haven’t used “you can use *.mycompany.com to associate the route http://www.mybluemix.net to your app”.

      I hope that helps. Greetings Thomas

      Like

  3. Thanks for video. for CF apps log, I can see DDNS domain route to app.
    i.e.
    1 add ddns DNS name to CF domain
    2 edit route in CF apps with DNS with app.DDNS name, choose the correct region endpoint
    3. add a new DDNS entry with app.DDNS name with CNAME for doc. e.g api…..

    The problem is it is accept HTTP connection.
    ibmcloud cf domains. in colume type, it still does not show TCP.
    Try
    ibmcloud cf router-groups, seems it is not supported
    also
    ibmcloud cf create-shared-domain default-tcp.

    So I think ibmcloud CF still do not support TCP routing.

    Like

    1. Hmm, I think this is more related to configuration of SSL Certificate and Domain.

      Here is also an older video Configuring custom domains and SSL to be verified with the related new IBM Cloud documentation Mapping the custom domain to the system domain and Creating certificate signing requests .

      Simplified: web -> (Provider Domain Mapping/SSL ) -> (IBM Cloud Custom Domain and SSL mapping) -> route to the CF application

      But I think the best is this case is to contact IBM Cloud Support, because I can’t reproduce the situation as I said before.

      I hope this helps a bit still and nice weekend with greetings Thomas

      PS: Here is a blog post from 2014

      Like

  4. Hi, This is cool.

    Im struggling with deploying a docker container using Terraform, it seems “ibm_app” required field “app_path” only supports path to a local .zip file, and not a container registry url. Do u have any idea if Its possible to deploy container to cloud foundry using terraform?

    Like

    1. Hi, Marcus,

      I didn’t use Terraform (https://www.terraform.io), so I don’t know which fields you means with “ibm_app”, “app_path”.

      Maybe you mean this link in the IBM Cloud Documentation
      https://cloud.ibm.com/docs/ibm-cloud-provider-for-terraform?topic=ibm-cloud-provider-for-terraform-sample_terraformtemplates

      and it’s maybe related to this line https://github.com/IBM-Cloud/terraform-provider-ibm/blob/bb35b78238b17ebcb1608b976a4505a8b381d46b/examples/ibm-app/main.tf#L50

      Keep in mind the “normal” deployment for Cloud Foundry apps to IBM Cloud assumes you have an existing source code and you push it using the available buildpacks https://cloud.ibm.com/docs/cloud-foundry?topic=cloud-foundry-available_buildpacks.

      Maybe here you can see what I mean
      https://github.com/IBM-Cloud/terraform-provider-ibm/blob/master/examples/ibm-app/README.md#cloud-foundry-ibm-app

      So, I would say the template is not build to fulfil, what my blog post here is about.

      I hope that help and regards,

      Thomas

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑

%d bloggers like this: