VictoriaLogs on Ubuntu 24.04 on Azure User Guide
Overview
VictoriaLogs is a user friendly, cost efficient database for logs from VictoriaMetrics. It ingests structured and plaintext logs over a wide range of protocols (its own JSON stream, Loki push, Elasticsearch bulk, OpenTelemetry and syslog), stores them compactly on disk, and lets you search and analyse them with the LogsQL query language through a built in web UI called vmui and simple HTTP APIs. It is a lightweight single binary alternative to heavier log stacks for self managed log management in your own Azure VNet.
The cloudimg image installs the pinned VictoriaLogs 1.52.0 single Go binary running under systemd, then locks it down for a marketplace appliance. VictoriaLogs has no built in authentication, so it is bound to loopback 127.0.0.1:9428 where it is never exposed directly, and an nginx reverse proxy on port 80 adds a per-VM HTTP Basic Auth gate (user admin, unique password generated on first boot) in front of the web UI and every ingestion and query API. An unauthenticated static /healthz endpoint is provided for load balancer probes. All stored log data lives on a dedicated Azure data disk mounted at /var/lib/victoria-logs. Backed by 24/7 cloudimg support.
What is included:
- VictoriaLogs 1.52.0 installed as a single Go binary and running as the
victorialogssystemd service - The vmui web interface plus the ingestion and query APIs on
:80, fronted by nginx with the binary bound to loopback only - Per-VM HTTP Basic Auth (user
admin) protecting the UI and every API, with a unique password generated on first boot and no default login - An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - A dedicated Azure data disk mounted at
/var/lib/victoria-logsholding all log data, with a 30 day default retention you can tune - A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
VictoriaLogs and VictoriaMetrics are trademarks of their respective owners. This image is provided by cloudimg and is not affiliated with, endorsed by, or sponsored by VictoriaMetrics.
Prerequisites
- An Azure subscription and permission to create a VM
- An SSH key pair (
ssh-keygen -t ed25519) - Inbound access to port 22 (SSH) and port 80 (the web UI and APIs) on the VM, and optionally 443 if you add TLS
- A recommended size of
Standard_B2sor larger
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for VictoriaLogs by cloudimg, and select Create. On Basics 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) and HTTP (80). Review the dedicated data disk on the Disks tab, then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name victorialogs \
--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 victorialogs --port 80 --priority 1010
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active victorialogs.service nginx.service
Both report active. VictoriaLogs serves the vmui web interface and its HTTP APIs on the loopback address 127.0.0.1:9428; nginx fronts it on port 80 and adds the per-VM HTTP Basic Auth gate. All log data lives on the dedicated Azure data disk mounted at /var/lib/victoria-logs.

Step 5 - Retrieve your web UI password
nginx protects the VictoriaLogs UI and APIs with HTTP Basic Auth. The username is admin and a unique password is generated on the first boot of your VM and written to a root-only file:
sudo cat /root/victorialogs-credentials.txt
This file contains victorialogs.username, victorialogs.password and the victorialogs.url to open in a browser. The password is stored on disk only as a bcrypt hash in /etc/nginx/.victorialogs.htpasswd, so no plaintext password ships in the image. Store the password somewhere safe.

Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes:
curl -s http://localhost/healthz
It returns ok. This endpoint never requires authentication, so it is safe for an Azure Load Balancer health probe. The VictoriaLogs engine's own /health endpoint sits behind the Basic Auth gate.
Step 7 - Confirm the authentication gate
Because a password is set on first boot, an unauthenticated request to the UI returns HTTP 401, so nobody reaches VictoriaLogs without the password. The following reads the per-VM password from the credentials file and proves the round-trip: unauthenticated is rejected, a wrong password is rejected, the correct password authenticates, and an authenticated call to the engine health endpoint returns OK:
PW=$(sudo sed -n 's/^victorialogs.password=//p' /root/victorialogs-credentials.txt)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/select/vmui/)"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw http://127.0.0.1/select/vmui/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/select/vmui/)"
echo "health : $(curl -s -u admin:$PW http://127.0.0.1/health)"
It prints unauth : 401, wrongpw : 401, authed : 200, then health : OK. Every endpoint except the static /healthz is only reachable with the per-VM password because VictoriaLogs itself is bound to loopback and nginx is the only way in.

