> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Execute Commands in Workloads

> Run commands inside workload containers without opening an interactive session.

The `cpln workload exec` command runs commands inside a container and returns the output. Unlike `connect`, it's designed for non-interactive commands and scripts, similar to `docker exec` or `kubectl exec`.

## When to use this

<CardGroup cols={2}>
  <Card title="Run scripts" icon="play">
    Execute maintenance scripts, health checks, or one-off commands
  </Card>

  <Card title="Automation" icon="robot">
    Run commands from CI/CD pipelines or monitoring systems
  </Card>

  <Card title="Quick commands" icon="bolt">
    Check environment variables, list files, or test connectivity
  </Card>

  <Card title="Scripted debugging" icon="code">
    Run diagnostic commands and capture output
  </Card>
</CardGroup>

## Prerequisites

<AccordionGroup>
  <Accordion title="CLI installed">
    Install the Control Plane CLI. See [Installation](/cli-reference/installation).
  </Accordion>

  <Accordion title="Running workload">
    You need a running [workload](/reference/workload) in at least one location. See the [Create a Workload](/guides/create-workload) guide.
  </Accordion>

  <Accordion title="Required permissions">
    You need `exec` permission on the workload. See [Workload Permissions](/reference/workload#permissions).
  </Accordion>
</AccordionGroup>

## Basic usage

```bash theme={null}
cpln workload exec <workload> -- <command> [args...]
```

The `--` separates the CLI options from the command to execute.

## Options

| Option        | Description                                               |
| ------------- | --------------------------------------------------------- |
| `--location`  | Target location (defaults to first available in GVC)      |
| `--replica`   | Target a specific replica (defaults to first replica)     |
| `--container` | Target a specific container (defaults to first container) |
| `-i, --stdin` | Pass stdin to the container                               |
| `-t, --tty`   | Allocate a TTY                                            |
| `-q, --quiet` | Only print output from the remote session                 |

## Run a simple command

```bash theme={null}
cpln workload exec my-app -- echo "Hello, World!"
```

Output:

```text theme={null}
Hello, World!
```

## Run commands with arguments

```bash theme={null}
cpln workload exec my-app -- ls -la
```

## Target specific locations or replicas

<Tabs>
  <Tab title="Specific location">
    ```bash theme={null}
    cpln workload exec my-app --location aws-eu-central-1 -- cat /etc/hostname
    ```
  </Tab>

  <Tab title="Specific replica">
    ```bash theme={null}
    cpln workload exec my-app --replica my-app-7f8d9c-abc12 -- cat /etc/hostname
    ```
  </Tab>

  <Tab title="Specific container">
    ```bash theme={null}
    cpln workload exec my-app --container sidecar -- ps aux
    ```
  </Tab>
</Tabs>

## Interactive mode

Combine `-i` (stdin) and `-t` (TTY) for interactive commands:

```bash theme={null}
cpln workload exec my-app -it -- /bin/bash
```

<Tip>
  For interactive sessions, consider using `cpln workload connect` which provides a simpler experience.
</Tip>

## Pipe input to commands

Use `-i` to pipe data into a container:

```bash theme={null}
# Pipe a SQL file into psql
cat schema.sql | cpln workload exec postgres-db -i -- psql -U postgres

# Pipe JSON data to a script
echo '{"key": "value"}' | cpln workload exec my-app -i -- python process.py
```

## Quiet mode

Suppress CLI output and show only command output:

```bash theme={null}
cpln workload exec my-app -q -- cat /app/version.txt
```

Useful for capturing output in scripts:

```bash theme={null}
VERSION=$(cpln workload exec my-app -q -- cat /app/version.txt)
echo "Deployed version: $VERSION"
```

## Common workflows

### Check environment variables

```bash theme={null}
cpln workload exec my-app -- env | grep -E "^(DATABASE|API)"
```

### View logs

```bash theme={null}
cpln workload exec my-app -- tail -100 /var/log/app.log
```

### Check disk usage

```bash theme={null}
cpln workload exec my-app -- df -h
```

### Test network connectivity

```bash theme={null}
cpln workload exec my-app -- curl -s http://api-service:8080/health
```

### Run database queries

```bash theme={null}
cpln workload exec postgres-db -- psql -U postgres -c "SELECT count(*) FROM users;"
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Command not found">
    The command may not exist in the container. Check what's available:

    ```bash theme={null}
    cpln workload exec my-app -- which bash
    cpln workload exec my-app -- ls /bin /usr/bin
    ```
  </Accordion>

  <Accordion title="Permission denied">
    The command may require elevated permissions, or you lack `exec` permission on the workload.
  </Accordion>

  <Accordion title="No replicas found">
    The workload may not be running:

    ```bash theme={null}
    cpln workload get my-app
    cpln workload replica get my-app
    ```
  </Accordion>

  <Accordion title="Command arguments parsed incorrectly">
    Ensure `--` separates CLI options from the command:

    ```bash theme={null}
    # Correct
    cpln workload exec my-app -- ls -la

    # Incorrect - CLI will try to parse -la
    cpln workload exec my-app ls -la
    ```
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Connect to Workloads" href="/guides/cli/workload/connect" icon="plug">
    Interactive shell access
  </Card>

  <Card title="Copy Files" href="/guides/cli/cpln-cp" icon="copy">
    Transfer files to/from workloads
  </Card>

  <Card title="Port Forwarding" href="/guides/cli/cpln-port-forward" icon="network-wired">
    Access workload ports locally
  </Card>

  <Card title="Command Reference" href="/cli-reference/commands/workload#workload-exec" icon="book">
    Full exec command reference
  </Card>
</CardGroup>
