---
icon: material/kubernetes
---

Deploy the [Compiler](https://doc.log10x.com/compile/) app to Kubernetes via [Helm](https://helm.sh){target="\_blank"} or integrate into your CI/CD pipeline.

Examples on this page name `log10x/compiler-10x:1.1.69`. Substitute the version you want, and see [Image tags](https://doc.log10x.com/install/docker/#image-tags) for why a CI job should never pull `:latest`.

???+ tenx-bootstrap "Step 1: Prerequisites"

    | Requirement | Description |
    |-------------|-------------|
    | Log10x License | Your license key ([get one](https://doc.log10x.com/run/bootstrap/#apikey)) |
    | Helm | [Helm CLI](https://helm.sh/docs/intro/install/){target="\_blank"} installed (for k8s deployment) |
    | kubectl | Configured to access your cluster (for k8s deployment) |
    | Git Token | Access token for your Git provider (GitHub, GitLab, Bitbucket, etc.) with repository read access |
    | Docker Credentials | Registry credentials if pulling from private registries |

??? tenx-checklist "Step 2: Choose Deployment Method"

    === ":material-kubernetes: Kubernetes"

        The Helm chart deploys a [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/){target="\_blank"} that periodically compiles symbols from source code and container images.

        **Best for**: Scheduled symbol compilation in production environments.

        Add the Helm repository:

        ``` { .console .copy }
        helm repo add log10x https://log-10x.github.io/helm-charts
        ```

        Verify the chart appears:

        ``` { .console .copy }
        helm search repo log10x-cron
        ```

    === ":fontawesome-solid-gears: CI/CD"

        Run the compiler as a `docker run` step in your CI/CD pipeline (GitHub Actions, GitLab CI, Jenkins) using the `log10x/compiler-10x` image. The compiler image pulls source repos, scans for symbols, and pushes the compiled [symbol library](https://doc.log10x.com/compile/link/#symbol-library) back to your config repository. It is the cloud compiler bundled with the source-fetch toolchain (`git`, `docker` CLI, `helm`) the [pull stage](https://doc.log10x.com/compile/pull/) shells out to. The lean `log10x/pipeline-10x` runtime image omits those tools.

        **Best for**: Event-driven compilation triggered by code commits. No Kubernetes required.

??? tenx-config "Step 3: Configure Deployment Settings"

    === ":material-kubernetes: Kubernetes"

        Create a new file called `my-compiler.yaml` in your working directory. This Helm values file will be used in all subsequent steps.

        ``` { .yaml title="my-compiler.yaml"}
        # License key added to all pods via TENX_LICENSE env var
        log10xLicense: "YOUR-LICENSE-KEY-HERE"

        jobs:
          - name: compiler-job
            runtimeName: my-compiler            # Optional: identifies this instance
            schedule: "*/30 * * * *"            # Run every 30 minutes
            args:
              - "@apps/compiler"
        ```

        **Airgapped mode (optional)**, for clusters with no path to the Log10x SaaS (security policy, isolated network), suppress every outbound call to the vendor gateway by setting `TENX_AIRGAPPED=true` on each job:

        ``` { .yaml title="my-compiler.yaml"}
        jobs:
          - name: compiler-job
            # ... (previous config)
            extraEnv:
              - name: TENX_AIRGAPPED
                value: "true"
        ```

        The compiler verifies its license JWT locally against the embedded public key; no startup validation, no metrics reporting to the Log10x backend, no user-attribute enrichment. Source-repo pulls and symbol-library pushes are unaffected, those are customer pipelines, not vendor telemetry. Airgapped mode is honored for every license type, including `demo` and `limited`.

    === ":fontawesome-solid-gears: CI/CD"

        Configuration is passed via environment variables and command-line arguments in the `docker run` command. See the complete platform examples in Step 6.

        **Airgapped mode (optional)**, for CI runners with no path to the Log10x SaaS, add `-e TENX_AIRGAPPED=true` to your `docker run` invocation:

        ``` { .bash }
        docker run --rm \
          -e TENX_LICENSE_FILE=/license.jwt \
          -e TENX_AIRGAPPED=true \
          ... \
          log10x/compiler-10x @apps/compiler
        ```

        With this set, the compiler verifies its license JWT locally and skips every call to the Log10x SaaS gateway (no startup validation, no metrics).Airgapped mode is honored for every license type.

??? tenx-githubsync "Step 4: Load Configuration"

    Load the 10x engine [config folder](https://github.com/log-10x/config){target="\_blank"} to customize which sources the compiler scans and where it writes output. If you skip this step, the default configuration bundled with the Log10x image is used.

    === ":material-kubernetes: Kubernetes"

        For Kubernetes CronJob deployments, load the config folder into the cluster using one of the methods below.

        === ":material-git: Git Repository"

            An init container clones your configuration repository before each CronJob run. Works with GitHub, GitLab, Bitbucket, or any HTTPS-accessible Git provider.

            1. Fork the [Config Repository](https://github.com/log-10x/config/fork){target="\_blank"}
            2. Create a branch for your configuration changes
            3. Edit the [app configuration](https://doc.log10x.com/compile/test/#config-files) to specify your source inputs and symbol outputs

            Add to your Helm values:

            ``` { .yaml title="my-compiler.yaml"}
            gitToken: "YOUR-GIT-TOKEN"

            jobs:
              - name: compiler-job
                # ... (previous config)

                config:
                  git:
                    enabled: true
                    url: "https://github.com/YOUR-ACCOUNT/REPO-NAME.git"
                    branch: "my-compiler-config"    # Optional: defaults to main
            ```

            For production, store the token in a Kubernetes Secret rather than in the values file.

        === ":material-harddisk: Persistent Volume"

            Mount an existing PersistentVolumeClaim containing your configuration directory. This approach works in air-gapped environments and requires no external network access.

            1. Create a PVC containing your configuration files (cloned from the [Config Repository](https://github.com/log-10x/config){target="\_blank"})
            2. Reference it in your Helm values:

            ``` { .yaml title="my-compiler.yaml"}
            jobs:
              - name: compiler-job
                # ... (previous config)

                config:
                  volume:
                    enabled: true
                    claimName: "my-config-pvc"
            ```

    === ":fontawesome-solid-gears: CI/CD"

        For CI/CD pipelines, the config folder is loaded at runtime via the [`@github` launch macro](https://doc.log10x.com/config/github/){target="\_blank"} or a local volume mount. The complete CI/CD examples in Step 6 include config loading inline.

        === ":material-git: Git Repository"

            The engine clones the config repo at startup:

            ```bash
            docker run --rm \
              log10x/compiler-10x:1.1.69 \
              '@github={"token": "$GH_TOKEN", "repo": "my-user/my-config"}' \
              @apps/compiler
            ```

        === ":material-harddisk: Local Mount"

            Mount a checked-out config directory:

            ```bash
            docker run --rm \
              -v /path/to/config:/etc/tenx/config \
              log10x/compiler-10x:1.1.69 \
              @apps/compiler
            ```

??? tenx-keyfiles "Step 5: Configure Secrets"

    === ":material-kubernetes: Kubernetes"

        Store sensitive credentials in Kubernetes Secrets rather than plain files.

        **Important**: Only add secrets for source repositories you've configured in your [Compiler](https://doc.log10x.com/compile/test/#configure) app configuration.

        **Create the secret:**

        ``` { .console .copy }
        kubectl create secret generic compiler-credentials \
          --from-literal=github-token=YOUR_GITHUB_TOKEN \
          --from-literal=docker-username=YOUR_DOCKER_USERNAME \
          --from-literal=docker-token=YOUR_DOCKER_TOKEN
        ```

        Add secret references to your `my-compiler.yaml`:

        ``` { .yaml title="my-compiler.yaml"}
        jobs:
          - name: compiler-job
            # ... (previous config)

            extraEnv:
              # For GitHub source repositories
              - name: GH_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: github-token

              # For Docker registries
              - name: DOCKER_USERNAME
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: docker-username
              - name: DOCKER_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: docker-token

              # For Artifactory repositories
              # - name: ARTIFACTORY_TOKEN
              #   valueFrom:
              #     secretKeyRef:
              #       name: compiler-credentials
              #       key: artifactory-token
        ```

    === ":fontawesome-solid-gears: CI/CD"

        Configure secrets in your CI platform:

        | Secret | Description |
        |--------|-------------|
        | `GH_TOKEN` | GitHub PAT with `repo` scope |
        | `DOCKER_USERNAME` | Container registry username |
        | `DOCKER_TOKEN` | Container registry token |
        | `ARTIFACTORY_TOKEN` | Artifactory token (if used) |

        === ":simple-github: GitHub Actions"

            Go to *Settings > Secrets and variables > Actions > Secrets* and add the secrets above.

        === ":simple-gitlab: GitLab CI"

            Go to *Settings > CI/CD > Variables* and add the secrets above.

        === ":simple-jenkins: Jenkins"

            Go to *Manage Jenkins > Credentials* and add credential IDs: `github-token`, `docker-username`, `docker-token`.

??? tenx-mainconfig "Step 6: Deploy"

    === ":material-kubernetes: Kubernetes"

        ``` { .console .copy }
        helm install my-compiler log10x/log10x-cron -f my-compiler.yaml
        ```

    === ":fontawesome-solid-gears: CI/CD"

        Add a `docker run` step to your CI/CD pipeline. Select your platform below.

        === ":simple-github: GitHub Actions"

            Create `.github/workflows/compile.yml`:

            ```yaml
            name: 10x Compile

            on:
              push:
                branches: [main]

            jobs:
              compile:
                runs-on: ubuntu-latest
                steps:
                  - uses: actions/checkout@v3
                  - name: Run 10x Compiler
                    run: |
                      docker run --rm \
                        -v $(pwd):/work \
                        -e GH_TOKEN=${{ secrets.GH_TOKEN }} \
                        -e DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} \
                        -e DOCKER_TOKEN=${{ secrets.DOCKER_TOKEN }} \
                        log10x/compiler-10x:1.1.69 \
                        '@github={"token": "${{ secrets.GH_TOKEN }}", "repo": "my-user/my-config"}' \
                        @apps/compiler
            ```

        === ":simple-gitlab: GitLab CI"

            Create `.gitlab-ci.yml`:

            ```yaml
            stages:
              - compile

            tenx_compile:
              stage: compile
              image: docker:28.5
              services:
                - docker:28.5-dind
              script:
                - docker run --rm \
                    -e GH_TOKEN=$GH_TOKEN \
                    -e DOCKER_USERNAME=$DOCKER_USERNAME \
                    -e DOCKER_TOKEN=$DOCKER_TOKEN \
                    log10x/compiler-10x:1.1.69 \
                    '@github={"token": "'$GH_TOKEN'", "repo": "my-user/my-config"}' \
                    @apps/compiler
            ```

        === ":simple-jenkins: Jenkins"

            Create `Jenkinsfile`:

            ```groovy
            pipeline {
                agent any
                stages {
                    stage('TenX Compile') {
                        steps {
                            withCredentials([
                                string(credentialsId: 'github-token', variable: 'GH_TOKEN'),
                                string(credentialsId: 'docker-username', variable: 'DOCKER_USERNAME'),
                                string(credentialsId: 'docker-token', variable: 'DOCKER_TOKEN')
                            ]) {
                                sh '''
                                    docker run --rm \
                                      -e GH_TOKEN=$GH_TOKEN \
                                      -e DOCKER_USERNAME=$DOCKER_USERNAME \
                                      -e DOCKER_TOKEN=$DOCKER_TOKEN \
                                      log10x/compiler-10x:1.1.69 \
                                      '@github={"token": "'$GH_TOKEN'", "repo": "my-user/my-config"}' \
                                      @apps/compiler
                                '''
                            }
                        }
                    }
                }
            }
            ```

??? tenx-checklist "Step 7: Verify"

    === ":material-kubernetes: Kubernetes"

        **Check the CronJob was created:**

        ``` { .console .copy }
        kubectl get cronjobs
        ```

        **Trigger a manual run to test:**

        ``` { .console .copy }
        kubectl create job --from=cronjob/compiler-job my-compiler-test
        ```

        **Check pod logs for errors:**

        ``` { .console .copy }
        kubectl logs -l job-name=my-compiler-test --tail=100
        ```

    === ":fontawesome-solid-gears: CI/CD"

        **Check your CI pipeline logs** for the compiler job output.

    Verify no errors appear in the [log file](https://doc.log10x.com/manage/logging/#log-file-location).

    **Check output files:**

    Verify symbol files were generated in your configured [outputSymbolFolder](https://doc.log10x.com/compile/scan/#outputsymbolfolder) and [outputSymbolLibraryFile](https://doc.log10x.com/compile/link/#outputsymbollibraryfile) paths.

??? tenx-distribute "Step 8: Distribute Output Symbol Libraries"

    The compiler [pushes](https://doc.log10x.com/compile/push/) output symbol files to your config repository. Edge and cloud apps [pull](https://doc.log10x.com/config/github/){target="\_blank"} these files at startup and poll for updates periodically.

??? tenx-run "Quickstart Full Sample"

    === ":material-kubernetes: Kubernetes"

        ``` { .yaml title="my-compiler.yaml"}
        log10xLicense: "YOUR-LICENSE-KEY-HERE"
        gitToken: "YOUR-GIT-TOKEN"

        jobs:
          - name: compiler-job
            runtimeName: my-compiler
            schedule: "*/30 * * * *"
            args:
              - "@apps/compiler"

            config:
              git:
                enabled: true
                url: "https://github.com/YOUR-ACCOUNT/REPO-NAME.git"
                branch: "my-compiler-config"

            extraEnv:
              - name: GH_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: github-token
              - name: DOCKER_USERNAME
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: docker-username
              - name: DOCKER_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: compiler-credentials
                    key: docker-token
        ```

    === ":fontawesome-solid-gears: CI/CD"

        See the Deploy step above for complete CI/CD configuration examples for GitHub Actions, GitLab CI, and Jenkins.
