> For the complete documentation index, see [llms.txt](https://docs.interactive.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.interactive.ai/deploy/service.md).

# Service

While Interactive Agent handles agent deployments through the UI wizard, service handles **custom containerized workloads through the InteractiveAI CLI** (`iai`). It is a terminal-based interface for **managing services**, **secrets**, and **infrastructure configuration**. The CLI is designed for automation and integration into CI/CD pipelines, and supports both imperative ad-hoc commands and declarative infrastructure management via stack.yaml files.

Navigate to **Deploy → Service** to access the guided tutorial that walks through the complete deployment lifecycle, from CLI installation through declarative synchronization.

{% hint style="info" %}
For detailed command reference, flags, and configuration options, see the [Deployment CLI Documentation](https://docs.interactive.ai/cli/).
{% endhint %}

### System Requirements

* The CLI requires Go 1.21+, Docker, and Git.

### Installation and Login

The CLI is distributed through Go's package manager. **Install Go** first, then **install the CLI**:

```bash
go install github.com/Interactive-AI-Labs/interactive-cli/cmd/iai@latest
```

Verify the installation by running:

```shellscript
iai --help
```

**To log in**, run the following command and enter your username and password when prompted:

```bash
iai login
```

Verify a successful login by listing the organizations your user belongs to:

```bash
iai organizations list
```

### Selecting Organizations and Projects

Most CLI commands require an **organization and project context**. You can pass them explicitly as arguments on every command, or set defaults to avoid repeating them:

```bash
iai organizations select
iai projects select
```

{% hint style="info" %}
The examples throughout this page pass `--organization` and `--project` explicitly for clarity.
{% endhint %}

### Creating a Service

Use `iai services create` to **deploy a containerized service**. The following example deploys an httpbin service from a public image:

```bash
iai services create httpbin \
  --organization my-org \
  --project my-project \
  --port 80 \
  --image-type external \
  --image-repository kennethreitz \
  --image-name httpbin \
  --image-tag latest \
  --replicas 1 \
  --cpu 1 \
  --memory '500M' \
  --endpoint
```

The command accepts the following parameters:

* `--organization` is the organization the service belongs to.
* `--project` is the project the service belongs to.
* `--port` is the port where the service listens to incoming traffic.
* `--image-type` specifies whether the image is stored in an internal or external repository. Internal images are stored in repositories hosted by InteractiveAI and only accessible to members of that project. External images are public and can be accessed by anyone, for example from DockerHub.
* `--image-name` is the name of the image to deploy.
* `--image-tag` is the specific reference tag of the image.
* `--replicas` is the number of instances to run for the service.
* `--cpu` is the number of CPU cores to request per replica. Can be specified as a decimal (e.g., `0.5`) or in millicores (e.g., `500m` for 0.5 cores).
* `--memory` is the memory per replica (e.g., `512M` for megabytes, `1G` for gigabytes).
* `--endpoint` makes the service accessible from the public internet. An endpoint of the form `<service-name>.interactive.ai` will be made available for it.

#### Using an Internal Image

The CLI also supports **internal and private images** **stored in InteractiveAI's platform**. These images are only accessible to members of the project where they have been pushed. To use an internal image, you must first build and push it.

**Build an image**:

```bash
iai images build my-image -t my-tag \
  -f ./docker/Dockerfile \
  -C .
```

**Push the image** to the project registry:

```bash
iai images push my-image -t my-tag \
  --organization my-org \
  --project my-project
```

Verify the upload by listing all available images in the project:

```bash
iai images list
```

Then reference the internal image in a service by setting `--image-type internal`:

```bash
iai services create httpbin \
  --organization my-org \
  --project my-project \
  --port 80 \
  --image-type internal \
  --image-name my-image \
  --image-tag my-tag \
  --replicas 1 \
  --cpu 1 \
  --memory '500M' \
  --endpoint
```

### Validating the Deployment

To verify that the service is running, **list the services** in the project:

```bash
iai services list --organization my-org --project my-project
```

The output should be something similar to:

```bash
NAME        REVISION  STATUS    ENDPOINT
httpbin     21        deployed  <service-endpoint>
other-service  23     deployed
```

Test the endpoint by sending a request:

```bash
curl \
  -L <service-endpoint>/headers \
  -H "Test-Header: InteractiveAI is the greatest platform"
```

### Environment Variables, Secrets, and Sync

Once you have a basic service deployed, you will usually want to configure environment variables for non-sensitive config, inject secrets for API keys and credentials, and use a stack config file with `iai services sync` to keep everything in sync.

#### Environment Variables

`iai services create` accepts an `--env` flag that you can repeat multiple times, using the `NAME=VALUE` format. Inside the container, these appear as normal environment variables:

```bash
iai services create httpbin \
  --organization my-org \
  --project my-project \
  --port 80 \
  --image-type external \
  --image-repository kennethreitz \
  --image-name httpbin \
  --image-tag latest \
  --replicas 1 \
  --cpu 1 \
  --memory '500M' \
  --endpoint \
  --env LOG_LEVEL=info \
  --env FEATURE_FLAG_EXPERIMENTAL=true
```

#### Secrets

Environment variables are convenient, but you should not put passwords, API keys, or tokens directly into commands or plain YAML. Use secrets instead.

The CLI has a `secrets` group of commands to **manage project-level secrets**: create, list, get, update, and delete.

**Create a secret** using CLI flags:

```bash
iai secrets create \
  --organization my-org \
  --project my-project \
  --secret-name httpbin-secret \
  --data DATABASE_URL="postgres://db:5432/mydb" \
  --data API_KEY="super-secret-key"
```

Key points about the `--data` flag: it accepts repeated KEY=VALUE pairs, `--from-env-file` can load them from a file instead, and if both are provided then `--data` takes precedence.

You can also **create a secret from an .env file**:

```bash
iai secrets create \
  --organization my-org \
  --project my-project \
  --secret-name httpbin-secret \
  --from-env-file .env.httpbin
```

List all secrets in a project:

```bash
iai secrets list \
  --organization my-org \
  --project my-project
```

#### Attaching a Secret to a Service

When creating a service via CLI, use `--secret` to specify which secrets to mount as environment variables:

```bash
iai services create httpbin \
  --organization my-org \
  --project my-project \
  --port 80 \
  --image-type external \
  --image-repository kennethreitz \
  --image-name httpbin \
  --image-tag latest \
  --replicas 1 \
  --cpu 1 \
  --memory '500M' \
  --endpoint \
  --secret httpbin-secret
```

Each `--secret` flag references a secret name created with `iai secrets create`. You can repeat `--secret` to mount several secrets. Every key inside those secrets becomes an environment variable in the container (e.g. `DATABASE_URL`, `API_KEY`), alongside any direct `--env` values. The actual values (passwords, API keys) live in the secret, and the config file just references the secret by name, so **it is safe to commit**.

#### Keeping Everything in Sync

`iai services sync` exists so that your deployment behaves like **Infrastructure as Code (IaC)** instead of a collection of ad-hoc commands. When you use the CLI normally (`iai services create`, `iai services update`, etc.), you are directly mutating live infrastructure. That works, but it becomes harder to track, reproduce, or collaborate on changes over time. With a stack config file and sync, the YAML file becomes the source of truth.

**Sync** creates anything missing, updates what has changed, and removes what should not exist anymore. Instead of managing services manually, you manage **a configuration file** and sync makes the platform match that configuration.

* **The stack-id**

The **stack-id** is a critical part of how `sync` works safely. It is a value you must provide and it needs to be unique in order to prevent collisions with other stacks. When you run `iai services sync`, the CLI needs to know which services it should manage and which ones it should ignore inside the same project. Think of stack-id as the namespace or ownership label of your infrastructure definition. When sync runs, it only touches resources with the same stack-id. Anything outside that stack is left untouched. This prevents dangerous scenarios like deleting services owned by another team or stack.

* **Running the Sync**

Define your stack configuration in a stack.yaml file:

```yaml
organization: my-org
project: my-project
stack-id: my-stack # Important!

services:
  httpbin:
    servicePort: 80
    image:
      type: external
      repository: kennethreitz
      name: httpbin
      tag: latest
    resources:
      memory: "512M"
      cpu: "250m"
    replicas: 1
    env:
      - name: DATABASE_URL
        value: "postgres://db:5432/mydb"
      - name: LOG_LEVEL
        value: "info"
    secrets:
      - secretName: httpbin-secret
    endpoint: true
    replicas: 1
```

Apply the desired state to your project:

```bash
iai services sync \
  --cfg-file stack.yaml
```

What happens when sync runs:

* If `httpbin` does not exist, it will be created according to the config.
* If it already exists, its configuration (port, image, resources, env, secrets, replicas, etc.) will be updated.
* If there are other services in `my-project` that belong to this stack but are not in `stack.yaml`, they will be deleted as part of the sync for that stack.
* The actual values (passwords, API keys) live in the secret.
* The config file just references the secret by name (`httpbin-secret`), so it is safe to commit to Git.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.interactive.ai/deploy/service.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
