> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/ai-dlc-insights/use-ai-dlc-insights/setup/ingestion-satellite/container.md).

# Run the Satellite container

Use Ingestion Satellites to integrate with on-premise tools and set up **Custom** integrations.

{% hint style="info" %}
The recommended memory for one container is 4GB to 6GB.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes" %}

1. Requirements:
   * A running Kubernetes cluster.
   * `kubectl` command-line tool configured to communicate with your cluster.
   * Access to the `levelops/ingestion-satellite` Docker image.
2. Use the following template to prepare the Kubernetes deployment.

   ```yaml
   apiVersion: rbac.authorization.k8s.io/v1
   kind: ClusterRoleBinding
   metadata:
     name: levelops-satellite
   subjects:
     - kind: ServiceAccount
       name: levelops-satellite
       namespace: default
       apiGroup: ""
   roleRef:
     kind: ClusterRole
     name: edit
     apiGroup: rbac.authorization.k8s.io
   ---
   apiVersion: v1
   kind: ServiceAccount
   metadata:
     name: levelops-satellite
     namespace: default ## It is recommended to change this.
     labels:
       app: levelops
   ---
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: levelops-satellite
     namespace: default ## It is recommended to change this.
   spec:
     selector:
       matchLabels:
         app: levelops-satellite
     template:
       metadata:
         labels:
           app: levelops-satellite
       spec:
         serviceAccountName: levelops-satellite
         containers:
           - name: levelops-satellite
             image: levelops/ingestion-satellite
             imagePullPolicy: Always
             resources:
               limits:
                 memory: "5Gi"
                 cpu: "1000m"
             volumeMounts:
               - name: config-volume
                 mountPath: /levelops/config.yml
                 subPath: config.yml
         volumes:
         - name: config-volume
           configMap:
             name: levelops-satellite-config
   ---
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: levelops-satellite-config
     namespace: default ## It is recommended to change this.
   data: ## This section comes from satellite.yml. If you copy and paste this section, you must fix the indentation.
     config.yml: |
       satellite:
         tenant: <TENANT>
         api_key: <API_KEY>
         url: <URL>
       integrations:
         - id: '<ID>'
   ```
3. Apply the deployment to your cluster.

   ```bash
   kubectl apply --namespace=your-name-space -f satellite.yml
   ```
4. Make sure the satellite is running correctly. You should see heartbeats being sent.

   ```bash
   kubectl get pods --namespace=your-name-space ## Use this to find the pod.
   kubectl logs <satellite pod> -f --namespace=your-name-space
   ```
5. Because the template configured the deployment with `imagePullPolicy: Always`, you get the latest updates when the pod is restarted.

   ```bash
   kubectl rollout restart deployment levelops-satellite
   ```

   To force a pod restart and get the latest updates, use the following command:

   ```bash
   kubectl rollout restart deployment levelops-satellite
   ```

   This ensures that your Satellite container stays up to date with the latest changes. Make sure to monitor the logs regularly to ensure the proper functioning of the container.
   {% endtab %}

{% tab title="Docker" %}

