Skip to Content
Onboarding a New Integration

Onboarding a New Integration

This guide walks you through adding a new Signals ELN integration to the monorepo, configuring infrastructure, and deploying it to Minerva.

Prerequisites

Before you begin, make sure you have:

If you don’t have access yet, follow the steps in Getting Started to request the ROLE-PRED-MINERVA-XRED-ELN-DEV role via CIDM.

Repository structure

All integrations live in the apps/ directory of the monorepo. Each app has a backend (FastAPI) and frontend (React):

        • Dockerfile
        • pyproject.toml
        • uv.lock
        • Dockerfile
        • package.json

Step-by-step guide

Create the app directory

Pick a short, lowercase name for your integration. This name is used in directory paths, Docker image tags, and Kubernetes resource names.

APP_NAME="my-integration" mkdir -p apps/$APP_NAME/backend/app apps/$APP_NAME/backend/tests apps/$APP_NAME/frontend/src

Set up the backend

Copy the structure from apps/demo/backend/ and modify:

  • pyproject.toml — update the project name and add your dependencies
  • app/main.py — implement your FastAPI endpoints (keep the /health endpoint)
  • tests/ — add your tests
cp apps/demo/backend/pyproject.toml apps/$APP_NAME/backend/ cp apps/demo/backend/app/main.py apps/$APP_NAME/backend/app/ cp apps/demo/backend/tests/test_health.py apps/$APP_NAME/backend/tests/

Generate the lock file:

cd apps/$APP_NAME/backend uv lock

Set up the Dockerfile (backend)

Create apps/$APP_NAME/backend/Dockerfile. The build context is the repo root, so paths must be fully qualified:

FROM python:3.12-slim COPY certs/ /usr/local/share/ca-certificates/roche/ RUN update-ca-certificates WORKDIR /app COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ COPY apps/my-integration/backend/pyproject.toml apps/my-integration/backend/uv.lock ./ RUN uv sync --frozen --no-install-project COPY apps/my-integration/backend/app/ ./app/ EXPOSE 8000 CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Replace my-integration with your actual app name in all COPY paths.

Set up the frontend (optional)

If your integration includes a frontend, copy the structure from apps/demo/frontend/ and modify:

  • package.json — update the project name
  • src/ — implement your React components
  • Dockerfile — update the COPY paths to match your app name
cp -r apps/demo/frontend/* apps/$APP_NAME/frontend/

Skip this step if your integration is backend-only.

Push to develop and verify CI

Create a feature branch and push:

git checkout -b feat/$APP_NAME/initial-setup git add apps/$APP_NAME git commit -m "feat($APP_NAME): initial integration scaffold" git push -u origin feat/$APP_NAME/initial-setup

Open a PR to develop. The CI pipeline will detect your new app automatically and run lint, test, and security stages. Once merged to develop, Docker images are built and pushed to GHCR.

Deploy to Minerva

There are two ways to deploy: the Deploy workflow (recommended) or manually creating K8s manifests.

The Deploy workflow automatically creates Kubernetes manifests if they don’t exist yet, or updates the image tag if they do.

  1. Go to Actions → Deploy 
  2. Click Run workflow
  3. Select the branch that matches your target environment (develop → DEV, uat → UAT, main → PROD)
  4. Fill in the inputs:
InputDescription
AppYour app name (e.g. my-integration)
Componentsbackend, frontend, or both

The environment and image tag are determined automatically from the branch. The workflow will:

  • Run preflight checks (CI status, image availability, Dockerfiles)
  • Scaffold the K8s manifests (deployment, service, ingress) if this is the first deploy
  • Update the image tag if manifests already exist
  • Push to the infrastructure repo  on the correct branch
  • ArgoCD picks up the change and deploys automatically

Option B: Manual K8s manifests

If you need more control, you can create the manifests yourself in the infrastructure repo  on the target environment branch (e.g. dev):

k8s/ ├── secretstore.yaml # Shared (already exists) ├── externalsecret-registry.yaml # Shared (already exists) ├── kustomization.yaml # Add your app here └── my-integration/ ├── deployment-backend.yaml ├── service-backend.yaml ├── ingress-backend.yaml └── kustomization.yaml

Each manifest must follow Minerva conventions:

  • securityContext.allowPrivilegeEscalation: false on all containers
  • Minerva labels: minerva.roche.com/project: xred-eln, minerva.roche.com/service: <app>
  • imagePullSecrets referencing ghcr-registry-secret
  • Ingress with cert-manager.io/cluster-issuer: roche-acme-prod and the correct hostname for the environment

The hostname depends on the environment:

EnvironmentDomain
DEVminerva.sandbox.pcloud.roche.com
UATapps.uat.minerva.roche.com
PRODapps.minerva.roche.com

Add your app to the top-level k8s/kustomization.yaml:

resources: - secretstore.yaml - externalsecret-registry.yaml - my-integration/ # Add this line

Push to the target branch and sync in ArgoCD.

Verify

Once ArgoCD shows Healthy and Synced, your backend should be reachable at:

https://xred-eln-my-integration-api.<domain>/health
EnvironmentDomain
DEVminerva.sandbox.pcloud.roche.com
UATapps.uat.minerva.roche.com
PRODapps.minerva.roche.com

Environment promotion

To promote your integration to a higher environment:

  1. Merge your code in the integrations repo: developuatmain
  2. Wait for CI to build the images on the target branch
  3. Run the Deploy workflow from the target branch
BranchDeploys toImage tag
developDEV:develop
uatUAT:uat
mainPROD:main

Deployments to UAT and PROD can only be triggered from the uat or main branch respectively — the workflow will fail on any other branch. This ensures only merged and reviewed code gets deployed. On DEV, the 4-eye principle is not enforced but recommended.

See Secret Management for how to add secrets in Vault and reference them in your deployments.

Environment mappings

The full mapping of xRED ELN environments across Signals, MuleSoft (Proxify), Gravitee, and ArgoCD:

EnvironmentSignalsSignals ProxyProxify1Gravitee (Minerva)Argo
PRE-DEV (SBX)xRED xRED DEV Proxy Development DEV DEV 
DEVDEV xRED DEV Proxy Development DEV DEV 
UATTEST xRED UAT Proxy Test UAT UAT 
TRAININGTRAINING xRED UAT Proxy Stage UAT UAT 
PRODPROD xRED PROD Proxy Production PROD PROD 

Footnotes

  1. Proxify — this layer typically exposes endpoints for Signals Data Sources.

Last updated on