Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Dashy Ubuntu
GUIDEInstall Guides

How to Install Dashy on Ubuntu 24.04 VPS: Privacy-Focused Self-Hosted Dashboard

22 min read

How to Install Dashy on Ubuntu 24.04 VPS: Privacy-Focused Self-Hosted Dashboard

If you run more than a handful of services on your VPS, you probably have a mental (or bookmark-folder) map of where everything lives: Portainer on one port, Grafana on another, a Git server on a subdomain, a media stack somewhere else. Dashy replaces that scattered mess with a single, beautiful start page that you fully own and control. It is a Vue.js single-page application that renders a YAML-defined list of your services, checks whether they are up, embeds live widgets (weather, crypto prices, system stats, RSS feeds), and gates the whole thing behind authentication if you want it to.

This guide walks through a production-ready Dashy install on Ubuntu 24.04 using Docker Compose, from first ssh to an HTTPS-protected dashboard at your own domain. You will end up with a persistent config volume, an Nginx reverse proxy, Let's Encrypt certificates, automated backups of your conf.yml, and a clear mental model of how sections, items, widgets, and themes fit together.

Want a one-click option? Our CloudCore Starter VPS is the ideal home for Dashy: plenty of headroom for the container, an NVMe disk for fast rebuilds, and a real public IP so you can put a proper TLS certificate on top.

