Skip to Content
Technical Articles

Deploy a complex application on SCP that uses non-standard ports

Often one finds examples and/or tutorials on how to deploy simple applications on SAP Cloud Platform. While those examples are very valuable and I’ve learned a lot from them, when it comes to “the real thing” often one has many different options that require a lot of experimentation.

In the following report you are going learn how do deploy a real world complex application on SAP Cloud Platform.

Through this report you are going to save a lot of time and effort in setting up your application on the powerful SAP Cloud Platform.

The Application

I wanted to deploy an Apache Licensed application, implemented using Scala and with a very large footprint. Namely, it had a large number of local files, and it also required a relational database. The application also would use different so called non-standard-ports for providing different functionalities to the users.

The application architecture clearly violated the 12 factor apps principles for cloud foundry development, and while several buildpacks existed, none of them was originally supported by cloudfoundry, and most of them was not up-to-date.

BuildPack

The first approach I tried was to be brave and try to use the BuildPack strategy.

Since a Scala project typically delivers JAR artifact binary compatible with Java Virtual Machine I was thinking that using a Java Buildpack should easily solve all of my problems. Unfortunately I was wrong: after several days of attempts I had to give up the approach and I got confirmation from SAP Support that this was not a supported way of using the Java buildpack. They suggested me using Docker.

Docker

Cloudfoundry supports the use of Docker and as well the SAP Cloud Platform. At the beginning I was a bit afraid, since I was going to introduce more code on the platform that I wanted, and since I had of course to take responsibility for the security of that layer – that instead by using buildpack was going to be taken care by “others”. Additionally, I had no clue on how to make the application inside the docker being able to use a database provided by the SAP Cloud Platform (not wanting myself to have to take care also of that e.g. deploying a second docker with the DBMS of choice). Finally, how would the network setup work ? These were the many questions one has to be prepared to answer, and the following few lines show how to do it quickly.

The final recipe

In spite of the many doubts, this path turned out to be the successful one and the one I am going to describe in detail.

Docker

Certainly the first step is in building a proper image. Often images are available on the internet (e.g. DockerHub ) however you have to consider if you really want to use them blindly. Those could in-fact security holes (willingly or not) and therefore a detailed secure assessment should be firstly performed. Remember, when you bring your own image, you are responsible for all the components in it : from the operating system up to the application layer and network connectivity. The SAP Cloud Platform provides some “safety bells” but security is security and there is never enough.

Setup

Depending to the platform on which you develop, you need to have Docker locally installed. Docker Desktop Community is good to start with.

Build your docker image

At least you should have a Dockerfile, then using docker have an image built and locally installed. How to do that is well described in the official documentation.

Tag it for the target repository from where CloudFoundry will have to fetch it

CloudFoundry allows to provide a docker repository from where it gathers the docker images.

Such location needs then to be specified in the MTAR that one deploys on SAP Cloud.

All SAP artefacts are in the SAP Docker Repositry and therefore

docker tag myimage myapp.docker.repositories.sap.ondemand.com/myapp

Push it to the target repository

The image needs clearly to be “pushed” into the repository, to which needs to be properly authenticated. In the case of SAP Docker Repository, one needs to login interactively and then collect the API Token available in the user configuration.

docker login --username=###myuserid### --password=##APITOKEN### myapp.docker.repositories.sap.ondemand.com

With a successful login one can therefore proceed with the proper push to the repository
docker push myapp.docker.repositories.sap.ondemand.com/myapp

At this point we can proceed on the preparation of the deployment for the SAP Cloud Platform.

SAP Cloud Platform

Setup

  1. you need to have an account on the SAP Cloud Platform, and the account needs to be assigned the Developer Role in one or more specific organisation and space.
  2. download the Multitarget Application build tool for cloud applications
  3. Update your CF local installation with the multiapps plugin

Now that such tools are ready, we need to create a configuration to be used for instructing SAP Cloud Platform to collect the docker image, and then appropriately configure the environment for the application.

