Skip to Content
Technical Articles
Author's profile photo Kai Niklas

How to deploy SAP CAP Anywhere with Docker

One key ingredient of SAP CAP is it’s openness. Openness especially means, that we are free to choose the development tools, the used database, the libraries, etc. Especially we are free to choose on which platform we run and operate CAP. All we need is @sap/cds-dk and node.js.

This article demonstrates:

  1. How to deploy a CAP App to Heroku, a popular PaaS which supports direct deployment from a git repository, and
  2. How to bundle a CAP App into a Docker container which provides even more flexibility to deploy on any docker supported platform

Sample Project

For this article I reuse my sample project “Yet Another Covid-19 Tracker” which I described recently in the article SAP CAP Remote Services & SAP Fiori Elements.

But of course you can follow this article as well with your own project or a sample cap project from the SAP Github Samples.

Prepare CAP for Production

While development SAP CAP comes with several Features activated by default to ease rapid development. These include for example an in-memory db, mocked authentication, Fiori Preview, live reload or mocked bindings. In production we usually do not want to lean back on default Features meant for development, but want to make Features explicit.

We can easily check which Features are activated by running cds env. In package.json or .cdsrc.json we can explicitly override the default setting, if we want to. Find more about environment variables in the official SAP CAP for node.js documentation.

The default cds environment variables are set according to the current NODE_ENV variable. NODE_ENV is usually set to production in productive environments and something else, e.g., development, in other environments. If set to production the development features are deactivated. This may cause problems and errors if we rely on these features, e.g., a missing service binding.

In the following table you can compare the difference between development and productive settings of a clean CAP project as of June 2021:

Parameter development production
_sources [.env, default-env.json, .cdsrc.json, defaults.js, process.env] [default-env.json, .cdsrc.json, defaults.js, process.env]
env  development
features.fiori_preview  true  false
features.fiori_routes  true  false
features.in_memory_db  true  false
features.live_reload  true  false
features.mocked_bindings  true  false
profiles  [ ‘development’ ]  [ ‘production’ ]
requires.auth.kind  mocked-auth  JWT-auth
requires.auth.strategy  mock  JWT
requires.auth.users.*  true
requires.auth.users.alice.roles  [ ‘admin’ ]
requires.auth.users.bob.roles  [ ‘builder’ ]
requires.sql.credentials.database  :memory:
requires.sql.kind  sqlite  hana
requires.sql.use  sqlite  hana

Configuring / Activating CDS Features

For my project I would like to use the in-memory DB Feature. Therefore, I simply add the following configuration into .cdsrc.json:

{
	"features": {
		"in_memory_db": true
	}
}

Test CAP Productive Setup

The different behavior of CAP in development and production requires us to test any CAP application (or node.js application in general) before deploying into production. We can do this by simulating a productive environment by first setting NODE_ENV to production.

# windows powershell
$env:NODE_ENV="production" 

# windows cmd
set NODE_ENV=production 

# unix
export NODE_ENV=production

Next we simulate typical steps a deployment executes by running the following commands:

# clean install of production dependencies
npm ci --only=production

# start cap app
npm run start

As the NODE_ENV variable is set to production the commands behave differently and remove dev dependencies and the cds commands included in the start script use the productive settings as well.

Warning: Be aware of the fact, that you may have installed @sap/cds-dk globally, which contains commands which are not available in a productive environment. If you rely on those commands you may need to add the package to your dependencies, or better rethink to not rely on the command(s) at all.

Environment specific variables

Another typical pitfall is to forget setting the environment variables in the target environment. While development we typically use configuration files like .env or default-env.json to set those variables. But they are usually not checked in into the code repository because they are not only environment specific but may contain sensitive information such as passwords or API keys.

Therefore, we need to check if we have set all environment variables in the target environment before deployment.

Note: Based on the environment variables, .env files are not evaluated in production.

Configuring Log Levels

In a productive environment we usually don’t want to log every http request we serve. Therefore, we can set the log level for the module cds to warn or error for examplein .cdsrc.json:

{
  "log": {
    "levels": {
      "cds": "warn"
    }
  }
}

Deploy CAP to Heroku

One popular Platforms (PaaS) to deploy and run projects in the cloud is Heroku. Heroku is especially handy for simple POCs or building MVPs as it is very simple and straight forward. You can directly deploy from your git repository to Heroku.

Configure environment variables

After we created a new project we need to configure all environment variables which are only included in environment specific files and therefore not part of the deployment. One typical variable could be the destinations variable, which contains name, url, user and password of a service which we want to integrate.

Deploy git repository

Deployment is as easy as clicking a button after connecting your git repository with heroku. Alternatively, you can also listen on changes on a specific branch and deploy whenever a new commit occurs.

Deploy Anywhere with Docker

Deploying to Heroku is straight forward. But we can do it even more generic and containerize the application with docker.

Therefore, we create a Dockerfile in the root folder of the project:

FROM node:14-alpine

# use productive environment
ENV NODE_ENV production

# copy source as node user
WORKDIR /usr/src/app
COPY --chown=node:node . .

# install dependencies
RUN npm ci --only=production

# run app as node user
EXPOSE 4004
USER node
CMD ["npm", "start"]

Then we can run the following command to build the docker file:

docker build -t <YOUR_CONTAINER_NAME> .

This docker container can now be deployed anywhere. You can test it locally as follows:

docker run -p 4004:4004 -t <YOUR_CONTAINER_NAME>

If something does not work and you want to inspect the container you can open a shell in the container like this:

docker run -i -t <YOUR_CONTAINER_NAME> /bin/sh

Final Thoughts

You see that it is quite simple to use and deploy SAP CAP anywhere. Staying in the SAP ecosystem and using SAP’s services eases developing enterprise grade applications, but it is not mandatory.

My application uses an in-memory DB for caching purposes only. If you want to use a persistent DB but do not want to use HANA, then you should give cds-pg a try, which is an adapter for PostgreSQL.

If you want to try out the app, you can find it here:

Assigned Tags

      6 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Martin Stenzig
      Martin Stenzig

      I think the big question is: Is that still supported by SAP if a customer deploys a CAP app to i.e. Azure?

      Author's profile photo Kai Niklas
      Kai Niklas
      Blog Post Author

      I cannot give any legal statement.

      But I assume, that if the issue is not related to the execution environment, but with the tooling itself, and you are a SAP customer, you can use the official ways to report incidents as described on the SAP CAP Resources & Support website.

      In any case you can ask for help using SAP CAP Community.

      Author's profile photo Gregor Wolf
      Gregor Wolf

      Hi Martin,

      I guess this discussions might be helpful:

      Best Regards
      Gregor

      Author's profile photo Martin Stenzig
      Martin Stenzig

      Thanks Gregor

      Author's profile photo Juliane Dombrowski
      Juliane Dombrowski

      So, that means CAP is free to use on any platform/db without legal repercussions? Are there any (legal) restrictions in choosing DB/other services?

      I wasn't aware that CAP can be used outside the SAP environment

      Author's profile photo Kai Niklas
      Kai Niklas
      Blog Post Author

      I cannot give any legal statement.

      But according to this answer it "is not forbidden by the SAP Developer License, but the scenario is not supported by SAP".