﻿---
title: APM Server binary
description: This guide will explain how to set up and configure the APM Server binary. First, see the Elastic Support Matrix for information about supported operating...
url: https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/binary
products:
  - APM
  - Elastic Observability
applies_to:
  - Elastic Stack: Generally available
---

# APM Server binary
This guide will explain how to set up and configure the APM Server binary.

## Prerequisites

First, see the [Elastic Support Matrix](https://www.elastic.co/support/matrix) for information about supported operating systems and product compatibility.
You’ll need:
- **Elasticsearch** for storing and indexing data.
- **Kibana** for visualizing with the Applications UI.

We recommend you use the same version of Elasticsearch, Kibana, and APM Server.
For more information about installing these products, refer to [Deploy](https://www.elastic.co/elastic/docs-builder/docs/3016/deploy-manage/deploy).
![Install Elastic APM yourself](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/images/observability-apm-architecture-diy.png)


## Step 1: Install

<note>
  **Before you begin**: If you haven’t installed the Elastic Stack, do that now.
  Refer to [Deploy](https://www.elastic.co/elastic/docs-builder/docs/3016/deploy-manage/deploy).
</note>

To download and install APM Server, use the commands below that work with your system. If you use `apt` or `yum`, you can [install APM Server from our repositories](#apm-setup-repositories) to update to the newest version more easily.

**deb:**
```shell
curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-9.3.2-amd64.deb
sudo dpkg -i apm-server-9.3.2-amd64.deb
```


**RPM:**
```shell
curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-9.3.2-x86_64.rpm
sudo rpm -vi apm-server-9.3.2-x86_64.rpm
```


**Other Linux:**
```shell
curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-9.3.2-linux-x86_64.tar.gz
tar xzvf apm-server-9.3.2-linux-x86_64.tar.gz
```

For more information, refer to [modifying the `nofile` ulimit](#modify-nofile-ulimit).

**Mac:**
```shell
curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-9.3.2-darwin-x86_64.tar.gz
tar xzvf apm-server-9.3.2-darwin-x86_64.tar.gz
```


**Windows:**
1. Download the APM Server Windows zip file from the [downloads page](https://www.elastic.co/downloads/apm/apm-server).
2. Extract the contents of the zip file into `C:\Program Files`.
3. Rename the `apm-server-<version>-windows` directory to `APM-Server`.
4. Open a PowerShell prompt as an Administrator (right-click the PowerShell icon and select *Run As Administrator*).
   If you are running Windows XP, you may need to download and install PowerShell.
5. From the PowerShell prompt, run the following commands to install APM Server as a Windows service:


**Docker:**
See [Running on Docker](#apm-running-on-docker) for deploying Docker containers.

## Step 2: Set up and configure

Configure APM by editing the `apm-server.yml` configuration file. The location of this file varies by platform—see the [Installation layout](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/installation-layout) for help locating it.
A minimal configuration file might look like this:
```yaml
apm-server:
  host: "localhost:8200" 
output.elasticsearch:
  hosts: ["localhost:9200"] 
  username: "elastic" 
  password: "changeme"
```

All available configuration options are outlined in [configuring APM Server](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/configure).

## Step 3: Start

In a production environment, you would put APM Server on its own machines, similar to how you run Elasticsearch. You *can* run it on the same machines as Elasticsearch, but this is not recommended, as the processes will be competing for resources.
To start APM Server, run:
```bash
./apm-server -e
```

<note>
  The `-e` [global flag](/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/command-reference#apm-global-flags) enables logging to stderr and disables syslog/file output. Remove this flag if you’ve enabled logging in the configuration file. For Linux systems, see [APM Server status and logs](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/systemd).
</note>

You should see APM Server start up. It will try to connect to Elasticsearch on localhost port `9200` and expose an API to agents on port `8200`. You can change the defaults in `apm-server.yml` or by supplying a different address on the command line:
```bash
./apm-server -e -E output.elasticsearch.hosts=ElasticsearchAddress:9200 -E apm-server.host=localhost:8200
```


### Debian Package / RPM

For Debian package and RPM installations, we recommend the `apm-server` process runs as a non-root user. Therefore, these installation methods create an `apm-server` user which you can use to start the process. In addition, APM Server will only start if the configuration file is [owned by the user running the process](/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/systemd#apm-config-file-ownership).
To start the APM Server in this case, run:
```bash
sudo -u apm-server apm-server [<argument...>]
```

By default, APM Server loads its configuration file from `/etc/apm-server/apm-server.yml`. See the [deb & rpm default paths](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/installation-layout) for a full directory layout.

## Step 4: Install APM agents

<tab-set>
  <tab-item title="Android">
    **1. Add the agent to your project**First, add the [Elastic APM agent plugin](https://plugins.gradle.org/plugin/co.elastic.apm.android) to your application’s `build.gradle` file as shown below:
    ```groovy
    // Android app's build.gradle file
    plugins {
        id "com.android.application"
        id "co.elastic.apm.android" version "[latest_version]" 
    }
    ```
    **2. Configure the agent**After adding the agent plugin, configure it. A minimal configuration sets the Elastic APM integration endpoint as shown below:
    ```groovy
    // Android app's build.gradle file
    plugins {
        //...
        id "co.elastic.apm.android" version "[latest_version]" 
    }

    elasticApm {
        // Minimal configuration
        serverUrl = "https://your.elastic.server"

        // Optional
        serviceName = "your app name" 
        serviceVersion = "0.0.0" 
        apiKey = "your server api key" 
        secretToken = "your server auth token" 
    }
    ```

    <note>
      When both `secretToken` and `apiKey` are provided, apiKey has priority and secretToken is ignored.
    </note>
    **3. Initialize the agent**After syncing your project with the Gradle changes above, the Elastic APM agent needs to be initialized within your [Application class](https://developer.android.com/reference/android/app/Application). This example shows the simplest way to configure the agent:
    ```java
    // Your Application class

    class MyApp extends android.app.Application {

        @Override
        public void onCreate() {
            super.onCreate();
            ElasticApmAgent.initialize(this); 
        }
    }
    ```
    All that’s left is to compile and run your application. That’s it!**Learn more in the agent reference**Read more in the [APM Android Agent Reference](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/opentelemetry/edot-sdks/android).
  </tab-item>

  <tab-item title="Go">
    **1. Install the agent**Install the Elastic APM Go agent package using `go get`:
    ```bash
    go get -u go.elastic.co/apm/v2
    ```
    **2. Configure the agent**To simplify development and testing, the agent defaults to sending data to the Elastic APM integration at `http://localhost:8200`. To send data to an alternative location, you must configure `ELASTIC_APM_SERVER_URL`.
    ```go
    # The APM integration host and port
    export ELASTIC_APM_SERVER_URL=

    # If you do not specify `ELASTIC_APM_SERVICE_NAME`, the Go agent will use the
    # executable name. For example, if your executable is called "my-app.exe", then your
    # service will be identified as "my-app".
    export ELASTIC_APM_SERVICE_NAME=

    # Secret tokens are used to authorize requests to the APM integration
    export ELASTIC_APM_SECRET_TOKEN=
    ```
    **3. Instrument your application**Instrumentation is the process of extending your application’s code to report trace data to Elastic APM. Go applications must be instrumented manually at the source code level. To instrument your applications, use one of the following approaches:
    - [Built-in instrumentation modules](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/go/builtin-modules).
    - [Custom instrumentation](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/go/custom-instrumentation) and context propagation with the Go Agent API.
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/go/supported-technologies)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/go/configuration)
    - [Detailed guide to instrumenting Go source code](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/go/set-up-apm-go-agent)
  </tab-item>

  <tab-item title="iOS">
    **1. Add the agent dependency to your project**Add the Elastic APM iOS Agent to your Xcode project or your `Package.swift`.Here are instructions for adding a [package dependency](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) to a standard Xcode project.Refer to [*Add a Dependency on Another Swift Package*](https://developer.apple.com/documentation/xcode/creating_a_standalone_swift_package_with_xcode#3578941) for details about adding dependencies to your `Package.swift`. Here is a helpful code-snippet:
    ```swift
    Package(
        dependencies:[
             .package(name: "apm-agent-ios", url: "https://github.com/elastic/apm-agent-ios.git", from: "1.0.0"),
        ],
      targets:[
        .target(
            name: "MyApp",
            dependencies: [
                .product(name: "ElasticApm", package: "apm-agent-ios")
            ]
        ),
    ])
    ```
    **2. Initialize the agent**If you’re using `SwiftUI` to build your app, add the following to your `App.swift`:
    ```swift
    import SwiftUI
    import ElasticApm

    class AppDelegate : NSObject, UIApplicationDelegate {
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            var config = AgentConfigBuilder()
                .withServerUrl(URL(string:"http://127.0.0.1:8200")) 
                .withSecretToken("<SecretToken>") 
                .build()

            ElasticApmAgent.start(with: config)
            return true
        }
    }

    @main
    struct MyApp: App {
        @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
        init() {
        }
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
    ```
    If you’re not using `SwiftUI`, you can alternatively add the same thing to your `AppDelegate.swift` file:
    ```swift
    import UIKit
    import ElasticApm
    @main
    class AppDelegate: UIResponder, UIApplicationDelegate {
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    var config = AgentConfigBuilder()
                           .withServerUrl(URL(string:"http://127.0.0.1:8200")) 
                           .withSecretToken("<SecretToken>") 
                           .build()
            ElasticApmAgent.start(with: config)
            return true
        }
    }
    ```
    **Learn more in the agent reference**Read more in the [APM iOS Agent Reference](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/opentelemetry/edot-sdks/ios).
  </tab-item>

  <tab-item title="Java">
    Manually set up and configure the agent with the `-javaagent` JVM option. No application code change is required, but this requires an application restart. See below for more information on this setup method.**1. Download the APM agent**The first step in getting started with the Elastic APM Java agent is to retrieve a copy of the agent JAR. Java agent releases are published to [Maven central](https://repo.maven.apache.org/maven2/). In order to get a copy you can either:
    - download the [latest agent](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=releases&g=co.elastic.apm&a=elastic-apm-agent&v=LATEST) or [previous releases](https://mvnrepository.com/artifact/co.elastic.apm/elastic-apm-agent) from Maven central.
    - download with `curl`:
      ```bash
      curl -o 'elastic-apm-agent.jar' -L 'https://oss.sonatype.org/service/local/artifact/maven/redirect?r=releases&g=co.elastic.apm&a=elastic-apm-agent&v=LATEST'
      ```
    **2. Add `-javaagent` flag**When starting your application, add the JVM flag `-javaagent:/path/to/elastic-apm-agent-<version>.jar`**3. Configure**Different application servers have different ways of setting the `-javaagent` flag and system properties. Start your application (for example a Spring Boot application or other embedded servers) and add the `-javaagent` JVM flag. Use the `-D` prefix to configure the agent using system properties:
    ```bash
    java -javaagent:/path/to/elastic-apm-agent-<version>.jar -Delastic.apm.service_name=my-cool-service -Delastic.apm.application_packages=org.example,org.another.example -Delastic.apm.server_url=http://127.0.0.1:8200 -jar my-application.jar
    ```
    Refer to [Manual setup with `-javaagent` flag](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/java/setup-javaagent) to learn more.**Alternate setup methods**
    - **Automatic setup with `apm-agent-attach-cli.jar`** Automatically set up the agent without needing to alter the configuration of your JVM or application server. This method requires no changes to application code or JVM options, and allows attaching to a running JVM. Refer to the [Java agent documentation](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/java/setup-attach-cli) for more information on this setup method.
    - **Programmatic API setup to self-attach** Set up the agent with a one-line code change and an extra `apm-agent-attach` dependency. This method requires no changes to JVM options, and the agent artifact is embedded within the packaged application binary. Refer to the [Java agent documentation](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/java/setup-attach-api) for more information on this setup method.
  </tab-item>

  <tab-item title=".NET">
    **Set up the APM agent**The .NET agent can be added to an application in a few different ways:
    - **Profiler runtime instrumentation**: The agent supports auto instrumentation without any code change and without any recompilation of your projects. See [Profiler auto instrumentation](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/dotnet/setup-auto-instrumentation).
    - **NuGet packages**: The agent ships as a set of [NuGet packages](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/dotnet/nuget-packages) available on [nuget.org](https://nuget.org). You can add the Agent and specific instrumentations to a .NET application by referencing one or more of these packages and following the package documentation.
    - **Host startup hook**: On .NET Core 3.0+ or .NET 5+, the agent supports auto instrumentation without any code change and without any recompilation of your projects. See [Zero code change setup on .NET Core](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/dotnet/setup-dotnet-net-core) for more details.
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/dotnet/supported-technologies)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/dotnet/configuration)
  </tab-item>

  <tab-item title="Node.js">
    **1. Install the APM agent**Install the APM agent for Node.js as a dependency to your application.
    ```js
    npm install elastic-apm-node --save
    ```
    **2. Initialization**It’s important that the agent is started before you require **any** other modules in your Node.js application - i.e. before `http` and before your router etc.This means that you should probably require and start the agent in your application’s main file (usually `index.js`, `server.js` or `app.js`).Here’s a simple example of how Elastic APM is normally required and started:
    ```js
    // Add this to the VERY top of the first file loaded in your app
    var apm = require('elastic-apm-node').start({
      // Override service name from package.json
      // Allowed characters: a-z, A-Z, 0-9, -, _, and space
      serviceName: '',

      // Use if APM integration requires a token
      secretToken: '',

      // Use if APM integration uses API keys for authentication
      apiKey: '',

      // Set custom APM integration host and port (default: http://127.0.0.1:8200)
      serverUrl: '',
    })
    ```
    The agent will now monitor the performance of your application and record any uncaught exceptions.**Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/nodejs/supported-technologies)
    - [Babel/ES Modules](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/nodejs/advanced-setup)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/nodejs/configuring-agent)
  </tab-item>

  <tab-item title="PHP">
    **1. Install the agent**Install the agent using one of the [packages for supported platforms](https://github.com/elastic/apm-agent-php/releases/latest).To use the RPM Package (RHEL/CentOS and Fedora):
    ```bash
    rpm -ivh <package-file>.rpm
    ```
    To use the DEB package (Debian and Ubuntu):
    ```bash
    dpkg -i <package-file>.deb
    ```
    To use the APK package (Alpine):
    ```bash
    apk add --allow-untrusted <package-file>.apk
    ```
    If you can’t find your distribution, you can install the agent by building it from the source. The following instructions will build the APM agent using the same docker environment that Elastic uses to build our official packages.
    <note>
      The agent is currently only available for Linux operating system.
    </note>

    1. Download the agent source from [[https://github.com/elastic/apm-agent-php/](https://github.com/elastic/apm-agent-php/)](https://github.com/elastic/apm-agent-php/).
    2. Execute the following commands to build the agent and install it:

    ```bash
    cd apm-agent-php
    # for linux glibc - libc distributions (Ubuntu, Redhat, etc)
    export BUILD_ARCHITECTURE=linux-x86-64
    # for linux with musl - libc distributions (Alpine)
    export BUILD_ARCHITECTURE=linuxmusl-x86-64
    # provide a path to php-config tool
    export PHP_CONFIG=php-config

    # build extensions
    make -f .ci/Makefile build

    # run extension tests
    PHP_VERSION=`$PHP_CONFIG --version | cut -d'.' -f 1,2` make -f .ci/Makefile run-phpt-tests

    # install agent extensions
    sudo cp agent/native/_build/${BUILD_ARCHITECTURE}-release/ext/elastic_apm-*.so `$PHP_CONFIG --extension-dir`

    # install automatic loader
    sudo cp agent/native/_build/${BUILD_ARCHITECTURE}-release/loader/code/elastic_apm_loader.so `$PHP_CONFIG --extension-dir`
    ```
    **2. Enable and configure the APM agent**Enable and configure your agent inside of the `php.ini` file:
    ```ini
    extension=elastic_apm_loader.so
    elastic_apm.bootstrap_php_part_file=<repo root>/agent/php/bootstrap_php_part.php
    ```
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/php/supported-technologies)
    - [Configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/php/configuration)
  </tab-item>

  <tab-item title="Python">
    <definitions>
      <definition term="Django">
        **1. Install the APM agent**
      </definition>
    </definitions>
    Install the APM agent for Python as a dependency.
    ```python
    $ pip install elastic-apm
    ```
    **2. Configure the agent**Agents are libraries that run inside of your application process. APM services are created programmatically based on the `SERVICE_NAME`.
    ```python
    # Add the agent to the installed apps
    INSTALLED_APPS = (
      'elasticapm.contrib.django',
      # ...
    )

    ELASTIC_APM = {
      # Set required service name. Allowed characters:
      # a-z, A-Z, 0-9, -, _, and space
      'SERVICE_NAME': '',

      # Use if APM integration requires a token
      'SECRET_TOKEN': '',

      # Set custom APM integration host and port (default: http://localhost:8200)
      'SERVER_URL': '',
    }

    # To send performance metrics, add our tracing middleware:
    MIDDLEWARE = (
      'elasticapm.contrib.django.middleware.TracingMiddleware',
      #...
    )
    ```

    <definitions>
      <definition term="Flask">
        **1. Install the APM agent**
      </definition>
    </definitions>
    Install the APM agent for Python as a dependency.
    ```python
    $ pip install elastic-apm[flask]
    ```
    **2. Configure the agent**Agents are libraries that run inside of your application process. APM services are created programmatically based on the `SERVICE_NAME`.
    ```python
    # initialize using environment variables
    from elasticapm.contrib.flask import ElasticAPM
    app = Flask(__name__)
    apm = ElasticAPM(app)

    # or configure to use ELASTIC_APM in your application settings
    from elasticapm.contrib.flask import ElasticAPM
    app.config['ELASTIC_APM'] = {
      # Set required service name. Allowed characters:
      # a-z, A-Z, 0-9, -, _, and space
      'SERVICE_NAME': '',

      # Use if APM integration requires a token
      'SECRET_TOKEN': '',

      # Set custom APM integration host and port (default: http://localhost:8200)
      'SERVER_URL': '',
    }

    apm = ElasticAPM(app)
    ```
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/python/supported-technologies)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/python/configuration)
  </tab-item>

  <tab-item title="Ruby">
    **1. Install the APM agent**Add the agent to your Gemfile.
    ```ruby
    gem 'elastic-apm'
    ```
    **2. Configure the agent**
    <definitions>
      <definition term="Ruby on Rails">
        APM is automatically started when your app boots. Configure the agent by creating the config file `config/elastic_apm.yml`:
      </definition>
    </definitions>

    ```ruby
    # config/elastic_apm.yml:

    # Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space
    # Defaults to the name of your Rails app
    service_name: 'my-service'

    # Use if APM integration requires a token
    secret_token: ''

    # Set custom APM integration host and port (default: http://localhost:8200)
    server_url: 'http://localhost:8200'
    ```

    <definitions>
      <definition term="Rack">
        For Rack or a compatible framework, like Sinatra, include the middleware in your app and start the agent.
      </definition>
    </definitions>

    ```ruby
    # config.ru

    app = lambda do |env|
      [200, {'Content-Type' => 'text/plain'}, ['ok']]
    end

    # Wraps all requests in transactions and reports exceptions
    use ElasticAPM::Middleware

    # Start an instance of the Agent
    ElasticAPM.start(service_name: 'NothingButRack')

    run app

    # Gracefully stop the agent when process exits.
    # Makes sure any pending transactions are sent.
    at_exit { ElasticAPM.stop }
    ```
    **Create a config file**Create a config file config/elastic_apm.yml:
    ```ruby
    # config/elastic_apm.yml:

    # Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space
    # Defaults to the name of your Rack app's class.
    service_name: 'my-service'

    # Use if APM integration requires a token
    secret_token: ''

    # Set custom APM integration host and port (default: http://localhost:8200)
    server_url: 'http://localhost:8200'
    ```
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/ruby/supported-technologies)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/ruby/configuration)
  </tab-item>

  <tab-item title="RUM">
    **1. Enable Real User Monitoring (RUM)**RUM is disabled by default. Enable it by setting `Enable RUM` to `true`.**2. Set up the agent**Set up the agent with `<script>` tags or by using a bundler.*Synchronous / Blocking Pattern*Add a <script> tag to load the bundle and use the `elasticApm` global object to initialize the agent:
    ```html
    <script src="<YOUR_URL>/path/to/elastic-apm-rum.umd.min-<VERSION>.js" crossorigin></script>
    <script>
      elasticApm.init({
        serviceName: '<instrumented-app>',
        serverUrl: '<apm-server-url>',
      })
    </script>
    ```
    *Asynchronous / Non-Blocking Pattern*Loading the script asynchronously ensures the agent script will not block other resources on the page, however, it will still block browsers `onload` event.
    ```html
    <script>
      ;(function(d, s, c) {
        var j = d.createElement(s),
          t = d.getElementsByTagName(s)[0]

        j.src = '<YOUR_URL>/path/to/elastic-apm-rum.umd.min-<VERSION>.js'
        j.onload = function() {elasticApm.init(c)}
        t.parentNode.insertBefore(j, t)
      })(document, 'script', {serviceName: '<INSTRUMENTED_APP>', serverUrl: '<APM_SERVER_URL>'})
    </script>
    ```
    *Using Bundlers*Install the Real User Monitoring APM agent as a dependency to your application:
    ```bash
    npm install @elastic/apm-rum --save
    ```
    Configure the agent:
    ```js
    import { init as initApm } from '@elastic/apm-rum'

    const apm = initApm({

      // Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)
      serviceName: '',

      // Set custom APM integration host and port (default: http://localhost:8200)
      serverUrl: 'http://localhost:8200',

      // Set service version (required for sourcemap feature)
      serviceVersion: ''
    })
    ```
    **Learn more in the agent reference**
    - [Supported technologies](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/rum-js/supported-technologies)
    - [Advanced configuration](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3016/reference/apm/agents/rum-js/configuration)
  </tab-item>

  <tab-item title="OpenTelemetry">
    Elastic integrates with OpenTelemetry, allowing you to reuse your existing instrumentation to easily send observability data to the Elastic Stack.For more information on how to combine Elastic and OpenTelemetry, see [OpenTelemetry integration](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/opentelemetry).
  </tab-item>
</tab-set>


## Step 5: View your data

Once you have at least one APM agent sending data to APM Server, you can start visualizing your data in the [Kibana Applications UI](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/overviews).
![Applications UI with data](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/images/observability-kibana-apm-sample-data.png)


## Repositories for APT and YUM

We have repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
We use the PGP key [D88E42B4](https://pgp.mit.edu/pks/lookup?op=vindex&search=0xD27D666CD88E42B4), Elasticsearch Signing Key, with fingerprint
```
4609 5ACC 8548 582C 1A26 99A9 D27D 666C D88E 42B4
```

to sign all our packages. It is available from [[https://pgp.mit.edu](https://pgp.mit.edu)](https://pgp.mit.edu).

### APT

To add the apm-server repository for APT:
1. Download and install the Public Signing Key:
   ```shell
   wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
   ```
2. You may need to install the `apt-transport-https` package on Debian before proceeding:
   ```shell
   sudo apt-get install apt-transport-https
   ```
3. Save the repository definition to `/etc/apt/sources.list.d/elastic-9.0.0.list`:
   ```shell
   echo "deb https://artifacts.elastic.co/packages/9.0.0-prerelease/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-9.0.0-prerelease.list
   ```
   <warning>
   To add the Elastic repository, make sure that you use the `echo` method shown in the example. Do not use `add-apt-repository` because it will add a `deb-src` entry, but we do not provide a source package.If you have added the `deb-src` entry by mistake, you will see an error like the following:
   ```text
   Unable to find expected entry 'main/source/Sources' in Release file (Wrong sources.list entry or malformed file)
   ```
   </warning>
4. Run `apt-get update`, and the repository is ready for use. For example, you can install APM Server by running:
   ```shell
   sudo apt-get update && sudo apt-get install apm-server
   ```
5. To configure APM Server to start automatically during boot, run:
   ```shell
   sudo systemctl enable apm-server
   ```


### YUM

To add the apm-server repository for YUM:
1. Download and install the public signing key:
   ```shell
   sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
   ```
2. Create a file with a .repo extension (for example, elastic.repo) in your /etc/yum.repos.d/ directory and add the following lines:
   ```shell
   [elastic-9.0.0]
   name=Elastic repository for 9.0.0 packages
   baseurl=https://artifacts.elastic.co/packages/9.0.0/yum
   gpgcheck=1
   gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
   enabled=1
   autorefresh=1
   type=rpm-md
   ```
   Your repository is ready to use. For example, you can install APM Server by running:
   ```shell
   sudo yum install apm-server
   ```
3. To configure APM Server to start automatically during boot, run:
   ```shell
   sudo systemctl enable apm-server
   ```


## Run APM Server on Docker

Docker images for APM Server are available from the Elastic Docker registry. The base image is Red Hat Universal Base Images (UBI) or [Wolfi](https://github.com/wolfi-dev/) if you use hardened Docker images.
A list of all published Docker images and tags is available at [www.docker.elastic.co](https://www.docker.elastic.co).
These images are free to use under the Elastic license. They contain open source and free commercial features and access to paid commercial features. [Start a 30-day trial](https://www.elastic.co/elastic/docs-builder/docs/3016/deploy-manage/license/manage-your-license-in-self-managed-cluster) to try out all of the paid commercial features. See the [Subscriptions](https://www.elastic.co/subscriptions) page for information about Elastic license levels.

### Pull the image

Obtaining APM Server for Docker is as simple as issuing a `docker pull` command against the Elastic Docker registry and then, optionally, verifying the image.
1. Pull the Docker image:
   ```shell
   docker pull docker.elastic.co/apm/apm-server:9.0.0
   ```
   Alternately, you can use the hardened [Wolfi](https://wolfi.dev/) image:
   ```shell
   docker pull docker.elastic.co/apm/apm-server-wolfi:9.0.0
   ```
2. Verify the Docker image:
   ```shell
   wget https://artifacts.elastic.co/cosign.pub
   cosign verify --key cosign.pub docker.elastic.co/apm/apm-server:9.0.0
   ```
   The `cosign` command prints the check results and the signature payload in JSON format:
   ```shell
   Verification for docker.elastic.co/apm/apm-server:9.0.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
   ```


### Configure APM Server on Docker

The Docker image provides several methods for configuring APM Server. The conventional approach is to provide a configuration file via a volume mount, but it’s also possible to create a custom image with your configuration included.

#### Example configuration file

Download this example configuration file as a starting point:
```sh
curl -L -O https://raw.githubusercontent.com/elastic/apm-server/master/apm-server.docker.yml
```


#### Volume-mounted configuration

One way to configure APM Server on Docker is to provide `apm-server.docker.yml` via a volume mount. With `docker run`, the volume mount can be specified like this.
```sh
docker run -d \
  -p 8200:8200 \
  --name=apm-server \
  --user=apm-server \
  --volume="$(pwd)/apm-server.docker.yml:/usr/share/apm-server/apm-server.yml:ro" \
  docker.elastic.co/apm/apm-server:9.0.0 \
  --strict.perms=false -e \
  -E output.elasticsearch.hosts=["elasticsearch:9200"] <1> 
```


#### Customize your configuration

The `apm-server.docker.yml` downloaded earlier should be customized for your environment. See [Configure APM Server](https://www.elastic.co/elastic/docs-builder/docs/3016/solutions/observability/apm/apm-server/configure) for more details. Edit the configuration file and customize it to match your environment then re-deploy your APM Server container.

#### Custom image configuration

It’s possible to embed your APM Server configuration in a custom image. Here is an example Dockerfile to achieve this:
```dockerfile
FROM docker.elastic.co/apm/apm-server:9.0.0
COPY --chmod=0644 --chown=1000:1000 apm-server.yml /usr/share/apm-server/apm-server.yml
```


#### Modify the `nofile` ulimit in Docker containers

You can set the `nofile` ulimit from the command line using `--ulimit=soft:hard`. For details, refer to [Set ulimits in container (--ulimit)](https://docs.docker.com/reference/cli/docker/container/run/#ulimit) in the Docker documentation.
```sh
docker run -d \
  -p 8200:8200 \
  --name=apm-server \
  --user=apm-server \
  --volume="$(pwd)/apm-server.docker.yml:/usr/share/apm-server/apm-server.yml:ro" \
  docker.elastic.co/apm/apm-server:9.0.0 \
  --strict.perms=false -e \
  --ulimit=524287:524287 \
  -E output.elasticsearch.hosts=["elasticsearch:9200"] <1> 
```


## Modify the `nofile` ulimit

When running APM Server as a standalone binary, it inherits the `nofile` limit from the user running the process. On most systems, this limit is set to `1024`, which is too low for high-throughput scenarios or when using tail-based sampling.
To choose an appropriate limit, take the following into consideration:
- A limit of 1024 is typically sufficient for low-throughput use cases.
- There is no performance downside to not setting a limit.
- The main contributor to open files is the number of incoming connections.
- Tail-based sampling is file-based, and increases the number of open files proportionally to throughput and sampling policies.


### Set the limit for your user

To configure the limit for your user:
1. Determine which user runs the APM Server process:

```sh
whoami
```

1. Edit `/etc/security/limits.conf` with root privileges:

```sh
sudo nano /etc/security/limits.conf
```

Add the following lines to set soft and hard limits for your user:
```text
apm-server soft nofile 524287 
apm-server hard nofile 524287 
```


### Update the limit for a running process

To modify the `nofile` limit of a running APM Server process:
1. Get the process ID (PID):

```sh
pgrep -f apm-server
```

1. Apply the new limits:

```sh
prlimit --pid PID --nofile=524287:524287 
```