Logdy on Ubuntu 24.04 on Azure User Guide
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.servicerunning aslogdy, bound to loopback127.0.0.1:8080logdy-demo.servicegenerating a demo log so the UI is populated on first boot (demo data only)nginx.servicereverse proxy on TCP 80, TLS ready, with the whole UI behind HTTP Basic auth and WebSocket upgrade for the live streamlogdy-firstboot.servicegenerating 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",...))

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>/

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

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>/

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:

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:

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:

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

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.txtreadable 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