Observability Azure

Logdy on Ubuntu 24.04 on Azure User Guide

| Product: Logdy on Ubuntu 24.04 LTS on Azure

Overview

Logdy is a self hosted, web based real time log viewer and tailer. It follows a log source, a file, a program's standard output, or a socket, and serves a clean browser interface that streams every line live, with sortable columns, faceted filters and search so you can slice a noisy log down to exactly the events you care about. Structured JSON logs are parsed into real columns automatically, so tailing a file in a terminal becomes a fast, visual, shareable experience. It is a single Go binary that holds logs in an in memory buffer, so it stays lightweight, starts instantly and needs no database or external services.

The cloudimg image installs Logdy 0.17.1 and puts it behind an nginx reverse proxy that binds Logdy to loopback. The appliance is secure by default: the entire interface, including the WebSocket that streams the log data, is protected by HTTP Basic authentication, and only a static health endpoint is left open for liveness checks. There is no default login. On first boot logdy-firstboot.service generates a per VM password, stores only its bcrypt hash for nginx, and writes the plaintext once to a root only file at /root/logdy-info.txt. Nothing is baked into the image.

To show the interface working on first boot, the image follows a small demo log: a generator appends structured JSON lines every couple of seconds so the columns, facets and search are populated the moment you log in. This is demo data only, and Step 11 shows you how to point Logdy at your own file, journald or socket.

What is included:

  • Logdy 0.17.1 single Go binary (/usr/local/bin/logdy)
  • In memory log buffer (no database to maintain)
  • A column and facet layout (/etc/logdy/logdy.config.json) that parses the structured demo JSON into sortable columns
  • logdy.service running as logdy, bound to loopback 127.0.0.1:8080
  • logdy-demo.service generating a demo log so the UI is populated on first boot (demo data only)
  • nginx.service reverse proxy on TCP 80, TLS ready, with the whole UI behind HTTP Basic auth and WebSocket upgrade for the live stream
  • logdy-firstboot.service generating a per VM UI password on first boot, stored only as a bcrypt hash
  • Ubuntu 24.04 LTS base, latest patches, unattended security upgrades enabled
  • 24/7 cloudimg support, 24h response SLA

Prerequisites

An active Azure subscription, an SSH key, and a VNet with a subnet. Recommended VM size: Standard_B2s (Logdy is very light; 4 GB RAM is plenty).

Step 1: Deploy from the Azure Portal

Search the Azure Marketplace for Logdy, choose the plan, and create the VM. In the networking step attach an NSG that allows inbound TCP 22 (SSH) and TCP 80 (the web UI) from your client networks only. Put a TLS reverse proxy in front of port 80 for production.

Step 2: Deploy from the Azure CLI

RG="logdy-prod"; LOCATION="eastus"; VM_NAME="logdy-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/logdy-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name lg-vnet --address-prefix 10.105.0.0/16 --subnet-name lg-subnet --subnet-prefix 10.105.1.0/24
az network nsg create -g "$RG" --name lg-nsg
az network nsg rule create -g "$RG" --nsg-name lg-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name lg-nsg --name allow-web --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name lg-vnet --subnet lg-subnet --nsg lg-nsg --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

logdy.service, logdy-demo.service, nginx.service and logdy-firstboot.service all start automatically on first boot.

Step 4: Verify the Service

sudo systemctl is-active logdy logdy-demo nginx
sudo test -f /var/lib/cloudimg/logdy-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':80 |:8080 '

Expected output — the services are active, nginx is bound to the public port 80 and Logdy is bound to loopback 127.0.0.1:8080 only:

active
active
active
FIRSTBOOT_DONE
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:*  users:(("logdy",...))
LISTEN 0 511  0.0.0.0:80     0.0.0.0:*  users:(("nginx",...))

Logdy, the demo generator and nginx all active, with nginx bound to public port 80 and Logdy bound to loopback 127.0.0.1:8080 only

