Uptrace
Overview
Uptrace is an open-source application performance monitoring and observability platform built around OpenTelemetry. Your applications and agents send traces, metrics and logs to its OTLP endpoints. Uptrace stores them in a columnar backend, so you can search spans, chart metrics and correlate a slow trace with the logs and metrics around it, all from one web interface.
This image runs the full stack behind nginx over HTTPS. The Uptrace server is published on the loopback interface only, and nginx terminates TLS in front of it.
What you get:
- Uptrace
v2.0.3from the official pinned container imageuptrace/uptrace:2.0.3, baked into the image and published on loopback127.0.0.1:8080 - Its backing stores, all pinned and baked in: ClickHouse
26.3(telemetry store, memory-capped to fit a 4 GiB VM), PostgreSQL17(metadata store) and Redis7(query cache), on a private container network - nginx terminating TLS on
:443in front of Uptrace (UI and OTLP HTTP), with:80redirecting to HTTPS, and OTLP gRPC on:4317 - A per-VM administrator account, per-VM database passwords, a per-VM OTLP ingest token and a per-VM signing secret, all generated on first boot. No default or shared credential ships in the image, and the upstream default
admin@uptrace.locallogin never exists docker.service,uptrace-firstboot.service,uptrace.serviceandnginx.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
- Uptrace is distributed under the AGPL-3.0 open-source license
Secure by default: per-VM credentials
This image ships with no default or shared secret: no databases, no user accounts, no ingest token and no signing secret ship in the image. On first boot, a one-shot service resolves your public URL and regenerates a per-VM TLS certificate. It mints a unique ClickHouse password, PostgreSQL password, administrator password, OTLP project token and service signing secret, and renders them into the configuration before anything is reachable.
The Uptrace stack is held back until that has happened, so a fresh VM is never reachable with a well-known default login. Retrieve the credentials over SSH, and change the password after your first login.
Prerequisites
Before you deploy, you need:
- An active Azure subscription, an SSH key pair, and a VNet and subnet in the target region.
- A Standard_B2s VM (2 vCPU / 4 GiB RAM) as a starting point. The full stack idles at roughly 1.2 GiB with ClickHouse memory-capped. Scale up for heavier ingest volumes.
- NSG inbound rules that allow
22/tcpfrom your management network,80/tcpand443/tcpfrom wherever you browse the UI and send OTLP-over-HTTP, and4317/tcpfrom wherever your applications send OTLP-over-gRPC (:80only redirects to:443).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Uptrace by SecureAnyCloud, and select Create. On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22), HTTP (80) and HTTPS (443). Then click Review + create and Create. If you will send OTLP over gRPC, open 4317/tcp afterwards.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name uptrace \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name uptrace --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name uptrace --port 443 --priority 1020
az vm open-port --resource-group <your-rg> --name uptrace --port 4317 --priority 1030Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>The message of the day shows your VM's Uptrace URL, administrator email and OTLP endpoints.
Step 4 - Confirm the services are running
Uptrace runs as systemd units: the Docker engine, the first-boot provisioner, the compose stack and nginx:
systemctl is-active docker.service uptrace.service nginx.serviceactive active activeDocker compose manages four containers: Uptrace and its ClickHouse, PostgreSQL and Redis backends. Uptrace is published only on the loopback interface, and the databases are on a private network with no host ports:
cd /opt/uptrace-appliance && sudo docker compose ps --format 'table {{.Service}}\t{{.Status}}'SERVICE STATUS clickhouse Up (healthy) postgres Up (healthy) redis Up (healthy) uptrace Upnginx is the only service bound to public web ports (:80 and :443). The Uptrace UI is on loopback, and OTLP gRPC is on :4317:
sudo ss -tln | grep -E ':(80|443|4317|8080) 'LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* LISTEN 0 4096 0.0.0.0:4317 0.0.0.0:* LISTEN 0 511 0.0.0.0:443 0.0.0.0:* LISTEN 0 511 0.0.0.0:80 0.0.0.0:*The web UI is served over HTTPS, and plain HTTP redirects to it:
curl -sk -o /dev/null -w 'https:// -> %{http_code}\n' https://127.0.0.1/
curl -s -o /dev/null -w 'http:// -> %{http_code}\n' http://127.0.0.1/https:// -> 200 http:// -> 301Step 5 - Read the per-VM credentials
On first boot, the VM writes a root-only file with your Uptrace URL, the administrator email, the OTLP ingest token and the OTLP endpoints:
sudo grep -E '^UPTRACE_URL=|^UPTRACE_ADMIN_EMAIL=|^UPTRACE_OTLP_GRPC=' /root/uptrace-credentials.txtUPTRACE_URL=https://<vm-public-ip> UPTRACE_ADMIN_EMAIL=admin@sac.local UPTRACE_OTLP_GRPC=<vm-public-ip>:4317The UPTRACE_ADMIN_PASSWORD and UPTRACE_OTLP_TOKEN lines in that file hold your unique password and ingest token. Only the per-VM credential authenticates. A wrong password and the upstream default admin@uptrace.local / admin are both rejected:
E=$(sudo grep '^UPTRACE_ADMIN_EMAIL=' /root/uptrace-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^UPTRACE_ADMIN_PASSWORD=' /root/uptrace-credentials.txt | cut -d= -f2-) L() { curl -sk -o /dev/null -w "$1 -> HTTP %{http_code}\n" -X POST https://127.0.0.1/internal/v1/users/login \
-H 'Content-Type: application/json' --data "$2"; } L 'per-VM password' "{\"email\":\"$E\",\"password\":\"$P\"}" L 'wrong password ' "{\"email\":\"$E\",\"password\":\"wrong-nope\"}" L 'upstream default' '{"email":"admin@uptrace.local","password":"admin"}'per-VM password -> HTTP 200 wrong password -> HTTP 400 upstream default -> HTTP 400Step 6 - First login
Open Uptrace in your browser. Accept the self-signed certificate warning, or install a trusted certificate first (see Enabling a trusted TLS certificate):
https://<vm-public-ip>/Enter the administrator email (admin@sac.local) and the UPTRACE_ADMIN_PASSWORD from Step 5, then sign in. Immediately after your first sign-in, change your password from your profile settings.
Step 7 - Send telemetry to Uptrace
Uptrace ingests OpenTelemetry data over OTLP: gRPC on :4317 and HTTP on :443 (/v1/traces, /v1/metrics, /v1/logs). Every request is authenticated by your project's DSN, which embeds the per-VM ingest token. The DSN is written to your credentials file:
sudo grep '^UPTRACE_DSN=' /root/uptrace-credentials.txtUPTRACE_DSN=https://<uptrace-otlp-token>@<vm-public-ip>?grpc=4317Verify the pipeline end to end from the VM itself. Send a test span over OTLP-HTTP with your token and a current timestamp, and Uptrace accepts it (HTTP 200):
T=$(sudo grep '^UPTRACE_OTLP_TOKEN=' /root/uptrace-credentials.txt | cut -d= -f2-)
NOW=$(date +%s)000000000 curl -sk -o /dev/null -w 'OTLP ingest -> HTTP %{http_code}\n' https://127.0.0.1/v1/traces \
-H 'Content-Type: application/json' \
-H "uptrace-dsn: https://$T@127.0.0.1?grpc=4317" \
-d "{\"resourceSpans\":[{\"resource\":{\"attributes\":[{\"key\":\"service.name\",\"value\":{\"stringValue\":\"demo\"}}]},\"scopeSpans\":[{\"spans\":[{\"traceId\":\"c0ffee00038103d269b633813f0000aa\",\"spanId\":\"dec0de7ec3c100aa\",\"name\":\"demo-span\",\"kind\":2,\"startTimeUnixNano\":\"$NOW\",\"endTimeUnixNano\":\"$NOW\"}]}]}]}"OTLP ingest -> HTTP 200An OTLP request with a bad token is rejected (HTTP 403), so telemetry ingest is authenticated:
curl -sk -o /dev/null -w 'bad token -> HTTP %{http_code}\n' https://127.0.0.1/v1/traces \
-H 'Content-Type: application/json' \
-H 'uptrace-dsn: https://deadbeefdeadbeef@127.0.0.1?grpc=4317' \
-d '{"resourceSpans":[{"resource":{"attributes":[]},"scopeSpans":[{"spans":[{"traceId":"c0ffee00038103d269b633813f0000bb","spanId":"dec0de7ec3c100bb","name":"x","kind":2,"startTimeUnixNano":"1","endTimeUnixNano":"1"}]}]}]}'bad token -> HTTP 403To send data from your own applications, point any OpenTelemetry SDK or the OpenTelemetry Collector at the DSN above. For example, use the OTLP exporter environment variables:
OTEL_EXPORTER_OTLP_ENDPOINT=https://<vm-public-ip>:4317 OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=https://<uptrace-otlp-token>@<vm-public-ip>?grpc=4317 OTEL_EXPORTER_OTLP_PROTOCOL=grpcUse current timestamps in your telemetry. Uptrace applies retention to stored data, so spans stamped far in the past are dropped.
Exploring traces and metrics
Once telemetry is flowing, the Traces & Logs view lists incoming spans with their service, operation, duration and status. You can filter and group them with the Uptrace query language:
Select a trace to open the full span tree. You can see where time went across services and drill into the attributes of an individual span:
Use the Metrics explorer to chart any metric you have ingested and to build dashboards and alerts alongside your traces:
Step 8 - The official pinned container images
Uptrace and its backends run from official upstream container images, each pinned to an exact version and baked into the VM image (no runtime pull):
cd /opt/uptrace-appliance && sudo docker compose imagesCONTAINER REPOSITORY TAG PLATFORM IMAGE ID SIZE uptrace-clickhouse-1 clickhouse/clickhouse-server 26.3 linux/amd64 2ef11bbe2e44 266MB uptrace-postgres-1 postgres 17-alpine linux/amd64 742f40ea20b9 117MB uptrace-redis-1 redis 7-alpine linux/amd64 e7723ff73d96 16.3MB uptrace-uptrace-1 uptrace/uptrace 2.0.3 linux/amd64 5e42ea5f3bb9 57.1MBAdding projects and rotating the ingest token
Uptrace groups telemetry into projects, each with its own ingest token. The image ships one project ("Project1") with your per-VM token. To add projects, change token values or add users, edit the seed data in /opt/uptrace-appliance/config.yml (the seed_data: block). Then apply the change with cd /opt/uptrace-appliance && sudo docker compose restart uptrace. Administrators can also manage users from the UI.
Security updates
The image is patched at build time, including Ubuntu phased updates, and unattended-upgrades stays enabled, so later security patches reach your VM. No packages should be held back:
apt-mark showholdsystemd units manage the docker and nginx packages. The applications themselves are the pinned container images described above.
Your data
Uptrace stores telemetry in the ClickHouse volume and metadata in the PostgreSQL volume, both docker-managed on the VM's OS disk:
sudo docker volume ls --filter name=uptrace_To back up your telemetry, snapshot the OS disk of the VM in Azure. For a finer-grained schedule, use ClickHouse and PostgreSQL backup tooling.
Enabling a trusted TLS certificate
The image ships a per-VM self-signed certificate so HTTPS works out of the box. Browsers warn until you install a trusted certificate. To install one, point a DNS A record at the public IP of the VM and make sure 443/tcp is open in the NSG. Then install certbot and let it manage the nginx certificate. Replace the example values with your own domain and email:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com -m you@example.com --agree-toscertbot configures the HTTPS server block and sets up automatic renewal. After it completes, set site.url in /opt/uptrace-appliance/config.yml to https://your-domain.example.com and run cd /opt/uptrace-appliance && sudo docker compose restart uptrace. Uptrace is then available at your domain with a trusted certificate.
Upgrading Uptrace
Uptrace runs from pinned container images. To upgrade, edit the image tag in /opt/uptrace-appliance/docker-compose.yml. Then run cd /opt/uptrace-appliance && sudo docker compose pull uptrace && sudo docker compose up -d. The database schema migrates automatically on start. Always snapshot the OS disk first. SecureAnyCloud support can assist with planning and performing upgrades.
Support
This image is backed by 24/7 SecureAnyCloud support covering deployment, upgrades, OpenTelemetry integration, TLS termination and user administration. Contact us by email and chat.
Uptrace is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Uptrace on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com