Merge pull request #3 from wahyd4/upgrade-docker-images-2026-06

 chore: upgrade Docker images batch — June 2026
This commit is contained in:
2026-06-01 16:57:31 +10:00
committed by GitHub
11 changed files with 675 additions and 7 deletions
+2 -1
View File
@@ -84,7 +84,8 @@ spec:
spec:
containers:
- name: pocket-id-oauth-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
# Updated: v7.6.0 -> v7.15.2 (minor bump within v7.x, low risk)
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
args:
- --config=/etc/oauth2-proxy/oauth2_proxy.cfg
env:
+2 -1
View File
@@ -29,7 +29,8 @@ spec:
effect: NoSchedule
containers:
- name: qdrant
image: mirror.gcr.io/qdrant/qdrant:v1.16-unprivileged
# Updated: v1.16-unprivileged -> v1.18.1-unprivileged (minor bump, low risk)
image: mirror.gcr.io/qdrant/qdrant:v1.18.1-unprivileged
ports:
- containerPort: 6333
- containerPort: 6334
+2 -1
View File
@@ -47,7 +47,8 @@ spec:
spec:
containers:
- name: n8n
image: mirror.gcr.io/n8nio/n8n:2.15.0
# Updated: 2.15.0 -> 2.23.1 (minor bump, low-medium risk; review n8n changelog for workflow-level breaking changes)
image: mirror.gcr.io/n8nio/n8n:2.23.1
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 0
+2 -1
View File
@@ -58,7 +58,8 @@ spec:
value: "true"
- name: address
value: 192.168.1.10
image: ghcr.io/kube-vip/kube-vip:v0.4.4
# Updated: v0.4.4 -> v0.9.2 (conservative upgrade within v0.x; v0->v1 major jump too risky for critical infra)
image: ghcr.io/kube-vip/kube-vip:v0.9.2
imagePullPolicy: IfNotPresent
name: kube-vip
resources: {}
+2 -1
View File
@@ -31,7 +31,8 @@ spec:
containers:
- name: jackett
# https://hub.docker.com/r/linuxserver/jackett/tags
image: mirror.gcr.io/linuxserver/jackett:0.24.1124
# Updated: 0.24.1124 -> 0.24.1985 (patch bump, low risk)
image: mirror.gcr.io/linuxserver/jackett:0.24.1985
securityContext:
runAsUser: 0
imagePullPolicy: IfNotPresent
+2 -1
View File
@@ -57,7 +57,8 @@ spec:
cpu: 200m
memory: 256Mi
- name: qbit
image: mirror.gcr.io/linuxserver/qbittorrent:version-5.1.2-r4
# Updated: version-5.1.2-r4 -> version-5.2.1_v2.0.12 (major: 5.1->5.2, medium risk; stable release with libtorrent v2.0.12)
image: mirror.gcr.io/linuxserver/qbittorrent:version-5.2.1_v2.0.12
securityContext:
runAsUser: 0
imagePullPolicy: IfNotPresent
+2 -1
View File
@@ -11,7 +11,8 @@ spec:
containers:
- name: backup
# Same image as in /etc/kubernetes/manifests/etcd.yaml
image: k8s.gcr.io/etcd:3.5.1-0
# Updated: 3.5.1-0 -> 3.5.30-0 (patch bump within 3.5.x, low risk)
image: k8s.gcr.io/etcd:3.5.30-0
env:
- name: ETCDCTL_API
value: "3"
+251
View File
@@ -0,0 +1,251 @@
#!/usr/bin/env python3
"""Script to query Docker registries for latest versions."""
import subprocess
import json
import re
import sys
import time
# Active images with pinned versions (not commented out, not :latest, not :edge)
IMAGES = [
("dockerhub", "library/caddy", "2", "mirror.gcr.io/caddy:2"),
("dockerhub", "linuxserver/jackett", "0.24.1124", "mirror.gcr.io/linuxserver/jackett:0.24.1124"),
("dockerhub", "linuxserver/qbittorrent", "version-5.1.2-r4", "mirror.gcr.io/linuxserver/qbittorrent:version-5.1.2-r4"),
("dockerhub", "n8nio/n8n", "2.15.0", "mirror.gcr.io/n8nio/n8n:2.15.0"),
("dockerhub", "library/postgres", "14", "mirror.gcr.io/postgres:14"),
("dockerhub", "qdrant/qdrant", "v1.16-unprivileged", "mirror.gcr.io/qdrant/qdrant:v1.16-unprivileged"),
("ghcr", "kube-vip/kube-vip", "v0.4.4", "ghcr.io/kube-vip/kube-vip:v0.4.4"),
("quay", "oauth2-proxy/oauth2-proxy", "v7.6.0", "quay.io/oauth2-proxy/oauth2-proxy:v7.6.0"),
]
def safe_version_sort_key(tag_str):
parts = tag_str.lstrip('v').split('.')
nums = []
for p in parts:
try:
nums.append(int(re.match(r'(\d+)', p).group(1)))
except (ValueError, AttributeError, TypeError):
nums.append(0)
return nums
def fetch_dockerhub_tag_details(image_name, max_items=200):
try:
result = subprocess.run(
["curl", "-s", "-L", "-f",
f"https://hub.docker.com/v2/repositories/{image_name}/tags?page_size={max_items}&page=1"],
capture_output=True, text=True, timeout=20
)
if result.returncode != 0:
return None, f"curl failed: {result.stderr[:300]}"
data = json.loads(result.stdout)
tags_detail = []
for tag_data in data.get("results", []):
tag_name = tag_data.get("name", "")
if tag_name and not tag_name.startswith("sha256:"):
tags_detail.append({
"name": tag_name,
"last_updated": tag_data.get("last_updated", ""),
})
return tags_detail, None
except Exception as e:
return None, str(e)
def fetch_ghcr_tags(image_name):
url = f"https://ghcr.io/v2/{image_name}/tags/list"
result = subprocess.run(
["curl", "-s", "-L", "-f", url],
capture_output=True, text=True, timeout=20
)
if result.returncode != 0:
return None, f"GHCR API failed: {result.stderr[:300]}"
try:
data = json.loads(result.stdout)
tags = data.get("tags", [])
return [t for t in tags if not t.startswith("sha256:")], None
except Exception as e:
return None, str(e)
def fetch_quay_tags(image_name):
url = f"https://quay.io/api/v1/repository/{image_name}?includeTags=true&limit=100"
result = subprocess.run(
["curl", "-s", "-L", "-f", url],
capture_output=True, text=True, timeout=20
)
if result.returncode != 0:
return None, f"Quay API failed: {result.stderr[:300]}"
try:
data = json.loads(result.stdout)
tags = list(data.get("tags", {}).keys())
return tags, None
except Exception as e:
return None, str(e)
results = []
for registry_type, image_name, current_tag, display_name in IMAGES:
print(f"\n{'='*70}")
print(f"CHECKING: {display_name}")
print(f"{'='*70}")
tags_detail = None
err = None
time.sleep(0.5)
if registry_type == "dockerhub":
tags_detail, err = fetch_dockerhub_tag_details(image_name)
if err:
print(f" ❌ Error: {err}")
results.append((display_name, current_tag, "ERROR", err))
continue
if not tags_detail:
print(f" ❌ No tags found")
results.append((display_name, current_tag, "ERROR", "no tags found"))
continue
all_tag_names = [t["name"] for t in tags_detail]
print(f" Total tags: {len(all_tag_names)}")
# --- caddy ---
if image_name == "library/caddy":
# Filter for semver like v2.8.x, v2.9.x etc.
specific = [t for t in all_tag_names
if re.match(r'^v?\d+\.\d+\.\d+$', t)]
specific.sort(key=safe_version_sort_key, reverse=True)
print(f" Version tags: {specific[:15]}")
latest_stable = specific[0] if specific else "2"
print(f" → Latest stable version: {latest_stable}")
# '2' is a major-version alias that tracks latest 2.x
results.append((display_name, current_tag, latest_stable,
f"Tag '2' tracks latest 2.x ({latest_stable})"))
# --- jackett ---
elif image_name == "linuxserver/jackett":
# Jackett uses plain semver tags like 0.24.1124
jackett_stable = [t for t in all_tag_names
if re.match(r'^\d+\.\d+\.\d+$', t)]
jackett_stable.sort(key=safe_version_sort_key, reverse=True)
print(f" Stable tags (latest first): {jackett_stable[:10]}")
latest_stable = jackett_stable[0] if jackett_stable else "unknown"
print(f" → Latest stable version: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
# --- qbittorrent ---
elif image_name == "linuxserver/qbittorrent":
qbit_tags = [t for t in all_tag_names if re.match(r'version-', t)]
print(f" 'version-*' tags: {qbit_tags[:15]}")
qbit_tags.sort(key=safe_version_sort_key, reverse=True)
latest_stable = qbit_tags[0] if qbit_tags else "unknown"
print(f" → Latest 'version-*' tag: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
# --- n8n ---
elif image_name == "n8nio/n8n":
n8n_tags = [t for t in all_tag_names
if re.match(r'^\d+\.\d+\.\d+$', t)
and not re.search(r'(alpha|beta|rc|dev|nightly)', t, re.I)]
n8n_tags.sort(key=safe_version_sort_key, reverse=True)
print(f" Stable tags (latest first): {n8n_tags[:10]}")
latest_stable = n8n_tags[0] if n8n_tags else "unknown"
print(f" → Latest stable version: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
# --- postgres ---
elif image_name == "library/postgres":
major_tags = [t for t in all_tag_names
if re.match(r'^\d+$', t) and int(t) >= 10]
major_tags.sort(key=int, reverse=True)
print(f" Major version tags: {major_tags[:10]}")
latest_stable = major_tags[0] if major_tags else "unknown"
print(f" → Latest major version: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
# --- qdrant ---
elif image_name == "qdrant/qdrant":
# Unprivileged tags
unpriv = [t for t in all_tag_names if 'unprivileged' in t.lower()]
unpriv.sort(key=safe_version_sort_key, reverse=True)
print(f" Unprivileged tags: {unpriv[:15]}")
# Non-unprivileged stable
stable = [t for t in all_tag_names
if re.match(r'^v?\d+\.\d+', t)
and 'unprivileged' not in t.lower()
and not re.search(r'(alpha|beta|rc|dev|nightly)', t, re.I)]
stable.sort(key=safe_version_sort_key, reverse=True)
print(f" Stable version tags: {stable[:10]}")
latest_stable = unpriv[0] if unpriv else "unknown"
print(f" → Latest unprivileged: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
else:
stable = [t for t in all_tag_names
if re.match(r'^v?\d+\.\d+', t)
and not re.search(r'(alpha|beta|rc|dev|nightly)', t, re.I)]
stable.sort(key=safe_version_sort_key, reverse=True)
latest_stable = stable[0] if stable else "unknown"
results.append((display_name, current_tag, latest_stable, ""))
elif registry_type == "ghcr":
all_tags, err = fetch_ghcr_tags(image_name)
if err:
print(f" ❌ Error: {err}")
results.append((display_name, current_tag, "ERROR", err))
continue
stable = [t for t in all_tags
if re.match(r'^v?\d+\.\d+', t)
and not re.search(r'(alpha|beta|rc|dev|nightly)', t, re.I)]
stable.sort(key=safe_version_sort_key, reverse=True)
latest_stable = stable[0] if stable else all_tags[0] if all_tags else "unknown"
print(f" Tags: {all_tags[:20]}")
print(f" → Latest stable version: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
elif registry_type == "quay":
all_tags, err = fetch_quay_tags(image_name)
if err:
print(f" ❌ Error: {err}")
results.append((display_name, current_tag, "ERROR", err))
continue
stable = [t for t in all_tags
if re.match(r'^v?\d+\.\d+', t)
and not re.search(r'(alpha|beta|rc|dev|nightly)', t, re.I)]
stable.sort(key=safe_version_sort_key, reverse=True)
latest_stable = stable[0] if stable else all_tags[0] if all_tags else "unknown"
print(f" Tags (sample): {all_tags[:20]}")
print(f" → Latest stable version: {latest_stable}")
results.append((display_name, current_tag, latest_stable, ""))
# Print summary
print("\n\n" + "="*70)
print("SUMMARY")
print("="*70)
for display_name, current_tag, latest_tag, note in results:
print(f"\n {display_name}")
print(f" Current: {current_tag}")
if latest_tag == "ERROR":
print(f" Status: ❌ {note}")
continue
# Normalize for comparison
cur = current_tag.lstrip('v').lower()
lat = latest_tag.lstrip('v').lower()
if cur == lat:
print(f" Latest: {latest_tag}")
else:
print(f" Latest: {latest_tag}")
print(f" Status: ⚠ UPDATE AVAILABLE")
print()
+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
"""Extract all Docker image references from K8s YAML manifests."""
import os
import re
import sys
import fnmatch
REPO = "/home/ai-bot/Code/home-docker"
EXCLUDE_DIRS = ["archive", "telephone", "legacy-docker-compose", ".github", ".git"]
# Patterns to skip: :latest, no tag, or templated variables like ${...}
SKIP_TAG_PATTERNS = [
re.compile(r'^latest$'),
re.compile(r'^\$\{?.*\}?$'),
]
def should_exclude(path):
rel = os.path.relpath(path, REPO)
parts = rel.split(os.sep)
for ex in EXCLUDE_DIRS:
if ex in parts:
return True
return False
def extract_images(content):
"""Extract image references from YAML content (both image: field and image: line)."""
images = set()
for line in content.splitlines():
# Match image: field in YAML
m = re.match(r'^\s*image:\s*["\']?(.+?)["\']?\s*$', line)
if not m:
# Also match inline: image: "..."
m = re.search(r'image:\s*["\']?([a-zA-Z0-9._/-]+(?::[a-zA-Z0-9._-]+)?)["\']?', line)
if m:
img = m.group(1).strip()
# Skip if it contains env var patterns
if '${' in img or '$(' in img or img.startswith('$'):
continue
images.add(img)
continue
img = m.group(1).strip().rstrip(',')
# Handle YAML multiline/complex values
img = img.strip('"').strip("'")
# Skip if it contains env var patterns
if '${' in img or '$(' in img or img.startswith('$'):
continue
# Skip empty
if not img:
continue
images.add(img)
return images
def parse_image(img_str):
"""Parse image string into (registy_prefix, image_name, tag)."""
img_str = img_str.strip()
# Check for explicit registry (docker.io, ghcr.io, quay.io, etc.)
registry = ""
if '/' in img_str:
parts = img_str.split('/')
# Check if first part looks like a registry (contains . or :port)
if len(parts) >= 2 and ('.' in parts[0] or ':' in parts[0] or parts[0] == 'localhost' or parts[0] == 'docker.io'):
registry = parts[0]
image_path = '/'.join(parts[1:])
else:
image_path = img_str
else:
image_path = img_str
# Split tag
if ':' in image_path:
name, tag = image_path.rsplit(':', 1)
else:
name = image_path
tag = 'latest'
# Skip :latest and no-tag (we only care about pinned versions)
if tag == 'latest' or not tag:
return None
# Skip if tag looks like a variable
if re.match(r'^\$\{', tag) or tag.startswith('$'):
return None
# Full qualified name with registry prefix for lookups
if registry:
full_name = f"{registry}/{name}"
elif '/' not in name:
full_name = f"docker.io/library/{name}"
else:
# Default to docker.io
full_name = f"docker.io/{name}"
return {
'raw': img_str,
'registry': registry or 'docker.io',
'name': name,
'tag': tag,
'full_name': full_name,
'lookup_name': f"{name}" if not registry else f"{registry}/{name}",
}
def main():
all_images = {}
files_with_images = {}
for root, dirs, files in os.walk(REPO):
# Skip excluded dirs
dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS and not d.startswith('.')]
for fname in files:
if not (fname.endswith('.yaml') or fname.endswith('.yml')):
continue
fpath = os.path.join(root, fname)
if should_exclude(fpath):
continue
# Skip non-manifest files
rel = os.path.relpath(fpath, REPO)
if rel.startswith('legacy-docker-compose'):
continue
try:
with open(fpath, 'r') as f:
content = f.read()
except Exception as e:
print(f"Error reading {fpath}: {e}", file=sys.stderr)
continue
images = extract_images(content)
if images:
files_with_images[rel] = images
for img_str in images:
parsed = parse_image(img_str)
if parsed:
if img_str not in all_images:
all_images[img_str] = parsed
all_images[img_str]['files'] = []
all_images[img_str]['files'].append(rel)
# Print results
print("=" * 80)
print("DOCKER IMAGES FOUND IN K8S MANIFESTS")
print("=" * 80)
for img_str in sorted(all_images.keys()):
info = all_images[img_str]
print(f"\n--- {img_str} ---")
print(f" Registry: {info['registry']}")
print(f" Image Name: {info['name']}")
print(f" Tag: {info['tag']}")
print(f" Lookup Name: {info['lookup_name']}")
print(f" Files: {', '.join(info['files'])}")
print("\n" + "=" * 80)
print(f"Total unique images: {len(all_images)}")
# Output as JSON for further processing
import json
output = {}
for img_str, info in sorted(all_images.items()):
output[img_str] = {
'registry': info['registry'],
'image_name': info['name'],
'tag': info['tag'],
'lookup_name': info['lookup_name'],
'files': info['files'],
}
json_path = os.path.join(REPO, 'scripts', 'images.json')
with open(json_path, 'w') as f:
json.dump(output, f, indent=2)
print(f"\nJSON output written to: {json_path}")
if __name__ == '__main__':
main()
+112
View File
@@ -0,0 +1,112 @@
# Docker 镜像版本检查报告
## 仓库: /home/ai-bot/Code/home-docker
## 检查时间: 2026-06-01
---
## 一、检查范围
- 排除了 `archive/``telephone/` 目录
- 排除了 `legacy-docker-compose/` 目录(非 K8s 资源)
- 排除了 `:.latest`、无标签(默认 `:latest`)和移动标签(如 `:edge`
- 排除了注释掉的代码块
---
## 二、活跃的固定版本镜像
共发现 **9 个** 活跃的固定版本镜像。
---
### 1. `mirror.gcr.io/caddy:2` → `caddy:2.11.3` ✓ (标签 '2' 是 major version 别名)
- **文件**: `home-apps/home-proxy.yaml`, `media/static-file.yaml`
- **说明**: `caddy:2` 是 major version 标签,会自动跟踪最新的 2.x 版本(当前最新为 2.11.3
- **建议**: 无需更新,`caddy:2` 会自动跟随 2.x 最新
### 2. `mirror.gcr.io/linuxserver/jackett:0.24.1124` → `jackett:0.24.1985` ⚠️ 需要更新
- **文件**: `media/jackett.yaml`
- **当前版本**: 0.24.1124
- **最新版本**: 0.24.1985
- **差距**: 落后 861 个构建版本
### 3. `mirror.gcr.io/linuxserver/qbittorrent:version-5.1.2-r4` → `version-5.2.1_v2.0.12` ⚠️ 需要更新
- **文件**: `media/media.yaml`
- **当前版本**: version-5.1.2-r4
- **最新版本**: version-5.2.1_v2.0.12
- **差距**: 从 qBittorrent 5.1.2 升级到 5.2.1
### 4. `mirror.gcr.io/n8nio/n8n:2.15.0` → `n8n:2.23.1` ⚠️ 需要更新
- **文件**: `home-apps/n8n.yaml`
- **当前版本**: 2.15.0
- **最新版本**: 2.23.1
- **差距**: 落后 9 个小版本
### 5. `mirror.gcr.io/postgres:14` → `postgres:18` ⚠️ 可能需要考虑更新
- **文件**: `on-demand/once-postgres-backjobs.yaml`, `backup-jobs/backup-cronjobs.yaml`
- **当前版本**: 14PostgreSQL 14,已停止更新/维护)
- **最新版本**: 18PostgreSQL 18,最新 active 版本)
- **说明**: 此镜像仅用于 pg_dump 备份命令,版本兼容性较好,但仍建议考虑升级
- **PG 支持状态**: PostgreSQL 14 于 2025-11-13 停止接收修复
### 6. `mirror.gcr.io/qdrant/qdrant:v1.16-unprivileged` → `v1.18.1-unprivileged` ⚠️ 需要更新
- **文件**: `db/qdrant.yaml`
- **当前版本**: v1.16-unprivileged
- **最新版本**: v1.18.1-unprivileged
- **差距**: 落后 2 个 major 版本
### 7. `ghcr.io/kube-vip/kube-vip:v0.4.4` → `v1.2.0` ⚠️ 需要更新
- **文件**: `kube-vip/daemonset.yaml`
- **当前版本**: v0.4.4
- **最新 GHCR 可用**: v1.2.0GitHub release
- **最新 v0.9.x 可用**: v0.9.2
- **差距**: 落后 0.4.4 → 1.2.0 共 28+ 个版本
- **⚠️ 注意**: 这涉及 Kubernetes 集群 VIP 管理组件,升级需谨慎
### 8. `k8s.gcr.io/etcd:3.5.1-0` → `3.5.30-0` ⚠️ 需要更新
- **文件**: `on-demand/once-etcd-job.yaml`
- **当前版本**: 3.5.1-0
- **最新 3.5.x 版本**: 3.5.30-0
- **差距**: 落后 3.5.1 → 3.5.3029 个小版本)
- **说明**: 该镜像仅用于备份 Jobetcdctl snapshot),工具兼容性较好
### 9. `quay.io/oauth2-proxy/oauth2-proxy:v7.6.0` → `v7.15.2` ⚠️ 需要更新
- **文件**: `adhoc-config/oauth2-proxy.yaml`
- **当前版本**: v7.6.0
- **最新版本**: v7.15.2
- **差距**: 落后 7.6.0 → 7.15.29 个小版本)
---
## 三、跳过的镜像(不需要检查)
| 镜像 | 原因 |
|------|------|
| `mirror.gcr.io/oznu/cloudflare-ddns` | 无标签(默认 :latest |
| `czerkwonk/ping_exporter` | 无标签(默认 :latest |
| `mirror.gcr.io/qmcgaw/gluetun:latest` | :latest 标签 |
| `ghcr.io/wahyd4/hey-search:latest` | :latest 标签 |
| `mirror.gcr.io/wahyd4/aria2-ui:edge` | 移动标签 |
| `tikazyq/crawlab:latest` | :latest 标签 |
| `alpine:3` | 注释掉的代码块 |
| `ghcr.io/wonderfall/nextcloud:24` | 注释掉的代码块 |
| `docker.elastic.co/beats/elastic-agent:8.0.1` | 注释掉的代码块 |
| `k8s.gcr.io/etcd:3.5.1-0` (in backup-cronjobs.yaml) | 注释掉的代码块 |
---
## 四、需要更新的镜像汇总
```
镜像名:当前标签 → 最新可用标签 状态
─────────────────────────────────────────────────────────────────
linuxserver/jackett:0.24.1124 → 0.24.1985 ⚠️ 需要更新
linuxserver/qbittorrent:version-5.1.2-r4 → version-5.2.1_v2.0.12 ⚠️ 需要更新
n8nio/n8n:2.15.0 → 2.23.1 ⚠️ 需要更新
postgres:14 → 18 ⚠️ 建议更新
qdrant/qdrant:v1.16-unprivileged → v1.18.1-unprivileged ⚠️ 需要更新
kube-vip/kube-vip:v0.4.4 → v1.2.0 ⚠️ 需要更新
k8s.gcr.io/etcd:3.5.1-0 → 3.5.30-0 ⚠️ 需要更新
oauth2-proxy/oauth2-proxy:v7.6.0 → v7.15.2 ⚠️ 需要更新
caddy:2 (major version alias, tracks 2.x latest) ✓ 已最新
```
+122
View File
@@ -0,0 +1,122 @@
{
"alpine:3": {
"registry": "docker.io",
"image_name": "alpine",
"tag": "3",
"lookup_name": "alpine",
"files": [
"media/media.yaml"
]
},
"docker.elastic.co/beats/elastic-agent:8.0.1": {
"registry": "docker.elastic.co",
"image_name": "beats/elastic-agent",
"tag": "8.0.1",
"lookup_name": "docker.elastic.co/beats/elastic-agent",
"files": [
"es/agent.yaml"
]
},
"ghcr.io/kube-vip/kube-vip:v0.4.4": {
"registry": "ghcr.io",
"image_name": "kube-vip/kube-vip",
"tag": "v0.4.4",
"lookup_name": "ghcr.io/kube-vip/kube-vip",
"files": [
"kube-vip/daemonset.yaml"
]
},
"ghcr.io/wonderfall/nextcloud:24": {
"registry": "ghcr.io",
"image_name": "wonderfall/nextcloud",
"tag": "24",
"lookup_name": "ghcr.io/wonderfall/nextcloud",
"files": [
"media/media.yaml"
]
},
"k8s.gcr.io/etcd:3.5.1-0": {
"registry": "k8s.gcr.io",
"image_name": "etcd",
"tag": "3.5.1-0",
"lookup_name": "k8s.gcr.io/etcd",
"files": [
"on-demand/once-etcd-job.yaml",
"backup-jobs/backup-cronjobs.yaml"
]
},
"mirror.gcr.io/caddy:2": {
"registry": "mirror.gcr.io",
"image_name": "caddy",
"tag": "2",
"lookup_name": "mirror.gcr.io/caddy",
"files": [
"home-apps/home-proxy.yaml",
"media/static-file.yaml"
]
},
"mirror.gcr.io/linuxserver/jackett:0.24.1124": {
"registry": "mirror.gcr.io",
"image_name": "linuxserver/jackett",
"tag": "0.24.1124",
"lookup_name": "mirror.gcr.io/linuxserver/jackett",
"files": [
"media/jackett.yaml"
]
},
"mirror.gcr.io/linuxserver/qbittorrent:version-5.1.2-r4": {
"registry": "mirror.gcr.io",
"image_name": "linuxserver/qbittorrent",
"tag": "version-5.1.2-r4",
"lookup_name": "mirror.gcr.io/linuxserver/qbittorrent",
"files": [
"media/media.yaml"
]
},
"mirror.gcr.io/n8nio/n8n:2.15.0": {
"registry": "mirror.gcr.io",
"image_name": "n8nio/n8n",
"tag": "2.15.0",
"lookup_name": "mirror.gcr.io/n8nio/n8n",
"files": [
"home-apps/n8n.yaml"
]
},
"mirror.gcr.io/postgres:14": {
"registry": "mirror.gcr.io",
"image_name": "postgres",
"tag": "14",
"lookup_name": "mirror.gcr.io/postgres",
"files": [
"on-demand/once-postgres-backjobs.yaml",
"backup-jobs/backup-cronjobs.yaml"
]
},
"mirror.gcr.io/qdrant/qdrant:v1.16-unprivileged": {
"registry": "mirror.gcr.io",
"image_name": "qdrant/qdrant",
"tag": "v1.16-unprivileged",
"lookup_name": "mirror.gcr.io/qdrant/qdrant",
"files": [
"db/qdrant.yaml"
]
},
"mirror.gcr.io/wahyd4/aria2-ui:edge": {
"registry": "mirror.gcr.io",
"image_name": "wahyd4/aria2-ui",
"tag": "edge",
"lookup_name": "mirror.gcr.io/wahyd4/aria2-ui",
"files": [
"media/media.yaml"
]
},
"quay.io/oauth2-proxy/oauth2-proxy:v7.6.0": {
"registry": "quay.io",
"image_name": "oauth2-proxy/oauth2-proxy",
"tag": "v7.6.0",
"lookup_name": "quay.io/oauth2-proxy/oauth2-proxy",
"files": [
"adhoc-config/oauth2-proxy.yaml"
]
}
}