Table of Contents

  • What is Dashy?
  • Why Self-Host Your Dashboard?
  • Prerequisites
  • Step 1: Update System and Install Docker
  • Step 2: Create the Dashy Directory Structure
  • Step 3: Write the Docker Compose File
  • Step 4: Create Your First conf.yml
  • Step 5: Launch Dashy
  • Step 6: Organize Sections, Items, and Icons
  • Step 7: Add Widgets
  • Step 8: Enable Status Checks
  • Step 9: Configure Authentication
  • Step 10: Themes and Appearance
  • Step 11: Nginx Reverse Proxy with TLS
  • Step 12: Back Up conf.yml
  • Editing Config: UI vs Manual YAML
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Dashy?

    Dashy is an open-source, feature-rich dashboard for organizing the services you host and the links you care about. Under the hood it is a Vue 3 single-page app served by a Node.js backend that also handles status checks and a couple of proxy endpoints for widgets that cannot call third-party APIs directly from the browser (for example, anything blocked by CORS). The project is authored and maintained primarily by Alicia Sykes and the official Docker image is published as lissy93/dashy on Docker Hub.

    What makes Dashy stand out from the crowded self-hosted-dashboard space:

    • Extensive widget library. Out of the box you get status-check tiles, weather, crypto prices, stock tickers, system info (CPU, RAM, disk, uptime from the host where Dashy runs), RSS feeds, GitHub repo stats, public IP and geolocation, cron-ping health, code-repo releases, and dozens more. Widgets are just YAML entries, not code you have to write.
    • Declarative YAML configuration. The entire dashboard is described by a single conf.yml file. This is trivial to version-control, diff, migrate between servers, and restore from backup.
    • Built-in authentication. Dashy ships with two auth modes: a lightweight JWT-based scheme (a simple list of users and bcrypt-like hashed passwords in conf.yml) and full Keycloak SSO for organizations that already run an identity provider.
    • Theme library. Around two dozen themes are bundled (Material, Nord, Adventure, Minimal Dark, Hacker Terminal, and more) and you can author your own with CSS variables.
    • Two editing modes. Edit the YAML directly on disk, or use the visual config editor in the UI and let Dashy write the file for you.
    • Offline-first. Everything except a few third-party widgets runs locally; your browsing history on the dashboard stays on your server.
    Typical use cases: a homelab launcher for self-hosters who run 10-50 services, a team portal that links to internal tooling (Jira, Confluence, Grafana, Jenkins, staging URLs) for a small company, a NOC wall-display that surfaces status checks and alerts on a big screen in the corner of the office, or a personal bookmark replacement that syncs across every device you own.

    Why Self-Host Your Dashboard?

    You could use a hosted service like Start.me, Netvibes, or any of the browser new-tab extensions. Running your own Dashy instance on your own VPS buys you a few concrete things instead:

    • Privacy of your link graph. The list of services you access and how you organize them is a surprisingly revealing personal/organizational fingerprint. Hosted dashboards see all of it. Dashy sees none of it except your own server.
    • No upstream outages. When the hosted service has a bad day, your start page disappears. A self-hosted dashboard is as reliable as your VPS.
    • Internal service linking. Dashy happily links to http://10.0.0.5:9000 or https://grafana.internal.lan. Hosted dashboards cannot reach RFC1918 addresses at all.
    • No arbitrary limits. Free tiers cap the number of links, widgets, or themes. A self-hosted install has no such limits.
    • Integration with your stack. Status checks can hit http://traefik:8080/ping by Docker service name when Dashy shares a network. That is impossible with an external dashboard.
    Compared to siblings in the same category:
    DashboardConfig styleWidgetsAuthNotes
    DashyYAML, UI editor40+ widgets, status checksJWT + KeycloakMost feature-rich, Vue SPA
    HomepageYAML (split files)Strong service integrations (Sonarr, Pi-hole, etc.)Reverse-proxy authLightweight, Next.js
    HeimdallWeb UI (DB)MinimalBuilt-inSimplest, PHP-based
    FlameWeb UI (DB)Weather, searchPasswordMinimalist terminal aesthetic
    If you want the widest feature surface, the best status checks, and the most themes — Dashy is the pick. If you want something lighter and more integration-focused, see our Homepage install guide.

    Prerequisites

    Before starting, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access.
    • SSH access to the server.
    • At least 1 GB of RAM and 1 vCPU. Dashy is lightweight — the container idles under 150 MB of RAM.
    • A domain name (e.g. dash.example.com) with an A record pointing at your VPS IP, if you want HTTPS via Nginx (Step 11).
    • Docker and Docker Compose installed. Step 1 handles this if you have not done it yet. You can also refer to the dedicated Docker on Ubuntu 24.04 guide.
    Recommended plan: CloudCore Starter
    >
    Dashy will run on almost anything, but you will likely want the same VPS to host a bunch of other services it links to. The CloudCore Starter gives you:
    >
    - 4 vCPU cores
    - 8 GB RAM
    - 100 GB NVMe SSD
    - Unmetered bandwidth
    >
    That is enough for Dashy, Nginx, Docker, and a solid half-dozen companion services (Uptime Kuma, Portainer, Grafana, Gitea, and so on) without breaking a sweat.

    Connect to your server:

    bash
    ssh root@your-server-ip

    Step 1: Update System and Install Docker

    Refresh the package index and apply any pending upgrades:

    bash
    sudo apt update && sudo apt upgrade -y

    If the kernel was updated, reboot and reconnect:

    bash
    sudo reboot

    Install Docker Engine and the Compose plugin using the official convenience script:

    bash
    curl -fsSL https://get.docker.com | sudo sh
    sudo apt install -y docker-compose-plugin

    Verify both are installed:

    bash
    docker --version
    docker compose version

    Expected output (versions will vary):

    text
    Docker version 26.1.3, build b72abbb
    Docker Compose version v2.27.0

    Add your non-root user to the docker group so you do not have to sudo every command (log out and back in for it to apply):

    bash
    sudo usermod -aG docker $USER

    Step 2: Create the Dashy Directory Structure

    Pick a home for Dashy's config. /opt/dashy is a clean choice on a dedicated VPS:

    bash
    sudo mkdir -p /opt/dashy
    sudo chown -R $USER:$USER /opt/dashy
    cd /opt/dashy

    Create a user-data directory — this is the single volume Dashy needs — and an empty conf.yml inside it:

    bash
    mkdir -p /opt/dashy/user-data
    touch /opt/dashy/user-data/conf.yml

    Why user-data? Inside the container, Dashy reads /app/user-data/conf.yml and writes backups and uploaded assets (like custom icons) to the same directory. Mounting a single host directory there gives you persistence with no surprises.

    Step 3: Write the Docker Compose File

    Create /opt/dashy/docker-compose.yml:

    yaml
    services:
      dashy:
        image: lissy93/dashy:latest
        container_name: dashy
        restart: unless-stopped
        ports:
          - "127.0.0.1:4000:8080"
        volumes:
          - ./user-data:/app/user-data
        environment:
          - NODE_ENV=production
          - UID=1000
          - GID=1000
        healthcheck:
          test: ["CMD", "node", "/app/services/healthcheck"]
          interval: 90s
          timeout: 10s
          retries: 3
          start_period: 40s

    A few notes on the choices:

    • Image tag: lissy93/dashy:latest is fine for most people. If you want reproducible deploys, pin a version — for example lissy93/dashy:3.1.1 — and update it deliberately.
    • Port binding 127.0.0.1:4000:8080: the container listens on 8080 internally; we publish it only on localhost of the host. Nginx (Step 11) will provide the public-facing TLS endpoint. If you want to expose Dashy directly on the internet without Nginx, change this to 4000:8080 — but please do not skip the auth configuration in Step 9.
    • Volumes: bind-mount ./user-data so conf.yml survives container rebuilds and you can edit it with a normal text editor on the host.
    • UID/GID: match these to the owner of ./user-data on the host so the container can write backups and uploads.

    Step 4: Create Your First conf.yml

    Open /opt/dashy/user-data/conf.yml in your editor of choice and paste this minimal starter config:

    yaml
    pageInfo:
      title: My VPS Dashboard
      description: Everything I host, in one place
      navLinks:
        - title: GitHub
          path: https://github.com

    appConfig: theme: nord-frost layout: auto iconSize: medium language: en statusCheck: true statusCheckInterval: 300

    sections: - name: Infrastructure icon: fas fa-server items: - title: Portainer description: Container management icon: hl-portainer url: https://portainer.example.com - title: Traefik description: Reverse proxy dashboard icon: hl-traefik url: https://traefik.example.com/dashboard/ - name: Monitoring icon: fas fa-chart-line items: - title: Grafana description: Metrics and dashboards icon: hl-grafana url: https://grafana.example.com - title: Uptime Kuma description: Status page icon: hl-uptime-kuma url: https://status.example.com

    This gives you two sections, four items with icons drawn from dashboard-icons (the hl-* prefix), status checking enabled globally, and the Nord Frost theme. Adjust URLs to match what you actually run.

    Step 5: Launch Dashy

    From /opt/dashy, bring the stack up:

    bash
    docker compose up -d

    Expected output:

    text
    [+] Running 1/1
     ✔ Container dashy  Started

    Confirm the container is healthy:

    bash
    docker compose ps

    Expected output:

    text
    NAME    IMAGE                 STATUS                   PORTS
    dashy   lissy93/dashy:latest  Up 30 seconds (healthy)  127.0.0.1:4000->8080/tcp

    Because we bound to 127.0.0.1:4000, test locally via SSH tunnel or curl:

    bash
    curl -I http://127.0.0.1:4000

    Expected output:

    text
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: text/html; charset=UTF-8

    To open the dashboard in a browser before setting up Nginx, forward the port over SSH from your workstation:

    bash
    ssh -L 4000:127.0.0.1:4000 root@your-server-ip

    Then visit http://localhost:4000.

    Step 6: Organize Sections, Items, and Icons

    Dashy's information model is two levels deep:

    • Section — a titled group (e.g. Infrastructure, Media, Development). Each section can have its own icon, a displayData block to control column span, and an optional per-section background.
    • Item — a single link inside a section. Each item has a title, optional description, icon, url, target (how the link opens: newtab, sametab, modal, workspace), and optional statusCheck and tags.

    Icons: four sources

    Dashy accepts icons from several sources and you just prefix the icon: value:

  • Font Awesome classes: icon: fas fa-server, icon: fab fa-github. Full catalog at fontawesome.com.
  • Dashboard Icons (hl-* prefix): icon: hl-grafana, icon: hl-portainer. Maps to the walkxcode/dashboard-icons library — over 1,000 high-quality SVG icons of popular self-hosted apps. This is what you will use most often.
  • Simple Icons (si-* prefix): icon: si-docker. Uses the Simple Icons brand pack.
  • Auto-fetched favicons: icon: favicon tells Dashy to download the favicon from the url field. Works for any site but quality varies.
  • Custom image: drop a file into /opt/dashy/user-data/item-icons/ and reference it as icon: /item-icons/myapp.png.
  • Opening behavior

    The target field controls where links go:

    • newtab — standard new browser tab (default).
    • sametab — replace the dashboard page.
    • modal — open in an iframe inside Dashy. Only works if the target site allows framing (X-Frame-Options not set to DENY).
    • workspace — launch in Dashy's workspace view, a tabbed multi-pane overlay. Excellent for cycling between Grafana, Portainer, and your logs on a big display.

    Step 7: Add Widgets

    Widgets are live data tiles. They live either at the top of a section (via a section's widgets: key) or as standalone sections. A sampler:

    yaml
    sections:
      - name: Ops Widgets
        widgets:
          - type: system-info
            options:
              hideId: true
          - type: public-ip
          - type: weather
            options:
              apiKey: your-openweathermap-api-key
              city: Berlin
              units: metric
          - type: crypto-price-chart
            options:
              asset: bitcoin
              currency: USD
              days: 30
          - type: cron-ping
            options:
              hookId: your-cronhub-id
          - type: rss-feed
            options:
              rssUrl: https://news.ycombinator.com/rss
              limit: 5

    Popular widgets and what they need:

    WidgetPurposeRequired options
    status-checkExplicit HTTP check tileurl
    weatherCurrent conditionsapiKey (OpenWeatherMap), city
    crypto-price-chartBTC/ETH/etc price historyasset, currency, days
    system-infoOS, uptime, load (reads from Dashy's host)none
    public-ipWAN IP + geo lookupnone
    rss-feedArbitrary RSS readerrssUrl
    github-trendingTrending reposlang, since
    uptime-kumaPull status from Uptime Kumaurl
    cron-pingHealth of a scheduled jobhookId
    gluetun-port-forwardVPN forwarded port displayurl
    A few widgets — notably anything hitting a third-party API that returns CORS-restricted headers — use Dashy's built-in proxy endpoint. This is transparent to you; Dashy just routes the request through its Node backend. If a widget is stuck loading and the browser console shows a CORS error, set useProxy: true in the widget's options.

    The full catalog lives at dashy.to/docs/widgets.

    Step 8: Enable Status Checks

    Status checks turn every item into a live "is this up?" tile with a green/red indicator and an HTTP status code on hover.

    Enable globally in appConfig:

    yaml
    appConfig:
      statusCheck: true
      statusCheckInterval: 300      # seconds

    Override per item if you need different behavior:

    yaml
    - title: Grafana
      url: https://grafana.example.com
      statusCheck: true
      statusCheckUrl: https://grafana.example.com/api/health
      statusCheckHeaders:
        Authorization: "Bearer xyz"
      statusCheckAcceptCodes: "200,201,204"
      statusCheckAllowInsecure: false

    Key fields:

    • statusCheckUrl — if your app has a dedicated /health or /ping endpoint, point at it instead of the homepage. Saves bandwidth and works even when the homepage redirects.
    • statusCheckAcceptCodes — some apps return 401 or 403 on unauthenticated homepage hits but are actually healthy. Add those codes here to avoid false reds.
    • statusCheckAllowInsecure: true — only for self-signed certs on a LAN. Never enable this for a public endpoint.
    Status checks are performed by Dashy's backend (not your browser), so they work equally well for public and internal URLs.

    Step 9: Configure Authentication

    Until you put Dashy behind auth, anyone who knows the URL can see every link on your dashboard. Two options:

    Option A: Simple JWT Auth (built in, no extra services)

    Generate a bcrypt-ish hash for your password. Dashy accepts the hex-encoded SHA-256 of the password, which you can produce right on the server:

    bash
    echo -n "your-strong-password" | sha256sum | awk '{print $1}'

    Expected output:

    text
    5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

    Add an auth block to conf.yml:

    yaml
    appConfig:
      auth:
        users:
          - user: admin
            hash: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
            type: admin
          - user: viewer
            hash: 7c6a180b36896a0a8c02787eeafb0e4c1c5e2e9d1c1d3fa4a94c4b7e2f91c8de
            type: normal

    Apply the change:

    bash
    cd /opt/dashy
    docker compose restart

    Now visiting Dashy presents a login screen. admin users can access the visual config editor; normal users just view the dashboard.

    This auth is client-side JWT — tokens live in the browser and the underlying assets can still be fetched directly if someone knows exact URLs. It is perfectly fine for a personal dashboard but not a hard security boundary. Combine with Nginx basic auth or IP allow-lists (Step 11) for anything sensitive.

    Option B: Keycloak SSO

    If you already run Keycloak (or another OIDC provider fronted by Keycloak), Dashy can delegate to it:

    yaml
    appConfig:
      auth:
        enableKeycloak: true
        keycloak:
          serverUrl: https://sso.example.com
          realm: my-realm
          clientId: dashy

    In Keycloak, create a new client with Public access type, dashy as the Client ID, and add your Dashy URL as a valid redirect URI (e.g. https://dash.example.com/*). Restart Dashy and the login button will bounce users through your Keycloak realm.

    Keycloak is the right call when Dashy needs to share identity with the rest of your stack (Grafana, Nextcloud, GitLab, etc.).

    Step 10: Themes and Appearance

    Dashy ships with around two dozen themes. Some favorites:

    • nord-frost / nord-polar-night — cool muted blues.
    • material — Google Material defaults, clean and professional.
    • adventure — warm earth tones.
    • hacker-terminal — green-on-black, monospaced, for the full SRE aesthetic.
    • minimal-dark — pure dark mode with minimal chrome.
    • thebe — clean light theme with pink accents.
    Set one as the default:

    yaml
    appConfig:
      theme: nord-frost

    Users can switch themes from the UI; their choice is stored in localStorage and does not change the YAML.

    Custom themes

    Drop a CSS file into /opt/dashy/user-data/custom-css/ and reference it in appConfig:

    yaml
    appConfig:
      customCss: "body { background-image: url('/item-icons/bg.jpg'); }"

    For more involved custom themes, define CSS variables. Dashy exposes --primary, --background, --text-color, and dozens more; the full list is in the theming docs.

    Other appearance tweaks worth knowing:

    • layout: vertical | horizontal | auto — section stacking.
    • iconSize: small | medium | large
    • cssThemes: [my-first-theme, my-second-theme] — register custom theme names so they show up in the theme picker.

    Step 11: Nginx Reverse Proxy with TLS

    Point dash.example.com at your VPS in DNS first (A record, TTL 300). Then install Nginx and Certbot:

    bash
    sudo apt install -y nginx certbot python3-certbot-nginx

    Create /etc/nginx/sites-available/dashy:

    nginx
    server {
        listen 80;
        server_name dash.example.com;
        return 301 https://$host$request_uri;
    }

    server { listen 443 ssl http2; server_name dash.example.com;

    ssl_certificate /etc/letsencrypt/live/dash.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dash.example.com/privkey.pem;

    # Security headers add_header X-Content-Type-Options nosniff; add_header Referrer-Policy strict-origin-when-cross-origin; add_header X-Frame-Options SAMEORIGIN;

    client_max_body_size 10m;

    location / { proxy_pass http://127.0.0.1:4000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;

    # Required for Dashy's save-config endpoint and long status checks proxy_read_timeout 300s; proxy_send_timeout 300s; } }

    Enable and test:

    bash
    sudo ln -s /etc/nginx/sites-available/dashy /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx

    Obtain a Let's Encrypt certificate:

    bash
    sudo certbot --nginx -d dash.example.com

    Certbot will edit the Nginx config to serve HTTPS and install a systemd timer to renew automatically. Visit https://dash.example.com — you should see your dashboard with a valid green padlock.

    For a deeper dive into Nginx tuning see our Nginx on Ubuntu 24.04 guide.

    Step 12: Back Up conf.yml

    Your entire Dashy setup lives in one file. Back it up daily to remote storage (S3-compatible, rsync to another VPS, or an encrypted Borg repo).

    A minimal cron-driven snapshot to /opt/backups/dashy:

    bash
    sudo mkdir -p /opt/backups/dashy
    sudo tee /usr/local/bin/backup-dashy.sh > /dev/null <<'EOF'
    #!/bin/bash
    set -euo pipefail
    STAMP=$(date +%Y%m%d-%H%M%S)
    cp /opt/dashy/user-data/conf.yml /opt/backups/dashy/conf-${STAMP}.yml
    

    keep last 30 days

    find /opt/backups/dashy -name 'conf-*.yml' -mtime +30 -delete EOF sudo chmod +x /usr/local/bin/backup-dashy.sh

    Schedule via cron:

    bash
    sudo crontab -e

    Add:

    text
    0 3   * /usr/local/bin/backup-dashy.sh

    For offsite copies, add an aws s3 cp or rclone copyto line after the cp in the script.

    Restoring is as easy as copying the backup back to /opt/dashy/user-data/conf.yml and running docker compose restart dashy.

    Editing Config: UI vs Manual YAML

    Dashy gives you two ways to edit conf.yml. Understanding when each is safe will save you grief.

    Visual config editor (UI)

    With an admin user logged in, click the settings gear → Edit Config. You get a schema-driven form editor for sections, items, widgets, and app settings. When you save, Dashy writes the new YAML to /app/user-data/conf.yml inside the container — which, because of our bind mount, is /opt/dashy/user-data/conf.yml on the host.

    Pros: guided, validated, prevents YAML typos, good for quick item additions.

    Cons: comments and custom formatting in your YAML are lost on save; re-indenting is sometimes cosmetically different from what you wrote.

    Manual YAML editing

    Edit /opt/dashy/user-data/conf.yml with vim, nano, or VS Code over SSH/Remote-SSH.

    Pros: full control, preserves comments, easy to manage in Git, unlocks features the UI editor does not yet support (custom CSS paths, certain widget options).

    Cons: a stray indent crashes the dashboard on the next reload.

    When to rebuild vs restart

    Dashy hot-reloads most config changes when you hit "Reload" in the UI. In a few cases you need to explicitly restart the container:

    • Auth changes (adding users, switching to Keycloak) — docker compose restart dashy.
    • Custom CSS paths that reference new files mounted into the container.
    • Image or version bump:
    bash
    cd /opt/dashy
      docker compose pull
      docker compose up -d

    A hard rebuild (regenerating the frontend bundle) is only necessary if you have forked Dashy and modified the source. The Docker image ships a pre-built bundle.

    Troubleshooting

    ProblemCauseSolution
    502 Bad Gateway from NginxContainer not running, or Nginx pointing at wrong portCheck docker compose ps, confirm container is (healthy) and that Nginx proxy_pass matches 127.0.0.1:4000
    Dashboard shows "Config is invalid" bannerYAML syntax errorRun docker compose logs dashy — the error points to a line number. Lint with yamllint /opt/dashy/user-data/conf.yml before restarting
    Widgets stuck on "Loading…" foreverCORS blocked browser-side requestAdd useProxy: true inside the widget's options block
    Status checks all red even though apps are upDashy backend cannot reach the URL from inside the containerIf checking an internal container, use the Docker service name or attach Dashy to the same Docker network; do not use localhost
    Can't save config from UIuser-data directory not writable by the container's UIDsudo chown -R 1000:1000 /opt/dashy/user-data
    Login loop with KeycloakRedirect URI mismatchIn Keycloak client, set Valid Redirect URIs to exactly your Dashy URL with a trailing /*
    Status check hits Cloudflare interstitialJS challenge blocking Dashy's backendAdd the VPS IP to a Cloudflare firewall bypass rule or use the app's direct origin URL
    Weather widget shows "Invalid API key"OpenWeatherMap free keys take up to 2 hours to activateWait, then restart: docker compose restart dashy
    Container unhealthy after upgradeBreaking change in a minor versiondocker compose logs dashy, then pin to a previous tag: image: lissy93/dashy:3.0.0

    Viewing logs

    bash
    cd /opt/dashy
    docker compose logs -f dashy

    Grep for the common noisy lines:

    bash
    docker compose logs dashy | grep -iE 'error|warn|invalid'

    FAQ

    How much RAM does Dashy actually use?

    Idle, Dashy uses 100-150 MB RAM. Under heavy status-checking (50+ items, 60-second interval) it climbs to 200-250 MB. CPU is negligible on any modern VPS — even a 1 vCPU instance handles it without noticeable load.

    Can Dashy monitor services on other servers?

    Yes. Status checks are plain HTTP/HTTPS requests made by Dashy's backend. Point them at any reachable URL — another VPS, a cloud endpoint, a LAN service accessible via VPN. For internal-only services, the Dashy container must be on the same network (Docker network, Tailscale tailnet, WireGuard tunnel).

    Does Dashy support multiple dashboards for different users?

    Kind of. The multi-page feature lets you define several pages in one conf.yml, each with its own sections. Combined with per-user JWT auth, you can restrict pages by user role. For fully independent dashboards per team, run multiple Dashy containers with separate user-data directories and different subdomains.

    How do I migrate an existing Homepage or Heimdall setup to Dashy?

    There is no automated import, but both Homepage's services.yaml and Heimdall's exported DB map cleanly to Dashy sections/items. Write a short script (Python or yq) that iterates the source list and emits Dashy's YAML schema. Start with 5-10 items by hand first so you learn the shape.

    Is Dashy still actively maintained?

    Yes. The lissy93/dashy repository sees regular commits, the Docker image is rebuilt on a predictable cadence, and the issue tracker is responsive. Release notes live at github.com/lissy93/dashy/releases.

    Can I version-control my conf.yml in a private Git repo?

    Absolutely, and you should. Create a repo, add /opt/dashy/user-data/conf.yml as a symlink or commit it from a working copy elsewhere, and push after each change. Combined with the backup script in Step 12 you get bulletproof recoverability.

    Next Steps

    Dashy becomes more valuable the more of your stack you link to from it. Some natural follow-ups:

    • Install Homepage alongside Dashy — run both on separate subdomains and compare styles for a week before picking a permanent start page. Our Homepage install guide has the same Docker-Compose-and-Nginx structure, so setup takes 10 minutes.
    • Set up Uptime Kuma — wire its status JSON into Dashy's uptime-kuma widget for a richer monitoring tile. See our Uptime Kuma install guide.
    • Deploy Portainer for visual Docker management — perfect companion service to link from Dashy's Infrastructure section.
    • Harden with Fail2ban on the SSH and Nginx ports that now serve your dashboard publicly.
    • Put everything behind Tailscale if you want private-only access without public DNS — skip Step 11 entirely and bind Dashy to your tailnet IP instead.
    • Read the official Dashy documentation — we covered the 90% path; docs cover the last 10% (custom pages, advanced widget options, API endpoints).

    Get Dashy-Ready Hosting in One Click
    >
    Every CloudCore Starter VPS ships with Ubuntu 24.04, Docker support, and a real public IPv4 — the exact base this guide assumes. Deploy in under 60 seconds and paste in the Docker Compose file above.
    >
    - 4 vCPU cores
    - 8 GB RAM
    - 100 GB NVMe SSD
    - Unmetered bandwidth
    - Public IPv4 included
    >
    Launch your CloudCore Starter now and have Dashy live at your own domain before your coffee gets cold.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket