﻿---
title: Run Elastic Agent in a container
description: You can run Elastic Agent inside a container — either with Fleet Server or standalone. Docker images for all versions of Elastic Agent are available from...
url: https://www.elastic.co/elastic/docs-builder/docs/2646/reference/fleet/elastic-agent-container
products:
  - Elastic Agent
  - Fleet
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Run Elastic Agent in a container
You can run Elastic Agent inside a container — either with Fleet Server or standalone. Docker images for all versions of Elastic Agent are available from the [Elastic Docker registry](https://www.docker.elastic.co/r/elastic-agent/elastic-agent). If you are running in Kubernetes, refer to [run Elastic Agent on ECK](https://www.elastic.co/elastic/docs-builder/docs/2646/deploy-manage/deploy/cloud-on-k8s/standalone-elastic-agent).
Running Elastic Agent in a container is supported only in Linux environments. For this reason we don't currently provide Elastic Agent container images for Windows.
In version 9.0.0, the default Ubuntu-based Docker images used for Elastic Agent have been changed to Red Hat UBI (Universal Base Image) minimal based images, to reduce the overall footprint of the agent Docker images and to improve compliance with enterprise standards. Refer to [#6427](https://github.com/elastic/elastic-agent/pull/6427) for details.
Considerations:
- When Elastic Agent runs inside a container, it cannot be upgraded through Fleet as it expects that the container itself is upgraded.
- Enrolling and running an Elastic Agent is usually a two-step process. However, this doesn’t work in a container, so a special subcommand, `container`, is called. This command allows environment variables to configure all properties, and runs the `enroll` and `run` commands as a single command.


## What you need

- [Docker installed](https://docs.docker.com/get-docker/).
- Elasticsearch for storing and searching your data, and Kibana for visualizing and managing it.
  <applies-switch>
  <applies-item title="{ serverless:, ess: }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Cloud Hosted: Generally available">
  To get started quickly, use [Elastic Cloud](https://cloud.elastic.co/).
  </applies-item>

  <applies-item title="self:" applies-to="Self-managed Elastic deployments: Generally available">
  To install and run Elasticsearch and Kibana, see [Installing the Elastic Stack](https://www.elastic.co/elastic/docs-builder/docs/2646/deploy-manage/deploy/self-managed/installing-elasticsearch).
  </applies-item>
  </applies-switch>


## Step 1: Pull the image

There are various flavors of images for Elastic Agent, elastic-agent and elastic-agent-complete. Refer to [Install Elastic Agents](https://www.elastic.co/elastic/docs-builder/docs/2646/reference/fleet/install-elastic-agents) for full details about each flavor.
Run the `docker pull` command against the Elastic Docker registry:

### Basic flavor

```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent-slim:9.3.0
```

Alternately, you can use the hardened [Wolfi](https://github.com/wolfi-dev/) image. Using Wolfi images requires Docker version 20.10.10 or later. For details about why the Wolfi images have been introduced, refer to our article [Reducing CVEs in Elastic container images](https://www.elastic.co/blog/reducing-cves-in-elastic-container-images).
```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent-slim-wolfi:9.3.0
```


### Server flavor

```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent:9.3.0
```

To run the server flavor using the hardened [Wolfi](https://github.com/wolfi-dev/) image, run:
```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent-wolfi:9.3.0
```


### Complete flavor

The Docker image you should use to run Elastic Agent as a Synthetic Private Location depends on the types of monitors that will run in that location:
- If running _only_ lightweight monitors, use the `elastic-agent` image (and the `wolfi` variant).
- If running _any_ browser monitors, use the `elastic-agent-complete` image.

Run the following docker pull command to fetch the `elastic-agent-complete` image:
```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent-complete:9.3.0
```

To run Synthetics tests using the hardened [Wolfi](https://github.com/wolfi-dev/) image, run:
```bash
docker pull docker.elastic.co/elastic-agent/elastic-agent-complete-wolfi:9.3.0
```


## Step 2: Optional: Verify the image

Although it’s optional, we highly recommend verifying the signatures included with your downloaded Docker images to ensure that the images are valid.
Elastic images are signed with Cosign which is part of the [Sigstore](https://www.sigstore.dev) project. Cosign supports container signing, verification, and storage in an OCI registry. Install the appropriate Cosign application for your operating system.
Run the following commands to verify the **elastic-agent** container image signature for Elastic Agent v9.3.0:
```bash
wget https://artifacts.elastic.co/cosign.pub 
cosign verify --key cosign.pub docker.elastic.co/elastic-agent/elastic-agent:9.3.0 
```

If you’re using the elastic-agent-complete image, run the commands as follows:
```bash
wget https://artifacts.elastic.co/cosign.pub
cosign verify --key cosign.pub docker.elastic.co/elastic-agent/elastic-agent-complete:9.3.0
```

The command prints the check results and the signature payload in JSON format, for example:
```bash
Verification for docker.elastic.co/elastic-agent/elastic-agent-complete:9.3.0 --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key
```


## Step 3: Get aware of the Elastic Agent container command

The Elastic Agent container command offers a wide variety of options. To see the full list, run:
```bash
docker run --rm docker.elastic.co/elastic-agent/elastic-agent:9.3.0 elastic-agent container -h
```


## Step 4: Run the Elastic Agent image

<applies-switch>
  <applies-item title="{ serverless:, ess: }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Cloud Hosted: Generally available">
    ```bash
    docker run \
      --env FLEET_ENROLL=1 \ 
      --env FLEET_URL=<fleet-server-host-url> \ 
      --env FLEET_ENROLLMENT_TOKEN=<enrollment-token> \ 
      --rm docker.elastic.co/elastic-agent/elastic-agent:9.3.0 
    ```
  </applies-item>

  <applies-item title="self:" applies-to="Self-managed Elastic deployments: Generally available">
    If you’re running a self-managed cluster and want to run your own Fleet Server, run the following command, which will spin up both Elastic Agent and Fleet Server in a container:
    ```bash
    docker run \
      --env FLEET_SERVER_ENABLE=true \ 
      --env FLEET_SERVER_ELASTICSEARCH_HOST=<elasticsearch-host> \ 
      --env FLEET_SERVER_SERVICE_TOKEN=<service-token> \ 
      --env FLEET_SERVER_POLICY_ID=<fleet-server-policy> \ 
      -p 8220:8220 \ 
      --rm docker.elastic.co/elastic-agent/elastic-agent:9.3.0 
    ```
  </applies-item>
</applies-switch>

If you need to run Fleet Server as well, adjust the `docker run` command above by adding these environment variables:
```bash
  --env FLEET_SERVER_ENABLE=true \ 
  --env FLEET_SERVER_ELASTICSEARCH_HOST=<elasticsearch-host> \ 
  --env FLEET_SERVER_SERVICE_TOKEN=<service-token> 
```

<tip>
  **Running Elastic Agent on a read-only file system**If you’d like to run Elastic Agent in a Docker container on a read-only file system, you can do so by specifying the `--read-only` option. Elastic Agent requires a stateful directory to store application data, so with the `--read-only` option you also need to use the `--mount` option to specify a path to where that data can be stored.For example:
  ```bash
  docker run --rm --mount source=$(pwd)/state,destination=/state -e STATE_PATH=/state --read-only docker.elastic.co/elastic-agent/elastic-agent:9.3.0 
  ```
  You can also add `type=tmpfs` to the mount parameter (`--mount type=tmpfs,destination=/state...`) to specify a temporary file storage location. This should be done with caution as it can cause data duplication, particularly for logs, when the container is restarted, as no state data is persisted.
</tip>


## Step 5: View your data in Kibana

1. Launch Kibana:
   <applies-switch>
   <applies-item title="{ serverless:, ess: }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Cloud Hosted: Generally available">
   1. [Log in](https://cloud.elastic.co/) to your Elastic Cloud account.
   2. Navigate to the Kibana endpoint in your deployment.
   </applies-item>

   <applies-item title="self:" applies-to="Self-managed Elastic deployments: Generally available">
   Point your browser to [http://localhost:5601](http://localhost:5601), replacing `localhost` with the name of the Kibana host.
   </applies-item>
   </applies-switch>
2. To check if your Elastic Agent is enrolled in Fleet, go to **Management → Fleet → Agents**.
   ![Elastic Agents Fleet page](https://www.elastic.co/elastic/docs-builder/docs/2646/reference/fleet/images/kibana-fleet-agents.png)
3. To view data flowing in, go to **Analytics → Discover** and select the index `metrics-*`, or even more specific, `metrics-kubernetes.*`. If you can’t see these indexes, [create a data view](https://www.elastic.co/elastic/docs-builder/docs/2646/explore-analyze/find-and-organize/data-views) for them.
4. To view predefined dashboards, either select **Analytics→Dashboard** or [install assets through an integration](https://www.elastic.co/elastic/docs-builder/docs/2646/reference/fleet/view-integration-assets).


## Docker compose

You can run Elastic Agent in docker-compose. The example below shows how to enroll an Elastic Agent:
```yaml
version: "3"
services:
  elastic-agent:
    image: docker.elastic.co/elastic-agent/elastic-agent:9.3.0 
    container_name: elastic-agent
    restart: always
    user: root                                                       
    environment:
      - FLEET_ENROLLMENT_TOKEN=<enrollment-token>
      - FLEET_ENROLL=1
      - FLEET_URL=<fleet-server-url>
```

If you need to run Fleet Server as well, adjust the docker-compose file above by adding these environment variables:
```yaml
      - FLEET_SERVER_ENABLE=true
      - FLEET_SERVER_ELASTICSEARCH_HOST=<elasticsearch-host>
      - FLEET_SERVER_SERVICE_TOKEN=<service-token>
```

Refer to [Environment variables](https://www.elastic.co/elastic/docs-builder/docs/2646/reference/fleet/agent-environment-variables) for all available options.

## Logs

Since a container supports only a single version of Elastic Agent, logs and state are stored a bit differently than when running an Elastic Agent outside of a container. The logs can be found under: `/usr/share/elastic-agent/state/data/logs/*`.
It’s important to note that only the logs from the Elastic Agent process itself are logged to `stdout`. Subprocess logs are not. Each subprocess writes its own logs to the `default` directory inside the logs directory:
```bash
/usr/share/elastic-agent/state/data/logs/default/*
```

<tip>
  Running into errors with Fleet Server? Check the fleet-server subprocess logs for more information.
</tip>


## Debugging

A monitoring endpoint can be enabled to expose resource usage and event processing data. The endpoint is compatible with Elastic Agents running in both Fleet mode and Standalone mode.
Enable the monitoring endpoint in `elastic-agent.yml` on the host where the Elastic Agent is installed. A sample configuration looks like this:
```yaml
agent.monitoring:
  enabled: true 
  logs: true 
  metrics: true 
  http:
      enabled: true 
      host: localhost 
      port: 6791 
```

The above configuration exposes a monitoring endpoint at `http://localhost:6791/processes`.
<dropdown title="http://localhost:6791/processes output">
  ```json
  {
     "processes":[
        {
           "id":"metricbeat-default",
           "pid":"36923",
           "binary":"metricbeat",
           "source":{
              "kind":"configured",
              "outputs":[
                 "default"
              ]
           }
        },
        {
           "id":"filebeat-default-monitoring",
           "pid":"36924",
           "binary":"filebeat",
           "source":{
              "kind":"internal",
              "outputs":[
                 "default"
              ]
           }
        },
        {
           "id":"metricbeat-default-monitoring",
           "pid":"36925",
           "binary":"metricbeat",
           "source":{
              "kind":"internal",
              "outputs":[
                 "default"
              ]
           }
        }
     ]
  }
  ```
</dropdown>

Each process ID in the `/processes` output can be accessed for more details.
<dropdown title="http://localhost:6791/processes/{{process-name}} output">
  ```json
  {
     "beat":{
        "cpu":{
           "system":{
              "ticks":537,
              "time":{
                 "ms":537
              }
           },
           "total":{
              "ticks":795,
              "time":{
                 "ms":796
              },
              "value":795
           },
           "user":{
              "ticks":258,
              "time":{
                 "ms":259
              }
           }
        },
        "info":{
           "ephemeral_id":"eb7e8025-7496-403f-9f9a-42b20439c737",
           "uptime":{
              "ms":75332
           },
           "version":"7.14.0"
        },
        "memstats":{
           "gc_next":23920624,
           "memory_alloc":20046048,
           "memory_sys":76104712,
           "memory_total":60823368,
           "rss":83165184
        },
        "runtime":{
           "goroutines":58
        }
     },
     "libbeat":{
        "config":{
           "module":{
              "running":4,
              "starts":4,
              "stops":0
           },
           "reloads":1,
           "scans":1
        },
        "output":{
           "events":{
              "acked":0,
              "active":0,
              "batches":0,
              "dropped":0,
              "duplicates":0,
              "failed":0,
              "toomany":0,
              "total":0
           },
           "read":{
              "bytes":0,
              "errors":0
           },
           "type":"elasticsearch",
           "write":{
              "bytes":0,
              "errors":0
           }
        },
        "pipeline":{
           "clients":4,
           "events":{
              "active":231,
              "dropped":0,
              "failed":0,
              "filtered":0,
              "published":231,
              "retry":112,
              "total":231
           },
           "queue":{
              "acked":0,
              "max_events":4096
           }
        }
     },
     "metricbeat":{
        "system":{
           "cpu":{
              "events":8,
              "failures":0,
              "success":8
           },
           "filesystem":{
              "events":80,
              "failures":0,
              "success":80
           },
           "memory":{
              "events":8,
              "failures":0,
              "success":8
           },
           "network":{
              "events":135,
              "failures":0,
              "success":135
           }
        }
     },
     "system":{
        "cpu":{
           "cores":8
        },
        "load":{
           "1":2.5957,
           "15":5.415,
           "5":3.5815,
           "norm":{
              "1":0.3245,
              "15":0.6769,
              "5":0.4477
           }
        }
     }
  }
  ```
</dropdown>