Compare commits

..
5 changed files with 36 additions and 32 deletions

No files matched your search

+9 -7
View File
@@ -1,22 +1,24 @@
# Since .env is gitignored, you can use .env.example to build a new `.env` file when you clone the repo. # Since .env is gitignored, you can use .env.example to build a new `.env` file when you clone the repo.
# Keep this file up-to-date when you add new variables to \`.env\`. # Keep this file up-to-date when you add new variables to `.env`.
# This file will be committed to version control, so make sure not to have any secrets in it. # This file will be committed to version control, so make sure not to have any secrets in it.
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets. # If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
# The below secret is not used anywhere but required for Auth.js (Would encrypt JWTs and Mail hashes, both not used) # Generate two different 64-character hex values with `openssl rand -hex 32` before starting Homarr.
AUTH_SECRET="supersecret" # Never reuse these values or commit the populated `.env` file.
AUTH_SECRET=
# The below secret is used to encrypt integration secrets in the database. # The below secret is used to encrypt integration secrets in the database.
# It should be a 32-byte string, generated by running `openssl rand -hex 32` on Unix # Homarr will reject an empty or invalid value and print a randomly generated candidate.
# or starting the project without any (which will show a randomly generated one). SECRET_ENCRYPTION_KEY=
SECRET_ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
LOG_LEVEL='info' LOG_LEVEL='info'
# This is how you can use the sqlite driver: # This is how you can use the sqlite driver:
DB_DRIVER='better-sqlite3' DB_DRIVER='better-sqlite3'
DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE' # Safe local source-development path. SQLite files are ignored by Git.
# Container images use /appdata/db/db.sqlite by default instead.
DB_URL='./db.sqlite'
# Those are the two ways to use the mysql2 driver: # Those are the two ways to use the mysql2 driver:
# 1. Using the URL format: # 1. Using the URL format:
@@ -244,18 +244,21 @@ Homarr supports multiple authentication options, from internal userbase (credent
- Create a group (e.g., `homarr-admins`) and assign users who require admin access. - Create a group (e.g., `homarr-admins`) and assign users who require admin access.
**2. Example .env file:** **2. Example .env file:**
Generate `SECRET_ENCRYPTION_KEY` with `openssl rand -hex 32`; do not copy an example key between installs.
```env ```env
OIDC_CLIENT_ID=identificationid #OIDC client ID OIDC_CLIENT_ID=<REPLACE_WITH_OIDC_CLIENT_ID>
OIDC_CLIENT_SECRET=secretsecretsecret #OIDC client secret OIDC_CLIENT_SECRET=<REPLACE_WITH_OIDC_CLIENT_SECRET>
OIDC_SLUG=homarr #Application slug in Authentik OIDC_SLUG=homarr #Application slug in Authentik
AUTH_DOMAIN=auth.example.com #Authentik FQDN AUTH_DOMAIN=auth.example.com #Authentik FQDN
ADMIN_GROUP=homarr-admins #Authentik group for Homarr admins ADMIN_GROUP=homarr-admins #Authentik group for Homarr admins
HOMARR_FQDN=homarr.example.com #Homarr FQDN HOMARR_FQDN=homarr.example.com #Homarr FQDN
SECRET_ENCRYPTION_KEY=encryptencryptencrypt #Homarr encryption key SECRET_ENCRYPTION_KEY=<REPLACE_WITH_64_HEX_CHARACTERS>
``` ```
**3. Example Docker Compose configuration:** **3. Example Docker Compose configuration:**
```yaml {14-26} ```yaml {14-24}
services: services:
homarr: homarr:
image: ghcr.io/homarr-labs/homarr:latest image: ghcr.io/homarr-labs/homarr:latest
@@ -269,8 +272,6 @@ Homarr supports multiple authentication options, from internal userbase (credent
environment: environment:
- TZ=America/Los_Angeles - TZ=America/Los_Angeles
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY} - SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- BASE_URL=https://${HOMARR_FQDN}
- NEXTAUTH_URL=https://${HOMARR_FQDN}
- AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback) - AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback)
- AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID} - AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
- AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET} - AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
@@ -322,15 +323,18 @@ Homarr supports multiple authentication options, from internal userbase (credent
- Record the `Client-ID` and `Client Key` (secret). - Record the `Client-ID` and `Client Key` (secret).
**2. Example .env file (Homarr):** **2. Example .env file (Homarr):**
Generate `SECRET_ENCRYPTION_KEY` with `openssl rand -hex 32`; do not copy an example key between installs.
```env ```env
OIDC_CLIENT_ID=identificationid #Google Client-ID OIDC_CLIENT_ID=<REPLACE_WITH_GOOGLE_CLIENT_ID>
OIDC_CLIENT_SECRET=secretsecretsecret #Google Client Key (secret) OIDC_CLIENT_SECRET=<REPLACE_WITH_GOOGLE_CLIENT_SECRET>
HOMARR_FQDN=homarr.example.com #Homarr FQDN HOMARR_FQDN=homarr.example.com #Homarr FQDN
SECRET_ENCRYPTION_KEY=encryptencryptencrypt #Homarr encryption key SECRET_ENCRYPTION_KEY=<REPLACE_WITH_64_HEX_CHARACTERS>
``` ```
**3. Example Docker Compose configuration (Homarr):** **3. Example Docker Compose configuration (Homarr):**
```yaml {16-22} ```yaml {14-20}
services: services:
homarr: homarr:
image: ghcr.io/homarr-labs/homarr:latest image: ghcr.io/homarr-labs/homarr:latest
@@ -344,8 +348,6 @@ Homarr supports multiple authentication options, from internal userbase (credent
environment: environment:
- TZ=Europe/Berlin - TZ=Europe/Berlin
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY} - SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- BASE_URL=https://${HOMARR_FQDN}
- NEXTAUTH_URL=https://${HOMARR_FQDN}
- AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback) - AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback)
- AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID} - AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
- AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET} - AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
@@ -38,13 +38,14 @@ This method is only useful, when you want to develop on Homarr or extend it with
Install all dependencies using <code>pnpm install</code> Install all dependencies using <code>pnpm install</code>
</li> </li>
<li> <li>
Copy the `.env.example` file to `.env` and replace `DB_URL` with the full path you want to use for the sqlite Copy the `.env.example` file to `.env`. Its `DB_URL='./db.sqlite'` value is ready for local use and stores the
database file. For example `DB_URL='/home/username/homarr/db.sqlite` database in the cloned repository. Replace it with an absolute writable path such as
`DB_URL='/home/username/homarr/db.sqlite'` if you want to store the database elsewhere.
</li> </li>
<li> <li>
Replace `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` both with a secure random string by using `openssl rand -hex 32` Run `openssl rand -hex 32` twice and set `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` to the two different generated
values. Keep both values secret and preserve `SECRET_ENCRYPTION_KEY` with your backups.
</li> </li>
<li>Replace `CRON_JOB_API_KEY` with a secure random string by using `openssl rand -base64 32`</li>
<li>Run `pnpm run db:migration:sqlite:run` and wait that it completes</li> <li>Run `pnpm run db:migration:sqlite:run` and wait that it completes</li>
<li>Build the source using `pnpm build`</li> <li>Build the source using `pnpm build`</li>
<li> <li>
+4 -5
View File
@@ -481,14 +481,13 @@ export function calculateCpuUsage(stats: ContainerStats): number {
return 0; return 0;
} }
const cpuDelta = stats.cpu_stats.cpu_usage.total_usage - (stats.precpu_stats?.cpu_usage?.total_usage ?? 0); const numberOfCpus = stats.cpu_stats.online_cpus;
const systemDelta = (stats.cpu_stats.system_cpu_usage ?? 0) - (stats.precpu_stats?.system_cpu_usage ?? 0); const usage = stats.cpu_stats.system_cpu_usage;
if (!usage || usage === 0) {
if (systemDelta <= 0 || cpuDelta < 0) {
return 0; return 0;
} }
return (cpuDelta / systemDelta) * 100; return (stats.cpu_stats.cpu_usage.total_usage / usage) * numberOfCpus * 100;
} }
export function calculateMemoryUsage(stats: ContainerStats): number { export function calculateMemoryUsage(stats: ContainerStats): number {
@@ -72,16 +72,16 @@ describe("calculateCpuUsage", () => {
const stats = createStats({ const stats = createStats({
cpu_stats: { online_cpus: 4, cpu_usage: { total_usage: 2000 }, system_cpu_usage: 10000 }, cpu_stats: { online_cpus: 4, cpu_usage: { total_usage: 2000 }, system_cpu_usage: 10000 },
}); });
// (2000 / 10000) * 100 = 20 // (2000 / 10000) * 4 * 100 = 80
expect(calculateCpuUsage(stats)).toBe(20); expect(calculateCpuUsage(stats)).toBe(80);
}); });
test("should handle fractional CPU usage", () => { test("should handle fractional CPU usage", () => {
const stats = createStats({ const stats = createStats({
cpu_stats: { online_cpus: 2, cpu_usage: { total_usage: 500 }, system_cpu_usage: 100000 }, cpu_stats: { online_cpus: 2, cpu_usage: { total_usage: 500 }, system_cpu_usage: 100000 },
}); });
// (500 / 100000) * 100 = 0.5 // (500 / 100000) * 2 * 100 = 1
expect(calculateCpuUsage(stats)).toBe(0.5); expect(calculateCpuUsage(stats)).toBe(1);
}); });
}); });