> ## Documentation Index
> Fetch the complete documentation index at: https://prismeai-legacy.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment

> Learn how to deploy, version, and manage AI Builder applications across environments

Deploying AI Builder use cases requires a structured approach to move your solutions from development to production. This guide outlines strategies for versioning, deploying, and managing applications across different environments to ensure reliability and performance.

## Deployment Strategies

<Tabs>
  <Tab title="Single Workspace">
    **Best for:** Basic applications with minimal complexity, such as simple prompting agents

    In this approach, you use a single workspace for both development and production:

    * **Development:** Create and test your application directly in the workspace
    * **Production:** Once tested, the same workspace serves as the production environment
    * **Version Control:** Use versioning to save stable points for potential rollback

    **Advantages:**

    * Simplest deployment approach
    * No need to migrate between workspaces
    * Quick iteration and updates

    **Considerations:**

    * Limited separation between development and production
    * Higher risk of disruptive changes affecting live users
    * Best suited for applications with low complexity and minimal regulatory constraints
  </Tab>

  <Tab title="Multi-Workspace">
    **Best for:** Moderately complex applications with some regulatory needs

    In this approach, you use multiple workspaces on the same Prisme.ai instance:

    * **Development Workspace:** For building and testing
    * **Production Workspace:** For live user access
    * **Optional Pre-Production Workspace:** For final testing before deployment
    * **Version Control:** Use version control to update the production workspace from a dev/release branch populated by the development workspace.

    **Advantages:**

    * Clear separation between development and production
    * Same instance simplifies resource management
    * Different access controls for each environment

    **Considerations:**

    * Requires process for migrating between workspaces
    * All environments share the same Prisme.ai instance resources
    * Good balance of separation and simplicity
  </Tab>

  <Tab title="Multi-Instance">
    **Best for:** Complex enterprise applications with strict regulatory requirements

    In this approach, you use separate Prisme.ai instances for each environment:

    * **Development Instance:** For building and initial testing
    * **Staging/Pre-production Instance:** For integration testing and validation
    * **Production Instance:** For live user access
    * **Version control :** Update production environment from dev environemnt using platform repositories and CI/CD, see below

    **Advantages:**

    * Complete isolation between environments
    * Independent scaling and resource allocation
    * Highest level of security and stability

    **Considerations:**

    * Most complex to manage
    * Requires robust deployment processes
    * Necessary for applications with strict compliance requirements
  </Tab>
</Tabs>

## Versioning Your Application

Workspaces can be synchronized with Git repositories to version your application, enabling push/pull workflows, collaboration, and rollback capabilities.

For complete documentation on repository configuration, authentication methods, push/pull operations, merge conflict handling, and bulk operations, see the dedicated [Versioning](/products/ai-builder/versioning) page.

## API deployment

Here is a small example script using archive export/import APIs to update a workspace from another :