The cloud configuration file MTAD.YAML


_schema-version: 3.2.0
ID: myapp
description: Deploy myapp in SCP CF
version: 0.0.1
modules:
- name: myapp
requires:
- name: db-service
- name: db-log
properties:
DB_USERNAME: $VCAP_SERVICES.postgresql.credentials.username
DB_PASSWORD: $CAP_SERVICES.postgresql.credentials.password
DB_URL: $VCAP_SERVICES.postgresql.uri
parameters:
disk-quota: 2G
memory: 3G
health-check-type: none
docker:
image: myapp.docker.repositories.sap.ondemand.com/myapp
username: myappusername
password: ###dockerpassword###
resources:
- name: db-service
type: postgresql
- name: db-log
type: application-logs

Now that the configuration informations is ready, it is time to generate the MTAR. This can be hand by hand, or using the MTA Archive Builder, or at best using the newly developed MBT tool.

mbt assemble
That command is the fastest and easiest to use, compared to the MTA Archive Builder, and provides more flexibility therefore is recommended. The result is to be found in the mta_archives subfolder, and is called ###module name##version##.mtar

Deploy the mtar

The mtar so built will very small since upon deployment it will get the image from the repository.
The first step is of course to login
cf login

After having selected the specific ORG and SPACE then execute the deployment. This can only work if the multiapp plugin had been previously appropriately downloaded and installed.
cf deploy mta_archives/yourprog.mtar

Appropriately configure the environment for the application

The DB_USERNAME, DB_PASSWORD and DB_URL are the specificy way in which myapp is expecting to have the environment ready before starting to connect to the database. If myapp would be using SpringBoot and the application be deployed with the BuildPack approach, then one could easily wire the app with a specific variable, in this case is however not possible since myapp is not using springboot. We therefore need to

    1. get the content of the variables of VCAP (cf env myapp)
    2. set the variables DB_USERNAME , DB_PASSWORD, DB_URL (in your case they could be different) to the values from VCAP
    3. restart the application
      cf restart myapp

Connect the special ports

As described at the beginning myapp is exposing port 8081 and 8082 for different purposes. If we now try to connect to it (for example from the laptop) these are not going to be accessible. The trick (this took to me more than one day to figure out ) is practically to do reverse-proxy however without installing any software but instead using native capabilities of the CF environment. Hereafter is how to do it.

    1. create a new route in the space and domain where you are logged into
      cf create-route dev cfapps.sap.hana.ondemand.com --hostname myapp-one
    2. get the GUID of the freshly created route
      cf curl /v2/routes?q=host:myapp-one –> this is the ##ROUTE_GUID##
    3. get the GUID of the application
      cf app myapp --guid –> this is the ##APP_GUID##
    4. Map the route to the specific port
      cf curl /v2/route_mappings -X POST -D '{"app_guid":"##APP_GUID##,"route_guid":"##ROUTE_GUID##","app_port":8081}'

Access the special port

At this point all what you need to do is to point your application / postman / browser to myapp-one.cfapps.sap.hana.ondemand.com and you will actually be getting response from port 8081 of myapp.cfapps.sap.hana.ondemand.com.

Conclusions

SAP Cloud Platform is very powerful and easy to deploy simple microservices as well as monolithic applications such as in my case.
One of its strengths is certainly the large marketplace of industrial quality ready to use services (in my case I used a database engine, and the logging engine) , and as well the support for developers that can focus on specific development scenario (e.g. Java springboot). By using Docker images, you can also deploy complex applications that would not match at first sight the foreseen cloud environment. This document demonstrates how to deploy a complex application with also custom ports, and should facilitate greatly those that for example want to rapidly deploy an existing Dockerized application without investing any time in adapting the code or the code architecture to the cloud design principles.

Addditional useful links:

  • https://gist.github.com/nota-ja/ef56ea0584ae2b37d6d3a535efe2d4ee
Be the first to leave a comment
You must be Logged on to comment or reply to a post.