Skip to content

Commit 2f1f3c5

Browse files
authored
🔀 Merge pull request #2113 from Lissy93/fix/implementing-user-requests
Small fixes and implementing user requests
2 parents bc1f3ce + 0f1f7ce commit 2f1f3c5

22 files changed

Lines changed: 155 additions & 300 deletions

File tree

.github/workflows/pr-quality-check.yml

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ concurrency:
1111
cancel-in-progress: true
1212

1313
jobs:
14+
changes:
15+
name: 🔎 Detect Changes
16+
runs-on: ubuntu-latest
17+
outputs:
18+
lockfile: ${{ steps.filter.outputs.lockfile }}
19+
steps:
20+
- name: 🛎️ Checkout Code
21+
uses: actions/checkout@v6
22+
23+
- name: 🔎 Filter Paths
24+
uses: dorny/paths-filter@v3
25+
id: filter
26+
with:
27+
filters: |
28+
lockfile:
29+
- 'yarn.lock'
30+
1431
lint:
1532
name: 📝 Lint Code
1633
runs-on: ubuntu-latest
@@ -111,23 +128,24 @@ jobs:
111128
run: sh tests/docker-smoke-test.sh
112129
timeout-minutes: 10
113130

114-
# TODO: Re-enable security audit job
115-
# security:
116-
# name: 🔒 Security Audit
117-
# runs-on: ubuntu-latest
118-
# continue-on-error: true
119-
# steps:
120-
# - name: 🛎️ Checkout Code
121-
# uses: actions/checkout@v6
122-
#
123-
# - name: 🔧 Setup Node.js
124-
# uses: actions/setup-node@v6
125-
# with:
126-
# node-version: '20'
127-
# cache: 'yarn'
128-
#
129-
# - name: 📦 Install Dependencies
130-
# run: yarn install --frozen-lockfile
131-
#
132-
# - name: 🔒 Run Security Audit
133-
# run: yarn audit --level high
131+
security:
132+
name: 🔒 Security Audit
133+
runs-on: ubuntu-latest
134+
needs: changes
135+
if: needs.changes.outputs.lockfile == 'true'
136+
continue-on-error: true
137+
steps:
138+
- name: 🛎️ Checkout Code
139+
uses: actions/checkout@v6
140+
141+
- name: 🔧 Setup Node.js
142+
uses: actions/setup-node@v6
143+
with:
144+
node-version: '20'
145+
cache: 'yarn'
146+
147+
- name: 📦 Install Dependencies
148+
run: yarn install --frozen-lockfile
149+
150+
- name: 🔒 Run Security Audit
151+
run: yarn audit --level high

docs/developing.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ Styleguides:
243243
│ │ ├── CloudBackupRestore.vue # Form where the user manages cloud sync options
244244
│ │ ├── ConfigContainer.vue # Main container, wrapping all other config components
245245
│ │ ├── CustomCss.vue # Form where the user can input custom CSS
246-
│ │ ├── EditSiteMeta.vue # Form where the user can edit site meta data
247246
│ │ ╰── JsonEditor.vue # JSON editor, where the user can modify the main config file
248247
│ ├── FormElements # Basic form elements used throughout the app
249248
│ │ ├── Button.vue # Standard button component

