Merge branch 'master' into patch-5

This commit is contained in:
Nicolas Meienberger 2024-05-19 13:44:16 +02:00 committed by GitHub
commit f4b121a459
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 288 additions and 34 deletions

View File

@ -1,7 +1,13 @@
module.exports = { module.exports = {
extends: ["plugin:json-schema-validator/recommended"], extends: ['plugin:json-schema-validator/recommended'],
plugins: [], plugins: [],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
rules: { rules: {
"json-schema-validator/no-invalid": "error", 'json-schema-validator/no-invalid': 'error',
}, },
}; };

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
- name: Install Bun - name: Install Bun
uses: oven-sh/setup-bun@v1 uses: oven-sh/setup-bun@v1

View File

@ -4,14 +4,14 @@
app_name=$1 app_name=$1
# find all docker-compose files under apps/$app_name (there should be only one) # find all docker-compose files under apps/$app_name (there should be only one)
docker_compose_files=$(find apps/$app_name -name docker-compose.yml) docker_compose_files=$(find apps/"$app_name" -name docker-compose.yml)
for docker_compose_file in $docker_compose_files for docker_compose_file in $docker_compose_files
do do
# Assuming that the app version will be from the first docker image # Assuming that the app version will be from the first docker image
first_service=$(yq '.services | keys | .[0]' $docker_compose_file) first_service=$(yq '.services | keys | .[0]' "$docker_compose_file")
image=$(yq .services.$first_service.image $docker_compose_file) image=$(yq .services."$first_service".image "$docker_compose_file")
# Only apply changes if the format is <image>:<version> # Only apply changes if the format is <image>:<version>
if [[ "$image" == *":"* ]]; then if [[ "$image" == *":"* ]]; then
@ -20,20 +20,39 @@ do
# Trim the "v" prefix # Trim the "v" prefix
trimmed_version=${version/#"v"} trimmed_version=${version/#"v"}
# Find config file # ------------------- Update config.json -------------------
config_file=${docker_compose_file/docker-compose.yml/config.json} config_file=${docker_compose_file/docker-compose.yml/config.json}
current_config_version=$(jq -r '.version' $config_file) current_config_version=$(jq -r '.version' "$config_file")
echo "Current config version: $current_config_version"
# Update the version in config.json, but only if there's a change # Update the version in config.json
if [[ "$current_config_version" != "$trimmed_version" ]]; then contents="$(jq --arg trimmed_version "$trimmed_version" '.version=$trimmed_version' "$config_file")"
contents="$(jq --arg trimmed_version "$trimmed_version" '.version=$trimmed_version' $config_file)" echo "${contents}" > "$config_file"
echo "${contents}" > $config_file
tipi_version=$(jq -r '.tipi_version' $config_file)
tipi_version=$((tipi_version + 1)) # ------------------- Update docker-compose.json -------------------
contents="$(jq --argjson tipi_version $tipi_version '.tipi_version=$tipi_version' $config_file)" # Update the version in docker-compose.json if it exists
echo "${contents}" > $config_file if [[ -f ${docker_compose_file/docker-compose.yml/docker-compose.json} ]]; then
fi compose_file=${docker_compose_file/docker-compose.yml/docker-compose.json}
echo "Updating $compose_file with version $image"
main_service_index=$(yq '.services | to_entries[] | select(.value.isMain == true) | .key' "$compose_file")
# apply trimmed version to docker-compose.json's main service
contents="$(jq --arg image "$image" --arg main_service_index "$main_service_index" '.services[$main_service_index | tonumber].image=$image' "$compose_file")"
echo "${contents}" > "$compose_file"
fi
# ------------------- Update config.json -------------------
tipi_version=$(jq -r '.tipi_version' "$config_file")
tipi_version=$((tipi_version + 1))
contents="$(jq --argjson tipi_version $tipi_version '.tipi_version=$tipi_version' "$config_file")"
echo "${contents}" > "$config_file"
# ------------------- Format files with prettier -------------------
npx prettier "$config_file" --write
npx prettier "$compose_file" --write
fi fi
done done

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
- name: Get last commit message - name: Get last commit message
id: get-last-commit-message id: get-last-commit-message
@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.PERSONAL_TOKEN }} token: ${{ secrets.PERSONAL_TOKEN }}
@ -58,7 +58,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.5 uses: actions/checkout@v4.1.6
- name: Self-hosted Renovate - name: Self-hosted Renovate
uses: renovatebot/github-action@v40.1.11 uses: renovatebot/github-action@v40.1.11
with: with:

View File

@ -1 +0,0 @@
{}

