As well as the default start view, Dashy has several other start pages, for different tasks. You can switch views with the view-switcher button in the top-right, or set a default starting view using the appConfig.startingView attribute (can be default, minimal or workspace).
This is the main page that you will land on when you first launch the application. Here all of your sections and items will be visible, you can modify settings and search + launch your applications.
The workspace view displays your links in a sidebar on the left-hand side, and apps are launched within Dashy. This enables you to use all of your self-hosted apps from one place, and makes multi-tasking easy.
In the workspace view, you can keep previously opened websites/ apps open in the background, by setting appConfig.enableMultiTasking: true. This comes at the cost of performance, but does mean that your session with each app is preserved, enabling you to quickly switch between your apps.
The minimal view aims to be super fast and simple, and can be used as a browser startpage. Items are grouped into a tab view, and the last opened tab will be remembered. Similar to the main view, you can search and launch items just by typing, and right-clicking will show more options.
Dashy supports several different ways to launch your apps. The default opening method for each app can be specified using the target attribute, with a value of one of the following:
sametab - The app will be launched in the current tab
newtab - The app will be launched in a new tab
modal - Launch app in a resizable/ movable popup modal on the current page
workspace - Changes to Workspace view, and launches app
Even if the target is not set (or is set to sametab), you can still launch any given app in an alternative method: Alt + Click will open the modal, and Ctrl + Click will open in a new tab. You can also right-click on any item to see all options (as seen in the screenshot below). This custom context menu can be disabled by setting appConfig.disableContextMenu: true.
If you get a 'Refused to Connect' error in the modal or workspace views, then the target app has it's X-Frame-Options HTTP set to block requests from embedded content. You can easily fix this by setting this header to ALLOW, for instructions on how to do so, see the Troubleshooting Docs.
Dashy has a basic login page included, and frontend authentication. You can enable this by adding users to the auth section under appConfig in your conf.yml. If this section is not specified, then no authentication will be required to access the app, and it the homepage will resolve to your dashboard.
The auth property takes an array of users. Each user needs to include a username, hash and optional user type (admin or normal). The hash property is a SHA-256 Hash of your desired password.
Dashy uses SHA-256 Hash, a 64-character string, which you can generate using an online tool, such as this one or CyberChef (which can be self-hosted/ ran locally).
A hash is a one-way cryptographic function, meaning that it is easy to generate a hash for a given password, but very hard to determine the original password for a given hash. This means, that so long as your password is long, strong and unique, it is safe to store it's hash in the clear. Having said that, you should never reuse passwords, hashes can be cracked by iterating over known password lists, generating a hash of each.
Once authentication is enabled, so long as there is no valid token in cookie storage, the application will redirect the user to the login page. When the user enters credentials in the login page, they will be checked, and if valid, then a token will be generated, and they can be redirected to the home page. If credentials are invalid, then an error message will be shown, and they will remain on the login page. Once in the application, to log out the user can click the logout button (in the top-right), which will clear cookie storage, causing them to be redirected back to the login page.
With authentication setup, by default no access is allowed to your dashboard without first logging in with valid credentials. Guest mode can be enabled to allow for read-only access to a secured dashboard by any user, without the need to log in. A guest user cannot write any changes to the config file, but can apply modifications locally (stored in their browser). You can enable guest access, by setting appConfig.enableGuestAccess: true.
Since all authentication is happening entirely on the client-side, it is vulnerable to manipulation by an adversary. An attacker could look at the source code, find the function used generate the auth token, then decode the minified JavaScript to find the hash, and manually generate a token using it, then just insert that value as a cookie using the console, and become a logged in user. Therefore, if you need secure authentication for your app, it is strongly recommended to implement this using your web server, or use a VPN to control access to Dashy. The purpose of the login page is merely to prevent immediate unauthorized access to your homepage.
Addressing this is on the todo list, and there are several potential solutions:
Encrypt all site data against the users password, so that an attacker can not physically access any data without the correct decryption key
Use a backend service to handle authentication and configuration, with no user data returned from the server until the correct credentials are provided. However, this would require either Dashy to be run using it's Node.js server, or the use of an external service
Implement authentication using a self-hosted identity management solution, such as Keycloak for VueThis is now implemented, and released in PR #174 of V 1.6.5!
Dashy also supports using a Keycloack authentication server. The setup for this is a bit more involved, but it gives you greater security overall, useful for if your instance is exposed to the internet.
Keycloak is a Java-based open source, high-performance, secure authentication system, supported by RedHad. It is easy to setup (with Docker), and enables you to secure multiple self-hosted applications with single-sign on using standard protocols (OpenID Connect, OAuth 2.0, SAML 2.0 and social login). It's also very customizable, you can write or use custom themes, plugins, password policies and more.
+The following guide will walk you through setting up Keycloak with Dashy. If you already have a Keycloak instance configured, then skip to Step 3.
First thing to do is to spin up a new instance of Keycloak. You will need Docker installed, and can then choose a tag, and pull the container from quay.io/keycloak/keycloak
Use the following run command, replacing the attributes (default credentials, port and name), or incorporate this into your docker-compose file.
If you need to pull from DockerHub, a non-official image is available here. Or if you would prefer not to use Docker, you can also directly install Keycloak from source, following this guide.
You should now be able to access the Keycloak web interface, using the port specified above (e.g. http://127.0.0.1:8081), login with the default credentials, and when prompted create a new password.
Before we can use Keycloak, we must first set it up with some users. Keycloak uses Realms (similar to tenants) to create isolated groups of users. You must create a Realm before you will be able to add your first user.
Head over to the admin console
In the top-left corner there is a dropdown called 'Master', hover over it and then click 'Add Realm'
Give your realm a name, and hit 'Create'
You can now create your first user.
In the left-hand menu, click 'Users', then 'Add User'
Fill in the form, including username and hit 'Save'
Under the 'Credentials' tab, give the new user an initial password. They will be prompted to change this after first login
The last thing we need to do in the Keycloak admin console is to create a new client
Within your new realm, navigate to 'Clients' on the left-hand side, then click 'Create' in the top-right
Choose a 'Client ID', set 'Client Protocol' to 'openid-connect', and for 'Valid Redirect URIs' put a URL pattern to where you're hosting Dashy (if you're just testing locally, then * is fine), and do the same for the 'Web Origins' field
Now that your Keycloak instance is up and running, all that's left to do is to configure Dashy to use it. Under appConfig, set auth.enableKeycloak: true, then fill in the details in auth.keycloak, including: serverUrl - the URL where your Keycloak instance is hosted, realm - the name you gave your Realm, and clientId - the Client ID you chose.
+For example:
Your app is now secured :) When you load Dashy, it will redirect to your Keycloak login page, and any user without valid credentials will be prevented from accessing your dashboard.
From within the Keycloak console, you can then configure things like user permissions, time outs, password policies, access, etc. You can also backup your full Keycloak config, and it is recommended to do this, along with your Dashy config. You can spin up both Dashy and Keycloak simultaneously and restore both applications configs using a docker-compose.yml file, and this is recommended.
If you are self-hosting Dashy, and require secure authentication to prevent unauthorized access, then you can either use Keycloak, or one of the following options:
Authelia is an open-source full-featured authentication server, which can be self-hosted and either on bare metal, in a Docker container or in a Kubernetes cluster. It allows for fine-grained access control rules based on IP, path, users etc, and supports 2FA, simple password access or bypass policies for your domains.
A catch-all solution to accessing services running from your home network remotely is to use a VPN. It means you do not need to worry about implementing complex authentication rules, or trusting the login implementation of individual applications. However it can be inconvenient to use on a day-to-day basis, and some public and corporate WiFi block VPN connections. Two popular VPN protocols are OpenVPN and WireGuard
If you have a static IP or use a VPN to access your running services, then you can use conditional access to block access to Dashy from everyone except users of your pre-defined IP address. This feature is offered by most cloud providers, and supported by most web servers.
Most web servers make password protecting certain apps very easy. Note that you should also set up HTTPS and have a valid certificate in order for this to be secure.
First crate a .htaccess file in Dashy's route directory. Specify the auth type and path to where you want to store the password file (usually the same folder). For example:
Then create a .htpasswd file in the same directory. List users and their hashed passwords here, with one user on each line, and a colon between username and password (e.g. [username]:[hashed-password]). You will need to generate an MD5 hash of your desired password, this can be done with an online tool. Your file will look something like:
NGINX has an authentication module which can be used to add passwords to given sites, and is fairly simple to set up. Similar to above, you will need to create a .htpasswd file. Then just enable auth and specify the path to that file, for example:
Caddy has a basic-auth directive, where you specify a username and hash. The password hash needs to be base-64 encoded, the caddy hash-password command can help with this. For example:
You can use the mod_auth module to secure your site with Lighttpd. Like with Apache, you need to first create a password file listing your usersnames and hashed passwords, but in Lighttpd, it's usually called .lighttpdpassword.
Then in your lighttpd.conf file (usually in the /etc/lighttpd/ directory), load in the mod_auth module, and configure it's directives. For example:
There are also authentication services, such as Ory.sh, Okta, Auth0, Firebase. Implementing one of these solutions would involve some changes to the Auth.js file, but should be fairly straight forward.
Dashy has a built-in feature for securely backing up your config to a hosted cloud service, and then restoring it on another instance. This feature is totally optional, and if you do not enable it, then Dashy will not make any external network requests.
This is useful not only for backing up your configuration off-site, but it also enables Dashy to be used without having write a YAML config file, and makes it possible to use a public hosted instance, without the need to self-host.
All data is encrypted before being sent to the backend. In Dashy, this is done in CloudBackup.js, using crypto.js's AES method, using the users chosen password as the key. The data is then sent to a Cloudflare worker (a platform for running serverless functions), and stored in a KV data store.
Once you've got Dashy configured to your preference, open the Backup & Restore menu (click the Cloud icon in the top-right corner). Here you will be prompted to choose a password, which will be used to encrypt your data. If you forget this password, there will be no way to recover your config. After clicking 'Backup' your data will be encrypted, compressed and sent to the hosted cloud service. A backup ID will be returned (in the format of xxxx-xxxx-xxxx-xxxx), this is what you use, along with your password to restore the backup on another system, so take note of it. To update a backup, return to this menu, enter your password, and click 'Update Backup'.
To restore a backup, navigate to the Backup & Restore menu, and under restore, enter your backup ID, and the password you chose. Your config file will be downloaded, decrypted and applied to local storage.
Data is only ever sent to the cloud when the user actively triggers a backup. All transmitted data is first encrypted using AES. Your selected password never leaves your device, and is hashed before being compared. It is only possible to restore a configuration if you have both the backup ID and decryption password.
Because the data is encrypted on the client-side (before being sent to the cloud), it is not possible for a man-in-the-middle, government entity, website owner, or even Cloudflare to be able read any of your data. The biggest risk to your data, would be a weak password, or a compromised system.
Having said that, although the code uses robust security libraries and is open source- it was never intended to be a security product, and has not been audited, and therefore cannot be considered totally secure - please keep that in mind.
Maximum of 24mb of storage per user. Please do not repeatedly hit the endpoint, as if the quota is exceeded the service may become less available to other users. Abuse may result in your IP being temporarily banned by Cloudflare.
We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+alicia@omg.lol.
+All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
Community Impact: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
Community Impact: A violation through a single incident or series
+of actions.
Consequence: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
Community Impact: A serious violation of community standards, including
+sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
Community Impact: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within
+the community.
You may find it helpful to look at some sample config files to get you started, a collection of which can be found here
You can check that your config file fits the schema, by running yarn validate-config
After modifying your config, the app needs to be recompiled, by running yarn build - this happens automatically whilst the app is running if you're using Docker
It is recommended to make and keep a backup of your config file. You can download your current config through the UI either from the Config menu, or using the /download endpoint. Alternatively, you can use the Cloud Backup feature.
The config can also be modified directly through the UI, validated and written to the conf.yml file.
If you're new to YAML, it's pretty straight-forward. The format is exactly the same as that of JSON, but instead of using curly braces, structure is denoted using whitespace. This quick guide should get you up to speed in a few minutes, for more advanced topics take a look at this Wikipedia article.
When updating the config through the JSON editor in the UI, you have two save options: Local or Write to Disk.
Changes saved locally will only be applied to the current user through the browser, and will not apply to other instances - you either need to use the cloud sync feature, or manually update the conf.yml file.
On the other-hand, if you choose to write changes to disk, then your main conf.yml file will be updated, and changes will be applied to all users, and visible across all devices. For this functionality to work, you must be running Dashy with using the Docker container, or the Node server. A backup of your current configuration will also be saved in the same directory.
To disallow any changes from being written to disk via the UI config editor, set appConfig.allowConfigEdit: false. If you are using users, and have setup auth within Dashy, then only users with type: admin will be able to write config changes to disk.
Your dashboard title, displayed in the header and browser tab
description
string
Optional
Description of your dashboard, also displayed as a subtitle
navLinks
array
Optional
Optional list of a maximum of 6 links, which will be displayed in the navigation bar. See navLinks
footerText
string
Optional
Text to display in the footer (note that this will override the default footer content). This can also include HTML and inline CSS
logo
string
Optional
The path to an image to display in the header (to the right of the title). This can be either local, where / is the root of ./public, or any remote image, such as https://i.ibb.co/yhbt6CY/dashy.png. It's recommended to scale your image down, so that it doesn't impact load times
The 2 (or 4-digit) ISO 639-1 code for your language, e.g. en or en-GB. This must be a language that the app has already been translated into. If your language is unavailable, Dashy will fallback to English. By default Dashy will attempt to auto-detect your language, although this may not work on some privacy browsers.
startingView
enum
Optional
Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either default, minimal or workspace. Defaults to default
statusCheck
boolean
Optional
When set to true, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting statusCheck under each item. Defaults to false
statusCheckInterval
boolean
Optional
The number of seconds between checks. If set to 0 then service will only be checked on initial page load, which is usually the desired functionality. If value is less than 10 you may experience a hit in performance. Defaults to 0
backgroundImg
string
Optional
Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
enableFontAwesome
boolean
Optional
Where true is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
fontAwesomeKey
string
Optional
If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. 13014ae648)
faviconApi
enum
Optional
Only applicable if you are using favicons for item icons. Specifies which service to use to resolve favicons. Set to local to do this locally, without using an API. Services running locally will use this option always. Available options are: local, faviconkit, google, clearbit, webmasterapi and allesedv. Defaults to faviconkit. See Icons for more info
auth
object
Optional
All settings relating to user authentication. See auth
layout
enum
Optional
App layout, either horizontal, vertical, auto or sidebar. Defaults to auto. This specifies the layout and direction of how sections are positioned on the home screen. This can also be modified from the UI.
iconSize
enum
Optional
The size of link items / icons. Can be either small, medium, or large. Defaults to medium. This can also be set directly from the UI.
theme
string
Optional
The default theme for first load (you can change this later from the UI)
cssThemes
string[]
Optional
An array of custom theme names which can be used in the theme switcher dropdown
customColors
object
Optional
Enables you to apply a custom color palette to any given theme. Use the theme name (lowercase) as the key, for an object including key-value-pairs, with the color variable name as keys, and 6-digit hex code as value. See Theming for more info
externalStyleSheet
string or string[]
Optional
Either a URL to an external stylesheet or an array or URLs, which can be applied as themes within the UI
customCss
string
Optional
Raw CSS that will be applied to the page. This can also be set from the UI. Please minify it first.
hideComponents
object
Optional
A list of key page components (header, footer, search, settings, etc) that are present by default, but can be removed using this option. See appConfig.hideComponents
enableMultiTasking
boolean
Optional
If set to true, will keep apps open in the background when in the workspace view. Useful for quickly switching between multiple sites, and preserving their state, but comes at the cost of performance.
allowConfigEdit
boolean
Optional
Should prevent / allow the user to write configuration changes to the conf.yml from the UI. When set to false, the user can only apply changes locally using the config editor within the app, whereas if set to true then changes can be written to disk directly through the UI. Defaults to true. Note that if authentication is enabled, the user must be of type admin in order to apply changes globally.
enableErrorReporting
boolean
Optional
Enable reporting of unexpected errors and crashes. This is off by default, and no data will ever be captured unless you explicitly enable it. Turning on error reporting helps previously unknown bugs get discovered and fixed. Dashy uses Sentry for error reporting. Defaults to false.
sentryDsn
boolean
Optional
If you need to monitor errors in your instance, then you can use Sentry to collect and process bug reports. Sentry can be self-hosted, or used as SaaS, once your instance is setup, then all you need to do is pass in the DSN here, and enable error reporting. You can learn more on the Sentry DSN Docs. Note that this will only ever be used if enableErrorReporting is explicitly enabled.
disableUpdateChecks
boolean
Optional
If set to true, Dashy will not check for updates. Defaults to false.
disableServiceWorker
boolean
Optional
Service workers cache web applications to improve load times and offer basic offline functionality, and are enabled by default in Dashy. The service worker can sometimes cause older content to be cached, requiring the app to be hard-refreshed. If you do not want SW functionality, or are having issues with caching, set this property to true to disable all service workers.
disableContextMenu
boolean
Optional
If set to true, the custom right-click context menu will be disabled. Defaults to false.
An array of objects containing usernames and hashed passwords. If this is not provided, then authentication will be off by default, and you will not need any credentials to access the app. See appConfig.auth.users. Note this method of authentication is handled on the client side, so for security critical situations, it is recommended to use an alternate authentication method.
enableKeycloak
object
Optional
If set to true, then authentication using Keycloak will be anabled. Note that you need to have an instance running, and have also configured auth.keycloak. Defaults to false
keycloak
boolean
Optional
Config options to point Dashy to your Keycloak server. Requires enableKeycloak: true. See auth.keycloak for more info
enableGuestAccess
boolean
Optional
When set to true, an unauthenticated user will be able to access the dashboard, with read-only access, without having to login. Requires auth.users to be configured. Defaults to false.
If set to true, the page title & sub-title will not be visible. Defaults to false
hideNav
boolean
Optional
If set to true, the navigation menu will not be visible. Defaults to false
hideSearch
boolean
Optional
If set to true, the search bar will not be visible. Defaults to false
hideSettings
boolean
Optional
If set to true, the settings menu will not be visible. Defaults to false
hideFooter
boolean
Optional
If set to true, the footer will not be visible. Defaults to false
hideSplashScreen
boolean
Optional
If set to true, splash screen will not be visible while the app loads. Defaults to true (except on first load, when the loading screen is always shown)
The text to display/ title of a given item. Max length 18
description
string
Optional
Additional info about an item, which is shown in the tooltip on hover, or visible on large tiles
url
string
Required
The URL / location of web address for when the item is clicked
icon
string
Optional
The icon for a given item. Can be a font-awesome icon, favicon, remote URL or local URL. See item.icon
target
string
Optional
The opening method for when the item is clicked, either newtab, sametab, modal or workspace. Where newtab will open the link in a new tab, sametab will open it in the current tab, and modal will open a pop-up modal with the content displayed within that iframe. Note that for the iframe to load, you must have set the CORS headers to either allow * ot allow the domain that you are hosting Dashy on, for some websites and self-hosted services, this is already set.
hotkey
number
Optional
Give frequently opened applications a numeric hotkey, between 0 - 9. You can then just press that key to launch that application.
tags
string[]
Optional
A list of tags, which can be used for improved search
statusCheck
boolean
Optional
When set to true, Dashy will ping the URL associated with the current service, and display its status as a dot next to the item. The value here will override appConfig.statusCheck so you can turn off or on checks for a given service. Defaults to appConfig.statusCheck, falls back to false
statusCheckUrl
string
Optional
If you've enabled statusCheck, and want to use a different URL to what is defined under the item, then specify it here
statusCheckHeaders
object
Optional
If you're endpoint requires any specific headers for the status checking, then define them here
color
string
Optional
An optional color for the text and font-awesome icon to be displayed in. Note that this will override the current theme and so may not display well
backgroundColor
string
Optional
An optional background fill color for the that given item. Again, this will override the current theme and so might not display well against the background
provider
string
Optional
The name of the provider for a given service, useful for when including hosted apps. In some themes, this is visible under the item name
If true, the section will be collapsed initially, and will need to be clicked to open. Useful for less regularly used, or very long sections. Defaults to false
color
string
Optional
A custom accent color for the section, as a hex code or HTML color (e.g. #fff)
customStyles
string
Optional
Custom CSS properties that should be applied to that section, e.g. border: 2px dashed #ff0000;
itemSize
string
Optional
Specify the size for items within this group, either small, medium or large. Note that this will overide any settings specified through the UI
rows
number
Optional
Height of the section, specified as the number of rows it should span vertically, e.g. 2. Defaults to 1. Max is 5.
cols
number
Optional
Width of the section, specified as the number of columns the section should span horizontally, e.g. 2. Defaults to 1. Max is 5.
sectionLayout
string
Optional
Specify which CSS layout will be used to responsivley place items. Can be either auto (which uses flex layout), or grid. If grid is selected, then itemCountX and itemCountY may also be set. Defaults to auto
itemCountX
number
Optional
The number of items to display per row / horizontally. If not set, it will be calculated automatically based on available space. Can only be set if sectionLayout is set to grid. Must be a whole number between 1 and 12
itemCountY
number
Optional
The number of items to display per column / vertically. If not set, it will be calculated automatically based on available space. If itemCountX is set, then itemCountY can be calculated automatically. Can only be set if sectionLayout is set to grid. Must be a whole number between 1 and 12
hideForUsers
string[]
Optional
Current section will be visible to all users, except for those specified in this list
showForUsers
string[]
Optional
Current section will be hidden from all users, except for those specified in this list
hideForGuests
boolean
Optional
Current section will be visible for logged in users, but not for guests (see appConfig.enableGuestAccess). Defaults to false
The icon for a given item or section. Can be a font-awesome icon, favicon, remote URL or local URL. If set to favicon, the icon will be automatically fetched from the items website URL. To use font-awesome, specify the category, followed by the icon name, e.g. fas fa-rocket, fab fa-monero or fal fa-duck - note that to use pro icons, you mut specify appConfig.fontAwesomeKey. Similarly, you can also use simple-icons by setting icon to si-[icon-name] or material-design-icons by setting icon to mdi-[icon-name]. If set to generative, then a unique icon is generated from the apps URL or IP. You can also use hosted any by specifying it's URL, e.g. https://i.ibb.co/710B3Yc/space-invader-x256.png. To use a local image, first store it in ./public/item-icons/ (or -v /app/public/item-icons/ in Docker) , and reference it by name and extension - e.g. set image.png to use ./public/item-icon/image.png, you can also use sub-folders if you have a lot of icons, to keep them organised.
---pageInfo:title: Home Labsections:# An array of sections-name: Section 1 - Getting Starteditems:# An array of items-title: GitHubdescription: Source code and documentation on GitHubicon: fab fa-githuburl: https://github.com/Lissy93/dashy-title: Issuesdescription: View currently open issues, or raise a new oneicon: fas fa-bugurl: https://github.com/Lissy93/dashy/issues-title: Demodescription: A live demoicon: far fa-rocketurl: https://dashy-demo-1.netlify.app -name: Section 2 - Local Servicesitems:-title: Firewallicon: faviconurl: http://192.168.1.1/-title: Game Servericon: https://i.ibb.co/710B3Yc/space-invader-x256.pngurl: http://192.168.130.1/
First off, thank you for considering contributing towards Dashy! 🙌
+There are several ways that you can help out (but don't feel you have to).
+Any contributions, however small will always be very much appreciated, and you will be appropriately credited in the readme - huge thank you to everyone who has helped so far 💞
Contributing to the code or documentation is super helpful. You can fix a bug, add a new feature or improve an existing one. I've written several guides to help you get started. For setting up the development environment, outline of the standards, and understanding the PR flow, see the Development Docs. I've tried to keep the code neat and documentation thorough, so understanding what everything does should be fairly straight forward, but feel free to ask if you have any questions.
If you speak another language, then adding translations would be really helpful, and you will be credited in the readme for your work. Multi-language support makes Dashy accessible for non-English speakers, which I feel is important. This is a very quick and easy task, as all application text is located in locales/en.json, so adding a new language is as simple as copying this file and translating the values. You don't have to translate it all, as any missing attributes will just fallback to English. For a full tutorial, see the Multi-Language Support Docs.
Help improve Dashy by taking a very short, 6-question survey. This will give me a better understanding of what is important to you, so that I can make Dashy better in the future :)
Dashy now has a Showcase where you can show off a screenshot of your dashboard, and get inspiration from other users. I also really enjoy seeing how people are using Dashy. To submit your dashboard, please either open a PR or raise an issue.
Found a typo, or something that isn't as clear as it could be? Maybe I've missed something off altogether, or you hit a roadblock that took you a while to figure out. Submitting a pull request to add to or improve the documentation will help future users get Dashy up and running more easily.
+All content is located either in the README or /docs/ directory, and synced to the Wiki and website using a GH action (workflows/wiki-sync.yml).
If you've found a bug, then please do raise it as an issue. This will help me know if there's something that needs fixing. Try and include as much detail as possible, such as your environment, steps to reproduce, any console output and maybe an example screenshot or recording if necessary.
I've enabled the discussion feature on GitHub, here you can share tips and tricks, useful information, or your dashboard. You can also ask questions, and offer basic support to other users.
Dashy is still a relatively young project, and as such not many people know of it. It would be great to see more users, and so it would be awesome if you could consider sharing on social platforms.
Please only do this is you can definitely afford to. Don't feel any pressure to donate anything, as Dashy and my other projects will always be 100% free, for everyone, for ever.
Sponsoring will give you several perks, from $1 / £0.70 per month, as well as a sponsor badge on your profile, you can also be credited on the readme, with a link to your website/ profile/ socials, get priority support, have your feature ideas implemented, plus lots more. For more info, see @Lissy93's Sponsor Page.
BountySource is a platform for sponsoring the development of certain features on open source projects. If there is a feature you'd like implemented into Dashy, but either isn't high enough priority or is deemed to be more work than it's worth, then you can instead contribute a bounty towards it's development. You won't pay a penny until your proposal is fully built, and you are satisfied with the result. This helps support the developers, and makes Dashy better for everyone.
Sentry is an open source error tracking and performance monitoring tool, which enables the identification any errors which occur in the production app (only if you enable it). It helps me to discover bugs I was unaware of, and then fix them, in order to make Dashy more reliable long term. This is a simple, yet really helpful step you can take to help improve Dashy.
To enable error reporting:
appConfig:enableErrorReporting:true
All reporting is disabled by default, and no data will ever be sent to any external endpoint without your explicit consent. In fact, the error tracking package will not even be imported unless you have actively enabled it. All statistics are anonomized and stored securely. For more about privacy and security, see the Sentry Docs.
This app definitely wouldn't have been quite so possible without the making use of the following package and components. Full credit and big kudos to their respective authors, who've done an amazing job in building and maintaining them. For a full breakdown of dependency licenses, please see Legal
At it's core, the application uses Vue.js, as well as it's services. Styling is done with SCSS, JavaScript is currently Babel, (but I am in the process of converting to TypeScript). Linting is done with ESLint and Prettier, both following the AirBnB Styleguide. The config is defined in YAML, and there is a simple Node.js server to serve up the static app and the optional API endpoints.
Although the app is purely frontend, there is an optional cloud backup and restore feature. This is built as a serverless function on Cloudflare workers using KV and web crypto
Welcome to Dashy, so glad you're here :) Deployment is super easy, and there are several methods available depending on what type of system you're using. If you're self-hosting, then deploying with Docker (or similar container engine) is the recommended approach.
-d Detached mode (not running in the foreground of your terminal)
-p The port that should be exposed, and the port it should be mapped to in your host system [host-port][container-port], leave the container port as is
-v Specify volumes, to pass data from your host system to the container, in the format of [host-path]:[container-path], you can use this to pass your config file, directory of assets (like icons), custom CSS or web assets (like favicon.ico, manifest.json etc)
--name Give your container a human-readable name
--restart=always Spin up the container when the daemon starts, or after it has been stopped
lissy93/dashy:latest This last option is the image the container should be built from, you can also use a specific version or architecture type, by replacing :latest with one of the tags
For all available options, and to learn more, see the Docker Run Docs
Dashy is also available through GHCR: docker pull ghcr.io/lissy93/dashy:latest
If you're deploying Dashy on a modern ARM-based board, such as a Raspberry Pi (2+), then you'll need to use one of Dashy's ARM images. Set the base image + tag to either lissy93/dashy:arm64v8 or lissy93/dashy:arm32v7, depending on your system architecture. You can also use the multi-arch image, which should work on all system architectures.
The image defaults to :latest, but you can instead specify a specific version, e.g. docker pull lissy93/dashy:release-1.5.0
Using Docker Compose can be useful for saving your specific config in files, without having to type out a long run command each time. Save compose config as a YAML file, and then run docker compose up (optionally use the -f flag to specify file location, if it isn't located at ./docker-compose.yml). Compose is also useful if you are using clusters, as the format is very similar to stack files, used with Docker Swarm.
The following is a complete example of a docker-compose.yml for Dashy. Run it as is, or uncomment the additional options you need.
---version:"3.8"services:dashy:# To build from source, replace 'image: lissy93/dashy' with 'build: .'# build: .image: lissy93/dashycontainer_name: Dashy# Pass in your config file below, by specifying the path on your host machine# volumes:# - /root/my-config.yml:/app/public/conf.ymlports:- 4000:80# Set any environmental variablesenvironment:- NODE_ENV=production# Specify your user ID and group ID. You can find this by running `id -u` and `id -g`# - UID=1000# - GID=1000# Specify restart policyrestart: unless-stopped# Configure healthcheckshealthcheck:test:['CMD','node','/app/services/healthcheck']interval: 1m30stimeout: 10sretries:3start_period: 40s
You can use a different tag, by for example setting image: lissy93/dashy:arm64v8, or pull from GHCR instead by setting image: ghcr.io/lissy93/dashy.
If you are building from source, and would like to use one of the other Dockerfiles, then under services.dashy first set context: ., then specify the the path to the dockerfile, e.g. dockerfile: ./docker/Dockerfile-arm32v7
If you do not want to use Docker, you can run Dashy directly on your host system. For this, you will need both git and the latest or LTS version of Node.js installed, and optionally yarn
Get Code: git clone https://github.com/Lissy93/dashy.git and cd dashy
Configuration: Fill in you're settings in ./public/conf.yml
If you don't have a home server, then fear not - Dashy can be deployed to pretty much any cloud provider. The above Docker and NPM guides will work exactly the same on a VPS, but I've also setup some 1-Click deploy links for 10+ of the most common cloud providers, to make things easier. Note that if your instance is exposed to the internet, it will be your responsibility to adequately secure it.
Some hosting providers required a bit of extra configuration, which was why I've made separate branches for deploying to those services (named: deploy_cloudflare, deploy_digital-ocean, deploy_platform-sh and deploy_render). If there's another cloud service which you'd like 1-click deployment to be supported for, feel free to raise an issue.
Note If you use a static hosting provider, then status checks, writing new config changes to disk from the UI, and triggering a rebuild through the UI will not be availible. This is because these features need endpoints provided by Dashy's local Node server. Everything else should work just the same though.
Netlify offers Git-based serverless cloud hosting for web applications. Their services are free to use for personal use, and they support deployment from both public and private repos, as well as direct file upload. The free plan also allows you to use your own custom domain or sub-domain, and is easy to setup.
To deploy Dashy to Netlify, use the following link
Heroku is a fully managed cloud platform as a service. You define app settings in a Procfile and app.json, which specifying how the app should be build and how the server should be started. Heroku is free to use for unlimited, non-commercial, single dyno apps, and supports custom domains. Heroku's single-dyno service is not as quite performant as some other providers, and the app will have a short wake-up time when not visited for a while
Cloudflare Workers is a simple yet powerful service for running cloud functions and hosting web content. It requires a Cloudflare account, but is completely free for smaller projects, and very reasonably priced ($0.15/million requests per month) for large applications. You can use your own domain, and applications are protected with Cloudflare's state of the art DDoS protection. For more info, see the docs on Worker Sites
To deploy Dashy to Cloudflare, use the following link
Vercel is a performance-focused platform for hosting static frontend apps. It comes bundled with some useful tools for monitoring and anaylzing application performance and other metrics. Vercel is free for personal use, allows for custom domains and has very reasonable limits.
DigitalOcan is a cloud service providing affordable developer-friendly virtual machines from $5/month. But they also have an app platform, where you can run web apps, static sites, APIs and background workers. CDN-backed static sites are free for personal use.
Cloud Run is a service offered by Google Cloud. It's a fully managed serverless platform, for developing and deploying highly scalable containerized applications. Similar to AWS and Azure, GCP offers a wide range of cloud services, which are billed on a pay‐per‐use basis, but Cloud Run has a free tier offering 180,000 vCPU-seconds, 360,000 GiB-seconds, and 2 million requests per month.
Platform.sh is an end-to-end solution for developing and deploying applications. It is geared towards enterprise users with large teams, and focuses on allowing applications to scale up and down. Unlike the above providers, Platform.sh is not free, although you can deploy a test app to it without needing a payment method
To deploy Dashy to Platform.sh, use the following link
Render is cloud provider that provides easy deployments for static sites, Docker apps, web services, databases and background workers. Render is great for developing applications, and very easy to use. Static sites are free, and services start at $7/month. Currently there are only 2 server locations - Oregon, USA and Frankfurt, Germany. For more info, see the Render Docs
Scalingo is a scalable container-based cloud platform as a service. It's focus is on compliance and uptime, and is geared towards enterprise users. Scalingo is also not free, although they do have a 3-day free trial that does not require a payment method
To deploy Dashy to Scalingo, use the following link
Play with Docker is a community project by Marcos Liljedhal and Jonathan Leibiusky and sponsored by Docker, intended to provide a hands-on learning environment. Their labs let you quickly spin up a Docker container or stack, and test out the image in a temporary, sandboxed environment. There's no need to sign up, and it's completely free.
Once Dashy has been built, it is effectivley just a static web app. This means that it can be served up with pretty much any static host, CDN or web server. To host Dashy through a CDN, the steps are very similar to building from source: clone the project, cd into it, install dependencies, write your config file and build the app. Once build is complete you will have a ./dist directory within Dashy's root, and this is the build application which is ready to be served up.
However without Dashy's node server, there are a couple of features that will be unavailible to you, including: Writing config changes to disk through the UI, triggering a rebuild through the UI and application status checks. Everything else will work fine.
This article outlines how to get Dashy running in a development environment, and outlines the basics of the architecture.
+If you're adding new features, you may want to check out the Development Guides docs, for tutorials covering basic tasks.
You will need either the latest or LTS version of Node.js to build and serve the application and Git to easily fetch the code, and push any changes. If you plan on running or deploying the container, you'll also need Docker. To avoid any unexpected issues, ensure you've got at least NPM V 7.5 or Yarn 1.22 (you may find NVM helpful for switching/ managing versions).
Get Code: git clone https://github.com/Lissy93/dashy.git
Navigate into the directory: cd dashy
Install dependencies: yarn
Start dev server: yarn dev
Dashy should now be being served on http://localhost:8080/. Hot reload is enabled, so making changes to any of the files will trigger them to be rebuilt and the page refreshed.
yarn dev - Starts the development server with hot reloading
yarn build - Builds the project for production, and outputs it into ./dist
yarn start - Starts a web server, and serves up the production site from ./dist
yarn validate-config - Parses and validates your conf.yml against Dashy's schema
yarn lint - Lints code to ensure it follows a consistent, neat style
yarn test - Runs tests, and outputs results
There is also:
yarn build-and-start will run yarn build and yarn start
yarn build-watch will output contents to ./dist and recompile when anything in ./src is modified, you can then use either yarn start or your own server, to have a production environment that watches for changes.
Using the Vue CLI:
The app is build with Vue, and uses the Vue-CLI Service for basic commands.
If you have NPX installed, then you can invoke the Vue CLI binary using npx vue-cli-service [command]
Vue also has a GUI environment that can be used for basic project management, and may be useful for beginners, this can be started by running vue ui, and opening up http://localhost:8000
Note:
If you are using NPM, replace yarn with npm run
If you are using Docker, precede each command with docker exec -it [container-id]. Container ID can be found by running docker ps
All environmental variables are optional. Currently there are not many environmental variables used, as most of the user preferences are stored under appConfig in the conf.yml file.
You can set variables within your local development environment using a .env file.
Any environmental variables used by the frontend are preceded with VUE_APP_. Vue will merge the contents of your .env file into the app in a similar way to the 'dotenv' package, where any variables that you set on your system will always take preference over the contents of any .env file.
PORT - The port in which the application will run (defaults to 4000 for the Node.js server, and 80 within the Docker container)
NODE_ENV - Which environment to use, either production, development or test
VUE_APP_DOMAIN - The URL where Dashy is going to be accessible from. This should include the protocol, hostname and (if not 80 or 443), then the port too, e.g. https://localhost:3000, http://192.168.1.2:4002 or https://dashy.mydomain.com
If you do add new variables, ensure that there is always a fallback (define it in defaults.js), so as to not cause breaking changes. Don't commit your .env file to git, but instead take a few moments to document what you've added under the appropriate section. Try and follow the concepts outlined in the 12 factor app.
You can set the environment using the NODE_ENV variable.
+The correct environment will be selected based on the script you run by default
+The following environments are supported.
The format of your branch name should be something similar to: [TYPE]/[TICKET]_[TITLE]
+For example, FEATURE/420_Awesome-feature or FIX/690_login-server-error
New to Web Development? Glad you're here! Dashy is a pretty simple app, so it should make a good candidate for your first PR. Presuming that you already have a basic knowledge of JavaScript, the following articles should point you in the right direction for getting up to speed with the technologies used in this project:
Linting is done using ESLint, and using the Vue.js Styleguide, which is very similar to the AirBnB Stylguide. You can run yarn lint to report and fix issues. While the dev server is running, issues will be reported to the console automatically, and any lint errors will trigger the build to fail. Note that all lint checks must pass before any PR can be merged. Linting is also run as a git pre-commit hook
The most significant things to note are:
Indentation should be done with two spaces
Strings should use single quotes
All statements must end in a semi-colon
The final element in all objects must be preceded with a comma
Maximum line length is 100
There must be exactly one blank line between sections, before function names, and at the end of the file
With conditionals, put else on the same line as your if block’s closing brace
╮├── package.json # Project meta-data, dependencies and paths to scripts├── src/ # Project front-end source code├── server.js # A Node.js server to serve up the /dist directory├── vue.config.js # Vue.js configuration├── Dockerfile # The blueprint for building the Docker container├── docker-compose.yml # A Docker run command├── .env # Location for any environmental variables├── yarn.lock # Auto-generated list of current packages and version numbers├── docs/ # Markdown documentation├── README.md # Readme, basic info for getting started├── LICENSE.md # License for use╯
./src├── App.vue # Vue.js starting file├── assets # Static non-compiled assets│ ├── fonts # .ttf font files│ ├── locales # All app text, each language in a separate JSON file│ ╰── interface-icons # SVG icons used in the app ├── components # All front-end Vue web components│ ├── Configuration # Components relating to the user config pop-up│ │ ├── AppInfoModal.vue # A modal showing core app info, like version, language, etc│ │ ├── CloudBackupRestore.vue # Form where the user manages cloud sync options│ │ ├── ConfigContainer.vue # Main container, wrapping all other config components│ │ ├── CustomCss.vue # Form where the user can input custom CSS│ │ ├── EditSiteMeta.vue # Form where the user can edit site meta data│ │ ├── JsonEditor.vue # JSON editor, where the user can modify the main config file│ │ ╰── RebuildApp.vue # A component allowing user to trigger a rebuild through the UI│ ├── FormElements # Basic form elements used throughout the app│ │ ├── Button.vue # Standard button component│ │ ╰── Input.vue # Standard text field input component│ ├── LinkItems # Components for Sections and Link Items│ │ ├── Collapsable.vue # The collapsible functionality of sections│ │ ├── ContextMenu.vue # The right-click menu, for showing Item opening methods and info│ │ ├── IframeModal.vue # Pop-up iframe modal, for viewing websites within the app│ │ ├── Item.vue # Main link item, which is displayed within an item group│ │ ├── ItemGroup.vue # Item group is a section containing icons│ │ ├── ItemIcon.vue # The icon used by both items and sections│ │ ├── ItemOpenMethodIcon.vue # A small icon, visible on hover, indicating opening method │ │ ╰── StatusIndicator.vue # Traffic light dot, showing if app is online or down│ ├── PageStrcture # Components relating the main structure of the page│ │ ├── Footer.vue # Footer, visible at the bottom of all pages│ │ ├── Header.vue # Header, visible at the top of pages, and includes title and nav│ │ ├── LoadingScreen.vue # Splash screen shown on first load│ │ ├── Nav.vue # Navigation bar, includes a list of links│ │ ╰── PageTitle.vue # Page title and sub-title, visible within the Header│ ╰── Settings # Components relating to the quick-settings, in the top-right│ ├── AuthButtons.vue # Logout button and other app info│ ├── ConfigLauncher.vue # Icon that when clicked will launch the Configuration component│ ├── CustomThemeMaker.vue # Color pickers for letting user build their own theme│ ├── ItemSizeSelector.vue # Set of buttons used to set and save item size│ ├── KeyboardShortcutInfo.vue# Small pop-up displaying the available keyboard shortcuts│ ├── LanguageSwitcher.vue # Dropdown in a modal for changing app language│ ├── LayoutSelector.vue # Set of buttons, letting the user select their desired layout│ ├── SearchBar.vue # The input field in the header, used for searching the app│ ├── SettingsContainer.vue # Container that wraps all the quick-settings components│ ╰── ThemeSelector.vue # Drop-down menu enabling the user to select and change themes├── main.js # Main front-end entry point├── registerServiceWorker.js # Registers and manages service workers, for PWA apps├── router.js # Defines all available application routes├── styles # Directory of all globally used common SCSS styles├── utils # Directory of re-used helper functions│ ├── ArrowKeyNavigation.js # Functionality for arrow-key navigation│ ├── Auth.js # Handles all authentication related actions│ ├── ClickOutside.js # A directive for detecting click, used to hide dropdown, modal or context menu│ ├── ConfigAccumulator.js # Central place for managing and combining config│ ├── ConfigHelpers.js # Helper functions for managing configuration│ ├── CloudBackup.js # Functionality for encrypting, processing and network calls│ ├── ConfigSchema.json # The schema, used to validate the users conf.yml file│ ├── ConfigValidator.js # A helper script that validates the config file against schema│ ├── defaults.js # Global constants and their default values│ ├── ErrorHandler.js # Helper function called when an error is returned│ ├── JsonToYaml.js # Function that parses and converts raw JSON into valid YAML│ ├── languages.js # Handles fetching, switching and validating languages│ ╰── ThemeHelper.js # Function that handles the fetching and setting of user themes╰── views # Directory of available pages, corresponding to available routes ├── Home.vue # The home page container ├── About.vue # About page ├── Login.vue # TAuthentication page ├── Minimal.vue # The minimal view ╰── Workspace.vue # The workspace view with apps in sidebar
All frontend code is located in the ./src directory, which is split into 5 sub-folders:
Components - All frontend web components are located here. Each component should have a distinct, well defined and simple task, and ideally should not be too long. The components directory is organised into a series of sub-directories, representing a specific area of the application
FormElements - Reusable form elements (button, input field, etc)
LinkItems - Components relating to Dashy's sections and items (item group, item, item icon, etc)
Configuration - Components relating to Dashy's configuration forms (cloud backup, JSON editor, etc)
Views - Each view directly corresponds to a route (defined in the router), and in effectively a page. They should have minimal logic, and just contain a few components
Utils - These are helper functions, or logic that is used within the app does not include an UI elements
Styles - Any SCSS that is used globally throughout that app, and is not specific to a single component goes here. This includes variables, color themes, typography settings, CSS reset and media queries
Assets - Static assets that need to be bundled into the application, but do not require any manipulation go here. This includes interface icons and fonts
The structure of the components directory is similar to that of the frontend application layout
The easiest method of checking performance is to use Chromium's build in auditing tool, Lighthouse. To run the test, open Developer Tools (usually F12) --> Lighthouse and click on the 'Generate Report' button at the bottom.
When running the build command, several warnings appear. These are not errors, and do not affect the security or performance of the application. They will be addressed in a future update
WARN A new version of sass-loader is available. Please upgrade for best experience. - Currently we're using an older version of SASS loader, since the more recent releases do not seem to be compatible with the Vue CLI's webpack configuration.
WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). - For the PWA to support Windows 10, a splash screen asset is required, and is quite large. This throws a warning, however PWA assets are not loaded until needed, so shouldn't have any impact on application performance. A similar warning is thrown for the Raleway font, and that is looking to be addressed.
glob-parent Security Alert - This will be fixed soon. The version of glob-parent that is used by the latest version of Vue-CLI has a security issue associated with it. I am waiting on Vue to update their dependencies.
Adding a new theme is really easy. There's two things you need to do: Pass the theme name to Dashy, so that it can be added to the theme selector dropdown menu, and then write some styles!
Put your theme's styles inside color-themes.scss.
+Create a new block, and make sure that data-theme matches the theme name you chose above. For example:
Then you can go ahead and write you're own custom CSS. Although all CSS is supported here, the best way to define you're theme is by setting the CSS variables. You can find a list of all CSS variables, here.
Note that if you're theme is just for yourself, and you're not submitting a PR, then you can instead just pass it under appConfig.cssThemes inside your config file. And then put your theme in your own stylesheet, and pass it into the Docker container - see how.
Create a new JSON file in ./src/assets/locales name is a 2-digit ISO-639 code for your language, E.g. for German de.json, French fr.json or Spanish es.json - You can find a list of all ISO codes at iso.org.
Using en.json as an example, translate the JSON values to your language, while leaving the keys as they are. It's fine to leave out certain items, as if they're missing they will fall-back to English. If you see any attribute which include curly braces ({xxx}), then leave the inner value of these braces as is, as this is for variables.
First import your new translation file, do this at the top of the page.
+E.g. import de from '@/assets/locales/de.json';
Second, add it to the array of languages, e.g:
exportconst languages =[{ name:'English', code:'en', locale: en, flag:'🇬🇧',},{ name:'German',// The name of your language code:'de',// The ISO code of your language locale: de,// The name of the file you imported (no quotes) flag:'🇩🇪',// An optional flag emoji},];
You can also add your new language to the readme, under the Language Switching section, and optionally include your name/ username if you'd like to be credited for your work. Done!
If you are not comfortable with making pull requests, or do not want to modify the code, then feel free to instead send the translated file to me, and I can add it into the application. I will be sure to credit you appropriately.
Adding a new option in the config file
This section is for, if you're adding a new component or setting, that requires an additional item to be added to the users config file.
All of the users config is specified in ./public/conf.yml - see Configuring Docs for info.
+Before adding a new option in the config file, first ensure that there is nothing similar available, that is is definitely necessary, it will not conflict with any other options and most importantly that it will not cause any breaking changes. Ensure that you choose an appropriate and relevant section to place it under.
Next decide the most appropriate place for your attribute:
Application settings should be located under appConfig
Page info (such as text and metadata) should be under pageInfo
Data relating to specific sections should be under section[n].displayData
And for setting applied to specific items, it should be under item[n]
In order for the user to be able to add your new attribute using the Config Editor, and for the build validation to pass, your attribute must be included within the ConfigSchema. You can read about how to do this on the ajv docs. Give your property a type and a description, as well as any other optional fields that you feel are relevant. For example:
"fontAwesomeKey":{"type":"string","pattern":"^[a-z0-9]{10}$","description":"API key for font-awesome","example":"0821c65656"}
or
"iconSize":{"enum":["small","medium","large"],"default":"medium","description":"The size of each link item / icon"}
Next, if you're property should have a default value, then add it to defaults.js. This ensures that nothing will break if the user does not use your property, and having all defaults together keeps things organised and easy to manage.
If your property needs additional logic for fetching, setting or processing, then you can add a helper function within ConfigHelpers.js.
Finally, add your new property to the configuring.md API docs. Put it under the relevant section, and be sure to include field name, data type, a description and mention that it is optional. If your new feature needs more explaining, then you can also document it under the relevant section elsewhere in the documentation.
Checklist:
Ensure the new attribute is actually necessary, and nothing similar already exists
Update the Schema with the parameters for your new option
Set a default value (if required) within defaults.js
Running yarn upgrade will updated all dependencies based on the ranges specified in the package.json. The yarn.lock file will be updated, as will the contents of ./node_modules, for more info, see the yarn upgrade documentation. It is important to thoroughly test after any big dependency updates.
For some pages (such as the login page, the minimal start page, etc) the basic page furniture, (like header, footer, nav, etc) is not needed. This section explains how you can hide furniture on a new view (step 1), or add a component that should be hidden on certain views (step 2).
Both sections and items can have an icon, which is specified using the icon attribute. Using icons improves the aesthetics of your UI and makes the app more intuitive to use. There are several options when it comes to setting icons, and this article outlines each of them
Note that, if you are using icons from an external source (like font-awesome or material-design-icons), then the relevant font file will be loaded in automatically if and when needed, but combining icons from multiple services may have a negative impact on performance.
You can use any Font Awesome Icon simply by specifying it's identifier. This is in the format of [category] [name] and can be found on the page for any given icon on the Font Awesome site. For example: fas fa-rocket, fab fa-monero or fas fa-unicorn.
Font-Awesome has a wide variety of free icons, but you can also use their pro icons if you have a membership. To do so, you need to specify your license key under: appConfig.fontAwesomeKey. This is usually a 10-digit string, for example 13014ae648.
Dashy can auto-fetch the favicon for a given service using it's URL. Just set icon: favicon to use this feature. If the services URL is a local IP, then Dashy will attempt to find the favicon from http://[ip]/favicon.ico. This has two issues, favicons are not always hosted at the same location for every service, and often the default favicon is a low resolution. Therefore to fix this, for remote services an API is used to return a high-quality icon for any online service.
The default favicon API is Favicon Kit, a free and reliable service for returning images from any given URL. However several other API's are supported. To change the API used, under appConfig, set faviconApi to one of the following values:
allesedv - allesedv.com is a highly efficient IPv6-enabled service
You can also force Dashy to always get favicons from the root of the domain, and not use an external service, by setting appConfig.faviconApi to local.
Uses a unique and programmatically generated icon for a given service. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with ipsicon.io. To use this option, just set an item's to: icon: generative.
You can use almost any emoji as an icon for items or sections. You can specify the emoji either by pasting it directly, using it's unicode ( e.g. 'U+1F680') or shortcode (e.g. ':rocket:'). You can find these codes for any emoji using Emojipedia (near the bottom of emoji each page), or for a quick reference to emoji shortcodes, check out emojis.ninja by @nomanoff.
The following examples will all render the same rocket (🚀) emoji:
You can also set an icon by passing in a valid URL pointing to the icons location. For example icon: https://i.ibb.co/710B3Yc/space-invader-x256.png, this can be in .png, .jpg or .svg format, and hosted anywhere- so long as it's accessible from where you are hosting Dashy. The icon will be automatically scaled to fit, however loading in a lot of large icons may have a negative impact on performance, especially if you visit Dashy from new devices often.
You may also want to store your icons locally, bundled within Dashy so that there is no reliance on outside services. This can be done by putting the icons within Dashy's ./public/item-icons/ directory. If you are using Docker, then the easiest option is to map a volume from your host system, for example: -v /local/image/directory:/app/public/item-icons/. To reference an icon stored locally, just specify it's name and extension. For example, if my icon was stored in /app/public/item-icons/maltrail.png, then I would just set icon: maltrail.png.
You can also use sub-folders within the item-icons directory to keep things organised. You would then specify an icon with it's folder name slash image name. For example: networking/monit.png
MIT License
+Copyright (c) 2021 Alicia Sykes <https://aliciasykes.com>
+Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE.
+
+
+
+
\ No newline at end of file
diff --git a/docs/management/index.html b/docs/management/index.html
new file mode 100644
index 00000000..e762b07f
--- /dev/null
+++ b/docs/management/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+Management | Dashy
+
+
+
+
+
Although not essential, you will most likely want to provide several assets to Dashy. All web assets can be found in the /public directory.
./public/conf.yml - As mentioned, this is your main application config file
./public/item-icons - If you're using your own icons, you can choose to store them locally for better load time, and this is the directory to put them in. You can also use sub-folders here to keep things organized. You then reference these assets relative this the direcroties path, for example: to use ./public/item-icons/networking/netdata.png as an icon for one of your links, you would set icon: networking/netdata.png
Also within ./public you'll find standard website assets, including favicon.ico, manifest.json, robots.txt, etc. There's no need to modify these, but you can do so if you wish.
Now that you've got Dashy running, there are a few commands that you need to know.
The following commands are defined in the package.json file, and are run with yarn. If you prefer, you can use NPM, just replace instances of yarn with npm run. If you are using Docker, then you will need to precede each command with docker exec -it [container-id], where container ID can be found by running docker ps. For example docker exec -it 26c156c467b4 yarn build.
yarn build - In the interest of speed, the application is pre-compiled, this means that the config file is read during build-time, and therefore the app needs to rebuilt for any new changes to take effect. Luckily this is very straight forward. Just run yarn build or docker exec -it [container-id] yarn build
yarn validate-config - If you have quite a long configuration file, you may wish to check that it's all good to go, before deploying the app. This can be done with yarn validate-config or docker exec -it [container-id] yarn validate-config. Your config file needs to be in /public/conf.yml (or within your Docker container at /app/public/conf.yml). This will first check that your YAML is valid, and then validates it against Dashy's schema.
yarn health-check - Checks that the application is up and running on it's specified port, and outputs current status and response times. Useful for integrating into your monitoring service, if you need to maintain high system availability
yarn build-watch - If you find yourself making frequent changes to your configuration, and do not want to have to keep manually rebuilding, then this option is for you. It will watch for changes to any files within the projects root, and then trigger a rebuild. Note that if you are developing new features, then yarn dev would be more appropriate, as it's significantly faster at recompiling (under 1 second), and has hot reloading, linting and testing integrated
yarn build-and-start - Builds the app, runs checks and starts the production server. Commands are run in parallel, and so is faster than running them in independently
yarn pm2-start - Starts the Node server using PM2, a process manager for Node.js applications, that helps them stay alive. PM2 has some built-in basic monitoring features, and an optional management solution. If you are running the app on bare metal, it is recommended to use this start command
Healthchecks are configured to periodically check that Dashy is up and running correctly on the specified port. By default, the health script is called every 5 minutes, but this can be modified with the --health-interval option. You can check the current container health with: docker inspect --format "{{json .State.Health }}" [container-id], and a summary of health status will show up under docker ps. You can also manually request the current application status by running docker exec -it [container-id] yarn health-check. You can disable healthchecks altogether by adding the --no-healthcheck flag to your Docker run command.
To restart unhealthy containers automatically, check out Autoheal. This image watches for unhealthy containers, and automatically triggers a restart. This is a stand in for Docker's --exit-on-unhealthy that was proposed, but not merged.
You can view logs for a given Docker container with docker logs [container-id], add the --follow flag to stream the logs. For more info, see the Logging Documentation. There's also Dozzle, a useful tool, that provides a web interface where you can stream and query logs from all your running containers from a single web app.
You can check the resource usage for your running Docker containers with docker stats or docker stats [container-id]. For more info, see the Stats Documentation. There's also cAdvisor, a useful web app for viewing and analyzing resource usage and performance of all your running containers.
You can also view logs, resource usage and other info as well as manage your entire Docker workflow in third-party Docker management apps. For example Portainer an all-in-one open source management web UI for Docker and Kubernetes, or LazyDocker a terminal UI for Docker container management and monitoring.
Docker supports using Prometheus to collect logs, which can then be visualized using a platform like Grafana. For more info, see this guide. If you need to route your logs to a remote syslog, then consider using logspout. For enterprise-grade instances, there are managed services, that make monitoring container logs and metrics very easy, such as Sematext with Logagent.
You can use Docker's restart policies to instruct the container to start after a system reboot, or restart after a crash. Just add the --restart=always flag to your Docker compose script or Docker run command. For more information, see the docs on Starting Containers Automatically.
For Podman, you can use systemd to create a service that launches your container, the docs explains things further. A similar approach can be used with Docker, if you need to start containers after a reboot, but before any user interaction.
To restart the container after something within it has crashed, consider using docker-autoheal by @willfarrell, a service that monitors and restarts unhealthy containers. For more info, see the Healthchecks section above.
Enabling HTTPS with an SSL certificate is recommended if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit.
Let's Encrypt is a global Certificate Authority, providing free SSL/TLS Domain Validation certificates in order to enable secure HTTPS access to your website. They have good browser/ OS compatibility with their ISRG X1 and DST CA X3 root certificates, support Wildcard issuance done via ACMEv2 using the DNS-01 and have Multi-Perspective Validation. Let's Encrypt provide CertBot an easy app for generating and setting up an SSL certificate
ZeroSSL is another popular certificate issuer, they are free for personal use, and also provide easy-to-use tools for getting things setup.
If you're hosting Dashy behind Cloudflare, then they offer free and easy SSL.
If you're not so comfortable on the command line, then you can use a tool like SSL For Free to generate your Let's Encrypt or ZeroSSL certificate, and support shared hosting servers. They also provide step-by-step tutorials on setting up your certificate on most common platforms. If you are using shared hosting, you may find this tutorial helpful.
Dashy has basic authentication built in, however at present this is handled on the front-end, and so where security is critical, it is recommended to use an alternative method. See here for options regarding securing Dashy.
You can automate the above process using Watchtower.
+Watchtower will watch for new versions of a given image on Docker Hub, pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
The following section only applies if you are not using Docker, and would like to use your own web server
Dashy ships with a pre-configured Node.js server, in server.js which serves up the contents of the ./dist directory on a given port. You can start the server by running node server. Note that the app must have been build (run yarn build), and you need Node.js installed.
If you wish to run Dashy from a sub page (e.g. example.com/dashy), then just set the BASE_URL environmental variable to that page name (in this example, /dashy), before building the app, and the path to all assets will then resolve to the new path, instead of ./.
However, since Dashy is just a static web application, it can be served with whatever server you like. The following section outlines how you can configure a web server.
Note, that if you choose not to use server.js to serve up the app, you will loose access to the following features:
Dashy has built-in authentication and login functionality. However, since this is handled on the client-side, if you are using Dashy in security-critical situations, it is recommended to use an alternate method for authentication, such as Authelia, a VPN or web server and firewall rules. For more info, see Authentication Docs.
Internationalization is the process of making an application available in other languages. This is important, as not everyone is a native English speaker.
An up-to-date list of all currently supported languages can be found in ./src/utils/languages.js. Languages are specified by their 2-digit ISO-639 code (e.g. en, fr, de, es, etc)
By default, Dashy will attempt to use the language of your browser or system. If a translation for your language does not yet exist, it will fallback to English.
You can also manually select your language. This can be done, either through the UI (Config --> Language), or by setting it in your config file:
Create a new JSON file in ./src/assets/locales name is a 2-digit ISO-639 code for your language, E.g. for German de.json, French fr.json or Spanish es.json - You can find a list of all ISO codes at iso.org.
+If your language is a specific dialect or regional language, then use the Posfix CLDR format, where, e.g. en-GB.json (British), es-MX.json (Spanish, in Mexico) or zh-CN.json (Chinese, simplified) - A list of which can be found here
Using en.json as an example, translate the JSON values to your language, while leaving the keys as they are. It's fine to leave out certain items, as if they're missing they will fall-back to English. If you see any attribute which include curly braces ({xxx}), then leave the inner value of these braces as is, as this is for variables.
First import your new translation file, do this at the top of the page.
+E.g. import de from '@/assets/locales/de.json';
Second, add it to the array of languages, e.g:
exportconst languages =[{ name:'English', code:'en', locale: en, flag:'🇬🇧',},{ name:'German',// The name of your language code:'de',// The ISO code of your language locale: de,// The name of the file you imported (no quotes) flag:'🇩🇪',// An optional flag emoji},];
You can also add your new language to the readme, under the Language Switching section and optionally include your name/ username if you'd like to be credited for your work. Done!
If you are not comfortable with making pull requests, or do not want to modify the code, then feel free to instead send the translated file to me, and I can add it into the application. I will be sure to credit you appropriately.
If you're working on a new component, then any text that is displayed to the user should be extracted out of the component, and stored in the file. This also applies to any existing components, that might have been forgotten to be translated.
Thankfully, everything is already setup, and so is as easy as adding text to the JSON file, and pasting the key to that text in your component.
Firstly, go to ./src/assets/locales/en.json, and either find the appropriate section, or create a new section. Lets say you're new component is called my-widget, you could add "my-widget": {} to store all your text as key-value-pairs. E.g.
"my-widget":{"awesome-text":"I am some text, that will be seen by the user"}
Note that you must add English translations for all text. Missing languages are not a problem, as they will always fallback to Enslish, but if the English is missing, then nothing can be displayed.
Once your text is in the translation file, you can now use it within your component. There is a global $t function, with takes the key of your new translation, and returns the value. For example:
<p>{{ $t('my-widget.awesome-text') }}</p>
Note that the {{ }} just tells Vue that this is JavaScript/ dynamic.
+This will render: <p>I am some text, that will be seen by the user</p>
If you need to display text programmatically, from within the components JavaScript (e.g. in a toast popup), then use this.$t.
+For example: alert(this.$t('my-widget.awesome-text')).
You may also need to pass a variable to be displayed within a translation. Vue I18n supports Interpolations using mustache-like syntax.
For example, you would set your translation to:
{"welcome-message":"Hello {name}!"}
And then pass that variable (name) within a JSON object as the second parameter on $t, like:
$t('welcome-message',{ name:'Alicia'})
Which will render:
Hello Alicia!
There are many other advanced features, including Pluralization, Datetime & Number Formatting, Message Support and more, all of which are outlined in the Vue-i18n Docs.
Dashy was built with privacy in mind. Self-hosting your own apps and services is a great way to protect yourself from the mass data collection employed by big tech companies, and Dashy was designed to keep your local services organized and accessible from a single place.
It's fully open source, and I've tried to keep to code as clear and thoroughly documented as possible, which will make it easy for you to understand exactly how it works, and what goes on behind the scenes.
By default, Dashy will not make any external requests, unless you configure it to. Some features (which are all off by default) do require internat access, and this section outlines those features, the services used, and links to their privacy policies.
If either any of your sections or items are using font-awesome icons, then these will be fetched directly from font-awesome on page load. See the Font Awesome Privacy Policy for more info.
If an item's icon is set to favicon, then it will be auto-fetched from the corresponding URL. Since not all websites have their icon located at /favicon.ico, and if they do, it's often very low resolution (like 16 x 16 px). Therefore, the default behavior is for Dashy to check if the URL is public, and if so will use an API to fetch the favicon. For self-hosted services, the favion will be fetched from the default path, and no external requests will be made.
The default favicon API is Favicon Kit, but this can be changed by setting appConfig.faviconApi to an alternate source (google, clearbit, webmasterapi and allesedv are supported). If you do not want to use any API, then you can set this property to local, and the favicon will be fetched from the default path. For hosted services, this will still incur an external request.
Section icons, item icons and app icons are able to accept a URL to a raw image, if the image is hosted online then an external request will be made. To avoid the need to make external requests for icon assets, you can either use a self-hosted CDN, or store your images within ./public/item-icons (which can be mounted as a volume if you're using Docker).
By default, all assets required by Dashy come bundled within the source, and so no external requests are made. If you add an additional font, which is imported from a CDN, then that will incur an external request. The same applies for other web assets, like external images, scripts or styles.
The status check util will ping your services directly, and does not rely on any third party. If you are checking the uptime status of a public/ hosted application, then please refer to that services privacy policy. For all self-hosted services, requests happen locally within your network, and are not external.
When the application loads, it checks for updates. The results of which are displayed in the config menu of the UI. This was implemented because using a very outdated version of Dashy may have unfixed issues. Your version is fetched from the source (local request), but the latest version is fetched from GitHub, which is an external request. This can be disabled by setting appConfig.disableUpdateChecks: true
Error reporting is disabled by default, and no data will ever be sent without your explicit consent. In fact, the error tracking method will not even be imported unless you have actively enabled it. Sentry is used for this, it's an open source error tracking and performance monitoring tool, which is used to identify any issues which occur in the production app (if you enable it).
The crash report includes the file or line of code that triggered the error, and a 2-layer deep stack trace. Reoccurring errors will also include the following user information: OS type (Mac, Windows, Linux, Android or iOS) and browser type (Firefox, Chrome, IE, Safari). Data scrubbing is enabled. IP address will not be stored. If any potentially identifiable data ever finds its way into a crash report, it will be automatically and permanently erased. All statistics collected are anonomized and stored securely, and ae automatically deleted after 14 days. For more about privacy and security, see the Sentry Docs.
Enabling anonymous error reporting helps me to discover bugs I was unaware of, and then fix them, in order to make Dashy more reliable long term. Error reporting is activated by setting appConfig.enableErrorReporting: true.
If you need to monitor bugs yourself, then you can self-host your own Sentry Server, and use it by setting appConfig.sentryDsn to your Sentry instances Data Source Name, then just enable error reporting in Dashy.
In order for user preferences to be persisted between sessions, certain data needs to be stored in the browsers local storage. No personal info is kept here, none of this data can be accessed by other domains, and no data is ever sent to any server without your prior consent.
+You can view your browsers session storage by opening up the dev tools (F12) --> Application --> Storage.
The following section outlines all data that is stored in the browsers, as cookies or local storage.
As with most web projects, Dashy relies on several dependencies. For links to each, and a breakdown of their licenses, please see Legal.
Dependencies can introduce security vulnerabilities, but since all these packages are open source any issues are usually very quickly spotted. Dashy is using Snyk for dependency security monitoring, and you can see the latest report here. If any issue is detected by Snyk, a note about it will appear at the top of the Reamde, and will usually be fixed within 48 hours.
Note that packages listed under deDependencies section are only used for building the project, and are not included in the production environment.
Running your self-hosted applications in individual, containerized environments (such as containers or VMs) helps keep them isolated, and prevent an exploit in one service effecting another.
There is very little complexity involved with Dashy, and therefore the attack surface is reasonably small, but it is still important to follow best practices and employ monitoring for all your self-hosted apps. A couple of things that you should look at include:
If you think you've found a critical issue with Dashy, please send an email to security@mail.alicia.omg.lol. You can encrypt it, using 0688 F8D3 4587 D954 E9E5 1FB8 FEDB 68F5 5C02 83A7. You should receive a response within 48 hours.
All non-critical issues can be raised as a ticket.
Please include the following information:
Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
Full paths of source file(s) related to the manifestation of the issue
The location of the affected source code (tag/branch/commit or direct URL)
Any special configuration required to reproduce the issue
Step-by-step instructions to reproduce the issue
Proof-of-concept or exploit code (if possible)
Impact of the issue, including how an attacker might exploit the issue
The quickest and easiest method of running Dashy is using Docker (or another container engine). You can find installation instructions for your system in the Docker Documentation.
+If you don't want to use Docker, then you can use one of Dashy's other supported installation methods instead, all of which are outlined in the Deployment Docs.
Your dashboard should now be up and running at http://localhost:8080 (or your servers IP address/ domain, and the port that you chose). The first build will may take a few minutes
Now that you've got Dashy running, you are going to want to set it up with your own content.
+Config is written in YAML Format, and saved in /public/conf.yml.
+The format on the config file is pretty straight forward. There are three root attributes:
pageInfo - Dashboard meta data, like title, description, nav bar links and footer text
appConfig - Dashboard settings, like themes, authentication, language and customization
sections - An array of sections, each including an array of items
You can view a full list of all available config options in the Configuring Docs.
pageInfo:title: Home Labsections:# An array of sections-name: Example Sectionicon: far fa-rocketitems:-title: GitHubdescription: Dashy source code and docsicon: fab fa-githuburl: https://github.com/Lissy93/dashy-title: Issuesdescription: View open issues, or raise a new oneicon: fas fa-bugurl: https://github.com/Lissy93/dashy/issues-name: Local Servicesitems:-title: Firewallicon: faviconurl: http://192.168.1.1/-title: Game Servericon: https://i.ibb.co/710B3Yc/space-invader-x256.pngurl: http://192.168.130.1/
Notes:
You can use a Docker volume to pass a config file from your host system to the container
E.g. -v ./host-system/my-local-conf.yml:/app/public/conf.yml
It's also possible to edit your config directly through the UI, and changes will be saved in this file
Check your config against Dashy's schema, with docker exec -it [container-id] yarn validate-config
You might find it helpful to look at some examples, a collection of which can be found here
After editing your config, the app will rebuild in the background, which may take a minute
Once you've got Dashy setup, you'll want to ensure the container is properly healthy, secured, backed up and kept up-to-date. All this is covered in the Management Docs.
You might also want to check out the docs for specific features you'd like to use:
Authentication - Setting up authentication to protect your dashboard
If you're enjoying Dashy, and have a few minutes to spare, please do take a moment to look at the Contributing Page. There are a few things that we really need some help with, and whatever your skill set, there are ways you can help out. Any contributions, however small would be greatly appreciated.
+Thank you to everyone who is already doing so, without developing and maintaining Dashy would not have been so possible.
You can also consider sharing your dashboard in the Showcase, to help provide inspiration for others.
For more info, check out the Documentation. If you've got any questions feel free to ask in the Discussion, and if you think you've found a bug you can raise an issue to get it fixed.
One of the primary purposes of Dashy is to allow you to quickly find and launch a given app. To make this as quick as possible, there is no need to touch the mouse, or press a certain key to begin searching - just start typing. Results will be filtered in real-time. No need to worry about case, special characters or small typos, these are taken care of, and your results should appear.
You can navigate through your items or search results using the keyboard. You can use Tab to cycle through results, and Shift + Tab to go backwards. Or use the arrow keys, ↑, →, ↓ and ←.
You can launch a elected app by hitting Enter. This will open the app using your default opening method, specified in target (either newtab, sametab, modal or workspace). You can also use Alt + Enter to open the app in a pop-up modal, or Ctrl + Enter to open it in a new tab. For all available opening methods, just right-click on an item, to bring up the context menu.
By default, items are filtered by the title attribute, as well as the hostname (extracted from url), the provider and description. If you need to find results based on text which isn't included in these attributes, then you can add tags to a given item.
items:-title: Plexdescription: Media libraryicon: faviconurl: https://plex.lab.localtags:[ movies, videos, music ]-title: FreshRSSdescription: RSS Readericon: faviconurl: https://freshrss.lab.localtags:[ news, updates, blogs ]
+
In the above example, Plex will be visible when searching for 'movies', and FreshRSS with 'news'
For apps that you use regularly, you can set a custom keybinding. Use the hotkey parameter on a certain item to specify a numeric key, between 0 - 9. You can then launch that app, by just pressing that key, which is much quicker than searching for it, if it's an app you use frequently.
-title: Bookstackicon: far fa-booksurl: https://bookstack.lab.local/hotkey:2-title: Git Teaicon: fab fa-giturl: https://git.lab.local/target: workspacehotkey:3
In the above example, pressing 2 will launch Bookstack. Or hitting 3 will open Git in the workspace view.
It's possible to search the web directly from Dashy, which might be useful if you're using Dashy as your start page. This can be done by typing your query as normal, and then pressing ⏎. Web search options are configured under appConfig.webSearch.
Set your default search engine using the webSearch.searchEngine property. This defaults to DuckDuckGo. Search engine must be referenced by their key, the following providers are supported:
You can also use a custom search engine, that isn't included in the above list (like a self-hosted instance of Whoogle or Searx). Set searchEngine: custom, and then specify the URL (plus query params) to you're search engine under customSearchEngine.
In a similar way to opening apps, you can specify where you would like search results to be opened. This is done under the openingMethod attribute, and can be set to either newtab, sametab or workspace. By default results are opened in a new tab.
Dashy has an optional feature that can display a small icon next to each of your running services, indicating it's current status. This can be useful if you are using Dashy as your homelab's start page, as it gives you an overview of the health of each of your running services. The status feature will show response time, response code, online/ offline check and if applicable, a relevant error message
By default, with status indicators enabled Dashy will check an applications status on page load, and will not keep indicators updated. This is usually desirable behavior. However, if you do want the status indicators to continue to poll your running services, this can be enabled by setting the statusCheckInterval attribute. Here you define an interval as an integer in seconds, and Dashy will poll your apps every x seconds. Note that if this number is very low (below 5 seconds), you may notice the app running slightly slower.
The following example, will instruct Dashy to continuously check the status of your services every 20 seconds
By default, the status checker will use the URL of each application being checked. In some situations, you may want to use a different endpoint for status checking. Similarly, some services provide a dedicated path for uptime monitoring.
You can set the statusCheckUrl property on any given item in order to do this. The status checker will then ping that endpoint, instead of the apps main url property.
If your service is responding with an error, despite being up and running, it is most likely because custom headers for authentication, authorization or encoding are required. You can define these headers under the statusCheckHeaders property for any service. It should be defined as an object format, with the name of header as the key, and header content as the value.
+For example, statusCheckHeaders: { 'X-Custom-Header': 'foobar' }
By default, (if you're using HTTPS) any requests to insecure or non-HTTPS content will be blocked. This will cause the status check to fail. If you trust the endpoint (e.g. you're self-hosting it), then you can disable this security measure for an individual item. This is done by setting statusCheckAllowInsecure: true
If the status is always returning an error, despite the service being online, then it is most likely an issue with access control, and should be fixed with the correct headers. Hover over the failing status to see the error code and response, in order to know where to start with addressing it.
+If your service requires requests to include any authorization in the headers, then use the statusCheckHeaders property, as described above.
+If you are still having issues, it may be because your target application is blocking requests from Dashy's IP. This is a CORS error, and can be fixed by setting the headers on your target app, to include:
If the URL you are checking is not using HTTPS, then you may need to disable the rejection of insecure requests. This can be done by setting statusCheckAllowInsecure to true for a given item.
If you're serving Dashy though a CDN, instead of using the Node server or Docker image, then the Node endpoint that makes requests will not be available to you, and all requests will fail. A workaround for this may be implemented in the future, but in the meantime, your only option is to use the Docker or Node deployment method.
For further troubleshooting, use an application like Postman to diagnose the issue.
When the app is loaded, if appConfig.statusCheck: true is set, or if any items have the statusCheck: true enabled, then Dashy will make a request, to https://[your-host-name]/ping?url=[address-or-servce] (may al include GET params for headers and the secure flag), which in turn will ping that running service, and respond with a status code. Response time is calculated from the difference between start and end time of the request.
When the response completes, an indicator will display next to each item. The color denotes the status: Yellow while waiting for the response to return, green if request was successful, red if it failed, and grey if it was unable to make the request all together.
All requests are made straight from your server, there is no intermediary. So providing you are hosting Dashy yourself, and are checking the status of other self-hosted services, there shouldn't be any privacy concerns. Requests are made asynchronously, so this won't have any significant impact on page load speeds. However recurring requests (using statusCheckInterval) may run more slowly if the interval between requests is very short.
By default Dashy comes with 20 built in themes, which can be applied from the dropwodwn menu in the UI
You can also add your own themes, apply custom styles, and modify colors.
You can customize Dashy by writing your own CSS, which can be loaded either as an external stylesheet, set directly through the UI, or specified in the config file. Most styling options can be set through CSS variables, which are outlined below.
The following content requires that you have a basic understanding of CSS. If you're just beginning, you may find this article helpful.
The theme switching is done by simply changing the data-theme attribute on the root DOM element, which can then be targeted by CSS. First off, in order for the theme to show up in the theme switcher, it needs to be added to the config file, under appConfig.cssThemes, either as a string, or an array of strings for multiple themes. For example:
appConfig:cssThemes:['tiger','another-theme']
You can now create a block to target you're theme with html[data-theme='my-theme']{} and set some styles. The easiest method is by setting CSS variables, but you can also directly override elements by their selector. As an example, see the built-in CSS themes.
Themes can be modified either through the UI, using the color picker menu (to the right of the theme dropdown), or directly in the config file, under appConfig.customColors. Here you can specify the value for any of the available CSS variables.
By default, any color modifications made to the current theme through the UI will only be applied locally. If you need these settings to be set globally, then click the 'Export' button, to get the color codes and variable names, which can then be backed up, or saved in your config file.
Custom colors are saved relative the the base theme selected. So if you switch themes after setting custom colors, then you're settings will no longer be applied. You're changes are not lost though, and switching back to the original theme will see your styles reapplied.
If these values are specified in your conf.yml file, then it will look something like the below example. Note that in YAML, values or keys which contain special characters, must be wrapped in quotes.
User-defined styles and custom themes should be defined in ./src/styles/user-defined-themes.scss. If you're using Docker, you can pass your own stylesheet in using the --volume flag. E.g. v ./my-themes.scss:/app/src/styles/user-defined-themes.scss. Don't forget to pass your theme name into appConfig.cssThemes so that it shows up on the theme-switcher dropdown.
Custom CSS can be developed, tested and applied directly through the UI. Although you will need to make note of your changes to apply them across instances.
This can be done from the Config menu (spanner icon in the top-right), under the Custom Styles tab. This is then associated with appConfig.customCss in local storage. Styles can also be directly applied to this attribute in the config file, but this may get messy very quickly if you have a lot of CSS.
The URI of a stylesheet, either local or hosted on a remote CDN can be passed into the config file. The attribute appConfig.externalStyleSheet accepts either a string, or an array of strings. You can also pass custom font stylesheets here, they must be in a CSS format (for example, https://fonts.googleapis.com/css2?family=Cutive+Mono).
+This is handled in ThemeHelper.js.
Some UI components have a color option, that can be set in the config file, to force the color of a given item or section no matter what theme is selected. These colors should be expressed as hex codes (e.g. #fff) or HTML colors (e.g. red). The following attributes are supported:
section.color - Custom color for a given section
item.color - Font and icon color for a given item
item.backgroundColor - Background color for a given icon
Essential fonts bundled within the app are located within ./src/assets/fonts/. All optional fonts that are used by themes are stored in ./public/fonts/, if you want to add your own font, this is where you should put it. As with assets, if you're using Docker then using a volume to link a directory on your host system with this path within the container will make management much easier.
Fonts which are not being used by the current theme are not fetched on page load. They are instead only loaded into the application if and when they are required. So having multiple themes with various typefaces shouldn't have any negative impact on performance.
Full credit to the typographers behind each of the included fonts. Specifically: Matt McInerney, Christian Robertson, Haley Fiege, Peter Hull, Cyreal and the legendary Vernon Adams
All colors as well as other variable values (such as borders, border-radius, shadows) are specified as CSS variables. This makes theming the application easy, as you only need to change a given color or value in one place. You can find all variables in color-palette.scss and the themes which make use of these color variables are specified in color-themes.scss
CSS variables are simple to use. You define them like: --background: #fff; and use them like: body { background-color: var(--background); }. For more information, see this guide on using CSS Variables.
You can determine the variable used by any given element, and visualize changes using the browser developer tools (Usually opened with F12, or Options --> More --> Developer Tools). Under the elements tab, click the Element Selector icon (usually top-left corner), you will then be able to select any DOM element on the page by hovering and clicking it. In the CSS panel you will see all styles assigned to that given element, including CSS variables. Click a variable to see it's parent value, and for color attributes, click the color square to modify the color. For more information, see this getting started guide, and these articles on selecting elements and inspecting and modifying colors.
This is not an issue with Dashy, but instead caused by the target app preventing direct access through embedded elements. It can be fixed by setting the X-Frame-Options HTTP header set to ALLOW [path to Dashy] or SAMEORIGIN, as defined in RFC-7034. These settings are usually set in the config file for the web server that's hosting the target application, here are some examples of how to enable cross-origin access with common web servers:
In Apache, you can use the mod_headers module to set the X-Frame-Options in your config file. This file is usually located somewhere like `/etc/apache2/httpd.conf
Header set X-Frame-Options: "ALLOW-FROM http://[dashy-location]/"
First of all, check that you've got yarn installed correctly - see the yarn installation docs for more info.
If you're getting an error about scenarios, then you've likely installed the wrong yarn... (you're not the only one!). You can fix it by uninstalling, adding the correct repo, and reinstalling, for example, in Debian:
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
Alternatively, as a workaround, you have several options:
Try using NPM instead: So clone, cd, then run npm install, npm run build and npm start
Try using Docker instead, and all of the system setup and dependencies will already be taken care of. So from within the directory, just run docker build -t lissy93/dashy . to build, and then use docker start to run the project, e.g: docker run -it -p 8080:80 lissy93/dashy (see the deploying docs for more info)
In V 1.6.5 an update was made that in the future will become a breaking change. You will need to update you config to reflect this before V 2.0.0 is released. In the meantime, your previous config will continue to function normally, but you will see a validation warning. The change means that the structure of the appConfig.auth object is now an object, which has a users property.
This situation relates to error messages similar to one of the following, returned when pulling, updating or running the Docker container from Docker Hub.
You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
When DockerHub returns one of these errors, or a 429 status, that means you've hit your rate limit. This was introduced last year, and prevents unauthenticated or free users from running docker pull more than 100 times per 6 hours.
+You can check your rate limit status by looking for the ratelimit-remaining header in any DockerHub responses.
Dashy is also availible through GHCR, which at present does not have any hard limits. Just use docker pull ghcr.io/lissy93/dashy:latest to fetch the image
You can also build the image from source, by cloning the repo, and running docker build -t dashy . or use the pre-made docker compose
The configuration file is validated against Dashy's Schema using AJV.
First, check that your syntax is valid, using YAML Validator or JSON Validator. If the issue persists, then take a look at the schema, and verify that the field you are trying to add/ modify matches the required format. You can also use this tool to validate your JSON config against the schema, or run yarn validate-config.
If you're trying to use a recently released feature, and are getting a warning, this is likely because you've not yet updated the the current latest version of Dashy.
If the issue still persists, you should raise an issue.
Node Sass does not yet support your current environment#
Caused by node-sass's binaries being built for a for a different architecture
+To fix this, just run: yarn rebuild node-sass
Please acknowledge the difference between errors and warnings before raising an issue about messages in the console. It's not unusual to see warnings about a new version of a certain package being available, an asset bundle bing oversized or a service worker not yet having a cache. These shouldn't have any impact on the running application, so please don't raise issues about these unless it directly relates to a bug or issue you're experiencing. Errors on the other hand should not appear in the console, and they are worth looking into further.
+
+
+
+
\ No newline at end of file
diff --git a/icons/banner_demo.svg b/icons/banner_demo.svg
new file mode 100644
index 00000000..eb7c6d00
--- /dev/null
+++ b/icons/banner_demo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/banner_docs.svg b/icons/banner_docs.svg
new file mode 100644
index 00000000..f35ca366
--- /dev/null
+++ b/icons/banner_docs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/banner_get-started.svg b/icons/banner_get-started.svg
new file mode 100644
index 00000000..5c4ff27e
--- /dev/null
+++ b/icons/banner_get-started.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/banner_source.svg b/icons/banner_source.svg
new file mode 100644
index 00000000..13678df6
--- /dev/null
+++ b/icons/banner_source.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_authentication.svg b/icons/docs_authentication.svg
new file mode 100644
index 00000000..7e24d415
--- /dev/null
+++ b/icons/docs_authentication.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_changelog.svg b/icons/docs_changelog.svg
new file mode 100644
index 00000000..1b01a6ad
--- /dev/null
+++ b/icons/docs_changelog.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_cloud-sync.svg b/icons/docs_cloud-sync.svg
new file mode 100644
index 00000000..5d17f8f5
--- /dev/null
+++ b/icons/docs_cloud-sync.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_conduct.svg b/icons/docs_conduct.svg
new file mode 100644
index 00000000..c0031034
--- /dev/null
+++ b/icons/docs_conduct.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_contributing.svg b/icons/docs_contributing.svg
new file mode 100644
index 00000000..130396f4
--- /dev/null
+++ b/icons/docs_contributing.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_credits.svg b/icons/docs_credits.svg
new file mode 100644
index 00000000..dd487e5c
--- /dev/null
+++ b/icons/docs_credits.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_developing.svg b/icons/docs_developing.svg
new file mode 100644
index 00000000..cb4a832f
--- /dev/null
+++ b/icons/docs_developing.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_guides.svg b/icons/docs_guides.svg
new file mode 100644
index 00000000..3d1d9ffd
--- /dev/null
+++ b/icons/docs_guides.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_icons.svg b/icons/docs_icons.svg
new file mode 100644
index 00000000..662690fc
--- /dev/null
+++ b/icons/docs_icons.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_internationalisation.svg b/icons/docs_internationalisation.svg
new file mode 100644
index 00000000..f16c5161
--- /dev/null
+++ b/icons/docs_internationalisation.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_legal.svg b/icons/docs_legal.svg
new file mode 100644
index 00000000..fd6af76e
--- /dev/null
+++ b/icons/docs_legal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_managment.svg b/icons/docs_managment.svg
new file mode 100644
index 00000000..030b3e89
--- /dev/null
+++ b/icons/docs_managment.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_quick-start.svg b/icons/docs_quick-start.svg
new file mode 100644
index 00000000..b4adc8f7
--- /dev/null
+++ b/icons/docs_quick-start.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_security.svg b/icons/docs_security.svg
new file mode 100644
index 00000000..09a1dc75
--- /dev/null
+++ b/icons/docs_security.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_showcase.svg b/icons/docs_showcase.svg
new file mode 100644
index 00000000..d10a5924
--- /dev/null
+++ b/icons/docs_showcase.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_status-indicators.svg b/icons/docs_status-indicators.svg
new file mode 100644
index 00000000..0b50597a
--- /dev/null
+++ b/icons/docs_status-indicators.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_theming.svg b/icons/docs_theming.svg
new file mode 100644
index 00000000..ae3571ea
--- /dev/null
+++ b/icons/docs_theming.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/docs_troubleshooting.svg b/icons/docs_troubleshooting.svg
new file mode 100644
index 00000000..ed896527
--- /dev/null
+++ b/icons/docs_troubleshooting.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_authentication.svg b/icons/features_authentication.svg
new file mode 100644
index 00000000..ac4026ed
--- /dev/null
+++ b/icons/features_authentication.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_cloud-sync.svg b/icons/features_cloud-sync.svg
new file mode 100644
index 00000000..5d17f8f5
--- /dev/null
+++ b/icons/features_cloud-sync.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_depoloyment.svg b/icons/features_depoloyment.svg
new file mode 100644
index 00000000..8f558775
--- /dev/null
+++ b/icons/features_depoloyment.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_icons.svg b/icons/features_icons.svg
new file mode 100644
index 00000000..d7a50dd7
--- /dev/null
+++ b/icons/features_icons.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_language.svg b/icons/features_language.svg
new file mode 100644
index 00000000..613b9e31
--- /dev/null
+++ b/icons/features_language.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_launching.svg b/icons/features_launching.svg
new file mode 100644
index 00000000..d247a58a
--- /dev/null
+++ b/icons/features_launching.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_layout-customization.svg b/icons/features_layout-customization.svg
new file mode 100644
index 00000000..d151e4cd
--- /dev/null
+++ b/icons/features_layout-customization.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_opening-methods.svg b/icons/features_opening-methods.svg
new file mode 100644
index 00000000..fc5a27d8
--- /dev/null
+++ b/icons/features_opening-methods.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_shortcuts.svg b/icons/features_shortcuts.svg
new file mode 100644
index 00000000..4b23205e
--- /dev/null
+++ b/icons/features_shortcuts.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_status-indicators.svg b/icons/features_status-indicators.svg
new file mode 100644
index 00000000..a1033906
--- /dev/null
+++ b/icons/features_status-indicators.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_themes.svg b/icons/features_themes.svg
new file mode 100644
index 00000000..65135385
--- /dev/null
+++ b/icons/features_themes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/features_ui-configuration.svg b/icons/features_ui-configuration.svg
new file mode 100644
index 00000000..5ee0ad38
--- /dev/null
+++ b/icons/features_ui-configuration.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/icons/interface_down.svg b/icons/interface_down.svg
new file mode 100644
index 00000000..9555f6f2
--- /dev/null
+++ b/icons/interface_down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/img/dashy.png b/img/dashy.png
new file mode 100644
index 00000000..332ca5c1
Binary files /dev/null and b/img/dashy.png differ
diff --git a/img/docusaurus.png b/img/docusaurus.png
new file mode 100644
index 00000000..f458149e
Binary files /dev/null and b/img/docusaurus.png differ
diff --git a/img/homepage-assets/config-editor-demo.gif b/img/homepage-assets/config-editor-demo.gif
new file mode 100644
index 00000000..09fcd584
Binary files /dev/null and b/img/homepage-assets/config-editor-demo.gif differ
diff --git a/img/homepage-assets/logo.png b/img/homepage-assets/logo.png
new file mode 100644
index 00000000..78fabd25
Binary files /dev/null and b/img/homepage-assets/logo.png differ
diff --git a/img/homepage-assets/searching-demo.gif b/img/homepage-assets/searching-demo.gif
new file mode 100644
index 00000000..b0a3a08d
Binary files /dev/null and b/img/homepage-assets/searching-demo.gif differ
diff --git a/img/homepage-assets/status-check-demo.gif b/img/homepage-assets/status-check-demo.gif
new file mode 100644
index 00000000..43422a02
Binary files /dev/null and b/img/homepage-assets/status-check-demo.gif differ
diff --git a/img/homepage-assets/theme-config-demo.gif b/img/homepage-assets/theme-config-demo.gif
new file mode 100644
index 00000000..2cc13b73
Binary files /dev/null and b/img/homepage-assets/theme-config-demo.gif differ
diff --git a/img/homepage-assets/theme-slideshow.gif b/img/homepage-assets/theme-slideshow.gif
new file mode 100644
index 00000000..73f94dc5
Binary files /dev/null and b/img/homepage-assets/theme-slideshow.gif differ
diff --git a/img/homepage-assets/workspace-demo.gif b/img/homepage-assets/workspace-demo.gif
new file mode 100644
index 00000000..c6e186ae
Binary files /dev/null and b/img/homepage-assets/workspace-demo.gif differ
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..627f1108
--- /dev/null
+++ b/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+Dashy | Dashy
+
+
+
+
+
With tons of built-in themes to choose form, plus a UI color palette editor, you can have a unique looking dashboard in no time. There is also support for custom CSS, and since all properties use CSS variables, it is easy to override.
Dashy can auto-fetch icons from the favicon of each of your apps/ services. There is also native support for Font Awesome, Material Design Icons, emoji icons and of course normal images.
Get an instant overview of the health of each of your apps with status indicators. Once enabled, a small dot next to each app will show weather it is up and online, with more info like response time visible on hover.
Need to protect your dashboard, the simple auth feature is super quick to enable, and has support for multiple users with granular controls. Dashy also has built-in support for Keycloak and other SSO providers.
As well as the default home, there is also a minimal view, which makes a great fast-loading browser startpage. Plus a workspace view useful for working on multiple apps at once, all without having to leave your dashboard.
Choose how to launch each of your apps by default, or right click for all options. Apps can be opened in a new tab, the same tab, a quick pop-up modal or in the workspace view.
To search, just start typing, results will be filtered instantly. Use the arrow keys or tab to navigate through results, and press enter to launch. You can also create custom shortcuts for frequently used apps, or add custom tags for easier searching. Dashy can also be used to search the web using your favorite search engine.
There is an optional, end-to-end encrypted, free backup cloud service. This enables you to have your config backed up off-site, and to sync data between multiple instances easily.
Dashy's config is specified in a simple YAML file. But you can also configure the directly through the UI, and have changes written to, and backed up on disk. Real-time validation and hints are in place to help you.
Dashy's UI has been translated into several languages by several amazing contributors. Currently English, German, French, Dutch and Slovenian are supported. Your language should be applied automatically, or you can change it in the config menu.
Although Dashy can be easily run on bare metal, the quickest method of getting started is with Docker. Just run `docker run -p 8080:80 lissy93/dashy` to pull, build and and run Dashy.
Structure your dashboard to fit your use case. From the UI, you can choose between different layouts, item sizes, show/ hide components, switch themes plus more. You can customize pretty much every area of your dashboard. There are config options for custom header, footer, nav bar links, title etc. You can also choose to hide any elements you don't need.
You don't need React to write simple standalone pages.
+
+
+
+
\ No newline at end of file
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 00000000..099807b8
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1 @@
+https://dashy.to/weekly0.5https://dashy.to/docsweekly0.5https://dashy.to/markdown-pageweekly0.5https://dashy.to/docs/alternate-viewsweekly0.5https://dashy.to/docs/authenticationweekly0.5https://dashy.to/docs/backup-restoreweekly0.5https://dashy.to/docs/changelogweekly0.5https://dashy.to/docs/code-of-conductweekly0.5https://dashy.to/docs/configuringweekly0.5https://dashy.to/docs/contributingweekly0.5https://dashy.to/docs/creditsweekly0.5https://dashy.to/docs/deploymentweekly0.5https://dashy.to/docs/developingweekly0.5https://dashy.to/docs/development-guidesweekly0.5https://dashy.to/docs/iconsweekly0.5https://dashy.to/docs/licenseweekly0.5https://dashy.to/docs/managementweekly0.5https://dashy.to/docs/multi-language-supportweekly0.5https://dashy.to/docs/privacyweekly0.5https://dashy.to/docs/quick-startweekly0.5https://dashy.to/docs/readmeweekly0.5https://dashy.to/docs/searchingweekly0.5https://dashy.to/docs/showcaseweekly0.5https://dashy.to/docs/showcase/readmeweekly0.5https://dashy.to/docs/status-indicatorsweekly0.5https://dashy.to/docs/themingweekly0.5https://dashy.to/docs/troubleshootingweekly0.5
\ No newline at end of file