docs/management.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,36 @@ docker run -d \
105105
willfarrell/autoheal
106106
```
107107

108+
### HTTP Healthcheck Endpoint
109+
110+
Dashy also exposes an unauthenticated HTTP liveness endpoint at `/healthz`, which returns a `200` with a small JSON body (`status`, `uptime`, `version`). It bypasses auth and SSL redirection so probes keep working regardless of how Dashy is configured.
111+
112+
Useful when fronting Dashy with a load balancer / reverse proxy that needs an HTTP probe for auto-failover, or when running on Kubernetes:
113+
114+
```yaml
115+
# Kubernetes
116+
livenessProbe:
117+
httpGet:
118+
path: /healthz
119+
port: 8080
120+
```
121+
122+
```yaml
123+
# Traefik (label on the Dashy service)
124+
- "traefik.http.services.dashy.loadbalancer.healthcheck.path=/healthz"
125+
- "traefik.http.services.dashy.loadbalancer.healthcheck.interval=30s"
126+
```
127+
128+
```caddyfile
129+
# Caddy (reverse_proxy block)
130+
reverse_proxy dashy:8080 {
131+
health_uri /healthz
132+
health_interval 30s
133+
}
134+
```
135+
136+
For Nginx Proxy Manager, set the *Forward Hostname* health-check path to `/healthz` under the proxy host's *Custom locations* / advanced config.
137+
108138
**[⬆️ Back to Top](#management)**
109139

110140
---

docs/pages-and-sections.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,15 @@ Item groups may also have an optional title.
173173
items:
174174
- title: Normal Item 1
175175
- title: Normal Item 2
176-
- subItems:
176+
- title: Languages
177+
subItems:
177178
- title: JavaScript
178179
url: https://developer.mozilla.org
179180
icon: si-javascript
180181
- title: TypeScript
181182
url: https://www.typescriptlang.org/docs
182183
icon: si-typescript
183-
- title: Svelt
184+
- title: Svelte
184185
url: https://svelte.dev/docs
185186
icon: si-svelte
186187
- title: Go

docs/showcase.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@
212212

213213
---
214214

215+
## HomeLab 3.0
216+
217+
> <sup>Re: [#1999](https://github.com/Lissy93/dashy/issues/1999)</sup>
218+
219+
![screenshot-homelab-3](https://pixelflare.cc/alicia/dashy/12-skoogee-homelab-3)
220+
221+
---
222+
215223
## Morning Dashboard
216224

217225
> Displayed on my smart screen between 05:00 - 08:00, and includes all the info that I usually check before leaving for work

docs/widgets.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ This widget display email addresses / aliases from addy.io. Click an email addre
618618

619619
**Field** | **Type** | **Required** | **Description**
620620
--- | --- | --- | ---
621-
**`apiKey`** | `string` | Required | Your addy.io API Key / Personal Access Token. You can generate this under [Account Settings](https://app.addy.io/settings)
621+
**`apiKey`** | `string` | Required | Your addy.io API Key / Personal Access Token. You can generate this under [API Settings](https://app.addy.io/settings/api)
622622
**`hostname`** | `string` | _Optional_ | If your self-hosting addy.io, then supply the host name. By default it will use the public hosted instance
623623
**`apiVersion`** | `string` | _Optional_ | If you're using an API version that is not version `v1`, then specify it here
624624
**`limit`** | `number` | _Optional_ | Limit the number of emails shown per page. Defaults to `10`
@@ -631,7 +631,7 @@ This widget display email addresses / aliases from addy.io. Click an email addre
631631
#### Example
632632

633633
```yaml
634-
- type: anonaddy
634+
- type: addy
635635
options:
636636
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxx\
637637
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\

services/app.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const getUser = require('./get-user'); // Enables server side user lookup
3333

3434
/* Service endpoint URL paths (see also serviceEndpoints in src/utils/config/defaults.js) */
3535
const ENDPOINTS = {
36+
health: '/healthz',
3637
statusPing: '/status-ping',
3738
statusCheck: '/status-check',
3839
save: '/config-manager/save',
@@ -41,6 +42,11 @@ const ENDPOINTS = {
4142
getUser: '/get-user',
4243
};
4344

45+
/* Read package version once at startup, so healthcheck never touches the disk per-request */
46+
let appVersion = 'unknown';
47+
try { appVersion = require(path.join(rootDir, 'package.json')).version || 'unknown'; }
48+
catch { /* non-fatal — fall back to 'unknown' */ }
49+
4450
/* Indicates for the webpack config, that running as a server */
4551
process.env.IS_SERVER = 'True';
4652

@@ -173,6 +179,13 @@ function requireAdmin(req, res, next) {
173179
const method = (m, mw) => (req, res, next) => (req.method === m ? mw(req, res, next) : next());
174180

175181
const app = express()
182+
.get(ENDPOINTS.health, (req, res) => {
183+
res.set('Cache-Control', 'no-store').status(200).json({
184+
status: 'ok',
185+
uptime: Math.round(process.uptime()),
186+
version: appVersion,
187+
});
188+
})
176189
// Load SSL redirection middleware
177190
.use(sslServer.middleware)
178191
// Load middlewares for parsing JSON, and supporting HTML5 history routing

services/healthcheck.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const httpsCerts = {
1414
/* Check if either if simular conditions exist that would of had ssl-server.js to enable ssl */
1515
const isSsl = !!fs.existsSync(httpsCerts.private) && !!fs.existsSync(httpsCerts.public);
1616

17-
// eslint-disable-next-line import/no-dynamic-require
1817
const http = require(isSsl ? 'https' : 'http');
1918

2019
/* Location of the server to test */
@@ -33,7 +32,7 @@ const agent = new http.Agent({
3332
});
3433

3534
const requestOptions = {
36-
host, port, timeout, agent,
35+
host, port, timeout, agent, path: '/healthz',
3736
};
3837

3938
const startTime = new Date(); // Initialize timestamp to calculate time taken

src/assets/interface-icons/application-reload.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/assets/interface-icons/application-workspace.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)