docker-swarm-dashboard

June 27, 2026 · View on GitHub

GitHub release Docker CodeQL Cypress Frontend CI Server Go CI API Build & Healthcheck Lint server-src

docker-swarm-dashboard

Dashboard for Docker Swarm Cluster

Docker-Image Size: < 25 MB

Use a stable release in production, not the master-build! Don't expose this service to the world! The endpoints offer the configuration of your services.

If you like this project, please give a ⭐ on github. Feedback would be nice.

Frameworks & Libraries

Screenshots

Dashboard - Light Mode Dashboard - Dark Mode Timeline Stacks Nodes Tasks Ports Logs

Getting started

Tags

TagDescriptionImage
e.g. 1.4.1Stable releaseghcr.io/heckenmann/docker-swarm-dashboard:1.4.1
latestLatest stable releaseghcr.io/heckenmann/docker-swarm-dashboard:latest
masterCurrent unstable master-build (not well tested)ghcr.io/heckenmann/docker-swarm-dashboard:master

Configuration

Docker Swarm Dashboard supports environment variables for configuration.

Environment variableDescriptionDefault
DSD_HTTP_PORTHTTP port within the container. Usually does not need to be changed.8080
DSD_HANDLE_LOGSSet to false to prevent fetching and displaying logs.true
DSD_DASHBOARD_LAYOUTDefault dashboard layout. Either row (default) or column.row
DSD_HIDE_SERVICE_STATESComma-separated list of states to not show in the main dashboard.(none)
DSD_PATH_PREFIXSet a URL path prefix for the dashboard (e.g. /dashboard). Useful when running behind a reverse proxy or when the app should not be served from the root path./
DSD_ALLOWED_ORIGINSComma-separated list of allowed HTTP CORS and WebSocket origins (e.g. https://dashboard.example.com). The default keeps the historical behavior and allows all origins. Set a concrete allow-list to restrict browser access.*
DSD_NODE_EXPORTER_LABELDocker service label to identify node-exporter service for metrics collection.dsd.node-exporter
DSD_CADVISOR_LABELDocker service label to identify cAdvisor service for container memory metrics.dsd.cadvisor
LOCALETimestamp format based on a BCP 47 language tag.(system)
TZIANA Time zone to display timestamps in.(system)
DSD_VERSION_CHECK_ENABLEDWhen true, the system will check for updates and notify in the UI if a new version is available.false
DSD_VERSION_CHECK_CACHE_TIMEOUT_MINUTESCache duration in minutes for version check results.60
DSD_WELCOME_MESSAGEIf set, this message will be displayed to the user in a modal dialog when the web application is opened in the browser.(none)
DOCKER_API_VERSIONForces a specific Docker API version to use (e.g. 1.35, 1.41). When not specified, the server automatically negotiates the highest API version supported by both the client and Docker daemon. Only set this if you need to force a specific version for compatibility.(auto-negotiated)

If DSD_ALLOWED_ORIGINS is not set, the server logs a startup warning because all HTTP CORS and WebSocket origins are allowed for backward compatibility.

UI Default Settings

These environment variables control the default UI state. All settings can be changed by the user in the web interface and are persisted in the URL hash.

Environment variableDescriptionDefault
DSD_TABLE_SIZEDefault table size. Either sm (small) or lg (large).sm
DSD_SERVICE_NAME_FILTERDefault service name filter value.(none)
DSD_STACK_NAME_FILTERDefault stack name filter value.(none)
DSD_FILTER_TYPEDefault filter type. Either service or stack.service
DSD_LOGS_NUMBER_OF_LINESDefault number of log lines to fetch.100
DSD_LOGS_MESSAGE_MAX_LENMaximum length of log messages to display.2000
DSD_LOGS_FORM_TAILDefault value for tail option in logs form.true
DSD_LOGS_FORM_SINCEDefault value for since option in logs form.false
DSD_LOGS_FORM_SINCE_AMOUNTDefault amount for since option in logs form.15
DSD_LOGS_FORM_SINCE_UNITDefault unit for since option in logs form. Either minutes, hours, or days.minutes
DSD_LOGS_FORM_FOLLOWDefault value for follow option in logs form.false
DSD_LOGS_FORM_TIMESTAMPSDefault value for timestamps option in logs form.true
DSD_LOGS_FORM_STDOUTDefault value for stdout option in logs form.true
DSD_LOGS_FORM_STDERRDefault value for stderr option in logs form.true
DSD_LOGS_FORM_DETAILSDefault value for details option in logs form.true
DSD_LOGS_SEARCH_KEYWORDDefault search keyword for logs.(none)
DSD_DARK_MODEEnable dark mode by default. Either true or false.false
DSD_SHOW_NAMES_BUTTONSShow action buttons in entity names by default. Either true or false.true
DSD_SHOW_NAV_LABELSShow navigation labels by default. Either true or false.false
DSD_MAX_CONTENT_WIDTHMaximum content width. Either fluid (full width) or fixed (container width).fluid

Pull Image from ghcr.io

docker pull ghcr.io/heckenmann/docker-swarm-dashboard:master

docker-compose.yml

---
version: '3.5'

services:
  docker-swarm-dashboard:
    image: ghcr.io/heckenmann/docker-swarm-dashboard:master
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

docker-compose.yml with traefik and basic auth

This configuration sets a password for access. It is importand to configure ssl in traefik for better security.

In this example you can login with "docker / docker" on port 8080.

Have a look at https://doc.traefik.io/traefik/user-guides/docker-compose/acme-tls/

---
version: '3.5'

services:
  docker-swarm-dashboard:
    image: ghcr.io/heckenmann/docker-swarm-dashboard:master
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.dsd.entrypoints=web"
        - "traefik.http.routers.dsd.middlewares=basic-auth"
        - "traefik.http.services.dsd.loadbalancer.server.port=8080"
        - "traefik.http.routers.dsd.rule=PathPrefix(`/`)"
        # Login with docker / docker
        - "traefik.http.middlewares.basic-auth.basicauth.users=docker:$\$2y$\$10$\$81nFbUw842iBd7MlngMR4.1VBI9j6Y.vTiamBAqtVNfs4qehzZB.e"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  traefik:
    image: "traefik:v2.9"
    deploy:
      placement:
        constraints:
          - node.role == manager
    command:
      #- "--log.level=debug"
      #- "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:8080"
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

Deploy on docker-swarm

From the directory with docker-compose.yml run:

docker stack deploy --compose-file docker-compose.yml docker-swarm-dashboard

Metrics Integration (Optional)

Docker Swarm Dashboard supports optional integration with Prometheus Node Exporter and cAdvisor for enhanced metrics visualization.

Overview

Metric SourceProvidesDiscovery LabelDefault Label
Node ExporterNode-level metrics (CPU, memory, disk, network)dsd.node-exporterdsd.node-exporter=true
cAdvisorContainer-level metrics (memory usage per container)dsd.cadvisordsd.cadvisor=true

Both services should be deployed as global services on the same overlay network as the dashboard.


Node Exporter Setup

Purpose: Displays node-level system metrics (CPU, memory, disk, network usage per swarm node).

Deployment:

node-exporter:
  image: prom/node-exporter:latest
  deploy:
    mode: global
    placement:
      constraints:
        - node.role == manager   # Or remove for all nodes
    labels:
      - "dsd.node-exporter=true"
  networks:
    - your-network-name
  volumes:
    - /proc:/host/proc:ro
    - /sys:/host/sys:ro
    - /:/rootfs:ro
  command:
    - '--path.procfs=/host/proc'
    - '--path.sysfs=/host/sys'
    - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'

Customize Discovery Label:

environment:
  DSD_NODE_EXPORTER_LABEL: "my.custom.label"

cAdvisor Setup

Purpose: Displays container-level memory metrics per service (memory usage, limits, per-container breakdown).

Deployment:

cadvisor:
  image: gcr.io/cadvisor/cadvisor:latest
  deploy:
    mode: global
    placement:
      constraints:
        - node.role == manager   # Or remove for all nodes
    labels:
      - "dsd.cadvisor=true"
  networks:
    - your-network-name
  volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:ro
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro
    - /dev/disk/:/dev/disk:ro
  command:
    - '--docker_only=true'
    - '--housekeeping_interval=30s'

Customize Discovery Label:

environment:
  DSD_CADVISOR_LABEL: "my.custom.label"

Metrics Displayed

Node Exporter Metrics:

  • CPU usage per node
  • Memory usage per node
  • Disk I/O and storage
  • Network traffic per node

cAdvisor Metrics (Service Metrics Tab):

  • Total Memory Usage: Aggregate memory usage across all containers in the service
  • Memory Limits: Configured memory limits for each container
  • Per-Container Breakdown: Memory usage for each task/container in the service
  • Usage Percentage: Memory usage as a percentage of the configured limit

Benefits of cAdvisor:

  • Identify memory-hungry containers within a service
  • Monitor services approaching memory limits
  • Detect potential out-of-memory (OOM) situations before they occur

Network Configuration

Both services should be attached to the same overlay network as the dashboard for container-to-container communication:

networks:
  - your-network-name  # Same network as docker-swarm-dashboard

This ensures metrics are only reachable from within the overlay network (recommended for security).

logs-generator (for testing)

docker service create --name logger chentex/random-logger:latest 50 200

Development

Local Build

docker build -t ghcr.io/heckenmann/docker-swarm-dashboard:local .

Run api-mock-server

# from app-src
yarn run start-api-mock

Run UI

# from app-src
yarn run start-dev-server

When you run the UI with the api-mock-server, you have to open the ui with "base"-param (API-URL): http://localhost:3000#base="http%3A%2F%2Flocalhost%3A3001%2F"

Run UI-tests

# from app-src
yarn run cy:run