7
.prettierrc.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = {
singleQuote: true,
semi: true,
trailingComma: "all",
tabWidth: 2,
printWidth: 150,
};

View File

@ -6,20 +6,16 @@
"gid": 1000, "gid": 1000,
"available": true, "available": true,
"exposable": true, "exposable": true,
"dynamic_config": true,
"id": "2fauth", "id": "2fauth",
"tipi_version": 15, "tipi_version": 15,
"version": "5.1.1", "version": "5.1.1",
"categories": [ "categories": ["security"],
"security"
],
"description": "A Web app to manage your Two-Factor Authentication (2FA) accounts and generate their security codes.", "description": "A Web app to manage your Two-Factor Authentication (2FA) accounts and generate their security codes.",
"short_desc": "Manage your Two-Factor Authentication codes.", "short_desc": "Manage your Two-Factor Authentication codes.",
"author": "Bubka", "author": "Bubka",
"source": "https://github.com/Bubka/2FAuth", "source": "https://github.com/Bubka/2FAuth",
"website": "https://docs.2fauth.app/", "website": "https://docs.2fauth.app/",
"form_fields": [], "form_fields": [],
"supported_architectures": [ "supported_architectures": ["arm64", "amd64"]
"arm64",
"amd64"
]
} }

View File

@ -0,0 +1,20 @@
{
"services": [
{
"name": "2fauth",
"image": "2fauth/2fauth:5.1.1",
"internalPort": 8000,
"isMain": true,
"volumes": [
{
"hostPath": "${APP_DATA_DIR}/data",
"containerPath": "/2fauth"
}
],
"environment": {
"ASSET_URL": "https://${APP_DOMAIN}",
"APP_URL": "https://${APP_DOMAIN}"
}
}
]
}

View File

@ -0,0 +1,32 @@
import { z } from 'zod';
export const appConfigSchema = z.object({
services: z.array(
z.object({
name: z.string(),
image: z.string(),
internalPort: z.number().min(1).max(65535),
isMain: z.boolean().optional(),
command: z.string().optional(),
// eg: /path/to/volume:/path/in/container
volumes: z.array(
z.object({
hostPath: z.string().regex(/^\/.+/),
containerPath: z.string().regex(/^\/.+/),
}),
),
environment: z.record(z.string()).optional(),
healthCheck: z
.object({
test: z.string(),
// eg: 5s, 1m, 1h
interval: z.string().regex(/^\d+[smh]$/),
timeout: z.string().regex(/^\d+[smh]$/),
retries: z.number().min(0),
})
.optional(),
}),
),
});
export type AppConfig = z.input<typeof appConfigSchema>;

View File

@ -5,8 +5,8 @@
"exposable": true, "exposable": true,
"port": 8119, "port": 8119,
"id": "bookstack", "id": "bookstack",
"tipi_version": 19, "tipi_version": 20,
"version": "24.05.20240511", "version": "24.05.20240513",
"description": "BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information. Default login: admin@admin.com password: password", "description": "BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information. Default login: admin@admin.com password: password",
"short_desc": "BookStack is a self-hosted platform for organising and storing information.", "short_desc": "BookStack is a self-hosted platform for organising and storing information.",
"author": "Dan Brown", "author": "Dan Brown",

View File

@ -1,7 +1,7 @@
version: "3.7" version: "3.7"
services: services:
bookstack: bookstack:
image: lscr.io/linuxserver/bookstack:24.05.20240511 image: lscr.io/linuxserver/bookstack:24.05.20240513
container_name: bookstack container_name: bookstack
environment: environment:
- APP_URL=${APP_PROTOCOL:-http}://${APP_DOMAIN} - APP_URL=${APP_PROTOCOL:-http}://${APP_DOMAIN}

18
apps/glance/config.json Normal file
View File

@ -0,0 +1,18 @@
{
"$schema": "../schema.json",
"name": "Glance",
"port": 8568,
"available": true,
"exposable": true,
"id": "glance",
"tipi_version": 1,
"version": "v0.4.0",
"categories": ["utilities"],
"description": "A self-hosted dashboard that puts all your feeds in one place",
"short_desc": "Super configurable dashboard",
"author": "glanceapp",
"source": "https://github.com/glanceapp/glance",
"form_fields": [],
"supported_architectures": ["arm64", "amd64"],
"dynamic_config": true
}

View File

