{"id":14971961,"url":"https://github.com/grafana/docker-otel-lgtm","last_synced_at":"2026-04-03T11:02:38.535Z","repository":{"id":196631678,"uuid":"696777593","full_name":"grafana/docker-otel-lgtm","owner":"grafana","description":"OpenTelemetry backend in a Docker image","archived":false,"fork":false,"pushed_at":"2025-05-12T00:45:48.000Z","size":1429,"stargazers_count":1047,"open_issues_count":18,"forks_count":108,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-12T01:31:08.634Z","etag":null,"topics":["grafana","opentelemetry","opetelemetry-collector","prometheus"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grafana.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-26T12:21:12.000Z","updated_at":"2025-05-10T08:01:35.000Z","dependencies_parsed_at":"2023-09-26T17:21:48.173Z","dependency_job_id":"c23d6ca3-d92b-4295-ae6a-bb6b85f0c0f0","html_url":"https://github.com/grafana/docker-otel-lgtm","commit_stats":{"total_commits":133,"total_committers":16,"mean_commits":8.3125,"dds":0.6390977443609023,"last_synced_commit":"3e46c9705c6d151eabda3cfed35cd1cb4e8d7c3c"},"previous_names":["grafana/docker-otel-lgtm"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fdocker-otel-lgtm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fdocker-otel-lgtm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fdocker-otel-lgtm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fdocker-otel-lgtm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grafana","download_url":"https://codeload.github.com/grafana/docker-otel-lgtm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grafana","opentelemetry","opetelemetry-collector","prometheus"],"created_at":"2024-09-24T13:46:07.727Z","updated_at":"2026-04-03T11:02:38.520Z","avatar_url":"https://github.com/grafana.png","language":"Shell","funding_links":[],"categories":["Shell","others"],"sub_categories":[],"readme":"# docker-otel-lgtm\n\n[![Docker latest][docker-latest]][docker-hub]\n[![Docker pulls][docker-pulls]][docker-hub]\n\nAn OpenTelemetry backend in a Docker image. It bundles the **OpenTelemetry Collector**,\n**Prometheus** (metrics), **Tempo** (traces), **Loki** (logs), **Pyroscope** (profiles),\nand **Grafana** into a single container — with optional **OBI** (eBPF auto-instrumentation).\n\n\u003c!-- markdownlint-disable-next-line MD013 --\u003e\n![Overview of telemetry flow: applications, optionally auto-instrumented with OBI for traces and metrics, send telemetry to the OpenTelemetry Collector, which routes metrics to Prometheus, traces to Tempo, logs to Loki, and profiles to Pyroscope, with all signals visualized in Grafana](img/overview.png) \u003c!-- editorconfig-checker-disable-line --\u003e\n\nThe `grafana/otel-lgtm` Docker image is an open source backend for OpenTelemetry\nthat's intended for development, demo, and testing environments.\n\n\u003e [!IMPORTANT]\n\u003e If you are looking for a **production-ready**, out-of-the box solution to monitor applications\n\u003e and minimize MTTR (mean time to resolution) with OpenTelemetry and Prometheus,\n\u003e you should try [Grafana Cloud Application Observability][app-o11y].\n\n## Documentation\n\n- Blog posts:\n  - [_An OpenTelemetry backend in a Docker image: Introducing grafana/otel-lgtm_][otel-lgtm]\n  - [_Observability in under 5 seconds: Reflecting on a year of grafana/otel-lgtm_][otel-lgtm-one-year]\n\n## Get the Docker image\n\nThe Docker image is available on [Docker Hub][docker-hub].\n\n```sh\ndocker pull grafana/otel-lgtm:latest\n```\n\n## Run the Docker image\n\n### Linux/Unix\n\n```sh\n./run-lgtm.sh\n```\n\n### Windows (PowerShell)\n\n```powershell\n./run-lgtm\n```\n\n### Linux/Unix Using mise\n\nYou can also use [mise][mise] to run the Docker image:\n\n```sh\nmise run lgtm\n```\n\n## Configuration\n\n### Enable logging\n\nYou can enable logging in the .env file for troubleshooting:\n\n| Environment Variable     | Enables Logging in:     |\n|--------------------------|-------------------------|\n| `ENABLE_LOGS_GRAFANA`    | Grafana                 |\n| `ENABLE_LOGS_LOKI`       | Loki                    |\n| `ENABLE_LOGS_PROMETHEUS` | Prometheus              |\n| `ENABLE_LOGS_TEMPO`      | Tempo                   |\n| `ENABLE_LOGS_PYROSCOPE`  | Pyroscope               |\n| `ENABLE_LOGS_OTELCOL`    | OpenTelemetry Collector |\n| `ENABLE_LOGS_OBI`        | OBI                     |\n| `ENABLE_LOGS_ALL`        | All of the above        |\n\nThis has nothing to do with any application logs, which are collected by OpenTelemetry.\n\n### Enable OBI (eBPF auto-instrumentation)\n\n[OpenTelemetry eBPF Instrumentation (OBI)][obi] uses eBPF to automatically generate traces and\n[RED][red-method] metrics for HTTP/gRPC services — with zero code changes.\n\nTo enable OBI, add `ENABLE_OBI=true` to your `.env` file or pass it as an\nenvironment variable:\n\n```sh\nENABLE_OBI=true ./run-lgtm.sh\n\n# Using mise\nmise run lgtm-obi\n```\n\n**Requirements:** Linux kernel 5.8+ with BTF support. The `run-lgtm.sh` and\n`run-lgtm.ps1` scripts automatically add the required `--pid=host` and\n`--privileged` Docker flags when OBI is enabled. If you run `docker run`\ndirectly, you must add these flags manually.\n\n\u003e [!NOTE]\n\u003e The `--pid=host` flag shares the host's PID namespace with the container,\n\u003e so OBI can discover and instrument processes running on the host — not just\n\u003e inside the container. For example, `OBI_TARGET=java` will instrument Java\n\u003e processes running on the host as well.\n\n#### Target specific applications\n\nBy default, OBI discovers services on common ports (80, 443, 8080-8099,\n3000-3999, 5000-5999). You can target specific applications:\n\n```sh\n# Monitor all Java processes\nENABLE_OBI=true OBI_TARGET=java ./run-lgtm.sh\n\n# Monitor all Python processes\nENABLE_OBI=true OBI_TARGET=python ./run-lgtm.sh\n\n# Monitor a specific executable by name\nENABLE_OBI=true OBI_TARGET=myapp ./run-lgtm.sh\n\n# Monitor specific ports\nENABLE_OBI=true OTEL_EBPF_OPEN_PORT=8080,9090 ./run-lgtm.sh\n```\n\n\u003c!-- editorconfig-checker-disable --\u003e\n\n| Variable                    | Purpose                                                                                         |\n|-----------------------------|-------------------------------------------------------------------------------------------------|\n| `OBI_TARGET`                | Friendly language target: `java`, `python`, `node`, `dotnet`, `ruby`, or any regular expression |\n| `OTEL_EBPF_OPEN_PORT`       | Override ports to monitor (native OBI environment variable)                                     |\n| `OTEL_EBPF_AUTO_TARGET_EXE` | Executable name pattern (native OBI environment variable, set automatically by `OBI_TARGET`)    |\n\n\u003c!-- editorconfig-checker-enable --\u003e\n\n### Send data to vendors\n\nIn addition to the built-in observability tools, you can also send data to vendors.\nThat way, you can easily try and switch between different backends.\n\nIf the [`OTEL_EXPORTER_OTLP_ENDPOINT`][otlp-endpoint]\nvariable is set, the OpenTelemetry Collector will send data (logs, metrics, and traces)\nto the specified endpoint using \"OTLP/HTTP\".\n\nYou can also configure per-signal endpoints:\n\n* `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`\n* `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`\n* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`\n\nIf both global and per-signal endpoints are set, per-signal values take precedence.\nEndpoints must include the scheme (for example, `http://jaeger:4318`).\n\nIn addition, you can provide [`OTEL_EXPORTER_OTLP_HEADERS`][otlp-headers],\nfor example, to authenticate with the backend.\n\n#### Send data to Grafana Cloud\n\nYou can find the values for the environment variables in your [Grafana Cloud account][otel-setup].\n\n### Persist data across container instantiation\n\nThe various components in the repository are configured to write their data to the `/data`\ndirectory. If you need to persist data across containers being created and destroyed,\nyou can mount a volume to the `/data` directory. Note that this image is intended for\ndevelopment, demo, and testing environments and persisting data to an external volume\ndoesn't change that. However, this feature could be useful in certain cases for\nsome users even in testing situations.\n\n### Customize backend configuration\n\nEach backend supports a `*_EXTRA_ARGS` environment variable for passing additional\nCLI flags without modifying any files:\n\n| Backend                 | Env var                 | Example                              |\n|-------------------------|-------------------------|--------------------------------------|\n| Prometheus              | `PROMETHEUS_EXTRA_ARGS` | `--storage.tsdb.retention.time=90d`  |\n| Loki                    | `LOKI_EXTRA_ARGS`       | `--limits.retention-period=90d`      |\n| Tempo                   | `TEMPO_EXTRA_ARGS`      |                                      |\n| Pyroscope               | `PYROSCOPE_EXTRA_ARGS`  |                                      |\n| OpenTelemetry Collector | `OTELCOL_EXTRA_ARGS`    |                                      |\n\nFor example, to set a 90-day retention period for Prometheus:\n\n```sh\ndocker run -e PROMETHEUS_EXTRA_ARGS=\"--storage.tsdb.retention.time=90d\" grafana/otel-lgtm\n```\n\n\u003e [!NOTE]\n\u003e The value is split on whitespace into separate arguments. For options that\n\u003e require values with spaces, mount a custom configuration file instead (see below).\n\nFor deeper customization, you can mount custom configuration files into the container:\n\n| Backend                 | Config file path                            |\n|-------------------------|---------------------------------------------|\n| Prometheus              | `/otel-lgtm/prometheus.yaml`                |\n| Loki                    | `/otel-lgtm/loki-config.yaml`               |\n| Tempo                   | `/otel-lgtm/tempo-config.yaml`              |\n| Pyroscope               | `/otel-lgtm/pyroscope-config.yaml`          |\n| OpenTelemetry Collector | `/otel-lgtm/otelcol-config.yaml`            |\n\n```sh\ndocker run -v ./my-loki-config.yaml:/otel-lgtm/loki-config.yaml:ro grafana/otel-lgtm\n```\n\nGrafana is configured via `GF_*` environment variables — see the\n[Grafana documentation][grafana-env-overrides] for details.\n\n### Pre-install Grafana plugins\n\nYou can pre-install Grafana plugins by adding them to the `GF_PLUGINS_PREINSTALL` environment variable.\nSee the [Grafana documentation][grafana-preinstall-plugins] for more information.\n\n### Add custom dashboards\n\nYou can add custom Grafana dashboards by mounting them into the container with a provisioning configuration.\n\nCreate a dashboard JSON file and a provisioning YAML file:\n\n**dashboards-provisioning.yaml:**\n\n```yaml\napiVersion: 1\n\nproviders:\n  - name: \"Custom Dashboards\"\n    type: file\n    options:\n      path: /otel-lgtm/grafana/conf/provisioning/dashboards/custom\n      foldersFromFilesStructure: false\n```\n\nMount both files in your `docker-compose.yml`:\n\n```yaml\nservices:\n  lgtm:\n    image: grafana/otel-lgtm\n    volumes:\n      - ./custom-dashboard.json:/otel-lgtm/grafana/conf/provisioning/dashboards/custom/custom-dashboard.json:ro\n      - ./dashboards-provisioning.yaml:/otel-lgtm/grafana/conf/provisioning/dashboards/custom.yaml:ro\n```\n\nSee the [Java example][java-example] for a complete working example.\n\nTo set a custom dashboard as the home dashboard, add the `GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH`\nenvironment variable:\n\n```yaml\nservices:\n  lgtm:\n    image: grafana/otel-lgtm\n    environment:\n      GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /otel-lgtm/grafana/conf/provisioning/dashboards/custom/custom-dashboard.json\n```\n\n## Run lgtm in Kubernetes\n\n```sh\n# Create k8s resources\nkubectl apply -f k8s/lgtm.yaml\n\n# Configure port forwarding\nkubectl port-forward service/lgtm 3000:3000 4040:4040 4317:4317 4318:4318 9090:9090\n\n# Using mise\nmise k8s-apply\nmise k8s-port-forward\n```\n\n## Send OpenTelemetry Data\n\nThere's no need to configure anything: the Docker image works with OpenTelemetry's defaults.\n\n```sh\n# Not needed, but these are the defaults in OpenTelemetry\nexport OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf\nexport OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318\n```\n\n## View Grafana\n\nNavigate to \u003chttp://127.0.0.1:3000\u003e and log in with the default built-in user `admin` and password `admin`.\n\n## Build the Docker image from scratch\n\n```sh\ncd docker/\ndocker build . -t grafana/otel-lgtm\n\n# Using mise\nmise build-lgtm\n```\n\n\u003e [!TIP]\n\u003e If you built your image locally, you can use the `run-lgtm` scripts with\n\u003e the parameters `latest true` to run your local image (or `mise run local-lgtm`).\n\n## Build and run the example app\n\n\u003e [!TIP]\n\u003e You can run everything together using [mise][mise] with `mise run all`.\n\n### Run\n\nRun the example REST service:\n\n#### Unix/Linux\n\n```sh\n./run-example.sh\n```\n\n#### Windows (PowerShell)\n\n```powershell\n./run-example\n```\n\n#### Unix/Linux Using mise\n\n```sh\nmise run example\n```\n\n### Generate traffic\n\n#### Unix/Linux\n\n```sh\n./generate-traffic.sh\n```\n\n#### Windows (PowerShell)\n\n```powershell\n./generate-traffic\n```\n\n#### Unix/Linux Using mise\n\n```sh\nmise run generate-traffic\n```\n\n\u003e [!TIP]\n\u003e You can use [OTel Checker][otel-checker] to check if the instrumentation is correct.\n\n## Run example apps in different languages\n\nThe example apps are in the [`examples/`][examples] directory.\nEach example has a `run.sh` or `run.cmd` script to start the app.\n\nEvery example implements a rolldice service, which returns a random number between 1 and 6.\n\nEach example uses a different application port\n(to be able to run all applications at the same time).\n\n| Example | Service URL                           |\n|---------|---------------------------------------|\n| Java    | `curl http://127.0.0.1:8080/rolldice` |\n| Go      | `curl http://127.0.0.1:8081/rolldice` |\n| Python  | `curl http://127.0.0.1:8082/rolldice` |\n| .NET    | `curl http://127.0.0.1:8083/rolldice` |\n| Node.js | `curl http://127.0.0.1:8084/rolldice` |\n\n## Verifying Container Image Signatures\n\nThe container images that are published are signed using [cosign][cosign]. You\ncan verify the signatures using a command similar to the following example:\n\n```sh\nVERSION=\"0.11.16\"\nIMAGE=\"docker.io/grafana/otel-lgtm:${VERSION}\"\nIDENTITY=\"https://github.com/grafana/docker-otel-lgtm/.github/workflows/release.yml@refs/tags/v${VERSION}\"\nOIDC_ISSUER=\"https://token.actions.githubusercontent.com\"\n\ncosign verify ${IMAGE} --certificate-identity ${IDENTITY} --certificate-oidc-issuer ${OIDC_ISSUER}\n```\n\nIt is also possible to verify the signatures of images from our continuous integration\nthat are published to the [GitHub Container Registry][ghcr]. For example for the `main` branch:\n\n```sh\nVERSION=\"main\"\nIMAGE=\"ghcr.io/grafana/docker-otel-lgtm:${VERSION}\"\nWORKFLOW=\"ghcr-image-build-and-publish.yml\"\nIDENTITY=\"https://github.com/grafana/docker-otel-lgtm/.github/workflows/${WORKFLOW}@refs/heads/${VERSION}\"\nOIDC_ISSUER=\"https://token.actions.githubusercontent.com\"\n\ncosign verify ${IMAGE} --certificate-identity ${IDENTITY} --certificate-oidc-issuer ${OIDC_ISSUER}\n```\n\n## Related Work\n\n- [Metrics, Logs, Traces and Profiles in Grafana][mltp]\n- [OpenTelemetry Acceptance Tests (OATs)][oats]\n\n\u003c!-- editorconfig-checker-disable --\u003e\n\u003c!-- markdownlint-disable MD013 --\u003e\n\n[app-o11y]: https://grafana.com/products/cloud/application-observability/\n[obi]: https://opentelemetry.io/docs/zero-code/obi/ \"OpenTelemetry eBPF Instrumentation\"\n[cosign]: https://github.com/sigstore/cosign \"Cosign on GitHub\"\n[docker-hub]: https://hub.docker.com/r/grafana/otel-lgtm\n[docker-latest]: https://img.shields.io/docker/v/grafana/otel-lgtm?logo=docker\u0026label=latest\u0026color=blue\n[docker-pulls]: https://img.shields.io/docker/pulls/grafana/otel-lgtm?logo=docker\u0026label=pulls\n[examples]: examples/\n[ghcr]: https://github.com/grafana/docker-otel-lgtm/pkgs/container/docker-otel-lgtm\n[grafana-env-overrides]: https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#override-configuration-with-environment-variables\n[grafana-preinstall-plugins]: https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/#install-plugins-in-the-docker-container\n[java-example]: examples/java/\n[mise]: https://github.com/jdx/mise\n[mltp]: https://github.com/grafana/intro-to-mltp\n[otel-checker]: https://github.com/grafana/otel-checker/\n[otel-lgtm]: https://grafana.com/blog/2024/03/13/an-opentelemetry-backend-in-a-docker-image-introducing-grafana-otel-lgtm\n[otel-lgtm-one-year]: https://grafana.com/blog/2025/07/08/observability-in-under-5-seconds-reflecting-on-a-year-of-grafana-otel-lgtm/\n[otel-setup]: https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/#manual-opentelemetry-setup-for-advanced-users\n[otlp-endpoint]: https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_endpoint\n[otlp-headers]: https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_headers\n[oats]: https://github.com/grafana/oats\n[red-method]: https://grafana.com/blog/the-red-method-how-to-instrument-your-services/ \"The RED Method\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana%2Fdocker-otel-lgtm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrafana%2Fdocker-otel-lgtm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana%2Fdocker-otel-lgtm/lists"}