Step 5: Get Your UI Credentials

Logdy has no default login. On first boot a unique UI password is generated and written to a root only note. Only the bcrypt hash is stored for nginx, so there is no usable credential baked into the image:

sudo cat /root/logdy-info.txt

The note contains the username and password, unique to this machine:

LOGDY_UI_USERNAME=admin
LOGDY_UI_PASSWORD=<LOGDY_UI_PASSWORD>
LOGDY_URL=http://<vm-ip>/

The per VM credential note with the password masked, showing the file is mode 0600 root only, and the nginx htpasswd holding only the bcrypt hash

Step 6: Verify the Auth Round-Trip

The health endpoint is public for liveness checks, but the log viewer itself, including the WebSocket that streams the data, requires the per VM credential. Prove it end to end without ever printing your password:

PW=$(sudo grep '^LOGDY_UI_PASSWORD=' /root/logdy-info.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'GET /health          -> HTTP %{http_code}\n' http://127.0.0.1/health
curl -s -o /dev/null -w 'GET / (no creds)     -> HTTP %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'GET / (per-VM creds) -> HTTP %{http_code}\n' -u admin:"$PW" http://127.0.0.1/

The health endpoint answers 200, the UI is refused without credentials, and the per VM credential signs you in:

GET /health          -> HTTP 200
GET / (no creds)     -> HTTP 401
GET / (per-VM creds) -> HTTP 200

The auth round-trip: the health endpoint returns 200, the UI returns 401 without credentials and 200 with the per VM credentials, and Logdy is following the structured demo log

Step 7: Open the Live Log Stream

Open the web UI in a browser and sign in with the username and password from Step 5. Logdy shows the demo log streaming live, with the JSON parsed into sortable columns (time, level, service, method, path, status, duration and message) and a facet sidebar on the left:

open http://<vm-ip>/

The Logdy web UI streaming the structured demo log into sortable columns, with a facet sidebar showing counts per level, service and method

Step 8: Filter with Facets

The left sidebar turns any column you mark as a facet into a one click filter. Click a value, for example ERROR under level, and the stream instantly narrows to only the matching lines, with the counts updating live:

The log stream filtered to level ERROR by clicking the facet, showing only error lines with the ERROR facet highlighted and the count updated

Step 9: Inspect a Log Message

Click any row to open the message inspector. Every field of the structured line is broken out into its own labelled value, and you can jump to the next or previous message or reveal the raw line:

The Logdy message inspector showing a single log line broken out into its parsed fields: time, level, service, method, path, status, duration and message

Step 10: Filter by Service

Facets compose, so you can drill into a single service just as easily. Click a value under service, for example auth, to see only that service's traffic across every level and endpoint:

The log stream filtered to the auth service by clicking the facet, showing only auth traffic with the service counts on the left

Step 11: Point Logdy at Your Own Logs

The image ships a demo generator so the UI is populated on first boot. When you are ready to watch your own logs, disable the demo generator and edit the ExecStart line of logdy.service to follow your own file (Logdy can also follow standard output or a socket, see the Logdy documentation). Then reload the UI in your browser at http://<vm-ip>/:

# Stop the demo generator, then point Logdy at your own log file:
sudo systemctl disable --now logdy-demo.service
sudo sed -i 's#/var/log/logdy-demo/app.log#/var/log/myapp/app.log#' /etc/systemd/system/logdy.service
sudo systemctl daemon-reload && sudo systemctl restart logdy.service
# reload the UI at http://<vm-ip>/ to watch your own logs stream in

If your logs are not JSON, open the settings panel in the UI (the gear icon), remove the auto generated columns, and use Auto-generate or Add to define columns and facets that match your format.

Step 12: Server Components

Component Path
Logdy binary /usr/local/bin/logdy
Column and facet layout /etc/logdy/logdy.config.json
Demo log (demo data only) /var/log/logdy-demo/app.log
Systemd unit /etc/systemd/system/logdy.service
Demo generator unit /etc/systemd/system/logdy-demo.service
Firstboot script /usr/local/sbin/logdy-firstboot.sh
nginx Basic auth hash file /etc/nginx/logdy.htpasswd
Per VM info note /root/logdy-info.txt (mode 0600)
Sentinel /var/lib/cloudimg/logdy-firstboot.done
/usr/local/bin/logdy --version
ls /usr/local/bin/logdy /etc/logdy/logdy.config.json /etc/systemd/system/logdy.service
jq -r '.columns[].name' /etc/logdy/logdy.config.json | paste -sd' ' -

Logdy reports version 0.17.1, the component paths exist, and the layout parses the demo JSON into eight columns:

logdy version 0.17.1
/usr/local/bin/logdy /etc/logdy/logdy.config.json /etc/systemd/system/logdy.service
time level service method path status duration_ms message

Logdy reporting version 0.17.1, the installed component paths, and the eight columns the layout parses from the structured JSON logs

Step 13: Managing the Service

sudo systemctl restart logdy.service
sudo journalctl -u logdy.service --no-pager -n 20

Logdy restarts in well under a second because it is a single binary with an in memory buffer. The service is hardened with NoNewPrivileges, ProtectSystem=strict and ProtectHome, and only has write access to its own data directory.

Step 14: Configuration

Logdy is configured through the systemd unit logdy.service (the ExecStart flags) plus the column and facet layout in /etc/logdy/logdy.config.json. Useful flags already set by the image:

Flag Meaning Image default
follow <file> Follow a log file and stream new lines /var/log/logdy-demo/app.log
--full-read Read the whole file first, then follow on
--config Column and facet layout file /etc/logdy/logdy.config.json
--ui-ip Bind address for the web UI 127.0.0.1 (loopback)
--port Web UI port 8080
-n / --no-analytics Disable anonymous analytics on
-u / --no-updates Disable update checks on

Logdy binds to loopback only; nginx is the sole public listener and enforces the Basic auth credential. After editing the unit, apply changes with sudo systemctl daemon-reload && sudo systemctl restart logdy.service.

Step 15: Change the UI Password

The password is generated per VM at first boot. To set your own, rewrite the nginx htpasswd entry for admin and reload nginx (replace <new-password>):

printf '%s' '<new-password>' | sudo htpasswd -iB /etc/nginx/logdy.htpasswd admin
sudo systemctl reload nginx

Step 16: Add TLS (Optional)

For production, terminate TLS at nginx. Point a DNS record at the VM, then use the packaged nginx with a certificate from Let's Encrypt:

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>

certbot installs the certificate, rewrites the nginx server block to listen on 443 and sets up automatic renewal, so your credentials travel encrypted.

Step 17: Security Recommendations

  • Restrict the NSG so ports 80 and 22 only reach trusted networks.
  • Terminate TLS at nginx (Step 16) so the Basic auth credential and your log data travel encrypted.
  • Change the UI password (Step 15) and keep the credential note /root/logdy-info.txt readable only by root.
  • Treat the demo as demo data and point Logdy at your own logs (Step 11) before relying on it.
  • Mind what you stream: logs can contain secrets. Logdy holds lines in memory only unless you enable --append-to-file, and access is gated by the Basic auth credential, but restrict who can reach the UI.
  • Patch the OS monthly with sudo apt-get update && sudo apt-get upgrade; unattended security upgrades are already enabled.

Step 18: Support and Licensing

Logdy is Apache 2.0 licensed — no per CPU or per user fee. cloudimg provides commercial support separately.

  • Email: support@cloudimg.co.uk
  • Website: www.cloudimg.co.uk
  • Support hours: 24/7, 24h response SLA

Deploy on Azure

Launch Logdy on Ubuntu 24.04 with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7. support@cloudimg.co.uk