@ -0,0 +1,65 @@
pages:
- name: Home
columns:
- size: small
widgets:
- type: calendar
- type: rss
limit: 10
collapse-after: 3
cache: 3h
feeds:
- url: https://ciechanow.ski/atom.xml
- url: https://www.joshwcomeau.com/rss.xml
title: Josh Comeau
- url: https://samwho.dev/rss.xml
- url: https://awesomekling.github.io/feed.xml
- url: https://ishadeed.com/feed.xml
title: Ahmad Shadeed
- type: twitch-channels
channels:
- theprimeagen
- cohhcarnage
- christitustech
- blurbs
- asmongold
- jembawls
- size: full
widgets:
- type: hacker-news
- type: videos
channels:
- UCR-DXc1voovS8nhAvccRZhg # Jeff Geerling
- UCv6J_jJa8GJqFwQNgNrMuww # ServeTheHome
- UCOk-gHyjcWZNj3Br4oxwh0A # Techno Tim
- type: reddit
subreddit: selfhosted
- size: small
widgets:
- type: weather
location: London, United Kingdom
- type: stocks
stocks:
- symbol: SPY
name: S&P 500
- symbol: BTC-USD
name: Bitcoin
- symbol: NVDA
name: NVIDIA
- symbol: AAPL
name: Apple
- symbol: MSFT
name: Microsoft
- symbol: GOOGL
name: Google
- symbol: AMD
name: AMD
- symbol: RDDT
name: Reddit

View File

@ -0,0 +1,13 @@
{
"openPort": true,
"image": "glanceapp/glance:v0.4.0",
"name": "glance",
"internalPort": "8080",
"isMain": true,
"volumes": [
{
"hostPath": "${APP_DATA_DIR}/data/glance.yml",
"containerPath": "/app/glance.yml"
}
]
}

View File

@ -0,0 +1,39 @@
version: "3.9"
services:
glance:
image: glanceapp/glance:v0.4.0
restart: unless-stopped
container_name: glance
ports:
- ${APP_PORT}:8080
volumes:
- ${APP_DATA_DIR}/data/glance.yml:/app/glance.yml
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
networks:
- tipi_main_network
labels:
# Main
traefik.enable: true
traefik.http.middlewares.glance-web-redirect.redirectscheme.scheme: https
traefik.http.services.glance.loadbalancer.server.port: 8080
# Web
traefik.http.routers.glance-insecure.rule: Host(`${APP_DOMAIN}`)
traefik.http.routers.glance-insecure.entrypoints: web
traefik.http.routers.glance-insecure.service: glance
traefik.http.routers.glance-insecure.middlewares: glance-web-redirect
# Websecure
traefik.http.routers.glance.rule: Host(`${APP_DOMAIN}`)
traefik.http.routers.glance.entrypoints: websecure
traefik.http.routers.glance.service: glance
traefik.http.routers.glance.tls.certresolver: myresolver
# Local domain
traefik.http.routers.glance-local-insecure.rule: Host(`glance.${LOCAL_DOMAIN}`)
traefik.http.routers.glance-local-insecure.entrypoints: web
traefik.http.routers.glance-local-insecure.service: glance
traefik.http.routers.glance-local-insecure.middlewares: glance-web-redirect
# Local domain secure
traefik.http.routers.glance-local.rule: Host(`glance.${LOCAL_DOMAIN}`)
traefik.http.routers.glance-local.entrypoints: websecure
traefik.http.routers.glance-local.service: glance
traefik.http.routers.glance-local.tls: true

View File

@ -0,0 +1,40 @@
<p align="center"><em>What if you could see everything at a...</em></p>
<h1 align="center">Glance</h1>
![example homepage](https://raw.githubusercontent.com/glanceapp/glance/main/docs/images/readme-main-image.png)
### Features
#### Various widgets
- RSS feeds
- Subreddit posts
- Weather
- Bookmarks
- Latest YouTube videos from specific channels
- Calendar
- Stocks
- iframe
- Twitch channels & top games
- GitHub releases
- Repository overview
- Site monitor
#### Themeable
![multiple color schemes example](https://raw.githubusercontent.com/glanceapp/glance/main/docs/images/themes-example.png)
#### Optimized for mobile devices
![mobile device previews](https://raw.githubusercontent.com/glanceapp/glance/main/docs/images/mobile-preview.png)
#### Fast and lightweight
- Minimal JS, no bloated frameworks
- Very few dependencies
- Single, easily distributed <15mb binary and just as small docker container
- All requests are parallelized, uncached pages usually load within ~1s (depending on internet speed and number of widgets)
### Configuration
Checkout the [configuration docs](docs/configuration.md) to learn more. A [preconfigured page](docs/configuration.md#preconfigured-page) is also available to get you started quickly.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB