---
title: GitLab CI
description: Deploy documentation using GitLab CI/CD pipelines.
icon: gitlab
---

# GitLab CI

Configure GitLab CI/CD to automatically deploy your documentation on every push.

## Basic Pipeline

Create `.gitlab-ci.yml` in your repository:

```yaml
stages:
  - deploy

variables:
  SYNTEXT_API_KEY: $SYNTEXT_API_KEY

deploy_docs:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
```

## Setting Up Variables

1. Go to your project in GitLab
2. Navigate to **Settings** → **CI/CD**
3. Expand **Variables**
4. Add `SYNTEXT_API_KEY` with your API key
5. Check **Mask variable** to hide in logs

<Warning>
Enable "Mask variable" to prevent your API key from appearing in job logs.
</Warning>

## With Preview Deployments

Deploy previews for merge requests:

```yaml
stages:
  - deploy

deploy_preview:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy --preview --branch "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  environment:
    name: preview/$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
    url: https://$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME-docs.syntext.dev

deploy_production:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  environment:
    name: production
    url: https://my-docs-docs.syntext.dev
```

## With Caching

Speed up builds with GitLab's cache:

```yaml
deploy_docs:
  stage: deploy
  image: oven/bun:latest
  cache:
    key: syntext-$CI_COMMIT_REF_SLUG
    paths:
      - .syntext/cache/
      - ~/.syntext/
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
```

## Conditional Deployment

Only deploy when docs change:

```yaml
deploy_docs:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      changes:
        - docs/**/*
        - syntext.json
        - openapi.json
```

## Manual Deployment

Require manual approval for production:

```yaml
deploy_production:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
  environment:
    name: production
```

## Monorepo Setup

For docs in a subdirectory:

```yaml
deploy_docs:
  stage: deploy
  image: oven/bun:latest
  before_script:
    - cd packages/docs
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      changes:
        - packages/docs/**/*
```

## With Review Apps

Create dynamic environments for each MR:

```yaml
deploy_review:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - PREVIEW_URL=$(stx deploy --preview --json | jq -r '.url')
    - echo "PREVIEW_URL=$PREVIEW_URL" >> deploy.env
  artifacts:
    reports:
      dotenv: deploy.env
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    url: $PREVIEW_URL
    on_stop: stop_review
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

stop_review:
  stage: deploy
  script:
    - echo "Preview deployment stopped"
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    action: stop
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
```

## Protected Environments

Restrict production deployments to specific users:

1. Go to **Settings** → **CI/CD** → **Protected environments**
2. Add `production` environment
3. Set **Allowed to deploy** to specific roles or users

## Using GitLab Pages Alternative

If you want to use GitLab Pages instead of Syntext hosting:

```yaml
pages:
  stage: deploy
  image: oven/bun:latest
  script:
    - curl -fsSL https://get.syntext.dev | sh
    - stx build --output public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
```

<Note>
Self-hosted builds via GitLab Pages don't include AI search or the embedded assistant. Use `stx deploy` for full features.
</Note>
