Your First SAP Commerce Cloud Build and Deployment, Done Right
From empty Cloud Portal subscription to a deployed 2211 storefront: repository setup, manifest configuration, endpoint security, the initial build and deploy, and automating both through the Cloud Portal API.
The first build on a fresh SAP Commerce Cloud subscription sets patterns the project will live with for years. Teams that treat it as a checkbox end up with unsecured endpoints, secrets in Git, and a repository structure that fights the cloud builder on every release. This guide walks the path from empty subscription to running storefront, with the decisions that matter flagged at each step, current for 2211 and the composable storefront era.
Prerequisites: Access and Environments#
You need an SAP S-user and a role granted by someone with the Customer System Admin role. If nobody knows who that is, look up the Super Administrator under Important Contacts in SAP for Me. Once you can log in to the Cloud Portal at portal.commerce.ondemand.com, verify your environments are provisioned. A standard subscription gives you at least one development, one staging, and one production environment (conventionally D1, S1, P1). If the Environments list is empty, environment provisioning is self-service through SAP for Me, but it needs the Super Admin.
Decide now who gets which portal role. Customer System Admin can read service configuration values, which will include credentials. That role list should be short and audited.
Connect the Git Repository#
Each subscription connects to exactly one Git repository, reachable from the public internet (the CCv2 builder cannot see behind your corporate firewall; if your Git server is internal, you need a mirror or a hosted remote). Both SSH and HTTPS access work. Connect it in Cloud Portal under Repository before anything else; the builder validates connectivity when you save.
One repository per subscription is a real constraint, not a suggestion. Monorepo discipline follows: platform customization under core-customize/, composable storefront under js-storefront/, and nothing else fighting for the root.
Populate the Repository#
Start from the SAP-samples/cloud-commerce-sample-setup repository rather than an empty tree. It gives you the folder structure the cloud builder expects, a working manifest.json, and environment-specific property files.
The essentials of the structure:
core-customize/
├── manifest.json
└── hybris/
├── bin/custom/ # your extensions, the only bin content in Git
└── config/
├── localextensions.xml
├── local.properties
└── environments/
├── common.properties
├── local-dev.properties
└── p1.properties
js-storefront/
└── mystorefront/ # composable storefront app
Rules the sample encodes and you should keep:
- Never commit
hybris/bin/platformorhybris/bin/modules. The builder downloads the platform matching yourcommerceSuiteVersion. Locally, you unzip the same "CX COMM" artifact from the SAP Download Center into place;.gitignorekeeps it out of the repository. - Get it running locally before the first cloud build. A cloud build takes 15 to 45 minutes depending on extension count. Local
ant clean allplus a smoke test catches 90 percent of failures in a tenth of the time. - AddOns must be installed, not just listed. For an accelerator-based storefront this means
ant addoninstallagainst the storefront template, and the same list mirrored in the manifest'sstorefrontAddons. If you are starting fresh in 2026, skip the accelerator entirely: it has been deprecated since 2205 and the extensions are scheduled for removal from 2211 update releases in Q3 2027. Start composable.
For a composable storefront, the local loop is:
# platform side
cd core-customize/hybris/platform
. ./setantenv.sh
ant clean all
./hybrisserver.sh
# storefront side
cd js-storefront/mystorefront
npm ci
npm run build
npm run start # http://localhost:4200
The Manifest, Reviewed Line by Line#
manifest.json is the build contract. The sample ships a working one; before your first build, understand these keys because they are the ones you will change:
{
"commerceSuiteVersion": "2211",
"useCloudExtensionPack": false,
"extensionPacks": [
{
"name": "hybris-commerce-integrations",
"version": "2211.x"
}
],
"extensions": [],
"useConfig": {
"extensions": { "location": "hybris/config/localextensions.xml", "exclude": ["hac"] },
"properties": [
{ "location": "hybris/config/environments/common.properties" },
{ "location": "hybris/config/environments/p1.properties", "persona": "production" }
],
"solr": { "location": "solr" }
},
"storefrontAddons": [],
"aspects": [
{
"name": "backoffice",
"webapps": [
{ "name": "hac", "contextPath": "/hac" },
{ "name": "backoffice", "contextPath": "" }
]
},
{
"name": "backgroundProcessing",
"properties": [
{ "key": "cluster.node.groups", "value": "integration,yHotfolderCandidate,backgroundProcessing" }
]
},
{
"name": "api",
"webapps": [
{ "name": "commercewebservices", "contextPath": "/occ" }
]
}
],
"tests": {
"extensions": ["acmecore"],
"annotations": ["UnitTests"]
}
}
commerceSuiteVersionselects the update release. Plain"2211"floats to the latest; pinning"2211-jdk21.5"style versions makes builds reproducible. Pin it. Upgrades should be deliberate commits, not surprises.useCloudExtensionPackis legacy (1905-era). Integration extensions come throughextensionPacksnow.aspectsdefines what runs where. If you run composable storefront only, do not define anaccstorefrontaspect; fewer aspects means faster builds and fewer endpoints to secure.testsruns your unit test annotations during the cloud build. Wire this from day one; a build that runs zero tests verifies nothing except compilation.
Commit and push. The first build should be from a commit, on a branch you can name in the portal, typically develop or main depending on your branching model.
Secure Before You Deploy#
Every endpoint on a new environment defaults to Deny All. Resist the temptation to flip everything to Allow All just to see the storefront. Set the model up properly once:
| Endpoint | Recommended exposure |
|---|---|
| Storefront / JS storefront | Allow All (optionally with country or abuse-list restrictions) |
| API (OCC) | Same filter set as the storefront; it serves the same shoppers |
| Backoffice | Deny All plus an IP filter set covering offices and VPN egress ranges |
| Background processing | Same as Backoffice or stricter; admin troubleshooting only |
| Solr | Deny All plus admin filter set; nobody outside operations needs this |
Three more items that belong in the first session, not after go-live:
- SSL certificates. Default certificates exist per endpoint, but load your own now so certificate handling is tested from the first deployment, not discovered during cutover week.
- Security files. Certificates, keystores, salts, and tokens upload through the Security Files page and attach to environments at deployment. This is the mechanism for anything file-shaped and sensitive.
- Sensitive properties. Passwords and API keys go into each environment's service configuration, not into property files in Git. Know the trade-off: anyone with Customer System Admin can read service configuration values. If that circle is too wide, restrict the role, because the alternative (secrets in the repository) is strictly worse.
The Initial Build and Deploy#
Trigger the build in Cloud Portal: pick the branch, name the build, and wait. If it fails, the full build log is available from the build entry; the usual first-build culprits are an extension listed in localextensions.xml but missing from the repository, an addon listed in the manifest but never installed on the storefront template, or a Solr customization targeting the wrong Solr version.
Deploy the successful build to the development environment. For the first deployment, and only then, select Initialize database. Initialization drops and recreates the schema and runs essential plus project data. Every subsequent deployment should use Migrate data (or none), because initialization on an environment with real data is irreversible destruction. The portal will let you do it; nothing but process protects you.
After deployment, the JS storefront endpoint serves your composable storefront, Backoffice answers on its endpoint for your filtered IPs, and /occ/v2 (or the context path you chose) serves the API.
Automate It Early: The Cloud Portal API#
Everything above is clickable, and for build one that is fine. By build ten your team should not be clicking. CCv2 exposes a Commerce Cloud API for builds and deployments, authenticated with an API token created in the portal:
# Trigger a build
curl -X POST \
"https://portalrotapi.hana.ondemand.com/v2/subscriptions/${SUBSCRIPTION}/builds" \
-H "Authorization: Bearer ${CCV2_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"branch": "develop", "name": "develop-nightly"}'
# Poll build status
curl -H "Authorization: Bearer ${CCV2_TOKEN}" \
"https://portalrotapi.hana.ondemand.com/v2/subscriptions/${SUBSCRIPTION}/builds/${BUILD_CODE}"
# Deploy the build
curl -X POST \
"https://portalrotapi.hana.ondemand.com/v2/subscriptions/${SUBSCRIPTION}/deployments" \
-H "Authorization: Bearer ${CCV2_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"buildCode": "'"${BUILD_CODE}"'",
"environmentCode": "d1",
"databaseUpdateMode": "UPDATE",
"strategy": "ROLLING_UPDATE"
}'
Wrap those three calls in your CI pipeline and the cloud build becomes a stage, not a ceremony. The deployment strategies worth knowing: ROLLING_UPDATE keeps the site up and is the default for production, RECREATE is faster but takes downtime, and green deployments exist for production environments that need validation before traffic cutover.
Day-One Monitoring#
Both observability tools exist from the first deployment; open them before you have an incident:
- Dynatrace: every node carries the OneAgent. Find your environment's Dynatrace link in Cloud Portal, log in, and bookmark the service view for the storefront and API aspects. Response time percentiles and database call analysis are already flowing.
- Centralized logging: each environment has a logging endpoint (OpenSearch Dashboards). Aspect, log level, and message fields are indexed. Set up your first saved searches now: ERROR-level entries by aspect, and access log entries with HTTP 5xx status.
A team that looks at these dashboards weekly during development recognizes anomalies instantly during a go-live weekend. A team that first opens Dynatrace during an outage spends the first hour learning the UI.
Where This Leaves You#
You now have: a repository the cloud builder and your laptops share without translation, a pinned platform version, endpoints that are exactly as open as they should be, secrets outside Git, a deployed storefront, and the API calls to make every future build boring. The next guides in this series go deeper on the pieces you just touched: the local environment parity setup, continuous delivery pipelines around the Cloud Portal API, and go-live readiness.