Step 8 - Ship a log line and query it back
Send logs to VictoriaLogs over the JSON stream ingestion API, then read them back with a LogsQL query, both behind the same Basic Auth. The following ships one JSON log line to /insert/jsonline and queries it back from /select/logsql/query:
PW=$(sudo sed -n 's/^victorialogs.password=//p' /root/victorialogs-credentials.txt)
MARK="demo-$(date +%s)"
curl -s -o /dev/null -w 'ingest -> HTTP %{http_code}\n' -u admin:$PW \
-H 'Content-Type: application/stream+json' \
--data-binary "{\"_msg\":\"$MARK order shipped\",\"_time\":\"0\",\"level\":\"INFO\",\"app\":\"orders\"}" \
'http://127.0.0.1/insert/jsonline?_stream_fields=app,level&_time_field=_time&_msg_field=_msg'
sleep 2
curl -s -u admin:$PW --data-urlencode "query=$MARK" http://127.0.0.1/select/logsql/query
The ingest call returns HTTP 200, then the query prints the stored log line back as JSON with its _msg, _time, level and app fields. Point any log shipper (Fluent Bit, Vector, Promtail, the OpenTelemetry collector, rsyslog and more) at this VM using the matching /insert/* endpoint and the same admin credentials to stream real logs in.

Step 9 - Sign in and explore your logs in vmui
Open victorialogs.url from your credentials file (http://<vm-public-ip>/select/vmui/) in a browser and sign in as admin with the per-VM password. The Query view is the log explorer: enter a LogsQL query (start with * for everything), pick a time range, and click Execute. The hits histogram at the top shows log volume over time, the Stream fields panel on the left summarises the fields present, and the results appear below in the Group view, colour coded by level.

Step 10 - Filter with LogsQL
LogsQL is VictoriaLogs' query language. Filter by any field with field:value syntax and combine terms with AND, OR and NOT. For example, level:ERROR OR level:WARN narrows the results and the hits histogram to only warning and error entries, and the Stream fields panel updates to reflect the matching subset.

Step 11 - Switch between Table and JSON views
Above the results, switch the display between Group, Table and JSON. Table presents each log as a row with the _time, _msg and stream fields (app, host, level) as sortable columns, ideal for scanning structured logs.

JSON shows each log entry as its full structured record, including the _stream, _stream_id and every ingested field, which is useful when you need the exact stored representation.

Maintenance
Adjust retention. Logs older than the retention period are deleted automatically. The image ships a 30 day default (-retentionPeriod=30d). To change it, override the systemd unit and restart:
sudo systemctl edit victorialogs
# add, e.g.:
# [Service]
# ExecStart=
# ExecStart=/usr/local/bin/victoria-logs-prod -httpListenAddr=127.0.0.1:9428 -storageDataPath=/var/lib/victoria-logs -retentionPeriod=90d
sudo systemctl restart victorialogs
Change the web UI password. Regenerate the bcrypt Basic Auth entry for admin and reload nginx:
printf 'new-strong-password' | sudo htpasswd -iB /etc/nginx/.victorialogs.htpasswd admin
sudo systemctl reload nginx
Add a domain and TLS. For production, point a DNS name at the VM and terminate HTTPS at nginx with a certificate from Let's Encrypt (certbot --nginx) so the UI and APIs are served over https://.
Service management.
systemctl status victorialogs nginx --no-pager
VictoriaLogs writes its logs to the journal; view them with journalctl -u victorialogs.
Support
This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating VictoriaLogs on Azure, contact the cloudimg team through the Azure Marketplace listing. For the LogsQL language and the ingestion protocols, see the VictoriaLogs documentation.