```javascript theme={null}
// Example Node.js deployment script
async function deployWorkspace(sourceId, targetId, accessToken) {
  // Export source workspace
  const exportResponse = await fetch(`https://api.studio.prisme.ai/v2/workspaces/${sourceId}/export`, {
    headers: { 'Authorization': `Bearer ${accessToken}` },
  });
  const archive = await exportResponse.blob();

  // Import to target workspace
  const form = new FormData();
  form.append('archive', archive, 'workspace.zip');

  await fetch(`https://api.studio.prisme.ai/v2/workspaces/${targetId}/import`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${accessToken}` },
    body: form,
  });

  console.log('Deployment completed successfully');
}

deployWorkspace('source-workspace-id', 'target-workspace-id', 'your-access-token');
```

## CI/CD deployment

CI-based deployment enables more complex scenarios, especially useful for multi-instance environments where you need to promote workspaces from a development/sandbox instance to production instances.

The general approach is:

1. **Push workspaces to a Git repository** from the source environment (bulk push via API)
2. **Build a Docker image** embedding those workspaces into the `prismeai-workspaces` service
3. **Deploy the image** to the target environment, where workspaces are automatically imported at startup

An alternative scenario without building docker image could be to bulk import the source git repository directly into the destination environment.\
However, the scenario described here have the following advantages :

* CI/CD enable additional security and quality guardrails during the upgrade process
* The dest environment do not need any network access to the source environement git, and can be upgraded / roll-backed at any time even if the git is not available

### Prerequisites

#### Platform repository on the source environment

Configure a [platform repository](/self-hosting/kubernetes/environment-variables#platform-repositories) on your source environment (e.g. sandbox) so that all workspaces can be pushed to a shared Git repository:

```dotenv theme={null}
# Platform repository pointing to your Git server
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_NAME=My Workspaces
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_URL=https://gitlab.com/myorg/workspaces.git
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_BRANCH=sandbox
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_DIRPATH=workspaces
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_AUTH_USER=my-user
WORKSPACES_STORAGE_GIT_PLATFORM_myrepo_AUTH_PASSWORD=my-token
```

#### Workspace groups

Define [workspace groups](/self-hosting/kubernetes/environment-variables#workspace-groups) to organize which workspaces should be included in your releases:

```dotenv theme={null}
WORKSPACES_GROUP_base1_LABELS="production:app:base1"
WORKSPACES_GROUP_base2_LABELS="production:app:base2"
WORKSPACES_GROUP_extended_LABELS="production:app,production:product"
```

Workspaces are assigned to groups through their labels. During a bulk push, only workspaces matching the requested groups are included.

### Step 1: Bulk push workspaces to Git

Use the [bulk push API](/products/ai-builder/versioning#bulk-push) to export all workspace groups to the platform repository. This is typically the first stage of your CI/CD pipeline:

```yaml theme={null}
# GitLab CI example
version_workspaces:
  stage: version
  script:
    - |
      curl -N -w "\n__HTTP_STATUS__:%{http_code}" \
        "${SOURCE_API_URL}/v2/workspaces/platform/versions?sse=true" \
        --header 'Content-Type: application/json' \
        --header "Authorization: Bearer ${SOURCE_ACCESS_TOKEN}" \
        --data '{
          "repository": {"id": "myrepo"},
          "groups": ["base1", "base2", "extended"]
        }' | tee /tmp/sse_output.txt

      # Check HTTP status
      HTTP_CODE=$(grep -o '__HTTP_STATUS__:[0-9]*' /tmp/sse_output.txt | tail -1 | cut -d: -f2 || true)
      if [ -n "$HTTP_CODE" ] && { [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; }; then
        echo "ERROR: API returned HTTP $HTTP_CODE"
        exit 1
      fi

      # Check for errors in the final SSE event
      LAST_DATA=$(grep "^data: " /tmp/sse_output.txt | tail -1 | sed 's/^data: //' || true)
      if [ -z "$LAST_DATA" ]; then
        echo "ERROR: No SSE data received in response"
        exit 1
      fi
      ERRORS=$(echo "$LAST_DATA" | jq '.errors | length')
      CONFLICTS=$(echo "$LAST_DATA" | jq '.mergeConflictWorkspaceIds | length')
      if [ "$ERRORS" -gt 0 ] || [ "$CONFLICTS" -gt 0 ]; then
        echo "ERROR: Bulk push to git failed with errors or merge conflicts:"
        echo "$LAST_DATA" | jq '.'
        exit 1
      fi
      echo "All workspaces successfully versioned."
```

The `?sse=true` parameter enables [Server-Sent Events](/products/ai-builder/versioning#sse-streaming) for real-time progress tracking, which is recommended for CI pipelines to avoid HTTP timeouts on large deployments.

### Step 2: Build a Docker image with embedded workspaces

Once workspaces are pushed to Git, build a custom `prismeai-workspaces` Docker image that embeds them. This uses a Dockerfile that:

1. Clones the workspaces repository
2. Runs a security scan (e.g. TruffleHog) to detect leaked secrets
3. Copies the workspace files into the image
4. Configures a **filesystem-type platform repository** pointing to the embedded files

```dockerfile theme={null}
ARG BASE_IMAGE

# Security scan stage
FROM alpine:3.20 AS security-scan
ARG WORKSPACES_REPO_URL
ARG WORKSPACES_REPO_BRANCH=main
ARG WORKSPACES_REPO_SUBDIR=""

RUN apk add --no-cache git curl && \
    curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
    | sh -s -- -b /usr/local/bin

RUN git clone --depth 1 -b "$WORKSPACES_REPO_BRANCH" "$WORKSPACES_REPO_URL" /tmp/repo

RUN SCAN_DIR=$(if [ -n "$WORKSPACES_REPO_SUBDIR" ]; then \
      echo "/tmp/repo/$WORKSPACES_REPO_SUBDIR"; else echo "/tmp/repo"; fi) && \
    EXCLUDE_FILE=$(mktemp) && \
    echo '.*import\.yml' > "$EXCLUDE_FILE" && \
    trufflehog filesystem "$SCAN_DIR" -x "$EXCLUDE_FILE" --json --fail

# Build stage
FROM $BASE_IMAGE
ARG WORKSPACES_REPO_SUBDIR=""
ARG WORKSPACES_VERSION_NAME=""

# Make sure we get rid of previous workspaces if we're rebuilding this multiple times from / to the  same tag
RUN rm -rf /tmp/repo && rm -rf /www/workspaces
COPY --from=security-scan /tmp/repo /tmp/repo
RUN if [ -n "$WORKSPACES_REPO_SUBDIR" ]; then \
      mv "/tmp/repo/$WORKSPACES_REPO_SUBDIR" /www/workspaces; \
    else \
      mv /tmp/repo /www/workspaces; \
    fi && \
    rm -rf /www/workspaces/.git /tmp/repo

# Same workspace groups as defined in source environment 
ENV WORKSPACES_GROUP_base1_LABELS "production:app:base1"
ENV WORKSPACES_GROUP_base2_LABELS "production:app:base2"
ENV WORKSPACES_GROUP_extended_LABELS "production:app,production:product"

# Filesystem platform repository pointing to embedded workspaces
ENV WORKSPACES_STORAGE_GIT_PLATFORM_release_NAME "Release ${WORKSPACES_VERSION_NAME}"
ENV WORKSPACES_STORAGE_GIT_PLATFORM_release_TYPE "filesystem"
ENV WORKSPACES_STORAGE_GIT_PLATFORM_release_DIRPATH "/www/workspaces"
ENV WORKSPACES_STORAGE_GIT_PLATFORM_release_MODE "read-only"
```

The key part is the **filesystem platform repository** at the end: it tells the workspaces service to treat the embedded `/www/workspaces` directory as a read-only platform repository named "release". This allows the target environment to use the standard [bulk import](/products/ai-builder/versioning#bulk-import) mechanism to import workspaces from the Docker image itself, without needing Git credentials.

The CI job to build this image:

```yaml theme={null}
build_workspaces_image:
  stage: build
  needs: [version_workspaces]
  image: docker:25
  services:
    - docker:25-dind
  variables:
    WORKSPACES_REPO_BRANCH: "sandbox"
    WORKSPACES_REPO_SUBDIR: "workspaces"
  script:
    - >
      docker build
      --build-arg BASE_IMAGE=${WORKSPACES_IMAGE}:${BASE_TAG}
      --build-arg WORKSPACES_REPO_URL=https://ci-token:${CI_TOKEN}@gitlab.com/myorg/workspaces.git
      --build-arg WORKSPACES_REPO_BRANCH=${WORKSPACES_REPO_BRANCH}
      --build-arg WORKSPACES_REPO_SUBDIR=${WORKSPACES_REPO_SUBDIR}
      --build-arg WORKSPACES_VERSION_NAME=${CI_COMMIT_TAG:-latest}
      -t ${WORKSPACES_IMAGE}:${IMAGE_TAG}
      -f with-workspaces.Dockerfile .
    - docker push ${WORKSPACES_IMAGE}:${IMAGE_TAG}
```

### Step 3: Deploy and import on the target environment

Deploy the custom image to your target environment (e.g. production). On startup, workspaces can be automatically imported using the `STARTUP_IMPORT_*` environment variables:

```dotenv theme={null}
# Automatically import workspaces from the embedded filesystem repository at startup
STARTUP_IMPORT_REPOSITORY=release
STARTUP_IMPORT_GROUPS=base1,base2,extended
```

This triggers a [bulk import](/products/ai-builder/versioning#bulk-import) each time the workspaces service starts, importing all workspaces from the groups that match. Workspaces already up to date (based on version name comparison) are skipped automatically.

Alternatively, you can trigger the import manually via the API after deployment:

```bash theme={null}
curl -X POST "${PROD_API_URL}/v2/workspaces/platform/versions/latest/pull" \
  -H "Authorization: Bearer ${PROD_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"repository": {"id": "release"}, "groups": ["base1", "base2", "extended"]}'
```

Or you can also start these imports manually from the Platform workspace UI.

### Summary

The complete CI/CD flow looks like this:

```
Source environment                    Git repository                Target environment
┌──────────────┐     bulk push      ┌──────────────┐              ┌──────────────┐
│   Sandbox    │ ──────────────────► │  workspaces  │              │  Production  │
│  workspaces  │                     │    repo      │              │              │
└──────────────┘                     └──────┬───────┘              └──────▲───────┘
                                            │                            │
                                     docker build                  bulk import
                                            │                     (at startup)
                                     ┌──────▼───────┐                    │
                                     │ Docker image  │                   │
                                     │  (embedded    │ ──── deploy ──────┘
                                     │  workspaces)  │
                                     └──────────────┘
```

## Environment-Specific Configuration

Manage differences between environments:

<Steps>
  <Step title="Use Workspace Secrets">
    Store environment-specific values as secrets:

    ```yaml theme={null}
    # In development workspace
    secrets:
      apiEndpoint: https://dev-api.example.com
      maxRequests: 10

    # In production workspace
    secrets:
      apiEndpoint: https://api.example.com
      maxRequests: 100
    ```

    Access these values in your application using:

    ```
    {{secret.apiEndpoint}}
    ```
  </Step>

  <Step title="Conditional Logic">
    Implement environment-aware behavior in automations:

    ```yaml theme={null}
    # Example automation with environment detection
    slug: processData
    do:
      - conditions: 
        "{{environment}} == 'production'":
          - callAPI:
              url: "{{secret.productionApi}}"
        default:
          - callAPI:
              url: "{{secret.developmentApi}}"
    ```

    This allows your applications to adapt to different environments.
  </Step>
</Steps>

## Deployment Best Practices

<CardGroup cols={2}>
  <Card title="Version Everything" icon="code-branch">
    <p>Maintain complete history of your application:</p>

    <ul>
      <li>Commit changes frequently with clear messages</li>
      <li>Use branches for feature development</li>
      <li>Tag important releases (e.g., v1.0.0)</li>
      <li>Document significant version changes</li>
      <li>Never work directly in production</li>
    </ul>
  </Card>

  <Card title="Test Before Deployment" icon="vial">
    <p>Validate thoroughly before moving to production:</p>

    <ul>
      <li>Test in development environment first</li>
      <li>Verify integrations with external systems</li>
      <li>Test with realistic data sets</li>
      <li>Include user acceptance testing</li>
      <li>Conduct security testing</li>
    </ul>
  </Card>

  <Card title="Controlled Deployment" icon="shield-check">
    <p>Implement safeguards around deployment:</p>

    <ul>
      <li>Use approval workflows for production changes</li>
      <li>Deploy during low-traffic periods</li>
      <li>Implement monitoring during deployment</li>
      <li>Prepare rollback procedures</li>
      <li>Document deployment steps</li>
    </ul>
  </Card>

  <Card title="Environment Isolation" icon="layer-group">
    <p>Maintain clear boundaries between environments:</p>

    <ul>
      <li>Use separate API keys for each environment</li>
      <li>Configure different external service endpoints</li>
      <li>Apply appropriate security controls by environment</li>
      <li>Use visual indicators to distinguish environments</li>
      <li>Limit production access to necessary personnel</li>
    </ul>
  </Card>
</CardGroup>

## Troubleshooting Deployments

<AccordionGroup>
  <Accordion title="Infrastructure issues">
    First check that your infrastructure is properly configured and running with [readiness API](/self-hosting/operations/testing).
  </Accordion>

  <Accordion title="Import/Pull Failures">
    Common causes and solutions for import problems:

    **Issue: Slug Conflicts**

    ```
    "Could not rename workspace slug from {oldSlug} to {newSlug} as it is already used"
    ```

    **Solution:** Ensure unique slugs across workspaces or exclude index file from import.

    * For Platform bulk imports, check the detailed errors list in **workspaces.bulkImport.completed** event.
    * For bulk archive imports, check the same detailed errors list in **prismeai-workspaces** container logs.
    * Individual workspace import errors an also be checked in the **workspaces.imported** event emitted in their activity feed.
  </Accordion>

  <Accordion title="Rollback Procedures">
    How to revert to a previous state:

    **Platform rollback:**

    1. Identify the stable version tag
    2. Revert prismeai images to that tag
    3. Open **Platform** workspace and pull again all 3 native goups one after another : base1, base2, extended.

    **Workspace git versioning :**

    1. Open the workspace activity feed
    2. Filter events on type `workspaces.versions.published`
    3. Use the native "Rollback" UI button to roll back to the desired version

    **Export/Import Rollback:**

    1. Maintain archives of known-good workspace states
    2. Import the last stable archive if issues occur

    **Best Practice:** Test rollback procedures regularly to ensure they work when needed.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="RBAC" icon="user-lock" href="/products/ai-builder/rbac">
    Configure role-based access control across environments
  </Card>

  <Card title="Integrations" icon="plug-circle-plus" href="/products/ai-builder/integrations">
    Connect your applications to external systems
  </Card>

  <Card title="Testing & Debugging" icon="vial" href="/products/ai-builder/testing-debugging">
    Learn how to thoroughly test applications before deployment
  </Card>
</CardGroup>
