# Glance Dashboard for Orsi # Namespace: glance-system # Domain: orsi.dooplex.hu # Version: v0.8.4 # # Features: # - Custom background image (purple theme matching Homepage) # - Custom logo # - Weather widget (Budapest) # - YouTube subscriptions # - RSS feeds # - To-do list # - iFrames for Cal.com, Google Calendar, Outline # - Bookmarks/Links to all apps # - Calendar widget # # Authentik Integration: # 1. Create Application: "Glance Orsi" # 2. Create Provider: Proxy Provider with external host https://orsi.dooplex.hu # 3. Create Outpost: glance-outpost # 4. Update auth-url annotation with actual outpost service name --- apiVersion: v1 kind: Namespace metadata: name: glance-system labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi --- apiVersion: v1 kind: ConfigMap metadata: name: glance-config namespace: glance-system labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi data: glance.yml: | # Glance Configuration # Documentation: https://github.com/glanceapp/glance/blob/main/docs/configuration.md server: host: 0.0.0.0 port: 8080 assets-path: /app/assets document: head: | branding: logo-url: https://web.dooplex.hu/static/dooplex_logo_orsi_3.png favicon-url: https://web.dooplex.hu/static/dooplex_favicon_orsi.png app-name: "Orsi's Home" app-icon-url: https://web.dooplex.hu/static/dooplex_favicon_orsi.png app-background-color: "#2d1f3d" hide-footer: true theme: disable-picker: true background-color: 280 30 15 primary-color: 280 60 70 positive-color: 120 50 50 negative-color: 0 70 60 contrast-multiplier: 1.2 text-saturation-multiplier: 0.8 custom-css-file: /assets/custom.css pages: # ==================== HOME PAGE ==================== - name: Home slug: home width: wide columns: # ---------- LEFT COLUMN ---------- - size: small widgets: # Quick Links - Frequently used - type: bookmarks title: Frequently used groups: - title: "" links: - title: Youtube url: https://youtube.com icon: si:youtube - title: Facebook url: https://facebook.com icon: si:facebook - title: Spotify url: https://spotify.com icon: si:spotify - title: Gmail url: https://gmail.com icon: si:gmail - title: Google Drive url: https://drive.google.com icon: si:googledrive - title: Google Calendar url: https://calendar.google.com icon: si:googlecalendar - title: Yahoo Mail url: https://mail.yahoo.com icon: https://web.dooplex.hu/static/white-icons/yahoo.png # Quick Links - Productivity - type: bookmarks title: Productivity groups: - title: "" links: - title: Nextcloud url: https://nextcloud.dooplex.hu icon: si:nextcloud - title: Outline url: https://outline.dooplex.hu icon: si:outline - title: Paperless url: https://paperless.dooplex.hu icon: si:paperlessngx - title: Vaultwarden url: https://vaultwarden.dooplex.hu icon: si:bitwarden - title: Actual Budget url: https://actualbudget.dooplex.hu icon: si:actualbudget - title: Tandoor url: https://tandoor.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/tandoor.png - title: Bookstack url: https://bookstack.dooplex.hu icon: si:bookstack # Quick Links - File Sharing - type: bookmarks title: File Sharing groups: - title: "" links: - title: Fileshare url: https://fileshare.dooplex.hu icon: si:files - title: Privatebin url: https://privatebin.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/privatebin.png - title: Pastes (OpenGist) url: https://paste.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/opengist.png - title: Zipline url: https://zipline.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/zipline.png # ---------- CENTER COLUMN ---------- - size: full widgets: - type: split-column max-columns: 3 widgets: # Weather Widget (Időkép) - type: custom-api title: "Időkép — Budapest VII." url: "http://idokep-scraper.glance-system.svc.cluster.local:8000/api?v=2" cache: 30s template: | {{ $loc := .JSON.String "location.name" }} {{ if eq $loc "" }}{{ $loc = .JSON.String "place" }}{{ end }} {{ $curTemp := .JSON.Float "current.temp_c" }} {{ $curIcon := .JSON.String "current.icon_url" }} {{ $daily := .JSON.Array "daily" }} {{ $hourly := .JSON.Array "hourly" }}
{{ if $curIcon }}{{ end }}
{{ printf "%.0f" $curTemp }}°C
{{ $loc }}
Forrás: Időkép
{{ if gt (len $hourly) 0 }}
{{ range $i, $h := $hourly }}
{{ $h.String "time" }}
{{ if $h.String "icon_url" }}{{ $h.String {{ end }}
{{ printf "%.0f" ($h.Float "temp_c") }}°
{{ end }}
{{ end }} {{ if gt (len $daily) 0 }}
{{ range $daily }}
{{ .String "dow" }} {{ .String "daynum" }}
{{ if .String "icon_url" }}{{ .String {{ end }}
{{ printf "%.0f" (.Float "tmin_c") }}°
{{/* We construct the style manually to bypass Go security sanitization */}}
{{ printf "%.0f" (.Float "tmax_c") }}°
{{ end }}
{{ end }}
# Calendar Widget # - type: calendar # first-day-of-week: monday # To-Do List - type: to-do title: Tasks - type: custom-api title: Meal for the Day cache: 5m url: http://glance-helper.glance-system.svc.cluster.local:8000/tandoor/daily parameters: count: 3 cooldown: 14 options: tandoor_url: https://tandoor.dooplex.hu template: | {{ $tandoor := .Options.StringOr "tandoor_url" "https://tandoor.dooplex.hu" }} {{ $items := .JSON.Array "items" }} {{ $count := len $items }} {{ $last := sub $count 1 }}
Today's picks ({{ $count }} total) Open Tandoor
{{ if lt $count 1 }}
No recipes.
{{ else }}
{{ range $i, $_ := $items }}{{ end }}
{{ range $r := $items }}{{ $img := $r.String "image" }}{{ $url := $r.String "url" }}{{ $cook := $r.String "cook_url" }}{{ $cooked := $r.Int "cooked_count" }}
{{ if $img }}{{ else }}
No image
{{ end }}
{{ $r.String "name" }}
{{ if gt $cooked 0 }}
Cooked {{ $cooked }}× before
{{ end }}
{{ end }}
{{ if gt $count 1 }} {{ range $i, $_ := $items }}{{ if gt $i 0 }}{{ end }}{{ if lt $i $last }}{{ end }}{{ end }}
{{ range $i, $_ := $items }}{{ end }}
{{ end }}
{{ end }}
- type: split-column max-columns: 2 widgets: # Google Calendar iframe - type: iframe source: https://calendar.google.com/calendar/embed?src=b2884faf3db792ac082a6206057552c79080716efd5f966e169a41fc500e1c1c%40group.calendar.google.com&ctz=Europe%2FBudapest height: 500 title: Calendar # Reddit - type: group title: Reddit widgets: - type: reddit subreddit: psychology show-thumbnails: true - type: reddit subreddit: psychologystudents show-thumbnails: true - type: reddit subreddit: psychologytalk show-thumbnails: true - type: reddit subreddit: psychologists show-thumbnails: true - type: reddit subreddit: psychologyresearch show-thumbnails: true - type: reddit subreddit: academicpsychology show-thumbnails: true - type: reddit subreddit: social_psychology show-thumbnails: true # ---------- RIGHT COLUMN ---------- - size: small widgets: # Calendar Events Widget (Órák & Családi) - type: custom-api title: Events Calendar cache: 5m url: http://glance-helper.glance-system.svc.cluster.local:8000/calendar/events parameters: count: 10 days: 14 template: | {{ $events := .JSON.Array "events" }} {{ $count := len $events }} {{ $showCount := 5 }} {{ $hasMore := gt $count $showCount }}
{{ if lt $count 1 }}
No events in near future
{{ else }} {{ if $hasMore }}{{ end }}
{{ range $i, $e := $events }} {{ $isExtra := ge $i $showCount }} {{ $isAllDay := $e.Bool "is_all_day" }} {{ $calendar := $e.String "calendar" }} {{ $title := $e.String "title" }} {{ $startDate := $e.String "start_date_relative" }} {{ $startTime := $e.String "start_time" }}
{{ $title }}
{{ $calendar }}
{{ $startDate }}
{{ if $isAllDay }}
Whole day
{{ else }}
{{ $startTime }}
{{ end }}
{{ end }}
{{ if $hasMore }} {{ end }} {{ end }}
- type: rss title: News & Feeds limit: 15 collapse-after: 8 feeds: - url: https://telex.hu/rss title: telex.hu limit: 3 - url: https://444.hu/feed title: 444.hu limit: 3 - url: https://444.hu/feed title: 444.hu limit: 3 - url: https://hvg.hu/rss title: hvg.hu limit: 3 - url: http://www.socialpsychology.org/headlines.rss title: socialpsychology.org limit: 3 - url: https://youarenotsosmart.com/feed/ title: youarenotsosmart.com limit: 3 # ==================== TEACHING/LEARNING PAGE ==================== - name: Teaching & Learning slug: teaching width: wide columns: - size: small widgets: - type: iframe css-class: iframe-no-tint source: https://glance-helper.dooplex.hu/notes?key=oplQqnLnJK2vErRVYJpvVUcSDBOSbCHZSbsYY2bwSifgTMfT&user=orsi&accent=e292ff&bgcolor=2d1f3d height: 250 title: Quick Notes - type: bookmarks title: Links for Teaching groups: - links: - title: Plex url: https://plex.dooplex.hu icon: si:plex - type: bookmarks title: Links for Learning groups: - links: - title: Plex url: https://plex.dooplex.hu icon: si:plex # ---------- CENTER COLUMN ---------- - size: full widgets: # Outline Notes iframe - type: iframe source: https://outline.dooplex.hu/collection/tanulok-HUBgG382kV/recent height: 800 title: Recent Notes # Cal.com Booking iframe - type: iframe source: https://booking.dooplex.hu/bookings/upcoming height: 500 title: Upcoming Bookings # ==================== MEDIA PAGE ==================== - name: Media slug: media width: wide columns: - size: small widgets: - type: bookmarks title: Entertainment groups: - links: - title: Plex url: https://plex.dooplex.hu icon: si:plex - title: Immich (Photos) url: https://photos.dooplex.hu icon: si:immich - title: AudioBookshelf url: https://audiobookshelf.dooplex.hu icon: si:audiobookshelf - title: Calibre-Web (eBooks) url: https://books.dooplex.hu icon: si:calibreweb - title: Arcade (Retro Games) url: https://arcade.dooplex.hu icon: si:retroarch - type: bookmarks title: Media Management groups: - links: - title: Sonarr (TV Shows) url: https://sonarr.dooplex.hu icon: si:sonarr - title: Radarr (Movies) url: https://radarr.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/radarr.png - title: RadarrKids url: https://radarrkids.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/radarrkids.png - title: Prowlarr (Indexers) url: https://prowlarr.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/prowlarr.png - title: Seerr (Requests) url: https://seerr.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/seerr.png - size: full widgets: # YouTube Videos - type: videos title: YouTube channels: - UCir93b_ftqInEaDpsWYbo_g #Practical Psychology - @practicalpsychologytips - UCEwsbtepqts935wXykReKxg #CounsellingTutor - @Counsellingtutor1 - UCUdettijNYvLAm4AixZv4RA #SciShow Psych - @SciShowPsych - UClHVl2N3jPEbkNJVx-ItQIQ #HealthyGamerGG - @HealthyGamerGG - UCAvfZQ3r24F-V1JYqn2pfXg #The Psychology Podcast - @ThePsychologyPodcast - UC6Unpcb3T4QijIBs8hPfeyA #Psych Explained - @PsychExplained - UCl8TEoIOnMq_5ntJOYMq-Zg #DrJulie - @DrJulie limit: 12 collapse-after: 6 # Reddit - type: group title: Reddit widgets: - type: reddit subreddit: psychology show-thumbnails: true - type: reddit subreddit: psychologystudents show-thumbnails: true - type: reddit subreddit: psychologytalk show-thumbnails: true - type: reddit subreddit: psychologists show-thumbnails: true - type: reddit subreddit: psychologyresearch show-thumbnails: true - type: reddit subreddit: academicpsychology show-thumbnails: true - type: reddit subreddit: social_psychology show-thumbnails: true - size: small widgets: - type: bookmarks title: Other Apps groups: - links: - title: AdventureLog url: https://adventures.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/adventurelog.png - title: Wanderer url: https://wanderer.dooplex.hu icon: sh:wanderer - title: Plant-it url: https://plantit.dooplex.hu icon: si:leaflet - title: Workout (wger) url: https://workout.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/wger.png - title: Fileshare url: https://fileshare.dooplex.hu icon: si:files - title: Privatebin url: https://privatebin.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/privatebin.png - title: Pastes (OpenGist) url: https://paste.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/opengist.png - title: Zipline url: https://zipline.dooplex.hu icon: https://web.dooplex.hu/static/white-icons/zipline.png # ==================== FILES PAGE ==================== - name: Files slug: files width: wide columns: - size: full widgets: # Filebrowser iframe - type: iframe css-class: iframe-no-tint source: https://orsi-files.dooplex.hu/files/ height: 1200 title: My Files # ==================== NECTCLOUD PAGE ==================== - name: NextCloud slug: nextcloud width: wide columns: - size: full widgets: # Nextcloud iframe - type: iframe css-class: iframe-no-tint source: https://nextcloud.dooplex.hu/apps/files/files height: 1200 title: NextCloud custom.css: | /* ============================================================================= Custom CSS for Orsi's Glance Dashboard Purple theme with background image matching Homepage OPTIMIZED: Duplicates removed, styles consolidated ============================================================================= */ /* ============================================================================= 1. BACKGROUND & BASE TRANSPARENCY ============================================================================= */ html, body { height: 100%; } html { background: url("https://web.dooplex.hu/static/wallpaper-orsi.jpg") center / cover no-repeat fixed !important; } /* Make all Glance containers transparent to show wallpaper */ body, .page, #page-content, .page-content, .content-bounds, .body-content, .page-columns, .page-column { background: transparent !important; } /* Readability veil overlay */ body::before { content: ""; position: fixed; inset: 0; background: rgba(20, 10, 30, 0.25); pointer-events: none; z-index: 0; } body > * { position: relative; z-index: 1; } /* ============================================================================= 2. HEADER & NAVIGATION ============================================================================= */ .header-container, .header, .page-header, .nav, .navigation { background: transparent !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; box-shadow: none !important; border: 0 !important; } .header { min-height: 150px !important; display: flex !important; align-items: flex-end !important; gap: 18px !important; padding: 16px 18px !important; } /* Logo sizing */ .logo img { max-height: 170px !important; height: auto !important; width: auto !important; object-fit: contain !important; } /* Nav alignment and styling (consolidated) */ .header.flex > .nav.flex { height: 100% !important; align-items: flex-end !important; padding-bottom: 14px !important; } .header.flex > .nav.flex > .nav-item { display: flex !important; align-items: flex-end !important; height: 100% !important; padding: 0 14px 18px 14px !important; font-size: 20px !important; line-height: 1 !important; } /* Current tab underline */ .header .nav .nav-item-current::after, .header .nav .nav-item[aria-current="page"]::after { bottom: -6px !important; } /* ============================================================================= 3. WIDGETS - BASE STYLING ============================================================================= */ .widget { background: rgba(45, 31, 61, 0.55) !important; border: 1px solid rgba(226, 146, 255, 0.3) !important; border-radius: 10px !important; backdrop-filter: blur(6px) !important; -webkit-backdrop-filter: blur(6px) !important; } .widget-content { background: transparent !important; } /* Widget headers */ .widget-header { display: flex !important; align-items: center !important; border-bottom-color: rgba(226, 146, 255, 0.25) !important; } .widget-header, .widget-title { color: #e292ff !important; font-weight: 600 !important; } .widget-header .widget-title { display: flex !important; align-items: center !important; line-height: 1.2 !important; } /* ============================================================================= 4. SPLIT-COLUMN WIDGET ============================================================================= */ /* Container keeps glassy effect */ .widget.widget-type-split-column { background: rgba(45, 31, 61, 0.55) !important; border: 1px solid rgba(226, 146, 255, 0.15) !important; backdrop-filter: blur(6px) !important; -webkit-backdrop-filter: blur(6px) !important; } /* Content area - NO TOP PADDING to align headers with other widgets */ .widget.widget-type-split-column > .widget-content { padding: 0 3px 8px 3px !important; } /* Inner widgets should be transparent */ .widget-type-split-column .masonry-column .widget, .widget-type-split-column .widget-content .widget { background: transparent !important; border: none !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; box-shadow: none !important; } /* Masonry layout */ .widget-type-split-column .masonry-column { background: transparent !important; overflow: visible !important; } .widget-type-split-column .masonry { gap: 16px !important; } /* Inner widget headers - compact styling */ .widget-type-split-column .widget .widget-header { display: flex !important; align-items: center !important; justify-content: flex-start !important; min-height: unset !important; height: auto !important; padding: 0 0 8px 0 !important; margin: 0 !important; } .widget-type-split-column .widget .widget-header .widget-title { font-size: 0.9rem !important; line-height: 1 !important; padding: 0 !important; margin: 0 !important; } /* ============================================================================= 5. IFRAME WIDGETS ============================================================================= */ .widget.widget-type-iframe { position: relative !important; overflow: hidden !important; border-radius: 12px !important; } .widget.widget-type-iframe iframe { border-radius: 12px !important; width: 100% !important; border: 0 !important; filter: sepia(0.25) saturate(3) hue-rotate(250deg) brightness(1.02) !important; position: relative !important; z-index: 1 !important; } /* Header above overlay */ .widget.widget-type-iframe > .widget-header { position: relative; z-index: 3; } /* Purple overlay - positioned below header */ .widget.widget-type-iframe::after { content: ""; position: absolute; top: 45px; left: 0; right: 0; bottom: 0; z-index: 2; pointer-events: none; border-radius: 0 0 12px 12px; background: rgba(226, 146, 255, 0.16); } /* Frameless iframes - overlay covers everything */ .widget.widget-type-iframe.widget-content-frameless::after { top: 0; border-radius: 12px; } /* No-tint iframes (disable filter and overlay) */ .widget.iframe-no-tint iframe { filter: none !important; background: transparent !important; } .widget.iframe-no-tint::after { content: none !important; display: none !important; } /* ============================================================================= 6. LINKS & INTERACTIVE ELEMENTS ============================================================================= */ a { color: #e292ff !important; } a:hover { color: #f0b8ff !important; } /* Bookmark items */ .bookmark-link { background-color: rgba(60, 40, 80, 0.6) !important; border-radius: 8px !important; transition: background-color 0.2s ease !important; } .bookmark-link:hover { background-color: rgba(80, 50, 110, 0.8) !important; } /* RSS feed items */ .rss-item, .feed-item { background-color: rgba(60, 40, 80, 0.5) !important; border-radius: 6px !important; margin-bottom: 4px !important; } /* Video thumbnails */ .video-item, .videos-item { background-color: rgba(60, 40, 80, 0.5) !important; border-radius: 8px !important; } /* ============================================================================= 7. EXPAND/COLLAPSE BUTTONS ============================================================================= */ .expand-toggle-button, .expand-toggle-button.container-expanded { background: transparent !important; box-shadow: none !important; border: 0 !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; margin-top: 8px !important; padding: 10px 12px !important; border-top: 1px solid rgba(255,255,255,0.08) !important; color: rgba(255,255,255,0.75) !important; } .expand-toggle-button:hover { color: rgba(255,255,255,0.95) !important; } .expand-toggle-button::before, .expand-toggle-button::after, .expand-toggle-button-icon::before, .expand-toggle-button-icon::after { background: transparent !important; box-shadow: none !important; } /* ============================================================================= 8. SCROLLBAR STYLING ============================================================================= */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: rgba(45, 31, 61, 0.5); } ::-webkit-scrollbar-thumb { background: rgba(226, 146, 255, 0.5); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: rgba(226, 146, 255, 0.7); } /* ============================================================================= 9. IDŐKÉP WEATHER WIDGET ============================================================================= */ .idokep { display: flex; flex-direction: column; gap: 10px; } .idokep-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; } .idokep-top-left { display: flex; align-items: center; gap: 10px; } .idokep-icon { width: 42px; height: 42px; opacity: 0.95; } .idokep-temp { font-size: 42px; font-weight: 700; letter-spacing: 0.5px; line-height: 1; } .idokep-top-right { text-align: right; } .idokep-loc { opacity: 0.85; font-weight: 600; } .idokep-src { opacity: 0.6; font-size: 12px; margin-top: 2px; } .idokep-src a { opacity: 0.9; } .idokep-hourly { display: flex; gap: 6px; padding-top: 4px; } .idokep-hour { width: 48px; display: flex; flex-direction: column; align-items: center; gap: 6px; opacity: 0.9; } .idokep-hour-time { font-size: 12px; opacity: 0.65; } .idokep-hour-icon { width: 26px; height: 26px; } .idokep-hour-temp { font-weight: 700; } .idokep-muted { opacity: 0.6; font-size: 12px; padding: 4px 0; } .idokep-daily { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; } .idokep-row { display: grid; grid-template-columns: 44px 26px 36px 1fr 36px; gap: 10px; align-items: center; } .idokep-dow { display: grid; grid-template-columns: 22px 1fr; column-gap: 6px; align-items: center; opacity: 0.8; font-weight: 700; } .idokep-daynum { text-align: right; opacity: 0.75; font-variant-numeric: tabular-nums; } .idokep-dayicon img { width: 22px; height: 22px; opacity: 0.95; } .idokep-min, .idokep-max { text-align: right; font-weight: 700; opacity: 0.8; } /* Temperature bar */ .idokep-bar { position: relative; height: 10px; } .idokep-bar-track { position: absolute; inset: 0; border-radius: 999px; background: rgba(255,255,255,0.10); } .idokep-bar-fill { position: absolute; top: 0; bottom: 0; border-radius: 999px; overflow: hidden; box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset; left: var(--l, 0%); width: var(--w, 0%); } .idokep-bar-gradient { position: absolute; top: 0; bottom: 0; width: var(--gw, 100%); margin-left: var(--ml, 0%); background: linear-gradient(90deg, #ffffff var(--s-wht), #60a5fa var(--s-blu), #a78bfa var(--s-pur), #fb7185 var(--s-pnk), #ef4444 var(--s-red) ); } --- apiVersion: apps/v1 kind: Deployment metadata: name: glance-orsi namespace: glance-system labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi app.kubernetes.io/version: "v0.8.4" annotations: reloader.stakater.com/auto: "true" spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi template: metadata: labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi app.kubernetes.io/version: "v0.8.4" spec: securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 initContainers: - name: build-bookmarks-index image: mikefarah/yq:4.50.1 securityContext: runAsUser: 1000 runAsGroup: 1000 allowPrivilegeEscalation: false command: ["/bin/sh", "-c"] args: - | set -eux which yq yq --version mkdir -p /app/assets yq eval -o=json ' [ .pages[] as $p | $p.columns[]? as $c | $c.widgets[]? as $w | select($w.type == "bookmarks") | $w.groups[]? as $g | $g.links[]? | select(.url != null and .url != "") | { "title": (.title // .url), "url": .url, "page": ($p.name // ""), "widget": ($w.title // ""), "group": ($g.title // "") } ] | unique_by(.url) ' /config/glance.yml > /app/assets/bookmarks.json echo "Bookmarks indexed: $(yq eval -r 'length' /app/assets/bookmarks.json)" volumeMounts: - name: config mountPath: /config readOnly: true - name: assets mountPath: /app/assets containers: - name: glance image: glanceapp/glance:v0.8.4 imagePullPolicy: IfNotPresent env: - name: TZ value: "Europe/Budapest" ports: - name: http containerPort: 8080 protocol: TCP livenessProbe: httpGet: path: / port: http initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: / port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 resources: requests: cpu: 10m memory: 32Mi limits: cpu: 200m memory: 128Mi volumeMounts: - name: assets mountPath: /app/assets - name: config mountPath: /app/config/glance.yml subPath: glance.yml - name: config mountPath: /app/assets/custom.css subPath: custom.css volumes: - name: config configMap: name: glance-config - name: assets emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: glance-orsi namespace: glance-system labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi spec: type: ClusterIP ports: - name: http port: 8080 targetPort: http protocol: TCP selector: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi --- # Ingress WITH Authentik proxy authentication # Update the auth-url annotation with your actual outpost service name after creating in Authentik apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: glance-orsi namespace: glance-system labels: app.kubernetes.io/name: glance-orsi app.kubernetes.io/instance: glance-orsi annotations: cert-manager.io/cluster-issuer: letsencrypt-prod external-dns.alpha.kubernetes.io/hostname: orsi.dooplex.hu nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" nginx.ingress.kubernetes.io/proxy-buffers-number: "4" nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "32k" # Authentik Forward Auth annotations # TODO: Update 'glance-home-outpost' with your actual outpost name after creating in Authentik nginx.ingress.kubernetes.io/auth-url: http://ak-outpost-glance-orsi-outpost.auth-system.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx nginx.ingress.kubernetes.io/auth-signin: https://orsi.dooplex.hu/outpost.goauthentik.io/start?rd=$escaped_request_uri nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email nginx.ingress.kubernetes.io/auth-snippet: | proxy_set_header X-Forwarded-Host $http_host; nginx.ingress.kubernetes.io/configuration-snippet: | set $geo_allowed 0; if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } if ($geoip2_country_code = "HU") { set $geo_allowed 1; } if ($geoip2_country_code = "GB") { set $geo_allowed 1; } if ($geo_allowed = 0) { return 403 "Access restricted to Hungary"; } spec: ingressClassName: nginx-internal rules: - host: orsi.dooplex.hu http: paths: - path: / pathType: Prefix backend: service: name: glance-orsi port: number: 8080 tls: - hosts: - orsi.dooplex.hu secretName: glance-orsi-tls ---