1. Download and install Docker Desktop.

   * [Docker Desktop for Linux (Ubuntu)](https://docs.docker.com/install/linux/docker-ce/ubuntu/)
   * [Docker Desktop for macOS](https://download.docker.com/mac/stable/Docker.dmg)
   * [Docker Desktop for Microsoft Windows](https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe)

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>On Linux, add your user to the Docker group so that you can run Docker commands without <code>root</code> or <code>sudo</code>.</p><pre class="language-bash"><code class="lang-bash">sudo usermod -aG docker $(whoami)
   </code></pre><p>You need to log out and log back in for the change to take effect.</p></div>
2. Pull the latest version of the Ingestion Satellite container.

   ```bash
   docker pull levelops/ingestion-satellite
   ```

   If you aren't able to execute the `docker pull` command, you can manually [download the Ingestion Satellite image](https://hub.docker.com/r/levelops/ingestion-satellite) from Docker Hub and install it.
3. Run the Satellite container in the foreground.

   ```bash
   docker run \
     -v /absolute/path/to/satellite.yml:/levelops/config.yml \
     levelops/ingestion-satellite
   ```

<details>

<summary>Option: Encrypt satellite.yml</summary>

To avoid storing data at rest in the clear, you can encrypt `satellite.yml`. The Satellite can read AES-256 encrypted config files. You must provide an environment variable with the encryption password.

1. Use the following command to encrypt the configuration file. Edit the input path (`/absolute/path/to/input/satellite.yml`) and output path (`/path/to/output/satellite.yml.enc`) according to your environment.

   ```bash
   docker run -i --rm -v /absolute/path/to/input/satellite.yml:/levelops/input \
     --entrypoint /bin/bash levelops/ingestion-satellite \
     -c 'java -cp /levelops/satellite-agent.jar -Dloader.main=io.levelops.ingestion.agent.Encrypt org.springframework.boot.loader.PropertiesLauncher input' \
     > /path/to/output/satellite.yml.enc
   ```
2. There is no prompt, but you must enter your password in the terminal, and then press enter. When entering your password, it appears in plain text, but it isn't stored.
3. Run the `docker run` command with an encryption password environment variable.

   ```bash
   export ENCRYPTION_PASSWORD="<YOUR_PASSWORD>"; docker run -d --restart unless-stopped \
     -v /absolute/path/to/satellite.yml.enc:/levelops/config.yml \
     --env ENCRYPTION_PASSWORD \
     levelops/ingestion-satellite
   ```

If you need to make changes later on, you can use the following command to decrypt the configuration file. As before you must edit the input path and output path according to your environment. You'll also need to enter your password and press Enter.

```bash
docker run -i --rm -v /absolute/path/to/input/satellite.yml.enc:/levelops/input \
  --entrypoint /bin/bash levelops/ingestion-satellite \
  -c 'java -cp /levelops/satellite-agent.jar -Dloader.main=io.levelops.ingestion.agent.Decrypt org.springframework.boot.loader.PropertiesLauncher input' \
  > /path/to/output/satellite.yml
```

</details>

<details>

<summary>Troubleshooting: Satellite can't find satellite.yml</summary>

Errors mentioning `${levelops.api_key}` indicate that the Satellite can't find the config file. This can happen with older versions of Docker that can experience issues when mounting single files. To resolve this issue:

1. Rename `satellite.yml` to `config.yml`, and then move the file into an empty folder.
2. On Linux, check that your user (not `root`) owns both the folder and file, and that permissions are not too restrictive (as with `chmod 755`).
3. Run the `docker run` command with the parent folder instead of the specific config file.

   ```bash
   docker run \
     -v /absolute/path/to/parent/folder:/levelops/config \
     -e CONFIG_FILE=/levelops/config/config.yml \
     levelops/ingestion-satellite
   ```

**For newer versions of Docker, make sure that you are using the full paths and not relative paths.** For newer versions of Docker, it's essential to use full paths rather than relative paths when specifying file locations. Here's an example docker run command:

```bash
docker run \
-v /absolute/path/to/parent/folder:/levelops/config \
-e CONFIG_FILE=/levelops/config/config.yml \
levelops/ingestion-satellite
```

</details>

4. If everything is working, run the container in the background by adding `-d --restart unless-stopped`.

   ```bash
   docker run -d --restart unless-stopped \
     -v /absolute/path/to/satellite.yml:/levelops/config.yml \
     levelops/ingestion-satellite
   ```
5. Optionally, add `--name sei` to give the container a name. Use a unique name per container if you are running more than one.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>MANAGE BACKGROUND CONTAINERS</strong></p><p>These commands are helpful for managing background containers.</p><pre class="language-bash"><code class="lang-bash"># list containers
   docker container ls
   stop or restart container with ID
   docker container stop &#x3C;ID>
   docker container restart &#x3C;ID>
   delete container by ID
   docker rm &#x3C;ID>
   </code></pre></div>

{% endtab %}
{% endtabs %}
