Skip to main content

First Team App

This page follows the checkout team from a fresh onboarding to a real service running in production on Fedshi. It ties the team-setup steps to the developer workflow so you can see the whole arc in one place. Where a step has its own deep dive, we link to it rather than repeat it.

note

DevsPortal is built on the Control Plane Operator engine. The occ CLI and openchoreo.dev/v1alpha1 resources below are unchanged engine internals.

The scenario

The checkout team owns the checkout flow at Fedshi. Their first deliverable is cart-api, a backend service built from source in their monorepo, depending on a Postgres database, exposed only inside its project, and promoted from development up to production.

Before day one: onboarding (admin)

A platform engineer ran Onboard a team for the checkout team, which produced:

  • The checkout project in the fedshi namespace, bound to the default deployment pipeline (development → staging → production).
  • A developer role bound to the checkout-team group, scoped to the checkout project, with a condition that keeps production release-binding mutations off-limits to most of the team (see Roles and access → conditions).
  • The project annotated backstage.io/owner: group:default/checkout-team, so everything the team creates is attributed to them in the catalog.

The developers were pointed at Getting access and Quickstart. Everything below is what they do.

Day one: the team ships

1. Get connected

Each developer signs in to https://console.idp.fedshi.com via Sign in using Fedshi, installs occ, and configures a context for their project:

occ config controlplane add fedshi --url https://api.idp.fedshi.com
occ config context add fedshi-checkout \
--controlplane fedshi --credentials fedshi \
--namespace fedshi --project checkout
occ config context use fedshi-checkout # activate the context before logging in
occ login

The context use step is what makes occ login target the Fedshi control plane — without it the CLI stays on its default localhost:8080 and login fails. A quick occ component list then confirms access (empty for now — that's expected).

2. Create the component from source

cart-api will be built by the platform from the team's monorepo. They create it with a build workflow, auto-build on push, and auto-deploy to the first environment:

# cart-api.yaml
apiVersion: openchoreo.dev/v1alpha1
kind: Component
metadata:
name: cart-api
namespace: fedshi
spec:
owner:
projectName: checkout
componentType:
kind: ClusterComponentType
name: deployment/service
autoBuild: true
autoDeploy: true
workflow:
kind: ClusterWorkflow
name: dockerfile-builder
parameters:
repository:
url: "https://github.com/fedshi/checkout"
revision:
branch: "main"
appPath: "/cart-api"
docker:
context: "/cart-api"
filePath: "/cart-api/Dockerfile"
occ apply -f cart-api.yaml

(The team could equally have used the console's Create Component wizard — same result. See Projects and components.)

3. Describe the runtime with a descriptor

So the build produces a Workload with the right endpoint and its database dependency, the team commits a workload.yaml to cart-api/ in the repo:

# cart-api/workload.yaml
apiVersion: openchoreo.dev/v1alpha1
metadata:
name: cart-api
endpoints:
- name: http
type: HTTP
port: 8080
basePath: /api/v1
visibility:
- project # internal to the checkout project — not public
configurations:
env:
- name: LOG_LEVEL
value: info
dependencies:
resources:
- ref: cart-postgres

The endpoint is project-visible because only the checkout web app calls it — nothing here needs to be on the public internet. The Postgres dependency means the platform waits for the database to be Ready and injects its connection details. Details: Workloads and endpoints and Dependencies.

4. Build runs automatically

Pushing to main triggers a build (because autoBuild: true and the change is under appPath). The team watches it:

occ component workflow logs cart-api -f
occ component workflowrun list cart-api

On success the image is pushed to https://registry.idp.fedshi.com and a Workload is generated from the descriptor. Because autoDeploy: true, the new release lands in development immediately.

5. Verify in development

occ component get cart-api
occ releasebinding list -p checkout --component cart-api
occ component logs cart-api --env development -f

In the console, the cart-api Deploy tab shows the development card go Ready. The team exec's in to sanity-check the injected database variables:

occ component exec cart-api --env development -it -- env | grep DB_

6. Promote to staging, then production

The same verified release moves up the pipeline. Up to staging, any team developer can do it:

occ component deploy cart-api --to staging

Production is gated by the condition on their role, so the team lead (with unconditioned prod access) promotes the final hop — bumping replicas for prod via an override:

occ component deploy cart-api --to production \
--set spec.componentTypeEnvironmentConfigs.replicas=3

The byte-for-byte release validated in dev and staging is now running in production. Full mechanics: Deploy and promote.

7. Operate it

The team watches cart-api from the console's Logs, Metrics, and Alerts tabs, and would roll back instantly if needed by deploying a prior release. See Observability.

What the team experienced

  • No tickets. They created, built, deployed, and promoted entirely self-service.
  • Isolation by default. The project-visible endpoint stays inside the checkout cell; nothing leaked to other teams or the internet.
  • A golden path. They used the platform's ComponentType, build workflow, and Postgres ResourceType — all pre-approved — without seeing any Kubernetes.
  • Production was special. The promotion gate held automatically, as policy, not as a manual gatekeeper.

That's the whole point of onboarding a team: set the space, the access, the ownership, and the guardrails once, and the team ships safely forever after.

What's next