diff --git a/.github/AUTHORS.txt b/.github/AUTHORS.txt index 6ff33ab8..26ff0661 100644 --- a/.github/AUTHORS.txt +++ b/.github/AUTHORS.txt @@ -1,4 +1,5 @@ Alicia - 1 commits +BOZG - 1 commits Begin - 1 commits David - 1 commits DeepSource - 1 commits @@ -10,23 +11,26 @@ Ryan - 1 commits Shreya - 1 commits deepsource-io[bot] - 1 commits jnach <33467747+jnach@users.noreply.github.com> - 1 commits +Alicia - 2 commits +Brendan <'Lear> - 2 commits Dan - 2 commits liss-bot <87835202+liss-bot@users.noreply.github.com> - 2 commits ᗪєνιη <υн> - 2 commits +Walkx <71191962+walkxcode@users.noreply.github.com> - 3 commits Niklas - 4 commits -UrekD - 4 commits +UrekD - 5 commits Erik - 6 commits liss-bot - 6 commits -repo-visualizer - 11 commits -snyk-bot - 11 commits +repo-visualizer - 15 commits Alicia - 16 commits github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - 16 commits -Alicia - 18 commits snyk-bot - 18 commits -EVOTk <45015615+EVOTk@users.noreply.github.com> - 21 commits -Alicia - 25 commits -liss-bot - 28 commits +snyk-bot - 20 commits +EVOTk <45015615+EVOTk@users.noreply.github.com> - 22 commits +Alicia - 28 commits +Alicia - 32 commits +liss-bot - 42 commits Lissy93 - 78 commits -Lissy93 - 199 commits -Alicia - 276 commits -Alicia - 1165 commits \ No newline at end of file +Lissy93 - 202 commits +Alicia - 302 commits +Alicia - 1196 commits \ No newline at end of file diff --git a/.github/workflows/build-app.yml b/.github/workflows/build-app.yml index 0042da65..02c25696 100644 --- a/.github/workflows/build-app.yml +++ b/.github/workflows/build-app.yml @@ -18,7 +18,7 @@ jobs: npm run build - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@4.1.4 - if: ${{ github.repository_owner === 'lissy93' }} + if: ${{ github.repository_owner == 'lissy93' }} with: branch: dev-demo folder: dist diff --git a/.github/workflows/manage-pending-labels.yml b/.github/workflows/manage-pending-labels.yml index 9ade47b0..13f968f9 100644 --- a/.github/workflows/manage-pending-labels.yml +++ b/.github/workflows/manage-pending-labels.yml @@ -19,13 +19,7 @@ jobs: add-awaiting-author: runs-on: ubuntu-latest - if: > - ${{ - !github.event.issue.pull_request - && github.event.comment.author_association != 'COLLABORATOR' - && github.event.comment.author_association != 'OWNER' - && github.event.issue.state === 'open' - }} + if: ${{!github.event.issue.pull_request && github.event.comment.author_association != 'COLLABORATOR' && github.event.comment.author_association != 'OWNER' && github.event.issue.state === 'open' }} steps: - name: Add Awaiting Author labels when Updated uses: actions-cool/issues-helper@v2 diff --git a/README.md b/README.md index 025d3f18..59ab3746 100644 --- a/README.md +++ b/README.md @@ -66,23 +66,23 @@ ## Features 🌈 -- 🔎 Instant search by name, domain or tags + customizable hotkeys & keyboard shortcuts +- 🔎 Instant search by name, domain, or tags + customizable hotkeys & keyboard shortcuts - 🎨 Multiple built-in color themes, with UI color editor and support for custom CSS -- 🧸 Many icon options - Font-Awesome, homelab icons, auto-fetching favicon, images, emojis, etc. -- 🚦 Status monitoring for each of your apps / links for basic availability and uptime checking -- 💂 Optional authentication with multi-user access, configurable privileges and SSO support +- 🧸 Many icon options - Font-Awesome, homelab icons, auto-fetching Favicon, images, emojis, etc. +- 🚦 Status monitoring for each of your apps/links for basic availability and uptime checking +- 💂 Optional authentication with multi-user access, configurable privileges, and SSO support - 🌎 Multi-language support, with 10+ human-translated languages, and more on the way - ☁ Optional, encrypted, free off-site cloud backup and restore feature available -- 💼 A workspace view, for easily switching between multiple apps at simultaneously -- 🛩️ A minimal view, for use as a fast-loading browser startpage -- 🖱️ Choose app launch method, either new tab, same tab, a pop-up modal or in the workspace view -- 📏 Customizable layout, sizes, text, component visibility, sort order, behavior etc. -- 🖼️ Option for full-screen background image, custom nav-bar links, html footer, title, etc. +- 💼 A workspace view, for easily switching between multiple apps simultaneously +- 🛩️ A minimal view, for use as a fast-loading browser Startpage +- 🖱️ Choose app launch method, either new tab, same tab, a pop-up modal, or in the workspace view +- 📏 Customizable layout, sizes, text, component visibility, sort order, behavior, etc. +- 🖼️ Options for a full-screen background image, custom nav-bar links, HTML footer, title, etc. - 🚀 Easy to setup with Docker, or on bare metal, or with 1-Click cloud deployment - ⚙️ Easy single-file YAML-based configuration, and option to configure app through the UI - ✨ Under active development with improvements and new features added regularly -- 🤏 Small bundle size, fully responsive UI and PWA for basic offline access -- 🆓 100% free and open source +- 🤏 Small bundle size, fully responsive UI, and PWA for basic offline access +- 🆓 100% free and open-source - 🔐 Strong focus on privacy - 🌈 And loads more... @@ -128,16 +128,16 @@ docker run -d \ ``` [![Dashy on Docker Hub](https://dockeri.co/image/lissy93/dashy)](https://hub.docker.com/r/lissy93/dashy) -See also examples [with Docker Compose](./docs/deployment.md#using-docker-compose). Dashy is also available via GHCR, and tags for other architectures (`arm32-7`, `arm64-v8`, etc) and set versions are supported +See also examples [with Docker Compose](./docs/deployment.md#using-docker-compose). Dashy is also available via GHCR, and tags for other architectures (`arm32v7`, `arm64v8`, etc.) and set versions are supported -> Once you've got Dashy running, see [App Management Docs](./docs/management.md), for info on using health checks, updating, backups, web-server configs, logs, performance, security and more. +> Once you've got Dashy running, see [App Management Docs](./docs/management.md) for info on using health checks, updating, backups, web-server configs, logs, performance, security, and more. ### Deploying from Source 🚀 You will need [git](https://git-scm.com/downloads), the latest or LTS version of [Node.js](https://nodejs.org/) and (optionally) [Yarn](https://yarnpkg.com/) installed on your system. - Get Code: `git clone https://github.com/Lissy93/dashy.git` and `cd dashy` -- Configuration: Fill in you're settings in `./public/conf.yml` +- Configuration: Fill in your settings in `./public/conf.yml` - Install dependencies: `yarn` - Build: `yarn build` - Run: `yarn start` @@ -164,7 +164,7 @@ Dashy supports 1-Click deployments on several popular cloud platforms. To spin u > For full configuration documentation, see: [**Configuring**](./docs/configuring.md) -Dashy is configured through a YAML file, located at `./public/conf.yml`. You can find a complete list of available options in th [Configuring Docs](/docs/configuring.md). The config can also be edited and saved directly through the UI. +Dashy is configured through a YAML file, located at `./public/conf.yml`. In addition, you can find a complete list of available options in the [Configuring Docs](/docs/configuring.md). The config can also be edited and saved directly through the UI. **[⬆️ Back to Top](#dashy)** @@ -174,7 +174,7 @@ Dashy is configured through a YAML file, located at `./public/conf.yml`. You can > For full theming documentation, see: [**Theming**](./docs/theming.md) -Dashy comes pre-bundled with several built-in themes, which you can preview, applied and edited through the UI. With the theme configurator, and support for custom CSS, everything is in place for you to easily develop your own unique looking dashboard. +Dashy comes pre-bundled with several built-in themes, which you can preview, applied and edit through the UI. With the theme configurator and support for custom CSS, everything is in place to quickly develop your unique-looking dashboard.

@@ -199,12 +199,12 @@ Dashy comes pre-bundled with several built-in themes, which you can preview, app Both sections and items can have an icon associated with them, defined under the `icon` attribute. With several different icon packs supported, you'll be able to find the perfect thumbnail for any app or service. The following icon types are supported: -- **Favicon** - Automatically fetch an apps icon from it's favicon or logo image +- **Favicon** - Automatically fetch an apps icon from its Favicon or logo image - **Icon Packs** - Use any icon from [font-awesome], [simple-icons] or [material icons] - **Emoji** - Any valid emoji can be used as an icon - **Generative** - Unique, auto-generated images for easily identifying services - **URL** - Pass the URL of any valid image in to have it fetched and rendered -- **Local** - Store custom images locally, and reference by filename +- **Local** - Store custom images locally and reference by filename - **Homelab Icons** - Using [dashboard-icons] for logos of commonly self-hosted services @@ -227,9 +227,9 @@ The following icon types are supported: > For full monitoring documentation, see: [**Status Indicators**](./docs/status-indicators.md) -Dashy has an optional feature that can check if each app/ service is up and responding, then display a small status indicator icon. Hovering over it will show additional stats like response time and status code. +Dashy has an optional feature to check if each app/ service is up and responding, then display a small status indicator icon. Hovering over it will show additional stats like response time and status code. -Status indicators can be globally enabled by setting `appConfig.statusCheck: true`, or enabled/ disabled on a per-item basis. Status is checked on page load, but you can enable continuous polling by specifying a time interval between checks, in seconds under `appConfig.statusCheckInterval`. You can also use a different endpoint for status checking, with `statusCheckUrl`, and if needed pass in custom headers under `statusCheckHeaders`. +Status indicators can be globally enabled by setting `appConfig.statusCheck: true` or enabled/ disabled on a per-item basis. Status is checked on page load, but you can allow continuous polling by specifying a time interval between checks, in seconds under `appConfig.statusCheckInterval`. You can also use a different endpoint for status checking, with `statusCheckUrl`, and if needed, pass in custom headers under `statusCheckHeaders`.

Status Checks demo @@ -245,7 +245,7 @@ Status indicators can be globally enabled by setting `appConfig.statusCheck: tru Dashy has full support for secure single-sign-on using [Keycloak](https://www.keycloak.org/) for secure, easy authentication, see [setup docs](/docs/authentication.md#keycloak) for a full usage guide. -There is also a basic auth feature, which doesn't require any additional setup. To enable this, just add an `auth` attribute under `appConfig`, containing an array of `users`, each with a username, SHA-256 hashed password and optional user type. Basic auth also has support for several access control features, including read-only guest access and granular controls. +There is also a basic auth feature, which doesn't require additional setup. To enable this, add an `auth` attribute under `appConfig`, containing an array of `users`, each with a username, SHA-256 hashed password and optional user type. Basic auth also supports several access control features, including read-only guest access and granular controls. ```yaml @@ -266,10 +266,10 @@ Other access control systems are also supported, see the [Alternative Auth Metho ## Alternate Views 👓 As well as the default homepage, there is also: -- A minimal view, useful for use as a browser start page +- A minimal view, valid for use as a browser start page - A workspace view, useful for visiting many apps simultaneously -You can change the view from the UI, using the switch icon in the top-right corner, or select a default view in the config, under `appConfig.startingView` attribute. +You can change the view from the UI, using the switch icon in the top-right corner, or select a default view in the config under `appConfig.startingView` attribute.

Example of Workspace View
@@ -289,12 +289,12 @@ You can change the view from the UI, using the switch icon in the top-right corn > For full documentation on views and opening methods, see: [**Alternate Views**](./docs/alternate-views.md) -There are several different ways apps can be launched. You can specify the default opening method for any given item under the `target` attribute, or set a site-wide default under `appConfig.defaultOpeningMethod`. Right-click on an item to item for all options. The following options are supported: +There are several different ways you can launch apps. You can specify the default opening method for any given item under the `target` attribute or set a site-wide default under `appConfig.defaultOpeningMethod`. Right-click on an item to item for all options. The following options are supported: - `sametab` - The app will be launched in the current tab - `newtab` - The app will be launched in a new tab (or use Ctrl + Click) - `modal` - Launch app in a resizable/ movable popup modal on the current page (or use Alt + Click) -- `workspace` - Changes to Workspace view, and launches app -- `top` - Opens in the top-most browsing context, useful if your accessing Dashy through an iframe +- `workspace` - Changes to Workspace view and launches app +- `top` - Opens in the top-most browsing context, useful if you're accessing Dashy through an iframe --- @@ -302,15 +302,15 @@ There are several different ways apps can be launched. You can specify the defau > For full documentation on searching, see: [**Searching & Shortcuts**](./docs/searching.md) -Quickly finding and launching applications is the primary aim of Dashy. To that end instant search and customizable keyboard shortcuts are built-in. +Quickly finding and launching applications is the primary aim of Dashy. To that end, instant search and customizable keyboard shortcuts are built-in. -To start filtering, just start typing. No need to select the search bar or use any special key. Then use either the tab key or arrow keys to select and move between results, and hit enter to launch the currently selected application. +To start filtering, start typing—no need to select the search bar or use any special key. Then use either the tab key or arrow keys to select and move between results, and hit enter to launch the currently selected application. -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. +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. -You can also add custom tags to a given item, to make finding them based on keywords easier. For example, in the following example, searching for 'Movies' will show 'Plex' +You can also add custom tags to a given item to make finding them based on keywords easier. For example, in the following example, searching for 'Movies' will show 'Plex' -```yaml +"`yaml items: - title: Plex hotkey: 8 @@ -320,7 +320,7 @@ You can also add custom tags to a given item, to make finding them based on keyw tags: [ movies, videos, music ] ``` -To search the web directly through Dashy, just press enter after typing your query. Options for web search are set under `appConfig.webSearch`. There is built in support for [10+ search engines](./docs/searching.md#setting-search-engine), or [use your own custom provider](./docs/searching.md#using-custom-search-engine) or self-hosted instance. With the web search, you can also define your own bangs, to redirect results to any given app, website or search engine, when the query is preceded with a certain character sequence (usually beginning in `/`, `!` or `:`). +To search the web directly through Dashy, just press enter after typing your query. Options for web search are set under `appConfig.webSearch`. There is built-in support for [10+ search engines](./docs/searching.md#setting-search-engine), or [use your own custom provider](./docs/searching.md#using-custom-search-engine) or self-hosted instance. With the web search, you can also define your bangs to redirect results to any given app, website, or search engine, when the query is preceded with a certain character sequence (usually beginning in `/`, `!` or `:`). ```yaml webSearch: @@ -335,7 +335,7 @@ webSearch: ':git': github ``` -Hit `Esc` at anytime to close any open apps, clear the search field, or hide any modals. +Hit `Esc` at any time to close any open apps, clear the search field, or hide any modals. **[⬆️ Back to Top](#dashy)** @@ -344,11 +344,11 @@ Hit `Esc` at anytime to close any open apps, clear the search field, or hide any ## Config Editor ⚙️ > For full config documentation, see: [**Configuring**](./docs/configuring.md) -As well as passing in a YAML config file, you can also configure the app directly through the UI, and preview changes live. +As well as passing in a YAML config file, you can also configure the app directly through the UI and preview changes live. -To edit any section or item, right-click on it, and select "Edit", or enter the Edit Mode (using the Pen icon in the top-right), then click any part of the page to edit. Changes will be visible immediately, but will not be saved until you click "Save to Disk" or "Save Locally". +To edit any section or item, right-click on it, and select "Edit", or enter the Edit Mode (using the Pen icon in the top-right), then click any part of the page to edit. Changes will be visible immediately but will not be saved until clicking "Save to Disk" or "Save Locally". -Under the config menu, you can export, view, backup, or reset app config, as well as edit the raw config file in a text editor, with built-in schema validation. It's recommended to keep a backup of your config. +Under the config menu, you can export, view, backup, or reset app config and edit the raw config file in a text editor with built-in schema validation. It's recommended to keep a backup of your config.

Interactive Editor demo @@ -367,9 +367,9 @@ Under the config menu, you can export, view, backup, or reset app config, as wel > For full backup documentation, see: [**Cloud Backup & Sync**](./docs/backup-restore.md) -Dashy has an **optional** built-in feature for securely backing up your config to a hosted cloud service, and then restoring it on another instance. 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. +Dashy has an **optional** built-in feature for securely backing up your config to a hosted cloud service and then restoring it on another instance. This is useful not only for backing up your configuration off-site but also enables Dashy to be used without having to write a YAML config file. -All data is fully E2E encrypted before being sent to the backend (done in [`CloudBackup.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/CloudBackup.js) using [crypto.js](https://github.com/brix/crypto-js)'s AES method). The data is then sent to a [Cloudflare worker](https://developers.cloudflare.com/workers/learning/how-workers-works), and stored in a [KV](https://developers.cloudflare.com/workers/learning/how-kv-works) data store. +All data is fully E2E encrypted before being sent to the backend (done in [`CloudBackup.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/CloudBackup.js) using [crypto.js](https://github.com/brix/crypto-js) 's AES method). The data is then sent to a [Cloudflare worker](https://developers.cloudflare.com/workers/learning/how-workers-works) and stored in a [KV](https://developers.cloudflare.com/workers/learning/how-kv-works) data store. **[⬆️ Back to Top](#dashy)** @@ -378,7 +378,7 @@ All data is fully E2E encrypted before being sent to the backend (done in [`Clou ## Language Switching 🌎 > For full internationalization documentation, see: [**Multi-Language Support**](./docs/multi-language-support.md) -Dashy supports multiple languages and locales. When available, your language should be automatically detected and applied on load. But you can also select a language through the UI (under Config --> Switch Language), or set `appConfig.language` to your language (specified as a 2-digit [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)). +Dashy supports multiple languages and locales. When available, your language should be automatically detected and applied on load. But you can also select a language through the UI (under config --> Switch Language) or set `appConfig.language` to your language (specified as a 2-digit [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)). #### Supported Languages - 🇬🇧 **English**: `en` - _Default_ @@ -390,6 +390,7 @@ Dashy supports multiple languages and locales. When available, your language sho - 🇵🇱 **Polish**: `pl` - Contributed by **[@skaarj1989](https://github.com/skaarj1989)** - 🇪🇸 **Spanish**: `es` - Contributed by **[@lu4t](https://github.com/lu4t)** - 🇸🇮 **Slovenian**: `sl` - Contributed by **[@UrekD](https://github.com/UrekD)** +- 🇸🇪 **Swedish**: `sv` - Contributed by **[@BOZG](https://github.com/BOZG)** - 🇮🇹 **Italian**: `it` - Machine Translated *(awaiting human review)* - 🇵🇹 **Portuguese**: `pt` - Machine Translated *(awaiting human review)* - 🇷🇺 **Russian**: `ru` - Contributed by Anon @@ -398,7 +399,7 @@ Dashy supports multiple languages and locales. When available, your language sho - 🇯🇵 **Japanese**: `ja` - Contributed by Anon #### Add your Language -I would love Dashy to be available to everyone, without language being a barrier to entry. If you've got a few minutes to spare, consider adding translations for your language. It's a quick task and all text is in [a single JSON file](https://github.com/Lissy93/dashy/tree/master/src/assets/locales). Since any missing text will fallback to English, you don't need to translate it all. +I would love Dashy to be available to everyone without language being a barrier to entry. If you've got a few minutes to spare, consider adding translations for your language. It's a quick task, and all text is in [a single JSON file](https://github.com/Lissy93/dashy/tree/master/src/assets/locales). Since any missing text will fall back to English, you don't need to translate it all. **[⬆️ Back to Top](#dashy)** @@ -406,7 +407,7 @@ I would love Dashy to be available to everyone, without language being a barrier ## System Requirements 📊 -The hardware requirements vary depending on where and how you are running Dashy. Generally speaking, on a bare metal system or Docker container, 1GB of memory should be more than enough, and depending on whether you are using your own assets, then 1GB of disk space should be sufficient. +The hardware requirements vary depending on where and how you are running Dashy. Generally speaking, on a bare-metal system or Docker container, 1GB of memory should be more than enough, and depending on whether you are using your own assets, then 1GB of disk space should be sufficient. If you are using one of the 1-click cloud deployment methods, serving the app through a CDN or using a static hosting provider, then there are no specific requirements, as the built app is just a series of static JS files, and so is very light-weight. @@ -433,17 +434,17 @@ It's best to check the [docs](./docs), [previous issues](https://github.com/Liss ## Supporting Dashy 💖 -> For full details, and other ways you can help out, see: [**Contributing**](./docs/contributing.md) +> For full details and other ways you can help out, see: [**Contributing**](./docs/contributing.md) -If you're using Dashy, and would like to help support it's development, then that would be awesome! Contributions of any type, however small are always very much appreciated, and you will be appropriately credited for your effort. +If you're using Dashy and would like to help support its development, then that would be awesome! Contributions of any type, any size, are always very much appreciated, and we will appropriately credit you for your effort. Several areas that we need a bit of help with at the moment are: -- Translating - Help make Dashy available to non-native English speakers by [adding youre language](./docs/multi-language-support.md#adding-a-new-language) -- Donate a small amount, by [Sponsoring @Lissy93 on GitHub](https://github.com/sponsors/Lissy93) and receive some extra perks! -- Complete a [short survey](https://survey.typeform.com/to/gl0L68ou), to have your say about future features -- Share your dashboard in the [Showcase](https://github.com/Lissy93/dashy/blob/master/docs/showcase.md#dashy-showcase-), to provide inspiration for others -- Spread the word, by sharing Dashy or a screenshot of your dashboard, to help new users discover it -- Submit a PR, to add a new feature, fix a bug, update the docs, add a theme or something else +- Translating - Help make Dashy available to non-native English speakers by [adding your language](./docs/multi-language-support.md#adding-a-new-language) +- Donate a small amount by [Sponsoring @Lissy93 on GitHub](https://github.com/sponsors/Lissy93) and receive some extra perks! +- Complete a [short survey](https://survey.typeform.com/to/gl0L68ou) to have your say about future features +- Share your dashboard in the [Showcase](https://github.com/Lissy93/dashy/blob/master/docs/showcase.md#dashy-showcase-), to inspire others +- Spread the word by sharing Dashy or a screenshot of your dashboard to help new users discover it +- Submit a PR to add a new feature, fix a bug, update the docs, add a theme, or something else - Star Dashy on GitHub/ DockerHub or leave an upvote / review on [these platforms](https://github.com/Lissy93/dashy/blob/master/docs/contributing.md#star-upvote-or-leave-a-review) [![Sponsor Lissy93 on GitHub](./docs/assets/sponsor-button.svg)](https://github.com/sponsors/Lissy93) @@ -452,9 +453,9 @@ Several areas that we need a bit of help with at the moment are: ## Credits 🏆 -> For a full list of credits, and attributions to packages used within Dashy, see: [**Credits**](./docs/credits.md) +> For a complete list of credits, and attributions to packages used within Dashy, see: [**Credits**](./docs/credits.md) -Thank you so much to everyone who has helped with Dashy so far, every contribution is very much appreciated. +Thank you so much to everyone who has helped with Dashy so far; every contribution is very much appreciated. #### Sponsors @@ -463,17 +464,24 @@ Huge thanks to the sponsors helping to support Dashy's development! +
- - mfnalex + + BOZG
- Mfnalex + Stephen Rigney
- - Robert-Ernst + + vlad-timofeev
- Robert Ernst + Vlad Timofeev +
+
+ + matthewjdegarmo +
+ Matthew J. DeGarmo
@@ -501,9 +509,9 @@ To set up the development environment: 2. Install dependencies: `yarn` 3. Start dev server: `yarn dev` -Hot reload is enabled, so changes will be automatically detected, compiled and refreshed. +Hot reload is enabled, so changes will be automatically detected, compiled and, refreshed. -If you're new to web development, I've put together a short [list of resources](https://github.com/Lissy93/dashy/blob/master/docs/developing.md#resources-for-beginners), to help beginners get started +If you're new to web development, I've put together a short [list of resources](https://github.com/Lissy93/dashy/blob/master/docs/developing.md#resources-for-beginners) to help beginners get started **Repo Status**: [![Open PRs](https://flat.badgen.net/github/open-prs/lissy93/dashy?icon=github)](https://github.com/Lissy93/dashy/pulls) @@ -520,13 +528,13 @@ If you're new to web development, I've put together a short [list of resources]( > For full release, automation and CI documentation, see: [**Releases & Workflows**](./docs/release-workflow.md) -Dashy is under active development, with features, improvements and changes pushed almost daily. +Dashy is under active development, with features, improvements, and changes pushed almost daily. -We're using [Semantic Versioning](https://semver.org/), to indicate major, minor and patch versions. You can find the current version number in the readme, and check your apps version under the config menu. The version number is pulled from the [package.json](https://github.com/Lissy93/dashy/blob/master/package.json#L3) file. +We're using [Semantic Versioning](https://semver.org/) to indicate major, minor, and patch versions. You can find the current version number in the readme and check the version of your app under the config menu. The version number is pulled from the [package.json](https://github.com/Lissy93/dashy/blob/master/package.json#L3) file. -Typically there is a new major release every 2 - 4 weeks, usually on Sunday, and you can view these under the [Releases Page](https://github.com/Lissy93/dashy/releases) and [on DockerHub](https://hub.docker.com/r/lissy93/dashy/tags). New minor versions are pushed several times a week, and are [tagged here](https://github.com/Lissy93/dashy/tags). +Typically there is a new major release every 2 - 4 weeks, usually on Sunday, and you can view these under the [Releases Page](https://github.com/Lissy93/dashy/releases) and [on DockerHub](https://hub.docker.com/r/lissy93/dashy/tags). In addition, new minor versions are pushed several times a week and are [tagged here](https://github.com/Lissy93/dashy/tags). -For a full breakdown of each change, you can view the [Changelog](https://github.com/Lissy93/dashy/blob/master/.github/CHANGELOG.md). Each new feature or significant change needs to be submitted through [a pull request](https://github.com/Lissy93/dashy/pulls?q=is%3Apr), which makes it easy to review and track these changes, and roll back if needed. +For a full breakdown of each change, you can view the [Changelog](https://github.com/Lissy93/dashy/blob/master/.github/CHANGELOG.md). In addition, each new feature or significant change needs to be submitted through [a pull request](https://github.com/Lissy93/dashy/pulls?q=is%3Apr), which makes it easy to review and track these changes, and roll back if needed. **[⬆️ Back to Top](#dashy)** @@ -585,7 +593,7 @@ The following features and tasks are planned for the near future. ## Alternatives 🙌 -There are a few self-hosted web apps, that serve a similar purpose to Dashy. If you're looking for a dashboard, and Dashy doesn't meet your needs, I highly recommend you check these projects out! +A few self-hosted web apps serve a similar purpose to Dashy. If you're looking for a dashboard, and Dashy doesn't meet your needs, I highly recommend you check these projects out! - [Flame](https://github.com/pawelmalak/flame) by @pawelmalak (`MIT`) - [HomeDash2](https://lamarios.github.io/Homedash2) - [Homer](https://github.com/bastienwirtz/homer) (`Apache License 2.0`) @@ -599,13 +607,13 @@ There are a few self-hosted web apps, that serve a similar purpose to Dashy. If --- ## License 📜 -Dashy is License under [MIT X11](https://en.wikipedia.org/wiki/MIT_License) +Dashy is Licensed under [MIT X11](https://en.wikipedia.org/wiki/MIT_License) ``` Copyright © 2021 Alicia Sykes Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the “Software”), to deal in the Software +software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -613,15 +621,15 @@ persons to whom the Software is furnished to do so, subject to the following con The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWAREOR THE USE +LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, 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 THE SOFTWARE. Except as contained in this notice, Dashy shall not be used in advertising or otherwise -to promote the sale, use or other dealings in this Software without prior written +to promote the sale, use, or other dealings in this Software without prior written authorization from the repo owner. ``` diff --git a/docs/assets/CONTRIBUTORS.svg b/docs/assets/CONTRIBUTORS.svg index fa894849..ad833b9c 100644 --- a/docs/assets/CONTRIBUTORS.svg +++ b/docs/assets/CONTRIBUTORS.svg @@ -3,11 +3,11 @@
- - - - + + + + @@ -15,34 +15,40 @@ + + + - + - + + + + - + - + - + - + - + - + - + - + \ No newline at end of file diff --git a/docs/assets/repo-visualization.svg b/docs/assets/repo-visualization.svg index a6b05a90..ffe6a369 100644 --- a/docs/assets/repo-visualization.svg +++ b/docs/assets/repo-visualization.svg @@ -1 +1 @@ -viewsviewsutilsutilsstylesstylescomponentscomponentsassetsassetsWorkspaceWorkspaceSettingsSettingsPageStrcturePageStrctureMinimalViewMinimalViewLinkItemsLinkItemsInteractiveEditorInteractiveEditorFormElementsFormElementsConfigurationConfigurationlocaleslocalesinterface-iconsinterface-iconsHome.vueHome.vueHome.vueLogin.vueLogin.vueLogin.vueemojis.jsonemojis.jsonemojis.jsonConfigSch...ConfigSch...ConfigSch...color-the...color-the...color-the...CustomThe...CustomThe...CustomThe...Item.vueItem.vueItem.vueSection.vueSection.vueSection.vueEditItem...EditItem...EditItem...JsonEdito...JsonEdito...JsonEdito...ConfigCo...ConfigCo...ConfigCo...hi.jsonhi.jsonhi.jsonfr.jsonfr.jsonfr.jsonru.jsonru.jsonru.jsonen.jsonen.jsonen.jsonar.jsonar.jsonar.json.js.json.scss.svg.vueeach dot sized by file size \ No newline at end of file +viewsviewsutilsutilsstylesstylescomponentscomponentsassetsassetsWorkspaceWorkspaceSettingsSettingsPageStrcturePageStrctureMinimalViewMinimalViewLinkItemsLinkItemsInteractiveEditorInteractiveEditorFormElementsFormElementsConfigurationConfigurationlocaleslocalesinterface-iconsinterface-iconsHome.vueHome.vueHome.vueLogin.vueLogin.vueLogin.vueemojis.jsonemojis.jsonemojis.jsonConfigSch...ConfigSch...ConfigSch...color-the...color-the...color-the...CustomTh...CustomTh...CustomTh...Item.vueItem.vueItem.vueSection.vueSection.vueSection.vueItemIcon...ItemIcon...ItemIcon...EditItem...EditItem...EditItem...JsonEdit...JsonEdit...JsonEdit...ConfigCo...ConfigCo...ConfigCo...hi.jsonhi.jsonhi.jsonfr.jsonfr.jsonfr.jsonsv.jsonsv.jsonsv.jsonru.jsonru.jsonru.jsonsl.jsonsl.jsonsl.jsonen.jsonen.jsonen.json.js.json.scss.svg.vueeach dot sized by file size \ No newline at end of file diff --git a/docs/credits.md b/docs/credits.md index 96fb611d..6cfe1e57 100644 --- a/docs/credits.md +++ b/docs/credits.md @@ -5,24 +5,24 @@
- - mfnalex + + BOZG
- Mfnalex + Stephen Rigney
- - Robert-Ernst + + vlad-timofeev
- Robert Ernst + Vlad Timofeev
- - DylanBeMe + + matthewjdegarmo
- DylanH + Matthew J. DeGarmo
@@ -39,13 +39,6 @@ Alicia Sykes - - - EVOTk -
- EVOTk -
- liss-bot @@ -54,10 +47,10 @@ - - evroon + + EVOTk
- Erik Vroon + EVOTk
@@ -67,6 +60,13 @@ Snyk Bot + + + evroon +
+ Erik Vroon +
+ UrekD @@ -75,6 +75,13 @@ + + + walkxcode +
+ Walkx +
+ onedr0p @@ -89,6 +96,13 @@ Dan Gilbert + + + BOZG +
+ Stephen Rigney +
+ BeginCI @@ -102,7 +116,8 @@
David
- + + deepsourcebot @@ -116,8 +131,7 @@
FormatToday
- - + Compunctus @@ -145,7 +159,8 @@
Shreya Roy
- + + jnach diff --git a/docs/management.md b/docs/management.md index 088a0eca..fc8336e2 100644 --- a/docs/management.md +++ b/docs/management.md @@ -1,707 +1,756 @@ -# Management - -_The following article explains aspects of app management, and is useful to know for when self-hosting. It covers everything from keeping the Dashy (or any other app) up-to-date, secure, backed up, to other topics like auto-starting, monitoring, log management, web server configuration and using custom environments. It's like a top-20 list of need-to-know knowledge for self-hosting._ - -## Contents -- [Providing Assets](#providing-assets) -- [Running Commands](#running-commands) -- [Healthchecks](#healthchecks) -- [Logs and Performance](#logs-and-performance) -- [Auto-Starting at Boot](#auto-starting-at-system-boot) -- [Updating](#updating) -- [Backing Up](#backing-up) -- [Scheduling](#scheduling) -- [SSL Certificates](#ssl-certificates) -- [Authentication](#authentication) -- [Managing with Compose](#managing-containers-with-docker-compose) -- [Environmental Variables](#passing-in-environmental-variables) -- [Securing Containers](#container-security) -- [Remote Access](#remote-access) -- [Custom Domain](#custom-domain) -- [Web Server Configuration](#web-server-configuration) -- [Running a Modified App](#running-a-modified-version-of-the-app) -- [Building your Own Container](#building-your-own-container) - ---- - -## Providing Assets -Although not essential, you will most likely want to provide several assets to your running app. - -This is easy to do using [Docker Volumes](https://docs.docker.com/storage/volumes/), which lets you share a file or directory between your host system, and the container. Volumes are specified in the Docker run command, or Docker compose file, using the `--volume` or `-v` flags. The value of which consists of the path to the file / directory on your host system, followed by the destination path within the container. Fields are separated by a colon (`:`), and must be in the correct order. For example: `-v ~/alicia/my-local-conf.yml:/app/public/conf.yml` - -In Dashy, commonly configured resources include: -- `./public/conf.yml` - Your main application config file -- `./public/item-icons` - A directory containing your own icons. This allows for offline access, and better performance than fetching from a CDN -- Also within `./public` you'll find standard website assets, including `favicon.ico`, `manifest.json`, `robots.txt`, etc. There's no need to pass these in, but you can do so if you wish -- `/src/styles/user-defined-themes.scss` - A stylesheet for applying custom CSS to your app. You can also write your own themes here. - -**[⬆️ Back to Top](#management)** - ---- -## Running Commands - - If you're running an app in Docker, then commands will need to be passed to the container to be executed. This can be done by preceding 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`. You can also enter the container, with `docker exec -it [container-id] /bin/ash`, and navigate around it with normal Linux commands. - - Dashy has several commands that can be used for various tasks, you can find a list of these either in the [Developing Docs](/docs/developing.md#project-commands), or by looking at the [`package.json`](https://github.com/Lissy93/dashy/blob/master/package.json#L5). These can be used by running `yarn [command-name]`. - -**[⬆️ Back to Top](#management)** - ---- -## Healthchecks - -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](https://hub.docker.com/r/willfarrell/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](https://github.com/moby/moby/pull/22719)). There's also [Deunhealth](https://github.com/qdm12/deunhealth), which is super light-weight, and doesn't require network access. - -``` -docker run -d \ - --name autoheal \ - --restart=always \ - -e AUTOHEAL_CONTAINER_LABEL=all \ - -v /var/run/docker.sock:/var/run/docker.sock \ - willfarrell/autoheal -``` - -**[⬆️ Back to Top](#management)** - ---- -## Logs and Performance - -#### Container Logs -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](https://docs.docker.com/config/containers/logging/). There's also [Dozzle](https://dozzle.dev/), 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. - -#### Container Performance -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](https://docs.docker.com/engine/reference/commandline/stats/). There's also [cAdvisor](https://github.com/google/cadvisor), a useful web app for viewing and analyzing resource usage and performance of all your running containers. - -#### Management Apps -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](https://github.com/portainer/portainer) an all-in-one open source management web UI for Docker and Kubernetes, or [LazyDocker](https://github.com/jesseduffield/lazydocker) a terminal UI for Docker container management and monitoring. - -#### Advanced Logging and Monitoring -Docker supports using [Prometheus](https://prometheus.io/) to collect logs, which can then be visualized using a platform like [Grafana](https://grafana.com/). For more info, see [this guide](https://docs.docker.com/config/daemon/prometheus/). If you need to route your logs to a remote syslog, then consider using [logspout](https://github.com/gliderlabs/logspout). For enterprise-grade instances, there are managed services, that make monitoring container logs and metrics very easy, such as [Sematext](https://sematext.com/blog/docker-container-monitoring-with-sematext/) with [Logagent](https://github.com/sematext/logagent-js). - -**[⬆️ Back to Top](#management)** - ---- - -## Auto-Starting at System Boot - -You can use Docker's [restart policies](https://docs.docker.com/engine/reference/run/#restart-policies---restart) 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](https://docs.docker.com/config/containers/start-containers-automatically/). - -For Podman, you can use `systemd` to create a service that launches your container, [the docs](https://podman.io/blogs/2018/09/13/systemd.html) 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`](https://github.com/willfarrell/docker-autoheal) by @willfarrell, a service that monitors and restarts unhealthy containers. For more info, see the [Healthchecks](#healthchecks) section above. - -**[⬆️ Back to Top](#management)** - ---- -## Updating - -Dashy is under active development, so to take advantage of the latest features, you may need to update your instance every now and again. - -### Updating Docker Container -1. Pull latest image: `docker pull lissy93/dashy:latest` -2. Kill off existing container - - Find container ID: `docker ps` - - Stop container: `docker stop [container_id]` - - Remove container: `docker rm [container_id]` -3. Spin up new container: `docker run [params] lissy93/dashy` - -### Automatic Docker Updates - -You can automate the above process using [Watchtower](https://github.com/containrrr/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. - -To get started, spin up the watchtower container: - -``` -docker run -d \ - --name watchtower \ - -v /var/run/docker.sock:/var/run/docker.sock \ - containrrr/watchtower -``` - -For more information, see the [Watchtower Docs](https://containrrr.dev/watchtower/) - -### Updating Dashy from Source -Stop your current instance of Dashy, then navigate into the source directory. Pull down the latest code, with `git pull origin master`, then update dependencies with `yarn`, rebuild with `yarn build`, and start the server again with `yarn start`. - -**[⬆️ Back to Top](#management)** - ---- - -## Backing Up - -### Backing Up Containers - -You can make a backup of any running container really easily, using [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit/) and save it with [`docker export`](https://docs.docker.com/engine/reference/commandline/export/), to do so: -- First find the container ID, you can do this with `docker container ls` -- Now to create the snapshot, just run `docker commit -p [container-id] my-backup` -- Finally, to save the backup locally, run `docker save -o ~/dashy-backup.tar my-backup` -- If you want to push this to a container registry, run `docker push my-backup:latest` - -Note that this will not include any data in docker volumes, and the process here is a bit different. Since these files exist on your host system, if you have an existing backup solution implemented, you can incorporate and volume files within that system. - -### Backing Up Volumes -[offen/docker-volume-backup](https://github.com/offen/docker-volume-backup) is a useful tool for periodic Docker volume backups, to any S3-compatible storage provider. It's run as a light-weight Docker container, and is easy to setup, and also supports GPG-encryption, email notification, and routing away older backups. - -To get started, create a docker-compose similar to the example below, and then start the container. For more info, check out their [documentation](https://github.com/offen/docker-volume-backup), which is very clear. - -```yaml -version: '3' -services: - backup: - image: offen/docker-volume-backup:latest - environment: - BACKUP_CRON_EXPRESSION: "0 * * * *" - BACKUP_PRUNING_PREFIX: backup- - BACKUP_RETENTION_DAYS: 7 - AWS_BUCKET_NAME: backup-bucket - AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE - AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - volumes: - - data:/backup/my-app-backup:ro - - /var/run/docker.sock:/var/run/docker.sock:ro -volumes: - data: -``` - -It's worth noting that this process can also be done manually, using the following commands: - -Backup: -``` -docker run --rm -v some_volume:/volume -v /tmp:/backup alpine tar -cjf /backup/some_archive.tar.bz2 -C /volume ./ -``` -Restore: -``` -docker run --rm -v some_volume:/volume -v /tmp:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/some_archive.tar.bz2" -``` -### Dashy-Specific Backup -Since Dashy is open source, and freely available, providing you're configuration data is passed in as volumes, there shouldn't be any need to backup the main container. Your main config file, and any assets you're using should be kept backed up, preferably in at least two places, and you should ensure that you can easily restore from backup, if needed. - -Dashy also has a built-in cloud backup feature, which is free for personal users, and will let you make and restore fully encrypted backups of your config directly through the UI. To learn more, see the [Cloud Backup Docs](/docs/backup-restore.md) - -**[⬆️ Back to Top](#management)** - ---- - -## Scheduling - -If you need to periodically schedule the running of a given command on Dashy (or any other container), then a useful tool for doing so it [ofelia](https://github.com/mcuadros/ofelia). This runs as a Docker container and is really useful for things like backups, logging, updating, notifications, etc. Crons are specified using Go's crontab format, and a useful tool for visualizing this is [crontab.guru](https://crontab.guru/). This can also be done natively with Alpine: `docker run -it alpine ls /etc/periodic`. -I recommend combining this with [healthchecks](https://github.com/healthchecks/healthchecks) for easy monitoring of jobs, and failure notifications. - -**[⬆️ Back to Top](#management)** - ---- - -## SSL Certificates - -Enabling HTTPS with an SSL certificate is recommended, especially if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit. - -### Auto-SSL -If you are using [NGINX Proxy Manager](https://nginxproxymanager.com/), then SSL is supported out of the box. Once you've added your proxy host and web address, then set the scheme to HTTPS, then under the SSL Tab select "Request a new SSL certificate" and follow the on-screen instructions. - -If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/)- all you need to do is enable it under the SSL/TLS tab. Or if you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful. - -### Getting a Self-Signed SSL Certificate -[Let's Encrypt](https://letsencrypt.org/docs/) 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](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate. - -This process can be automated, using something like the [Docker-NGINX-Auto-SSL Container](https://github.com/Valian/docker-nginx-auto-ssl) to generate and renew certificates when needed. - -If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) or [ZeroSSL](https://zerossl.com/) to generate your cert. They also provide step-by-step setup instructions for most platforms. - -### Passing a Self-Signed Certificate to Dashy -Once you've generated your SSL cert, you'll need to pass it to Dashy. This can be done by specifying the paths to your public and private keys using the `SSL_PRIV_KEY_PATH` and `SSL_PUB_KEY_PATH` environmental variables. Or if you're using Docker, then just pass public + private SSL keys in under `/etc/ssl/certs/dashy-pub.pem` and `/etc/ssl/certs/dashy-priv.key` respectively, e.g: - -``` -docker run -d \ - -p 8080:80 \ - -v ~/my-private-key.key:/etc/ssl/certs/dashy-priv.key:ro \ - -v ~/my-public-key.pem:/etc/ssl/certs/dashy-pub.pem:ro \ - lissy93/dashy:latest -``` - -By default the SSL port is `443` within a Docker container, or `4001` if running on bare metal, but you can override this with the `SSL_PORT` environmental variable. - -Once everything is setup, you can verify your site is secured using a tool like [SSL Checker](https://www.sslchecker.com/sslchecker). - -**[⬆️ Back to Top](#management)** - ---- - -## Authentication - -Dashy natively supports secure authentication using KeyCloak. There is also a Simple Auth feature that doesn't require any additional setup. Usage instructions for both, as well as alternative auth methods, has now moved to the **[Authentication Docs](/docs/authentication.md)** page. - -**[⬆️ Back to Top](#management)** - ---- - -## Managing Containers with Docker Compose - -When you have a lot of containers, it quickly becomes hard to manage with `docker run` commands. The solution to this is [docker compose](https://docs.docker.com/compose/), a handy tool for defining all a containers run settings in a single YAML file, and then spinning up that container with a single short command - `docker compose up`. A good example of which can be seen in [@abhilesh's docker compose collection](https://github.com/abhilesh/self-hosted_docker_setups). - -You can use Dashy's default [`docker-compose.yml`](https://github.com/Lissy93/dashy/blob/master/docker-compose.yml) file as a template, and modify it according to your needs. - -An example Docker compose, using the default base image from DockerHub, might look something like this: - -```yaml ---- -version: "3.8" -services: - dashy: - container_name: Dashy - image: lissy93/dashy - volumes: - - /root/my-config.yml:/app/public/conf.yml - ports: - - 4000:80 - environment: - - BASE_URL=/my-dashboard - restart: unless-stopped - healthcheck: - test: ['CMD', 'node', '/app/services/healthcheck'] - interval: 1m30s - timeout: 10s - retries: 3 - start_period: 40s -``` - -**[⬆️ Back to Top](#management)** - ---- - -## Passing in Environmental Variables - -With Docker, you can define environmental variables under the `environment` section of your Docker compose file. Environmental variables are used to configure high-level settings, usually before the config file has been read. For a list of all supported env vars in Dashy, see [the developing docs](/docs/developing.md#environmental-variables), or the default [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file. - -A common use case, is to run Dashy under a sub-page, instead of at the root of a URL (e.g. `https://my-homelab.local/dashy` instead of `https://dashy.my-homelab.local`). In this use-case, you'd specify the `BASE_URL` variable in your compose file. - -```yaml -environment: - - BASE_URL=/dashy -``` - -You can also do the same thing with the docker run command, using the [`--env`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) flag. -If you've got many environmental variables, you might find it useful to put them in a [`.env` file](https://docs.docker.com/compose/env-file/). Similarly, for Docker run you can use [`--env-file`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) if you'd like to pass in a file containing all your environmental variables. - -**[⬆️ Back to Top](#management)** - ---- - -## Container Security - -- [Keep Docker Up-To-Date](#keep-docker-up-to-date) -- [Set Resource Quotas](#set-resource-quotas) -- [Don't Run as Root](#dont-run-as-root) -- [Specify a User](#specify-a-user) -- [Limit Capabilities](#limit-capabilities) -- [Prevent new Privilages being Added](#prevent-new-privilages-being-added) -- [Disable Inter-Container Communication](#disable-inter-container-communication) -- [Don't Expose the Docker Daemon Socket](#dont-expose-the-docker-daemon-socket) -- [Use Read-Only Volumes](#use-read-only-volumes) -- [Set the Logging Level](#set-the-logging-level) -- [Verify Image before Pulling](#verify-image-before-pulling) -- [Specify the Tag](#specify-the-tag) -- [Container Security Scanning](#container-security-scanning) -- [Registry Security](#registry-security) -- [Security Modules](#security-modules) - -### Keep Docker Up-To-Date -To prevent known container escape vulnerabilities, which typically end in escalating to root/administrator privileges, patching Docker Engine and Docker Machine is crucial. For more info, see the [Docker Installation Docs](https://docs.docker.com/engine/install/). - -### Set Resource Quotas -Docker enables you to limit resource consumption (CPU, memory, disk) on a per-container basis. This not only enhances system performance, but also prevents a compromised container from consuming a large amount of resources, in order to disrupt service or perform malicious activities. To learn more, see the [Resource Constraints Docs](https://docs.docker.com/config/containers/resource_constraints/) - -For example, to run Dashy with max of 1GB ram, and max of 50% of 1 CP core: -`docker run -d -p 8080:80 --cpus=".5" --memory="1024m" lissy93/dashy:latest` - -### Don't Run as Root -Running a container with admin privileges gives it more power than it needs, and can be abused. Dashy does not need any root privileges, and Docker by default doesn't run containers as root, so providing you don't specifically type sudo, you should be all good here. - -Note that if you're facing permission issues on Debian-based systems, you may need to add your user to the Docker group. First create the group: `sudo groupadd docker`, then add your (non-root) user: `sudo usermod −aG docker [my-username]`, finally `newgrp docker` to refresh. - -### Specify a User -One of the best ways to prevent privilege escalation attacks, is to configure the container to use an unprivileged user. This also means that any files created by the container and mounted, will be owned by the specified user (and not root), which makes things much easier. - -You can specify a user, using the [`--user` param](https://docs.docker.com/engine/reference/run/#user), and should include the user ID (`UID`), which can be found by running `id -u`, and the and the group ID (`GID`), using `id -g`. - -With Docker run, you specify it like: -`docker run --user 1000:1000 -p 8080:80 lissy93/dashy` - -Of if you're using Docker-compose, you could use an environmental variable - -```yaml -version: "3.8" -services: - dashy: - image: lissy93/dashy - user: ${CURRENT_UID} - ports: [ 4000:80 ] -``` - -And then to set the variable, and start the container, run: `CURRENT_UID=$(id -u):$(id -g) docker-compose up` - -### Limit capabilities -Docker containers run with a subset of [Linux Kernal's Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) by default. It's good practice to drop privilege permissions that are not needed for any given container. - -With Docker run, you can use the `--cap-drop` flag to remove capabilities, you can also use `--cap-drop=all` and then define just the required permissions using the `--cap-add` option. For a list of available capabilities, see the [Privilege Capabilities Docs](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities). - -Here's an example using docker-compose, removing privileges that are not required for Dashy to run: - -```yaml -version: "3.8" -services: - dashy: - image: lissy93/dashy - ports: [ 4000:80 ] - cap_drop: - - ALL - cap_add: - - CHOWN - - SETGID - - SETUID - - DAC_OVERRIDE - - NET_BIND_SERVICE -``` - -### Prevent new Privilages being Added -To prevent processes inside the container from getting additional privileges, pass in the `--security-opt=no-new-privileges:true` option to the Docker run command (see [docs](https://docs.docker.com/engine/reference/run/#security-configuration)). - -Run Command: -`docker run --security-opt=no-new-privileges:true -p 8080:80 lissy93/dashy` - -Docker Compose -```yaml -security_opt: -- no-new-privileges:true -``` - -### Disable Inter-Container Communication -By default Docker containers can talk to each other (using [`docker0` bridged network](https://docs.docker.com/config/containers/container-networking/)). If you don't need this capability, then it should be disabled. This can be done with the `--icc=false` in your run command. You can learn more about how to facilitate secure communication between containers in the [Compose Networking docs](https://docs.docker.com/compose/networking/). - -### Don't Expose the Docker Daemon Socket -Docker socket `/var/run/docker.sock` is the UNIX socket that Docker is listening to. This is the primary entry point for the Docker API. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. - -You should **not** enable TCP Docker daemon socket (`-H tcp://0.0.0.0:XXX`), as doing so exposes un-encrypted and unauthenticated direct access to the Docker daemon, and if the host is connected to the internet, the daemon on your computer can be used by anyone from the public internet- which is bad. If you need TCP, you should [see the docs](https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option) to understand how to do this more securely. -Similarly, never expose `/var/run/docker.sock` to other containers as a volume, as it can be exploited. - -### Use Read-Only Volumes -You can specify that a specific volume should be read-only by appending `:ro` to the `-v` switch. For example, while running Dashy, if we want our config to be writable, but keep all other assets protected, we would do: -``` -docker run -d \ - -p 8080:80 \ - -v ~/dashy-conf.yml:/app/public/conf.yml \ - -v ~/dashy-icons:/app/public/item-icons:ro \ - -v ~/dashy-theme.scss:/app/src/styles/user-defined-themes.scss:ro \ - lissy93/dashy:latest -``` - -You can also prevent a container from writing any changes to volumes on your host's disk, using the `--read-only` flag. Although, for Dashy, you will not be able to write config changes to disk, when edited through the UI with this method. You could make this work, by specifying the config directory as a temp write location, with `--tmpfs /app/public/conf.yml` - but that this will not write the volume back to your host. - -### Set the Logging Level -Logging is important, as it enables you to review events in the future, and in the case of a compromise this will let get an idea of what may have happened. The default log level is `INFO`, and this is also the recommendation, use `--log-level info` to ensure this is set. - -### Verify Image before Pulling -Only use trusted images, from verified/ official sources. If an app is open source, it is more likely to be safe, as anyone can verify the code. There are also tools available for scanning containers, - -Unless otherwise configured, containers can communicate among each other, so running one bad image may lead to other areas of your setup being compromised. Docker images typically contain both original code, as well as up-stream packages, and even if that image has come from a trusted source, the up-stream packages it includes may not have. - -### Specify the Tag -Using fixed tags (as opposed to `:latest` ) will ensure immutability, meaning the base image will not change between builds. Note that for Dashy, the app is being actively developed, new features, bug fixes and general improvements are merged each week, and if you use a fixed version you will not enjoy these benefits. So it's up to you weather you would prefer a stable and reproducible environment, or the latest features and enhancements. - -### Container Security Scanning -It's helpful to be aware of any potential security issues in any of the Docker images you are using. You can run a quick scan using Snyk on any image to output known vulnerabilities using [Docker scan](https://docs.docker.com/engine/scan/), e.g: `docker scan lissy93/dashy:latest`. - -A similar product is [Trivy](https://github.com/aquasecurity/trivy), which is free an open source. First install it (with your package manager), then to scan an image, just run: `trivy image lissy93/dashy:latest` - -For larger systems, RedHat [Clair](https://www.redhat.com/en/topics/containers/what-is-clair) is an app for parsing image contents and reporting on any found vulnerabilities. You run it locally in a container, and configure it with YAML. It can be integrated with Red Hat Quay, to show results on a dashboard. Most of these use static analysis to find potential issues, and scan included packages for any known security vulnerabilities. - -### Registry Security -Although over-kill for most users, you could run your own registry locally which would give you ultimate control over all images, see the [Deploying a Registry Docs](https://docs.docker.com/registry/deploying/) for more info. Another option is [Docker Trusted Registry](https://docker-docs.netlify.app/ee/dtr/), it's great for enterprise applications, it sits behind your firewall, running on a swarm managed by Docker Universal Control Plane, and lets you securely store and manage your Docker images, mitigating the risk of breaches from the internet. - -### Security Modules -Docker supports several modules that let you write your own security profiles. - -[AppArmor](https://www.apparmor.net/)is a kernel module that proactively protects the operating system and applications from external or internal threats, by enabling you to restrict programs' capabilities with per-program profiles. You can specify either a security policy by name, or by file path with the `apparmor` flag in docker run. Learn more about writing profiles, [here](https://gitlab.com/apparmor/apparmor/-/wikis/QuickProfileLanguage). - -[Seccomp](https://en.wikipedia.org/wiki/Seccomp) (Secure Computing Mode) is a sandboxing facility in the Linux kernel that acts like a firewall for system calls (syscalls). It uses Berkeley Packet Filter (BPF) rules to filter syscalls and control how they are handled. These filters can significantly limit a containers access to the Docker Host’s Linux kernel - especially for simple containers/applications. It requires a Linux-based Docker host, with secomp enabled, and you can check for this by running `docker info | grep seccomp`. A great resource for learning more about this is [DockerLabs](https://training.play-with-docker.com/security-seccomp/). - - -**[⬆️ Back to Top](#management)** - ---- - -## Remote Access - -- [WireGuard](#wireguard) -- [Reverse SSH Tunnel](#reverse-ssh-tunnel) - -### WireGuard - -Using a VPN is one of the easiest ways to provide secure, full access to your local network from remote locations. [WireGuard](https://www.wireguard.com/) is a reasonably new open source VPN protocol, that was designed with ease of use, performance and security in mind. Unlike OpenVPN, it doesn't need to recreate the tunnel whenever connection is dropped, and it's also much easier to setup, using shared keys instead. - -- **Install Wireguard** - See the [Install Docs](https://www.wireguard.com/install/) for download links + instructions - - On Debian-based systems, it's `sudo apt install wireguard` -- **Generate a Private Key** - Run `wg genkey` on the Wireguard server, and copy it to somewhere safe for later -- **Create Server Config** - Open or create a file at `/etc/wireguard/wg0.conf` and under `[Interface]` add the following (see example below): - - `Address` - as a subnet of all desired IPs - - `PrivateKey` - that you just generated - - `ListenPort` - Default is `51820`, but can be anything -- **Get Client App** - Download the [WG client app](https://www.wireguard.com/install/) for your platform (Linux, Windows, MacOS, Android or iOS are all supported) -- **Create new Client Tunnel** - On your client app, there should be an option to create a new tunnel, when doing so a client private key will be generated (but if not, use the `wg genkey` command again), and keep it somewhere safe. A public key will also be generated, and this will go in our saver config -- **Add Clients to Server Config** - Head back to your `wg0.conf` file on the server, create a `[Peer]` section, and populate the following info - - `AllowedIPs` - List of IP address inside the subnet, the client should have access to - - `PublicKey` - The public key for the client you just generated -- **Start the Server** - You can now start the WG server, using: `wg-quick up wg0` on your server -- **Finish Client Setup** - Head back to your client device, and edit the config file, leave the private key as is, and add the following fields: - - `PublicKey` - The public key of the server - - `Address` - This should match the `AllowedIPs` section on the servers config file - - `DNS` - The DNS server that'll be used when accessing the network through the VPN - - `Endpoint` - The hostname or IP + Port where your WG server is running (you may need to forward this in your firewall's settings) -- **Done** - Your clients should now be able to connect to your WG server :) Depending on your networks firewall rules, you may need to port forward the address of your WG server - -**Example Server Config** - -```ini -# Server file -[Interface] -# Which networks does my interface belong to? Notice: /24 and /64 -Address = 10.5.0.1/24, 2001:470:xxxx:xxxx::1/64 -PrivateKey = xxx -ListenPort = 51820 - -# Peer 1 -[Peer] -PublicKey = xxx -# Which source IPs can I expect from that peer? Notice: /32 and /128 -AllowedIps = 10.5.0.35/32, 2001:470:xxxx:xxxx::746f:786f/128 - -# Peer 2 -[Peer] -PublicKey = xxx -# Which source IPs can I expect from that peer? This one has a LAN which can -# access hosts/jails without NAT. -# Peer 2 has a single IP address inside the VPN: it's 10.5.0.25/32 -AllowedIps = 10.5.0.25/32,10.21.10.0/24,10.21.20.0/24,10.21.30.0/24,10.31.0.0/24,2001:470:xxxx:xxxx::ca:571e/128 -``` - -**Example Client Config** - -```ini -[Interface] -# Which networks does my interface belong to? Notice: /24 and /64 -Address = 10.5.0.35/24, 2001:470:xxxx:xxxx::746f:786f/64 -PrivateKey = xxx - -# Server -[Peer] -PublicKey = xxx -# I want to route everything through the server, both IPv4 and IPv6. All IPs are -# thus available through the Server, and I can expect packets from any IP to -# come from that peer. -AllowedIPs = 0.0.0.0/0, ::0/0 -# Where is the server on the internet? This is a public address. The port -# (:51820) is the same as ListenPort in the [Interface] of the Server file above -Endpoint = 1.2.3.4:51820 -# Usually, clients are behind NAT. to keep the connection running, keep alive. -PersistentKeepalive = 15 -``` - - -A useful tool for getting WG setup is [Algo](https://github.com/trailofbits/algo). It includes scripts and docs which cover almost all devices, platforms and clients, and has best practices implemented, and security features enabled. All of this is better explained in [this blog post](https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/). - - -### Reverse SSH Tunnel - -SSH (or [Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell)) is a secure tunnel that allows you to connect to a remote host. Unlike the VPN methods, an SSH connection does not require an intermediary, and will not be affected by your IP changing. However it only allows you to access a single service at a time. SSH was really designed for terminal access, but because of the latter mentioned benefits it's useful to setup, as a fallback option. - -Directly SSH'ing into your home, would require you to open a port (usually 22), which would be terrible for security, and is not recommended. However a reverse SSH connection is initiated from inside your network. Once the connection is established, the port is redirected, allowing you to use the established connection to SSH into your home network. - -The issue you've probably spotted, is that most public, corporate, and institutional networks will block SSH connections. To overcome this, you'd have to establish a server outside of your homelab that your homelab's device could SSH into to establish the reverse SSH connection. You can then connect to that remote server (the _mothership_), which in turn connects to your home network. - -Now all of this is starting to sound like quite a lot of work, but this is where services like [remot3.it](https://remote.it/) come in. They maintain the intermediary mothership server, and create the tunnel service for you. It's free for personal use, secure and easy. There are several similar services, such as [RemoteIoT](https://remoteiot.com/), or you could create your own on a cloud VPS (see [this tutorial](https://gist.github.com/nileshtrivedi/4c615e8d3c1bf053b0d31176b9e69e42) for more info on that). - -Before getting started, you'll need to head over to [Remote.it](https://app.remote.it/auth/#/sign-up) and create an account. - -Then setup your local device: -1. If you haven't already done so, you'll need to enable and configure SSH. - - This is out-of-scope of this article, but I've explained it in detail in [this post](https://notes.aliciasykes.com/22798/my-server-setup#configure-ssh). -2. Download the Remote.it install script from their [GitHub](https://github.com/remoteit/installer) - - `curl -LkO https://raw.githubusercontent.com/remoteit/installer/master/scripts/auto-install.sh` -3. Make it executable, with `chmod +x ./auto-install.sh`, and then run it with `sudo ./auto-install.sh` -4. Finally, configure your device, by running `sudo connectd_installer` and following the on-screen instructions - -And when you're ready to connect to it: -1. Login to [app.remote.it](https://app.remote.it/), and select the name of your device -2. You should see a list of running services, click SSH -3. You'll then be presented with some SSH credentials that you can now use to securely connect to your home, via the Remote.it servers - -Done :) - -**[⬆️ Back to Top](#management)** - ---- - -## Custom Domain - -- [Using DNS](#using-nginx) -- [Using NGINX](#using-dns) - -### Using DNS -For locally running services, a domain can be set up directly in the DNS records. This method is really quick and easy, and doesn't require you to purchase an actual domain. Just update your networks DNS resolver, to point your desired URL to the local IP where Dashy (or any other app) is running. For example, a line in your hosts file might look something like: `192.168.0.2 dashy.homelab.local`. - -If you're using Pi-Hole, a similar thing can be done in the `/etc/dnsmasq.d/03-custom-dns.conf` file, add a line like: `address=/dashy.example.com/192.168.2.0` for each of your services. - -If you're running OPNSense/ PfSense, then this can be done through the UI with Unbound, it's explained nicely in [this article](https://homenetworkguy.com/how-to/use-custom-domain-name-in-internal-network/), by Dustin Casto. - -### Using NGINX -If you're using NGINX, then you can use your own domain name, with a config similar to the below example. - -``` -upstream dashy { - server 127.0.0.1:32400; -} - -server { - listen 80; - server_name dashy.mydomain.com; - - # Setup SSL - ssl_certificate /var/www/mydomain/sslcert.pem; - ssl_certificate_key /var/www/mydomain/sslkey.pem; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; - ssl_session_timeout 5m; - ssl_prefer_server_ciphers on; - - location / { - proxy_pass http://dashy; - proxy_redirect off; - proxy_buffering off; - proxy_set_header host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; - } -} -``` -Similarly, a basic `Caddyfile` might look like: - -``` -dashy.example.com { - reverse_proxy / nginx:80 -} -``` - -For more info, [this guide](https://thehomelab.wiki/books/dns-reverse-proxy/page/create-domain-records-to-point-to-your-home-server-on-cloudflare-using-nginx-progy-manager) on Setting up Domains with NGINX Proxy Manager and CloudFlare may be useful. - -**[⬆️ Back to Top](#management)** - ---- - -## Web Server Configuration - -_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`](https://github.com/Lissy93/dashy/blob/master/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](https://nodejs.org) 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: -- Loading page, while the app is building -- Writing config file to disk from the UI -- Website status indicators, and ping checks - -Example Configs -- [NGINX](#nginx) -- [Apache](#apache) -- [cPanel](#cpanel) - -### NGINX - -Create a new file in `/etc/nginx/sites-enabled/dashy` - -``` -server { - listen 80; - listen [::]:80; - - root /var/www/dashy/html; - index index.html; - - server_name your-domain.com www.your-domain.com; - - location / { - try_files $uri $uri/ =404; - } -} -``` -Then upload the build contents of Dashy's dist directory to that location. -For example: `scp -r ./dist/* [username]@[server_ip]:/var/www/dashy/html` - -### Apache - -Copy Dashy's dist folder to your apache server, `sudo cp -r ./dashy/dist /var/www/html/dashy`. - -In your Apache config, `/etc/apche2/apache2.conf` add: -``` - - Options Indexes FollowSymLinks - AllowOverride All - Require all granted - -``` - -Add a `.htaccess` file within `/var/www/html/dashy/.htaccess`, and add: -``` -Options -MultiViews -RewriteEngine On -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^ index.html [QSA,L] -``` - -Then restart Apache, with `sudo systemctl restart apache2` - -### cPanel -1. Login to your WHM -2. Open 'Feature Manager' on the left sidebar -3. Under 'Manage feature list', click 'Edit' -4. Find 'Application manager' in the list, enable it and hit 'Save' -5. Log into your users cPanel account, and under 'Software' find 'Application Manager' -6. Click 'Register Application', fill in the form using the path that Dashy is located, and choose a domain, and hit 'Save' -7. The application should now show up in the list, click 'Ensure dependencies', and move the toggle switch to 'Enabled' -8. If you need to change the port, click 'Add environmental variable', give it the name 'PORT', choose a port number and press 'Save'. -9. Dashy should now be running at your selected path an on a given port - -**[⬆️ Back to Top](#management)** - ---- - -## Running a Modified Version of the App - -If you'd like to make any code changes to the app, and deploy your modified version, this section briefly explains how. - -The first step is to fork the project on GitHub, and clone it to your local system. Next, install the dependencies (`yarn`), and start the development server (`yarn dev`) and visit `localhost:8080` in your browser. You can then make changes to the codebase, and see the live app update in real-time. Once you've finished, running `yarn build` will build the app for production, and output the assets into `./dist` which can then be deployed using a web server, CDN or the built-in Node server with `yarn start`. For more info on all of this, take a look at the [Developing Docs](/docs/developing.md). To build your own Docker container from the modified app, see [Building your Own Container](#building-your-own-container) - -**[⬆️ Back to Top](#management)** - ---- - -## Building your Own Container - -Similar to above, you'll first need to fork and clone Dashy to your local system, and then install dependencies. - -Then, either use Dashy's default [`Dockerfile`](https://github.com/Lissy93/dashy/blob/master/Dockerfile) as is, or modify it according to your needs. - -To build and deploy locally, first build the app with: `docker build -t dashy .`, and then start the app with `docker run -p 8080:80 --name my-dashboard dashy`. Or modify the `docker-compose.yml` file, replacing `image: lissy93/dashy` with `build: .` and run `docker compose up`. - -Your container should now be running, and will appear in the list when you run `docker container ls –a`. If you'd like to enter the container, run `docker exec -it [container-id] /bin/ash`. - -You may wish to upload your image to a container registry for easier access. Note that if you choose to do this on a public registry, please name your container something other than just 'dashy', to avoid confusion with the official image. -You can push your build image, by running: `docker push ghcr.io/OWNER/IMAGE_NAME:latest`. You will first need to authenticate, this can be done by running `echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin`, where `CR_PAT` is an environmental variable containing a token generated from your GitHub account. For more info, see the [Container Registry Docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry). - -**[⬆️ Back to Top](#management)** - ---- \ No newline at end of file +# Management + +_The following article explains aspects of app management, and is useful to know for when self-hosting. It covers everything from keeping the Dashy (or any other app) up-to-date, secure, backed up, to other topics like auto-starting, monitoring, log management, web server configuration and using custom environments. It's like a top-20 list of need-to-know knowledge for self-hosting._ + +## Contents +- [Providing Assets](#providing-assets) +- [Running Commands](#running-commands) +- [Healthchecks](#healthchecks) +- [Logs and Performance](#logs-and-performance) +- [Auto-Starting at Boot](#auto-starting-at-system-boot) +- [Updating](#updating) +- [Backing Up](#backing-up) +- [Scheduling](#scheduling) +- [SSL Certificates](#ssl-certificates) +- [Authentication](#authentication) +- [Managing with Compose](#managing-containers-with-docker-compose) +- [Environmental Variables](#passing-in-environmental-variables) +- [Securing Containers](#container-security) +- [Remote Access](#remote-access) +- [Custom Domain](#custom-domain) +- [Web Server Configuration](#web-server-configuration) +- [Running a Modified App](#running-a-modified-version-of-the-app) +- [Building your Own Container](#building-your-own-container) + +--- + +## Providing Assets +Although not essential, you will most likely want to provide several assets to your running app. + +This is easy to do using [Docker Volumes](https://docs.docker.com/storage/volumes/), which lets you share a file or directory between your host system, and the container. Volumes are specified in the Docker run command, or Docker compose file, using the `--volume` or `-v` flags. The value of which consists of the path to the file / directory on your host system, followed by the destination path within the container. Fields are separated by a colon (`:`), and must be in the correct order. For example: `-v ~/alicia/my-local-conf.yml:/app/public/conf.yml` + +In Dashy, commonly configured resources include: +- `./public/conf.yml` - Your main application config file +- `./public/item-icons` - A directory containing your own icons. This allows for offline access, and better performance than fetching from a CDN +- Also within `./public` you'll find standard website assets, including `favicon.ico`, `manifest.json`, `robots.txt`, etc. There's no need to pass these in, but you can do so if you wish +- `/src/styles/user-defined-themes.scss` - A stylesheet for applying custom CSS to your app. You can also write your own themes here. + +**[⬆️ Back to Top](#management)** + +--- +## Running Commands + + If you're running an app in Docker, then commands will need to be passed to the container to be executed. This can be done by preceding 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`. You can also enter the container, with `docker exec -it [container-id] /bin/ash`, and navigate around it with normal Linux commands. + + Dashy has several commands that can be used for various tasks, you can find a list of these either in the [Developing Docs](/docs/developing.md#project-commands), or by looking at the [`package.json`](https://github.com/Lissy93/dashy/blob/master/package.json#L5). These can be used by running `yarn [command-name]`. + +**[⬆️ Back to Top](#management)** + +--- +## Healthchecks + +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](https://hub.docker.com/r/willfarrell/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](https://github.com/moby/moby/pull/22719)). There's also [Deunhealth](https://github.com/qdm12/deunhealth), which is super light-weight, and doesn't require network access. + +``` +docker run -d \ + --name autoheal \ + --restart=always \ + -e AUTOHEAL_CONTAINER_LABEL=all \ + -v /var/run/docker.sock:/var/run/docker.sock \ + willfarrell/autoheal +``` + +**[⬆️ Back to Top](#management)** + +--- +## Logs and Performance + +#### Container Logs +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](https://docs.docker.com/config/containers/logging/). There's also [Dozzle](https://dozzle.dev/), 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. + +#### Container Performance +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](https://docs.docker.com/engine/reference/commandline/stats/). There's also [cAdvisor](https://github.com/google/cadvisor), a useful web app for viewing and analyzing resource usage and performance of all your running containers. + +#### Management Apps +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](https://github.com/portainer/portainer) an all-in-one open source management web UI for Docker and Kubernetes, or [LazyDocker](https://github.com/jesseduffield/lazydocker) a terminal UI for Docker container management and monitoring. + +#### Advanced Logging and Monitoring +Docker supports using [Prometheus](https://prometheus.io/) to collect logs, which can then be visualized using a platform like [Grafana](https://grafana.com/). For more info, see [this guide](https://docs.docker.com/config/daemon/prometheus/). If you need to route your logs to a remote syslog, then consider using [logspout](https://github.com/gliderlabs/logspout). For enterprise-grade instances, there are managed services, that make monitoring container logs and metrics very easy, such as [Sematext](https://sematext.com/blog/docker-container-monitoring-with-sematext/) with [Logagent](https://github.com/sematext/logagent-js). + +**[⬆️ Back to Top](#management)** + +--- + +## Auto-Starting at System Boot + +You can use Docker's [restart policies](https://docs.docker.com/engine/reference/run/#restart-policies---restart) 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](https://docs.docker.com/config/containers/start-containers-automatically/). + +For Podman, you can use `systemd` to create a service that launches your container, [the docs](https://podman.io/blogs/2018/09/13/systemd.html) 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`](https://github.com/willfarrell/docker-autoheal) by @willfarrell, a service that monitors and restarts unhealthy containers. For more info, see the [Healthchecks](#healthchecks) section above. + +**[⬆️ Back to Top](#management)** + +--- +## Updating + +Dashy is under active development, so to take advantage of the latest features, you may need to update your instance every now and again. + +### Updating Docker Container +1. Pull latest image: `docker pull lissy93/dashy:latest` +2. Kill off existing container + - Find container ID: `docker ps` + - Stop container: `docker stop [container_id]` + - Remove container: `docker rm [container_id]` +3. Spin up new container: `docker run [params] lissy93/dashy` + +### Automatic Docker Updates + +You can automate the above process using [Watchtower](https://github.com/containrrr/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. + +To get started, spin up the watchtower container: + +``` +docker run -d \ + --name watchtower \ + -v /var/run/docker.sock:/var/run/docker.sock \ + containrrr/watchtower +``` + +For more information, see the [Watchtower Docs](https://containrrr.dev/watchtower/) + +### Updating Dashy from Source +Stop your current instance of Dashy, then navigate into the source directory. Pull down the latest code, with `git pull origin master`, then update dependencies with `yarn`, rebuild with `yarn build`, and start the server again with `yarn start`. + +**[⬆️ Back to Top](#management)** + +--- + +## Backing Up + +### Backing Up Containers + +You can make a backup of any running container really easily, using [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit/) and save it with [`docker export`](https://docs.docker.com/engine/reference/commandline/export/), to do so: +- First find the container ID, you can do this with `docker container ls` +- Now to create the snapshot, just run `docker commit -p [container-id] my-backup` +- Finally, to save the backup locally, run `docker save -o ~/dashy-backup.tar my-backup` +- If you want to push this to a container registry, run `docker push my-backup:latest` + +Note that this will not include any data in docker volumes, and the process here is a bit different. Since these files exist on your host system, if you have an existing backup solution implemented, you can incorporate and volume files within that system. + +### Backing Up Volumes +[offen/docker-volume-backup](https://github.com/offen/docker-volume-backup) is a useful tool for periodic Docker volume backups, to any S3-compatible storage provider. It's run as a light-weight Docker container, and is easy to setup, and also supports GPG-encryption, email notification, and routing away older backups. + +To get started, create a docker-compose similar to the example below, and then start the container. For more info, check out their [documentation](https://github.com/offen/docker-volume-backup), which is very clear. + +```yaml +version: '3' +services: + backup: + image: offen/docker-volume-backup:latest + environment: + BACKUP_CRON_EXPRESSION: "0 * * * *" + BACKUP_PRUNING_PREFIX: backup- + BACKUP_RETENTION_DAYS: 7 + AWS_BUCKET_NAME: backup-bucket + AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE + AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + volumes: + - data:/backup/my-app-backup:ro + - /var/run/docker.sock:/var/run/docker.sock:ro +volumes: + data: +``` + +It's worth noting that this process can also be done manually, using the following commands: + +Backup: +``` +docker run --rm -v some_volume:/volume -v /tmp:/backup alpine tar -cjf /backup/some_archive.tar.bz2 -C /volume ./ +``` +Restore: +``` +docker run --rm -v some_volume:/volume -v /tmp:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/some_archive.tar.bz2" +``` +### Dashy-Specific Backup +Since Dashy is open source, and freely available, providing you're configuration data is passed in as volumes, there shouldn't be any need to backup the main container. Your main config file, and any assets you're using should be kept backed up, preferably in at least two places, and you should ensure that you can easily restore from backup, if needed. + +Dashy also has a built-in cloud backup feature, which is free for personal users, and will let you make and restore fully encrypted backups of your config directly through the UI. To learn more, see the [Cloud Backup Docs](/docs/backup-restore.md) + +**[⬆️ Back to Top](#management)** + +--- + +## Scheduling + +If you need to periodically schedule the running of a given command on Dashy (or any other container), then a useful tool for doing so it [ofelia](https://github.com/mcuadros/ofelia). This runs as a Docker container and is really useful for things like backups, logging, updating, notifications, etc. Crons are specified using Go's crontab format, and a useful tool for visualizing this is [crontab.guru](https://crontab.guru/). This can also be done natively with Alpine: `docker run -it alpine ls /etc/periodic`. +I recommend combining this with [healthchecks](https://github.com/healthchecks/healthchecks) for easy monitoring of jobs, and failure notifications. + +**[⬆️ Back to Top](#management)** + +--- + +## SSL Certificates + +Enabling HTTPS with an SSL certificate is recommended, especially if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit. + +### Auto-SSL +If you are using [NGINX Proxy Manager](https://nginxproxymanager.com/), then SSL is supported out of the box. Once you've added your proxy host and web address, then set the scheme to HTTPS, then under the SSL Tab select "Request a new SSL certificate" and follow the on-screen instructions. + +If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/)- all you need to do is enable it under the SSL/TLS tab. Or if you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful. + +### Getting a Self-Signed SSL Certificate +[Let's Encrypt](https://letsencrypt.org/docs/) 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](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate. + +This process can be automated, using something like the [Docker-NGINX-Auto-SSL Container](https://github.com/Valian/docker-nginx-auto-ssl) to generate and renew certificates when needed. + +If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) or [ZeroSSL](https://zerossl.com/) to generate your cert. They also provide step-by-step setup instructions for most platforms. + +### Passing a Self-Signed Certificate to Dashy +Once you've generated your SSL cert, you'll need to pass it to Dashy. This can be done by specifying the paths to your public and private keys using the `SSL_PRIV_KEY_PATH` and `SSL_PUB_KEY_PATH` environmental variables. Or if you're using Docker, then just pass public + private SSL keys in under `/etc/ssl/certs/dashy-pub.pem` and `/etc/ssl/certs/dashy-priv.key` respectively, e.g: + +``` +docker run -d \ + -p 8080:80 \ + -v ~/my-private-key.key:/etc/ssl/certs/dashy-priv.key:ro \ + -v ~/my-public-key.pem:/etc/ssl/certs/dashy-pub.pem:ro \ + lissy93/dashy:latest +``` + +By default the SSL port is `443` within a Docker container, or `4001` if running on bare metal, but you can override this with the `SSL_PORT` environmental variable. + +Once everything is setup, you can verify your site is secured using a tool like [SSL Checker](https://www.sslchecker.com/sslchecker). + +**[⬆️ Back to Top](#management)** + +--- + +## Authentication + +Dashy natively supports secure authentication using KeyCloak. There is also a Simple Auth feature that doesn't require any additional setup. Usage instructions for both, as well as alternative auth methods, has now moved to the **[Authentication Docs](/docs/authentication.md)** page. + +**[⬆️ Back to Top](#management)** + +--- + +## Managing Containers with Docker Compose + +When you have a lot of containers, it quickly becomes hard to manage with `docker run` commands. The solution to this is [docker compose](https://docs.docker.com/compose/), a handy tool for defining all a containers run settings in a single YAML file, and then spinning up that container with a single short command - `docker compose up`. A good example of which can be seen in [@abhilesh's docker compose collection](https://github.com/abhilesh/self-hosted_docker_setups). + +You can use Dashy's default [`docker-compose.yml`](https://github.com/Lissy93/dashy/blob/master/docker-compose.yml) file as a template, and modify it according to your needs. + +An example Docker compose, using the default base image from DockerHub, might look something like this: + +```yaml +--- +version: "3.8" +services: + dashy: + container_name: Dashy + image: lissy93/dashy + volumes: + - /root/my-config.yml:/app/public/conf.yml + ports: + - 4000:80 + environment: + - BASE_URL=/my-dashboard + restart: unless-stopped + healthcheck: + test: ['CMD', 'node', '/app/services/healthcheck'] + interval: 1m30s + timeout: 10s + retries: 3 + start_period: 40s +``` + +**[⬆️ Back to Top](#management)** + +--- + +## Passing in Environmental Variables + +With Docker, you can define environmental variables under the `environment` section of your Docker compose file. Environmental variables are used to configure high-level settings, usually before the config file has been read. For a list of all supported env vars in Dashy, see [the developing docs](/docs/developing.md#environmental-variables), or the default [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file. + +A common use case, is to run Dashy under a sub-page, instead of at the root of a URL (e.g. `https://my-homelab.local/dashy` instead of `https://dashy.my-homelab.local`). In this use-case, you'd specify the `BASE_URL` variable in your compose file. + +```yaml +environment: + - BASE_URL=/dashy +``` + +You can also do the same thing with the docker run command, using the [`--env`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) flag. +If you've got many environmental variables, you might find it useful to put them in a [`.env` file](https://docs.docker.com/compose/env-file/). Similarly, for Docker run you can use [`--env-file`](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file) if you'd like to pass in a file containing all your environmental variables. + +**[⬆️ Back to Top](#management)** + +--- + +## Container Security + +- [Keep Docker Up-To-Date](#keep-docker-up-to-date) +- [Set Resource Quotas](#set-resource-quotas) +- [Don't Run as Root](#dont-run-as-root) +- [Specify a User](#specify-a-user) +- [Limit Capabilities](#limit-capabilities) +- [Prevent new Privilages being Added](#prevent-new-privilages-being-added) +- [Disable Inter-Container Communication](#disable-inter-container-communication) +- [Don't Expose the Docker Daemon Socket](#dont-expose-the-docker-daemon-socket) +- [Use Read-Only Volumes](#use-read-only-volumes) +- [Set the Logging Level](#set-the-logging-level) +- [Verify Image before Pulling](#verify-image-before-pulling) +- [Specify the Tag](#specify-the-tag) +- [Container Security Scanning](#container-security-scanning) +- [Registry Security](#registry-security) +- [Security Modules](#security-modules) + +### Keep Docker Up-To-Date +To prevent known container escape vulnerabilities, which typically end in escalating to root/administrator privileges, patching Docker Engine and Docker Machine is crucial. For more info, see the [Docker Installation Docs](https://docs.docker.com/engine/install/). + +### Set Resource Quotas +Docker enables you to limit resource consumption (CPU, memory, disk) on a per-container basis. This not only enhances system performance, but also prevents a compromised container from consuming a large amount of resources, in order to disrupt service or perform malicious activities. To learn more, see the [Resource Constraints Docs](https://docs.docker.com/config/containers/resource_constraints/) + +For example, to run Dashy with max of 1GB ram, and max of 50% of 1 CP core: +`docker run -d -p 8080:80 --cpus=".5" --memory="1024m" lissy93/dashy:latest` + +### Don't Run as Root +Running a container with admin privileges gives it more power than it needs, and can be abused. Dashy does not need any root privileges, and Docker by default doesn't run containers as root, so providing you don't specifically type sudo, you should be all good here. + +Note that if you're facing permission issues on Debian-based systems, you may need to add your user to the Docker group. First create the group: `sudo groupadd docker`, then add your (non-root) user: `sudo usermod −aG docker [my-username]`, finally `newgrp docker` to refresh. + +### Specify a User +One of the best ways to prevent privilege escalation attacks, is to configure the container to use an unprivileged user. This also means that any files created by the container and mounted, will be owned by the specified user (and not root), which makes things much easier. + +You can specify a user, using the [`--user` param](https://docs.docker.com/engine/reference/run/#user), and should include the user ID (`UID`), which can be found by running `id -u`, and the and the group ID (`GID`), using `id -g`. + +With Docker run, you specify it like: +`docker run --user 1000:1000 -p 8080:80 lissy93/dashy` + +Of if you're using Docker-compose, you could use an environmental variable + +```yaml +version: "3.8" +services: + dashy: + image: lissy93/dashy + user: ${CURRENT_UID} + ports: [ 4000:80 ] +``` + +And then to set the variable, and start the container, run: `CURRENT_UID=$(id -u):$(id -g) docker-compose up` + +### Limit capabilities +Docker containers run with a subset of [Linux Kernal's Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) by default. It's good practice to drop privilege permissions that are not needed for any given container. + +With Docker run, you can use the `--cap-drop` flag to remove capabilities, you can also use `--cap-drop=all` and then define just the required permissions using the `--cap-add` option. For a list of available capabilities, see the [Privilege Capabilities Docs](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities). + +Note that dropping privileges and capabilities on runtime is not fool-proof, and often any leftover privileges can be used to re-escalate, see [POS36-C](https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges). + +Here's an example using docker-compose, removing privileges that are not required for Dashy to run: + +```yaml +version: "3.8" +services: + dashy: + image: lissy93/dashy + ports: [ 4000:80 ] + cap_drop: + - ALL + cap_add: + - CHOWN + - SETGID + - SETUID + - DAC_OVERRIDE + - NET_BIND_SERVICE +``` + +### Prevent new Privilages being Added +To prevent processes inside the container from getting additional privileges, pass in the `--security-opt=no-new-privileges:true` option to the Docker run command (see [docs](https://docs.docker.com/engine/reference/run/#security-configuration)). + +Run Command: +`docker run --security-opt=no-new-privileges:true -p 8080:80 lissy93/dashy` + +Docker Compose +```yaml +security_opt: +- no-new-privileges:true +``` + +### Disable Inter-Container Communication +By default Docker containers can talk to each other (using [`docker0` bridged network](https://docs.docker.com/config/containers/container-networking/)). If you don't need this capability, then it should be disabled. This can be done with the `--icc=false` in your run command. You can learn more about how to facilitate secure communication between containers in the [Compose Networking docs](https://docs.docker.com/compose/networking/). + +### Don't Expose the Docker Daemon Socket +Docker socket `/var/run/docker.sock` is the UNIX socket that Docker is listening to. This is the primary entry point for the Docker API. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. + +You should **not** enable TCP Docker daemon socket (`-H tcp://0.0.0.0:XXX`), as doing so exposes un-encrypted and unauthenticated direct access to the Docker daemon, and if the host is connected to the internet, the daemon on your computer can be used by anyone from the public internet- which is bad. If you need TCP, you should [see the docs](https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option) to understand how to do this more securely. +Similarly, never expose `/var/run/docker.sock` to other containers as a volume, as it can be exploited. + +### Use Read-Only Volumes +You can specify that a specific volume should be read-only by appending `:ro` to the `-v` switch. For example, while running Dashy, if we want our config to be writable, but keep all other assets protected, we would do: +``` +docker run -d \ + -p 8080:80 \ + -v ~/dashy-conf.yml:/app/public/conf.yml \ + -v ~/dashy-icons:/app/public/item-icons:ro \ + -v ~/dashy-theme.scss:/app/src/styles/user-defined-themes.scss:ro \ + lissy93/dashy:latest +``` + +You can also prevent a container from writing any changes to volumes on your host's disk, using the `--read-only` flag. Although, for Dashy, you will not be able to write config changes to disk, when edited through the UI with this method. You could make this work, by specifying the config directory as a temp write location, with `--tmpfs /app/public/conf.yml` - but that this will not write the volume back to your host. + +### Set the Logging Level +Logging is important, as it enables you to review events in the future, and in the case of a compromise this will let get an idea of what may have happened. The default log level is `INFO`, and this is also the recommendation, use `--log-level info` to ensure this is set. + +### Verify Image before Pulling +Only use trusted images, from verified/ official sources. If an app is open source, it is more likely to be safe, as anyone can verify the code. There are also tools available for scanning containers, + +Unless otherwise configured, containers can communicate among each other, so running one bad image may lead to other areas of your setup being compromised. Docker images typically contain both original code, as well as up-stream packages, and even if that image has come from a trusted source, the up-stream packages it includes may not have. + +### Specify the Tag +Using fixed tags (as opposed to `:latest` ) will ensure immutability, meaning the base image will not change between builds. Note that for Dashy, the app is being actively developed, new features, bug fixes and general improvements are merged each week, and if you use a fixed version you will not enjoy these benefits. So it's up to you weather you would prefer a stable and reproducible environment, or the latest features and enhancements. + +### Container Security Scanning +It's helpful to be aware of any potential security issues in any of the Docker images you are using. You can run a quick scan using Snyk on any image to output known vulnerabilities using [Docker scan](https://docs.docker.com/engine/scan/), e.g: `docker scan lissy93/dashy:latest`. + +A similar product is [Trivy](https://github.com/aquasecurity/trivy), which is free an open source. First install it (with your package manager), then to scan an image, just run: `trivy image lissy93/dashy:latest` + +For larger systems, RedHat [Clair](https://www.redhat.com/en/topics/containers/what-is-clair) is an app for parsing image contents and reporting on any found vulnerabilities. You run it locally in a container, and configure it with YAML. It can be integrated with Red Hat Quay, to show results on a dashboard. Most of these use static analysis to find potential issues, and scan included packages for any known security vulnerabilities. + +### Registry Security +Although over-kill for most users, you could run your own registry locally which would give you ultimate control over all images, see the [Deploying a Registry Docs](https://docs.docker.com/registry/deploying/) for more info. Another option is [Docker Trusted Registry](https://docker-docs.netlify.app/ee/dtr/), it's great for enterprise applications, it sits behind your firewall, running on a swarm managed by Docker Universal Control Plane, and lets you securely store and manage your Docker images, mitigating the risk of breaches from the internet. + +### Security Modules +Docker supports several modules that let you write your own security profiles. + +[AppArmor](https://www.apparmor.net/)is a kernel module that proactively protects the operating system and applications from external or internal threats, by enabling you to restrict programs' capabilities with per-program profiles. You can specify either a security policy by name, or by file path with the `apparmor` flag in docker run. Learn more about writing profiles, [here](https://gitlab.com/apparmor/apparmor/-/wikis/QuickProfileLanguage). + +[Seccomp](https://en.wikipedia.org/wiki/Seccomp) (Secure Computing Mode) is a sandboxing facility in the Linux kernel that acts like a firewall for system calls (syscalls). It uses Berkeley Packet Filter (BPF) rules to filter syscalls and control how they are handled. These filters can significantly limit a containers access to the Docker Host’s Linux kernel - especially for simple containers/applications. It requires a Linux-based Docker host, with secomp enabled, and you can check for this by running `docker info | grep seccomp`. A great resource for learning more about this is [DockerLabs](https://training.play-with-docker.com/security-seccomp/). + + +**[⬆️ Back to Top](#management)** + +--- + +## Remote Access + +- [WireGuard](#wireguard) +- [Reverse SSH Tunnel](#reverse-ssh-tunnel) + +### WireGuard + +Using a VPN is one of the easiest ways to provide secure, full access to your local network from remote locations. [WireGuard](https://www.wireguard.com/) is a reasonably new open source VPN protocol, that was designed with ease of use, performance and security in mind. Unlike OpenVPN, it doesn't need to recreate the tunnel whenever connection is dropped, and it's also much easier to setup, using shared keys instead. + +- **Install Wireguard** - See the [Install Docs](https://www.wireguard.com/install/) for download links + instructions + - On Debian-based systems, it's `sudo apt install wireguard` +- **Generate a Private Key** - Run `wg genkey` on the Wireguard server, and copy it to somewhere safe for later +- **Create Server Config** - Open or create a file at `/etc/wireguard/wg0.conf` and under `[Interface]` add the following (see example below): + - `Address` - as a subnet of all desired IPs + - `PrivateKey` - that you just generated + - `ListenPort` - Default is `51820`, but can be anything +- **Get Client App** - Download the [WG client app](https://www.wireguard.com/install/) for your platform (Linux, Windows, MacOS, Android or iOS are all supported) +- **Create new Client Tunnel** - On your client app, there should be an option to create a new tunnel, when doing so a client private key will be generated (but if not, use the `wg genkey` command again), and keep it somewhere safe. A public key will also be generated, and this will go in our saver config +- **Add Clients to Server Config** - Head back to your `wg0.conf` file on the server, create a `[Peer]` section, and populate the following info + - `AllowedIPs` - List of IP address inside the subnet, the client should have access to + - `PublicKey` - The public key for the client you just generated +- **Start the Server** - You can now start the WG server, using: `wg-quick up wg0` on your server +- **Finish Client Setup** - Head back to your client device, and edit the config file, leave the private key as is, and add the following fields: + - `PublicKey` - The public key of the server + - `Address` - This should match the `AllowedIPs` section on the servers config file + - `DNS` - The DNS server that'll be used when accessing the network through the VPN + - `Endpoint` - The hostname or IP + Port where your WG server is running (you may need to forward this in your firewall's settings) +- **Done** - Your clients should now be able to connect to your WG server :) Depending on your networks firewall rules, you may need to port forward the address of your WG server + +**Example Server Config** + +```ini +# Server file +[Interface] +# Which networks does my interface belong to? Notice: /24 and /64 +Address = 10.5.0.1/24, 2001:470:xxxx:xxxx::1/64 +PrivateKey = xxx +ListenPort = 51820 + +# Peer 1 +[Peer] +PublicKey = xxx +# Which source IPs can I expect from that peer? Notice: /32 and /128 +AllowedIps = 10.5.0.35/32, 2001:470:xxxx:xxxx::746f:786f/128 + +# Peer 2 +[Peer] +PublicKey = xxx +# Which source IPs can I expect from that peer? This one has a LAN which can +# access hosts/jails without NAT. +# Peer 2 has a single IP address inside the VPN: it's 10.5.0.25/32 +AllowedIps = 10.5.0.25/32,10.21.10.0/24,10.21.20.0/24,10.21.30.0/24,10.31.0.0/24,2001:470:xxxx:xxxx::ca:571e/128 +``` + +**Example Client Config** + +```ini +[Interface] +# Which networks does my interface belong to? Notice: /24 and /64 +Address = 10.5.0.35/24, 2001:470:xxxx:xxxx::746f:786f/64 +PrivateKey = xxx + +# Server +[Peer] +PublicKey = xxx +# I want to route everything through the server, both IPv4 and IPv6. All IPs are +# thus available through the Server, and I can expect packets from any IP to +# come from that peer. +AllowedIPs = 0.0.0.0/0, ::0/0 +# Where is the server on the internet? This is a public address. The port +# (:51820) is the same as ListenPort in the [Interface] of the Server file above +Endpoint = 1.2.3.4:51820 +# Usually, clients are behind NAT. to keep the connection running, keep alive. +PersistentKeepalive = 15 +``` + + +A useful tool for getting WG setup is [Algo](https://github.com/trailofbits/algo). It includes scripts and docs which cover almost all devices, platforms and clients, and has best practices implemented, and security features enabled. All of this is better explained in [this blog post](https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/). + + +### Reverse SSH Tunnel + +SSH (or [Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell)) is a secure tunnel that allows you to connect to a remote host. Unlike the VPN methods, an SSH connection does not require an intermediary, and will not be affected by your IP changing. However it only allows you to access a single service at a time. SSH was really designed for terminal access, but because of the latter mentioned benefits it's useful to setup, as a fallback option. + +Directly SSH'ing into your home, would require you to open a port (usually 22), which would be terrible for security, and is not recommended. However a reverse SSH connection is initiated from inside your network. Once the connection is established, the port is redirected, allowing you to use the established connection to SSH into your home network. + +The issue you've probably spotted, is that most public, corporate, and institutional networks will block SSH connections. To overcome this, you'd have to establish a server outside of your homelab that your homelab's device could SSH into to establish the reverse SSH connection. You can then connect to that remote server (the _mothership_), which in turn connects to your home network. + +Now all of this is starting to sound like quite a lot of work, but this is where services like [remot3.it](https://remote.it/) come in. They maintain the intermediary mothership server, and create the tunnel service for you. It's free for personal use, secure and easy. There are several similar services, such as [RemoteIoT](https://remoteiot.com/), or you could create your own on a cloud VPS (see [this tutorial](https://gist.github.com/nileshtrivedi/4c615e8d3c1bf053b0d31176b9e69e42) for more info on that). + +Before getting started, you'll need to head over to [Remote.it](https://app.remote.it/auth/#/sign-up) and create an account. + +Then setup your local device: +1. If you haven't already done so, you'll need to enable and configure SSH. + - This is out-of-scope of this article, but I've explained it in detail in [this post](https://notes.aliciasykes.com/22798/my-server-setup#configure-ssh). +2. Download the Remote.it install script from their [GitHub](https://github.com/remoteit/installer) + - `curl -LkO https://raw.githubusercontent.com/remoteit/installer/master/scripts/auto-install.sh` +3. Make it executable, with `chmod +x ./auto-install.sh`, and then run it with `sudo ./auto-install.sh` +4. Finally, configure your device, by running `sudo connectd_installer` and following the on-screen instructions + +And when you're ready to connect to it: +1. Login to [app.remote.it](https://app.remote.it/), and select the name of your device +2. You should see a list of running services, click SSH +3. You'll then be presented with some SSH credentials that you can now use to securely connect to your home, via the Remote.it servers + +Done :) + +**[⬆️ Back to Top](#management)** + +--- + +## Custom Domain + +- [Using DNS](#using-nginx) +- [Using NGINX](#using-dns) + +### Using DNS +For locally running services, a domain can be set up directly in the DNS records. This method is really quick and easy, and doesn't require you to purchase an actual domain. Just update your networks DNS resolver, to point your desired URL to the local IP where Dashy (or any other app) is running. For example, a line in your hosts file might look something like: `192.168.0.2 dashy.homelab.local`. + +If you're using Pi-Hole, a similar thing can be done in the `/etc/dnsmasq.d/03-custom-dns.conf` file, add a line like: `address=/dashy.example.com/192.168.2.0` for each of your services. + +If you're running OPNSense/ PfSense, then this can be done through the UI with Unbound, it's explained nicely in [this article](https://homenetworkguy.com/how-to/use-custom-domain-name-in-internal-network/), by Dustin Casto. + +### Using NGINX +If you're using NGINX, then you can use your own domain name, with a config similar to the below example. + +``` +upstream dashy { + server 127.0.0.1:32400; +} + +server { + listen 80; + server_name dashy.mydomain.com; + + # Setup SSL + ssl_certificate /var/www/mydomain/sslcert.pem; + ssl_certificate_key /var/www/mydomain/sslkey.pem; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_session_timeout 5m; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass http://dashy; + proxy_redirect off; + proxy_buffering off; + proxy_set_header host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; + } +} +``` +Similarly, a basic `Caddyfile` might look like: + +``` +dashy.example.com { + reverse_proxy / nginx:80 +} +``` + +For more info, [this guide](https://thehomelab.wiki/books/dns-reverse-proxy/page/create-domain-records-to-point-to-your-home-server-on-cloudflare-using-nginx-progy-manager) on Setting up Domains with NGINX Proxy Manager and CloudFlare may be useful. + +**[⬆️ Back to Top](#management)** + +--- + +## Web Server Configuration + +_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`](https://github.com/Lissy93/dashy/blob/master/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](https://nodejs.org) 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: +- Loading page, while the app is building +- Writing config file to disk from the UI +- Website status indicators, and ping checks + +Example Configs +- [NGINX](#nginx) +- [Apache](#apache) +- [Caddy](#caddy) +- [Firebase](#firebase-hosting) +- [cPanel](#cpanel) + +### NGINX + +Create a new file in `/etc/nginx/sites-enabled/dashy` + +``` +server { + listen 80; + listen [::]:80; + + root /var/www/dashy/html; + index index.html; + + server_name your-domain.com www.your-domain.com; + + location / { + try_files $uri $uri/ =404; + } +} +``` + +To use HTML5 history mode (`appConfig.routingMode: history`), replace the inside of the location block with: `try_files $uri $uri/ /index.html;`. + +Then upload the build contents of Dashy's dist directory to that location. +For example: `scp -r ./dist/* [username]@[server_ip]:/var/www/dashy/html` + +### Apache + +Copy Dashy's dist folder to your apache server, `sudo cp -r ./dashy/dist /var/www/html/dashy`. + +In your Apache config, `/etc/apche2/apache2.conf` add: +``` + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.html$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.html [L] + +``` + +Add a `.htaccess` file within `/var/www/html/dashy/.htaccess`, and add: +``` +Options -MultiViews +RewriteEngine On +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^ index.html [QSA,L] +``` + +Then restart Apache, with `sudo systemctl restart apache2` + +### Caddy + +Caddy v2 +``` +try_files {path} / +``` + +Caddy v1 +``` +rewrite { + regexp .* + to {path} / +} +``` + +### Firebase Hosting + +Create a file names `firebase.json`, and populate it with something similar to: + +``` +{ + "hosting": { + "public": "dist", + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ] + } +} +``` + +### cPanel +1. Login to your WHM +2. Open 'Feature Manager' on the left sidebar +3. Under 'Manage feature list', click 'Edit' +4. Find 'Application manager' in the list, enable it and hit 'Save' +5. Log into your users cPanel account, and under 'Software' find 'Application Manager' +6. Click 'Register Application', fill in the form using the path that Dashy is located, and choose a domain, and hit 'Save' +7. The application should now show up in the list, click 'Ensure dependencies', and move the toggle switch to 'Enabled' +8. If you need to change the port, click 'Add environmental variable', give it the name 'PORT', choose a port number and press 'Save'. +9. Dashy should now be running at your selected path an on a given port + +**[⬆️ Back to Top](#management)** + +--- + +## Running a Modified Version of the App + +If you'd like to make any code changes to the app, and deploy your modified version, this section briefly explains how. + +The first step is to fork the project on GitHub, and clone it to your local system. Next, install the dependencies (`yarn`), and start the development server (`yarn dev`) and visit `localhost:8080` in your browser. You can then make changes to the codebase, and see the live app update in real-time. Once you've finished, running `yarn build` will build the app for production, and output the assets into `./dist` which can then be deployed using a web server, CDN or the built-in Node server with `yarn start`. For more info on all of this, take a look at the [Developing Docs](/docs/developing.md). To build your own Docker container from the modified app, see [Building your Own Container](#building-your-own-container) + +**[⬆️ Back to Top](#management)** + +--- + +## Building your Own Container + +Similar to above, you'll first need to fork and clone Dashy to your local system, and then install dependencies. + +Then, either use Dashy's default [`Dockerfile`](https://github.com/Lissy93/dashy/blob/master/Dockerfile) as is, or modify it according to your needs. + +To build and deploy locally, first build the app with: `docker build -t dashy .`, and then start the app with `docker run -p 8080:80 --name my-dashboard dashy`. Or modify the `docker-compose.yml` file, replacing `image: lissy93/dashy` with `build: .` and run `docker compose up`. + +Your container should now be running, and will appear in the list when you run `docker container ls –a`. If you'd like to enter the container, run `docker exec -it [container-id] /bin/ash`. + +You may wish to upload your image to a container registry for easier access. Note that if you choose to do this on a public registry, please name your container something other than just 'dashy', to avoid confusion with the official image. +You can push your build image, by running: `docker push ghcr.io/OWNER/IMAGE_NAME:latest`. You will first need to authenticate, this can be done by running `echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin`, where `CR_PAT` is an environmental variable containing a token generated from your GitHub account. For more info, see the [Container Registry Docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry). + +**[⬆️ Back to Top](#management)** + +--- diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 70c52539..da43493a 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -35,6 +35,16 @@ Header set X-Frame-Options: "ALLOW-FROM http://[dashy-location]/" --- +## 404 On Static Hosting + +If you're seeing Dashy's 404 page on initial load/ refresh, and then the main app when you go back to Home, then this is likely caused by the Vue router, and if so can be fixed in one of two ways. + +The first solution is to switch the routing mode, from HTML5 `history` mode to `hash` mode, by setting `appConfig.routingMode` to `hash`. + +If this works, but you wish to continue using HTML5 history mode, then a bit of extra [server configuration](/docs/management.md#web-server-configuration) is required. This is explained in more detaail in the [Vue Docs](https://router.vuejs.org/guide/essentials/history-mode.html). Once completed, you can then use `routingMode: history` again, for neater URLs. + +--- + ## Yarn Error For more info, see [Issue #1](https://github.com/Lissy93/dashy/issues/1) @@ -180,4 +190,4 @@ Currently, the status check needs a page to be rendered, so if this URL in your For further troubleshooting, use an application like [Postman](https://postman.com) to diagnose the issue. Set the parameter to `GET`, and then make a call to: `https://[url-of-dashy]/status-check/?&url=[service-url]`. Where the service URL must have first been encoded (e.g. with `encodeURIComponent()` or [urlencoder.io](https://www.urlencoder.io/)) -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. \ No newline at end of file +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. diff --git a/netlify.toml b/netlify.toml index 37bf6217..6ed4983e 100644 --- a/netlify.toml +++ b/netlify.toml @@ -4,7 +4,7 @@ # Essential site config [build] - base = "/" + base = "/" command = "yarn build" publish = "dist" functions = "services/serverless-functions" @@ -37,6 +37,6 @@ # Set any security headers here [[headers]] for = "/*" - [headers.values] + [headers.values] # Uncomment to enable Netlify user control. You must have a paid plan. # Basic-Auth = "someuser:somepassword anotheruser:anotherpassword" diff --git a/package.json b/package.json index 8e2b1280..d69335f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Dashy", - "version": "1.9.2", + "version": "1.9.3", "license": "MIT", "main": "server", "author": "Alicia Sykes (https://aliciasykes.com)", @@ -18,10 +18,10 @@ }, "dependencies": { "@formschema/native": "^2.0.0-beta.5", - "@sentry/tracing": "^6.13.1", + "@sentry/tracing": "^6.14.3", "@sentry/vue": "^6.13.1", - "ajv": "^8.6.3", - "axios": "^0.23.0", + "ajv": "^8.8.1", + "axios": "^0.24.0", "connect-history-api-fallback": "^1.6.0", "crypto-js": "^4.1.1", "express": "^4.17.1", @@ -31,7 +31,7 @@ "register-service-worker": "^1.6.2", "remedial": "^1.0.8", "rsup-progress": "^2.0.4", - "simple-icons": "^5.19.0", + "simple-icons": "^5.23.0", "v-jsoneditor": "^1.4.2", "v-tooltip": "^2.1.3", "vue": "^2.6.10", diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 5399cf18..ff90586b 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -20,6 +20,7 @@ "remember-me-hour": "4 Hours", "remember-me-day": "1 Day", "remember-me-week": "1 Week", + "remember-me-long-time": "A long time", "error-missing-username": "Missing Username", "error-missing-password": "Missing Password", "error-incorrect-username": "User not found", diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json index b2ccfb49..0af355f6 100644 --- a/src/assets/locales/fr.json +++ b/src/assets/locales/fr.json @@ -19,6 +19,7 @@ "remember-me-hour": "4 Heures", "remember-me-day": "1 Jour", "remember-me-week": "1 Semaine", + "remember-me-long-time": "Un long moment", "error-missing-username": "Nom d'utilisateur manquant", "error-missing-password": "Mot de passe manquant", "error-incorrect-username": "Utilisateur inexistant", @@ -77,7 +78,7 @@ "item-size-small": "Petite", "item-size-medium": "Moyenne", "item-size-large": "Grande", - "config-launcher-label": "Config.", + "config-launcher-label": "Configuration", "config-launcher-tooltip": "Modifier la configuration", "sign-out-tooltip": "Déconnexion", "sign-in-tooltip": "Connexion", @@ -101,6 +102,7 @@ "export-button": "Exporter des variables personnalisées", "reset-button": "Réinitialiser les styles pour", "show-all-button": "Afficher toutes les variables", + "change-fonts-button": "Changer les Polices d'écritures", "save-button": "Enregistrer", "cancel-button": "Annuler", "saved-toast": "{theme} mis à jour avec succès", @@ -112,6 +114,7 @@ "location-local-label": "Appliquer localement", "location-disk-label": "Appliquer dans le fichier de configuration", "save-button": "Enregistrer", + "preview-button": "Prévisuliser les modifications", "valid-label": "La configuration est valide", "status-success-msg": "Tâche terminée", "status-fail-msg": "Échec de la tâche", @@ -218,6 +221,7 @@ }, "edit-section": { "edit-section-title": "Éditeur", + "add-section-title": "Ajouter une section", "edit-tooltip": "Cliquer pour modifier ou cliquer droit pour plus d'options", "remove-confirm": "Voulez-vous vraiment supprimer cette section ? Cette action peut être annulée ultérieurement." }, diff --git a/src/assets/locales/sl.json b/src/assets/locales/sl.json index a3e708c9..6b8fec13 100644 --- a/src/assets/locales/sl.json +++ b/src/assets/locales/sl.json @@ -29,7 +29,7 @@ "already-logged-in-text": "Prijavljeni ste kot", "proceed-to-dashboard": "Nadaljujte na nadzorno ploščo", "log-out-button": "Odjava", - "proceed-guest-button": "Nadaljujte kot gost" + "proceed-guest-button": "Nadaljujte kot gost" }, "config": { "main-tab": "Glavni Meni", @@ -62,10 +62,11 @@ "css-note-l3": "Če želite odstraniti vse sloge po meri, izbrišite vsebino in pritisnite Shrani spremembe" }, "alternate-views": { + "alternate-view-heading": "Spremeni Pogled", "default": "Privzeto", "workspace": "Delovni prostor", "minimal": "Minimalno" - }, + }, "settings": { "theme-label": "Tema", "layout-label": "Postavitev", @@ -100,6 +101,7 @@ "export-button": "Izvozi Spremenljivke po Meri", "reset-button": "Ponastavi Sloge za", "show-all-button": "Pokaži Vse Spremenljivke", + "change-fonts-button": "Spremeni Pisavo", "save-button": "Shrani", "cancel-button": "Prekliči", "saved-toast": "{theme} Posodbljena Uspešno", @@ -111,6 +113,7 @@ "location-local-label": "Shrani Lokalno", "location-disk-label": "Zapišite spremembe v datoteko za konfiguracijo", "save-button": "Shrani Spremembe", + "preview-button": "Predogled Sprememb", "valid-label": "Konfiguracija je veljavna", "status-success-msg": "Operacija dokončana", "status-fail-msg": "Operacija ni uspela", @@ -163,10 +166,82 @@ "restore-success-msg": "Konfiguracija Uspešno Obnovljena" }, "menu": { + "open-section-title": "Odpri V", "sametab": "Odpri v Trenutnem Zavihku", "newtab": "Odpri v Novem Zavihku", "modal": "Odpri v Pojavnem Oknu", - "workspace": "Odpri v Delovnem Pogledu" + "workspace": "Odpri v Delovnem Pogledu", + "options-section-title": "Nastavitve", + "edit-item": "Uredi", + "move-item": "Kopiral ali Premakni", + "remove-item": "Odstrani" + }, + "context-menus": { + "item": { + "open-section-title": "Odpri V", + "sametab": "Trenutni Zavihek", + "newtab": "Nov Zavihek", + "modal": "Pojavno Okno", + "workspace": "Delovni Pogled", + "options-section-title": "Nastavitve", + "edit-item": "Uredi", + "move-item": "Kopiral ali Premakni", + "remove-item": "Odstrani" + }, + "section": { + "open-section": "Odpri Razdelek", + "edit-section": "Uredi", + "move-section": "Premakni v", + "remove-section": "Odstrani" + } + }, + "interactive-editor": { + "menu": { + "start-editing-tooltip": "Vstopite v Interaktivni Urejevalnik", + "edit-site-data-subheading": "Uredi Podatke Strani", + "edit-page-info-btn": "Uredi Informacije Strani", + "edit-page-info-tooltip": "Naslov, opis, nav linki, teks noge. itd", + "edit-app-config-btn": "Urejanje Konfiguracije", + "edit-app-config-tooltip": "Vse druge možnosti konfiguracije aplikacije", + "config-save-methods-subheading": "Možnosti Shranjevanja Konfiguracije", + "save-locally-btn": "Shrani Lokalno", + "save-locally-tooltip": "Shranite konfiguracijo lokalno v pomnilnik brskalnika. To ne bo vplivalo na vašo konfiguracijsko datoteko, vendar bodo spremembe shranjene samo v tej napravi", + "save-disk-btn": "Shrani na Disk", + "save-disk-tooltip": "Shranite konfiguracijo v datoteko conf.yml na disku. To bo varnostno kopiralo in nato prepisalo vašo obstoječo konfiguracijo", + "export-config-btn": "Izvozi Nastavitve", + "export-config-tooltip": "Oglejte si in izvozite novo konfiguracijo v datoteko ali v odložišče", + "cloud-backup-btn": "Varnostno kopiranje v Oblak", + "cloud-backup-tooltip": "Shranite šifrirano varnostno kopijo konfiguracije v oblak", + "edit-raw-config-btn": "Urejanje Raw Konfiguracije", + "edit-raw-config-tooltip": "Oglejte si in spremenite raw konfiguracijo prek urejevalnika JSON", + "cancel-changes-btn": "Prekliči Urejanje", + "cancel-changes-tooltip": "Ponastavite trenutne spremembe in zapustite način urejanja. To ne bo vplivalo na vašo shranjeno konfiguracijo", + "edit-mode-name": "Način Urejanja", + "edit-mode-subtitle": "Ste v načinu za Urejanje", + "edit-mode-description": "To pomeni, da lahko spremenite svojo konfiguracijo in si ogledate predogled rezultatov, vendar dokler ne shranite, nobena od vaših sprememb ne bo ohranjena.", + "save-stage-btn": "Shrani", + "cancel-stage-btn": "Prekliči" + }, + "edit-section": { + "edit-section-title": "Uredi Razdelek", + "add-section-title": "Dodaj Razdelek", + "edit-tooltip": "Kliknite za Urejanje ali z desno tipko miške kliknite za Več Možnosti", + "remove-confirm": "Ali ste prepričani, da želite odstraniti ta razdelek? To dejanje lahko pozneje razveljavite." + }, + "edit-app-config": { + "warning-msg-title": "Nadaljuj Previdno", + "warning-msg-l1": "Naslednje možnosti so za napredno konfiguracijo aplikacije.", + "warning-msg-l2": "Če niste prepričani glede katerega od polj, se obrnite na", + "warning-msg-docs": "dokumentacija", + "warning-msg-l3": "da bi se izognili neželenim posledicam." + }, + "export": { + "export-title": "Izvozi Nastavitve", + "copy-clipboard-btn": "Kopirati v Odložišče", + "copy-clipboard-tooltip": "Kopirajte vso konfiguracijo aplikacije v sistemsko odložišče v formatu YAML", + "download-file-btn": "Prenesi kot Datoteko", + "download-file-tooltip": "Prenesite vso konfiguracijo aplikacije v svojo napravo v formatu YAML", + "view-title": "Ogled Konfiguracije" + } } -} - +} \ No newline at end of file diff --git a/src/assets/locales/sv.json b/src/assets/locales/sv.json new file mode 100644 index 00000000..30b7b53c --- /dev/null +++ b/src/assets/locales/sv.json @@ -0,0 +1,248 @@ +{ + "home": { + "no-results": "Inga sökresultat", + "no-data": "Ingen data konfigurerad" + }, + "search": { + "search-label": "Sök", + "search-placeholder": "Börja skriva för att filtrera", + "clear-search-tooltip": "Rensa sök", + "enter-to-search-web": "Tryck på Retur för att söka på webben" + }, + "login": { + "title": "Dashy", + "username-label": "Användarnamn", + "password-label": "Lösenord", + "login-button": "Logga in", + "remember-me-label": "Kom ihåg mig", + "remember-me-never": "Aldrig", + "remember-me-hour": "4 Timmar", + "remember-me-day": "1 Dag", + "remember-me-week": "1 Vecka", + "remember-me-long-time": "Länge", + "error-missing-username": "Användarnamn saknas", + "error-missing-password": "Lösenord saknas", + "error-incorrect-username": "Användaren hittas inte", + "error-incorrect-password": "Fel lösenord", + "success-message": "Loggar in...", + "logout-message": "Utloggad", + "already-logged-in-title": "Redan inloggad", + "already-logged-in-text": "Du är inloggad som", + "proceed-to-dashboard": "Fortsätt till Dashboard", + "log-out-button": "Logga ut", + "proceed-guest-button": "Fortsätt som Gäst" + }, + "config": { + "main-tab": "Huvudmeny", + "view-config-tab": "Visa konfiguration", + "edit-config-tab": "Redigera konfiguration", + "custom-css-tab": "Egendefinierade stilmallar", + "heading": "Konfigurationsalternativ", + "download-config-button": "Visa / Exportera konfiguration", + "edit-config-button": "Redigera konfiguration", + "edit-css-button": "Redigera egendefinierad CSS", + "cloud-sync-button": "Aktivera molnsynkronisering", + "edit-cloud-sync-button": "Redigera molnsynkronisering", + "rebuild-app-button": "Återuppbygga appen", + "change-language-button": "Ändra appspråk", + "reset-settings-button": "Återställ lokala inställningar", + "app-info-button": "Appinfo", + "backup-note": "Det rekommenderas att du gör en säkerhetskopia av din konfiguration innan du gör ändringar.", + "reset-config-msg-l1": "Detta tar bort alla användarinställningar från lokal lagring, men påverkar inte din 'conf.yml'-fil", + "reset-config-msg-l2": "Du bör först göra en säkerhetskopia av alla ändringar du har gjort lokalt, om du vill använda dem i framtiden.", + "reset-config-msg-l3": "Är du säker på att du vill fortsätta?", + "data-cleared-msg": "Datarensning har lyckats", + "actions-label": "Åtgärder", + "copy-config-label": "Kopiera konfiguration", + "data-copied-msg": "Konfiguration har kopierats till urklipp", + "reset-config-label": "Återställ konfiguration", + "css-save-btn": "Spara ändringar", + "css-note-label": "Not", + "css-note-l1": "Du måste uppdatera sidan för att dina ändringar ska gälla.", + "css-note-l2": "Styles overrides lagras bara lokalt, så det rekommenderas att du gör en kopia av din CSS.", + "css-note-l3": "För att ta bort alla egendefinierade stilmallar, radera innehållet och tryck på Spara ändringar" + }, + "alternate-views": { + "alternate-view-heading": "Ändra vy", + "default": "Standard", + "workspace": "Workspace", + "minimal": "Minimal" + }, + "settings": { + "theme-label": "Tema", + "layout-label": "Layout", + "layout-auto": "Auto", + "layout-horizontal": "Vågrät", + "layout-vertical": "Lodrät", + "item-size-label": "Storlek", + "item-size-small": "Liten", + "item-size-medium": "Mellan", + "item-size-large": "Stor", + "config-launcher-label": "Konfig", + "config-launcher-tooltip": "Uppdatera konfiguration", + "sign-out-tooltip": "Logga ut", + "sign-in-tooltip": "Logga in", + "sign-in-welcome": "Hej {username}!" + }, + "updates": { + "app-version-note": "Dashy-version", + "up-to-date": "Uppdaterat", + "out-of-date": "Uppdatering finns", + "unsupported-version-l1": "Du använder en icke-stödd version av Dashy", + "unsupported-version-l2": "För den bästa upplevelsen och de senaste säkerhetskorrigeringarna, uppdatera till" + }, + "language-switcher": { + "title": "Ändra appspråk", + "dropdown-label": "Välj språk", + "save-button": "Spara", + "success-msg": "Språket har ändrats till" + }, + "theme-maker": { + "title": "Temakonfigurator", + "export-button": "Exportera egendefinierade variabler", + "reset-button": "Återställ stilmallar för", + "show-all-button": "Visa alla variabler", + "change-fonts-button": "Ändra typsnitt", + "save-button": "Spara", + "cancel-button": "Avbryt", + "saved-toast": "Uppdatering av {theme} har lyckats", + "copied-toast": "Temadatan för {theme} har kopierats till urklipp", + "reset-toast": "Egendefinierade färger för {theme} har tagits bort" + }, + "config-editor": { + "save-location-label": "Sparningsplats", + "location-local-label": "Tillämpa lokalt", + "location-disk-label": "Skriv ändringar till konfigurationsfil", + "save-button": "Spara ändringar", + "preview-button": "Förhandsgranska ändringar", + "valid-label": "Konfigurationen är giltig", + "status-success-msg": "Åtgärden slutförts", + "status-fail-msg": "Åtgärden misslyckats", + "success-msg-disk": "Konfigurationsfil har skrivits till disk utan problem", + "success-msg-local": "Lokala ändringar har sparats utan problem", + "success-note-l1": "Återskapa", + "success-note-l2": "Detta kan ta upp till en minut.", + "success-note-l3": "Du måste uppdatera sidan för att ändringar ska gälla", + "error-msg-save-mode": "Välj Lagringsläge: Lokalt eller Fil", + "error-msg-cannot-save": "Ett fel uppstod när konfigurationen skulle sparas", + "error-msg-bad-json": "Fel i JSON, möjligen felformaterat", + "warning-msg-validation": "Valideringsvarning", + "not-admin-note": "Du kan inte skriva ändringar till disk, eftersom du inte är inloggad som admin" + }, + "app-rebuild": { + "title": "Återskapa appen", + "rebuild-note-l1": "Appen måste återskapas för att ändringar som skrivits till filen conf.yml ska gälla.", + "rebuild-note-l2": "Detta bör ske automatiskt, men om det inte har gjort det kan du aktivera det manuellt här.", + "rebuild-note-l3": "Detta krävs inte för ändringar som lagras lokalt.", + "rebuild-button": "Återskapa", + "rebuilding-status-1": "Återskapar...", + "rebuilding-status-2": "Detta kan ta några minuter", + "error-permission": "Du har inte behörighet att utföra denna åtgärd", + "success-msg": "Återskapning lyckats", + "fail-msg": "Återskapning misslyckats", + "reload-note": "En omladdning av sidan krävs nu för att ändringarna ska gälla", + "reload-button": "Ladda om sidan" + }, + "cloud-sync": { + "title": "Molnsäkerhetskopiering och återställning", + "intro-l1": "Molnsäkerhetskopiering och återställning är en valfri funktion som gör att du kan ladda upp din konfiguration till internet och sedan återställa den på någon annan enhet eller instans av Dashy.", + "intro-l2": "All data är fullständigt end-to-end krypterad med AES, med ditt lösenord som nyckel.", + "intro-l3": "För mer information, vänligen se", + "backup-title-setup": "Gör en säkerhetskopia", + "backup-title-update": "Uppdatera säkerhetskopia", + "password-label-setup": "Välj lösenord", + "password-label-update": "Ange ditt lösenord", + "backup-button-setup": "Säkerhetskopiering", + "backup-button-update": "Uppdatera säkerhetskopia", + "backup-id-label": "Ditt säkerhetskopierings-ID", + "backup-id-note": "Detta används för att återställa från säkerhetskopior senare. Så förvara det tillsammans med ditt lösenord någonstans säkert.", + "restore-title": "Återställ en säkerhetskopia", + "restore-id-label": "Återställ ID", + "restore-password-label": "Lösenord", + "restore-button": "Återställ", + "backup-missing-password": "Lösenord saknas", + "backup-error-unknown": "Begäran kan inte behandlas", + "backup-error-password": "Fel lösenord. Vänligen ange ditt aktuella lösenord.", + "backup-success-msg": "Slutfört utan problem", + "restore-success-msg": "Konfigurationen har återställts utan problem" + }, + "menu": { + "open-section-title": "Öppna i", + "sametab": "Denna flik", + "newtab": "Ny flik", + "modal": "Pop-Up Modal", + "workspace": "Workspace-vy", + "options-section-title": "Alternativ", + "edit-item": "Redigera", + "move-item": "Kopiera eller flytta", + "remove-item": "Ta bort" + }, + "context-menus": { + "item": { + "open-section-title": "Öppna i", + "sametab": "Denna flik", + "newtab": "Ny flik", + "modal": "Pop-Up Modal", + "workspace": "Workspace View", + "options-section-title": "Alternativ", + "edit-item": "Redigera", + "move-item": "Kopiera eller flytta", + "remove-item": "Ta bort" + }, + "section": { + "open-section": "Öppna sektion", + "edit-section": "Redigera", + "move-section": "Flytta till", + "remove-section": "Ta bort" + } + }, + "interactive-editor": { + "menu": { + "start-editing-tooltip": "Öppna den interaktiva redigeraren", + "edit-site-data-subheading": "Redigera webbplatsinformation", + "edit-page-info-btn": "Redigera sidinformation", + "edit-page-info-tooltip": "Appnamn, beskrivning, navigeringslänkar, sidfotstext, etc", + "edit-app-config-btn": "Redigera appkonfiguration", + "edit-app-config-tooltip": "Övriga appkonfigurationsalternativ", + "config-save-methods-subheading": "Alternativ för konfigurationssparande", + "save-locally-btn": "Spara lokalt", + "save-locally-tooltip": "Spara konfigurationen lokalt, till webbläsarens lagring. Detta påverkar inte din konfigurationsfil, men ändringarna sparas bara på denna enhet", + "save-disk-btn": "Spara till disk", + "save-disk-tooltip": "Spara konfiguration to conf.yml-filen på disk. Detta kommer att säkerhetskopiera och sedan skriva över din befintliga konfiguration", + "export-config-btn": "Exportera konfiguration", + "export-config-tooltip": "Visa och exportera den nya konfigurationen, antingen till fil eller urklipp", + "cloud-backup-btn": "Säkerhetskopiera till molnet", + "cloud-backup-tooltip": "Spara krypterad säkerhetskopia av konfigurationen i molnet", + "edit-raw-config-btn": "Redigera raw-konfiguration", + "edit-raw-config-tooltip": "Visa och redigera raw-konfiguration via JSON-redigeraren", + "cancel-changes-btn": "Avbryt redigering", + "cancel-changes-tooltip": "Radera nuvarande ändringar och lämna Redigeringsläge. Detta kommer in påverka din sparade konfiguration.", + "edit-mode-name": "Redigeringsläge", + "edit-mode-subtitle": "Du är i Redigeringsläge", + "edit-mode-description": "Detta innebär att du kan göra ändringar i din konfiguration och förhandsgranska resultaten, men tills du sparar kommer inga av dina ändringar att bevaras.", + "save-stage-btn": "Spara", + "cancel-stage-btn": "Avbryt" + }, + "edit-section": { + "edit-section-title": "Redigera sektion", + "add-section-title": "Lägg till ny sektion", + "edit-tooltip": "Tryck för att redigera, eller högerklicka för fler alternativ", + "remove-confirm": "Är du säker på att du vill ta bort denna sektion? Denna åtgärd kan ångras senare." + }, + "edit-app-config": { + "warning-msg-title": "Fortsätt med försiktighet", + "warning-msg-l1": "Följande alternativ är för avancerade appkonfigurationer.", + "warning-msg-l2": "Om du är osäker på något av fälten, vänligen kolla", + "warning-msg-docs": "dokumentationen", + "warning-msg-l3": "för att undvika oavsiktliga konsekvenser." + }, + "export": { + "export-title": "Exportera konfiguration", + "copy-clipboard-btn": "Kopiera till urklipp", + "copy-clipboard-tooltip": "Kopiera alla appkonfigurationer till systemets urklipp i YAML-format", + "download-file-btn": "Ladda ned som fil", + "download-file-tooltip": "Ladda ner alla appkonfigurationer till din enhet som en YAML-fil", + "view-title": "Visa konfiguration" + } + } + } \ No newline at end of file diff --git a/src/components/InteractiveEditor/EditItem.vue b/src/components/InteractiveEditor/EditItem.vue index e924f3ef..14c7bfa0 100644 --- a/src/components/InteractiveEditor/EditItem.vue +++ b/src/components/InteractiveEditor/EditItem.vue @@ -227,6 +227,9 @@ export default { }; if (newItem.tags) newItem.tags = strToTags(newItem.tags); if (newItem.statusCheck) newItem.statusCheck = strToBool(newItem.statusCheck); + if (newItem.statusCheckAllowInsecure) { + newItem.statusCheckAllowInsecure = strToBool(newItem.statusCheckAllowInsecure); + } // if (newItem.hotkey) newItem.hotkey = parseInt(newItem.hotkey, 10); return newItem; }, diff --git a/src/components/LinkItems/Section.vue b/src/components/LinkItems/Section.vue index ae87ba5d..6d230af6 100644 --- a/src/components/LinkItems/Section.vue +++ b/src/components/LinkItems/Section.vue @@ -210,7 +210,7 @@ export default { }, /* Sorts items alphabetically using the title attribute */ sortAlphabetically(items) { - return items.sort((a, b) => (a.title > b.title ? 1 : -1)); + return items.sort((a, b) => (a.title.toLowerCase() > b.title.toLowerCase() ? 1 : -1)); }, /* Sorts items by most used to least used, based on click-count */ sortByMostUsed(items) { diff --git a/src/utils/ConfigSchema.json b/src/utils/ConfigSchema.json index ccab89f9..a4d84141 100644 --- a/src/utils/ConfigSchema.json +++ b/src/utils/ConfigSchema.json @@ -145,13 +145,15 @@ "type": "string", "enum": [ "local", - "faviconkit", - "google", + "allesedv", "clearbit", - "webmasterapi", - "allesedv" + "faviconkit", + "duckduckgo", + "yandex", + "google", + "besticon" ], - "default": "faviconkit", + "default": "allesedv", "description": "Which service to use to resolve favicons. Set to local to do this locally instead" }, "layout": { @@ -719,4 +721,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/utils/languages.js b/src/utils/languages.js index bea5b973..45a7eb40 100644 --- a/src/utils/languages.js +++ b/src/utils/languages.js @@ -15,6 +15,7 @@ import pt from '@/assets/locales/pt.json'; import ru from '@/assets/locales/ru.json'; import nb from '@/assets/locales/nb.json'; import pirate from '@/assets/locales/zz-pirate.json'; +import sv from '@/assets/locales/sv.json'; // Language data - Next register your language by adding it to this list export const languages = [ @@ -114,6 +115,12 @@ export const languages = [ locale: pirate, flag: '🏴‍☠️', }, + { // Swedish + name: 'Svenska', + code: 'sv', + locale: sv, + flag: '🇸🇪', + }, ]; /** diff --git a/src/views/Login.vue b/src/views/Login.vue index cfd4ec74..a26685ec 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -111,6 +111,7 @@ export default { { label: this.$t('login.remember-me-hour'), time: 14400 * 1000 }, { label: this.$t('login.remember-me-day'), time: 86400 * 1000 }, { label: this.$t('login.remember-me-week'), time: 604800 * 1000 }, + { label: this.$t('login.remember-me-long-time'), time: 604800 * 52 * 1000 }, ]; }, /* Translations for login response messages */ diff --git a/yarn.lock b/yarn.lock index 3a90a685..1a4dadc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1134,6 +1134,15 @@ "@sentry/utils" "6.14.1" tslib "^1.9.3" +"@sentry/hub@6.15.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.15.0.tgz#fb8a91d12fdd2726a884374ea7242f6bbd081d69" + integrity sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA== + dependencies: + "@sentry/types" "6.15.0" + "@sentry/utils" "6.15.0" + tslib "^1.9.3" + "@sentry/minimal@6.14.1": version "6.14.1" resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.14.1.tgz#6fbce5b873fb096411dbb9a01ff6706ed684f2e8" @@ -1143,15 +1152,24 @@ "@sentry/types" "6.14.1" tslib "^1.9.3" -"@sentry/tracing@^6.13.1": - version "6.14.1" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.14.1.tgz#fadea88b505078f61b949ecd99891ddb5538f08e" - integrity sha512-Bv/+S5Wn9OPxP7sA9VYMV1wpmXWptFVIMFoG4BuyV4aFYdIAMxSNE/ktqXwmqn+nkBic04nP9rF6lMJBLIvIaA== +"@sentry/minimal@6.15.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.15.0.tgz#fcc083ba901cfe57d25303d0b5fa8cd13e164466" + integrity sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg== dependencies: - "@sentry/hub" "6.14.1" - "@sentry/minimal" "6.14.1" - "@sentry/types" "6.14.1" - "@sentry/utils" "6.14.1" + "@sentry/hub" "6.15.0" + "@sentry/types" "6.15.0" + tslib "^1.9.3" + +"@sentry/tracing@^6.14.3": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.15.0.tgz#5a5f08ee6b9cc1189227536fca053cd23488600d" + integrity sha512-V5unvX8qNEfdawX+m2n0jKgmH/YR2ItWZLH+3UevBTptO+xyfvRtpgGXYWUCo3iGvFgWb1C+iIC7LViR9rTvBg== + dependencies: + "@sentry/hub" "6.15.0" + "@sentry/minimal" "6.15.0" + "@sentry/types" "6.15.0" + "@sentry/utils" "6.15.0" tslib "^1.9.3" "@sentry/types@6.14.1": @@ -1159,6 +1177,11 @@ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.14.1.tgz#0d562a7aa91253b7843723344b4ba03a010e6376" integrity sha512-RIk3ZwQKZnASrYWfV5i4wbzVveHz8xLFAS2ySIMqh+hICKnB0N4/r8a1Of/84j7pj+iAbf5vPS85639eIf+9qg== +"@sentry/types@6.15.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.15.0.tgz#a2917f8aed91471bdfd6651384ffcd47b95c43ad" + integrity sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA== + "@sentry/utils@6.14.1": version "6.14.1" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.14.1.tgz#cb746858665314c07cfe9b0f307b410e377032ad" @@ -1167,6 +1190,14 @@ "@sentry/types" "6.14.1" tslib "^1.9.3" +"@sentry/utils@6.15.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.15.0.tgz#0c247cb092b1796d39c3d16d8e6977b9cdab9ca2" + integrity sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw== + dependencies: + "@sentry/types" "6.15.0" + tslib "^1.9.3" + "@sentry/vue@^6.13.1": version "6.14.1" resolved "https://registry.yarnpkg.com/@sentry/vue/-/vue-6.14.1.tgz#2528d03e2068e28a6a5874f39a5686add509dd55" @@ -1913,7 +1944,7 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1, ajv@^8.6.3: +ajv@^8.0.1: version "8.7.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.7.1.tgz#52be6f1736b076074798124293618f132ad07a7e" integrity sha512-gPpOObTO1QjbnN1sVMjJcp1TF9nggMfO4MBR5uQl6ZVTOaEPq5i4oq/6R9q2alMMPB3eg53wFv1RuJBLuxf3Hw== @@ -1923,6 +1954,16 @@ ajv@^8.0.1, ajv@^8.6.3: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.8.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" + integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -2206,10 +2247,10 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axios@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.23.0.tgz#b0fa5d0948a8d1d75e3d5635238b6c4625b05149" - integrity sha512-NmvAE4i0YAv5cKq8zlDoPd1VLKAqX5oLuZKs8xkJa4qi6RGn0uhCYFjWtHHC9EM/MwOwYWOs53W+V0aqEXq1sg== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== dependencies: follow-redirects "^1.14.4" @@ -8703,10 +8744,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== -simple-icons@^5.19.0: - version "5.22.0" - resolved "https://registry.yarnpkg.com/simple-icons/-/simple-icons-5.22.0.tgz#c987aeea658828e858b774ab334264dabbe0344c" - integrity sha512-crEorhti73Sh88EZbw9mG/toCEoSQexf8HJCFFloz2V7bP7/lDpgcEmoWrW3SAh9tOQL8sWau4DSSRBVvRIRew== +simple-icons@^5.23.0: + version "5.24.0" + resolved "https://registry.yarnpkg.com/simple-icons/-/simple-icons-5.24.0.tgz#6485a5713c2e5758605b461b833396c4874e9e4d" + integrity sha512-wKHeqUBsHYB5KPqdc3e7BGQPQCx/NbHfJuukjo70ABGk6hegjTDSoJhsSEcVadknVG4W3+jcC3G3RbytJnapGQ== simple-swizzle@^0.2.2: version "0.2.2"