Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41e4a72836 | ||
|
|
5f483e7090 | ||
|
|
aad73bf9e8 | ||
|
|
4093888749 | ||
|
|
50a27873c1 | ||
|
|
3be9556eb4
|
||
|
|
e952c8161a
|
||
|
|
8d665a7f34
|
||
|
|
6e4f8c06b4
|
||
|
|
8cd122d50d | ||
|
|
f531393481 | ||
|
|
ce43b34ce0 | ||
|
|
ddb755e7e5 | ||
|
|
682a5b949f | ||
|
|
6c72acc59e | ||
|
|
b381c7b012 | ||
|
|
a3c12855fe | ||
|
|
bbd374590e | ||
|
|
fd72b415c5 | ||
|
|
97f6aeb538 |
No files matched your search
@@ -1,80 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Local regressions only: kubectl is mocked and Docker is used for config parsing.
|
|
||||||
set -euo pipefail
|
|
||||||
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
||||||
scratch="$(mktemp -d)"
|
|
||||||
trap 'rm -rf "$scratch"' EXIT
|
|
||||||
|
|
||||||
mkdir -p "$scratch/repo/app" "$scratch/repo/postgres" "$scratch/repo/netbird" "$scratch/repo/renovate"
|
|
||||||
git -C "$scratch/repo" init -q
|
|
||||||
for file in app/compose.yaml postgres/shared-compose.yaml netbird/client.compose.yaml renovate/renovate-compose.yaml; do
|
|
||||||
touch "$scratch/repo/$file"
|
|
||||||
done
|
|
||||||
git -C "$scratch/repo" add .
|
|
||||||
# shellcheck source=../workflows/compose-lint.sh
|
|
||||||
source "$repo/.gitea/workflows/compose-lint.sh"
|
|
||||||
actual="$(cd "$scratch/repo" && compose_files)"
|
|
||||||
expected=$'app/compose.yaml\nnetbird/client.compose.yaml\npostgres/shared-compose.yaml\nrenovate/renovate-compose.yaml'
|
|
||||||
[ "$actual" = "$expected" ] || { echo 'Compose discovery missed a file' >&2; exit 1; }
|
|
||||||
|
|
||||||
cat >"$scratch/compose.yaml" <<'YAML'
|
|
||||||
services:
|
|
||||||
example:
|
|
||||||
image: busybox:1.37.0
|
|
||||||
environment:
|
|
||||||
REQUIRED: ${HOMELAB_TEST_REQUIRED:?required for this regression}
|
|
||||||
YAML
|
|
||||||
unset HOMELAB_TEST_REQUIRED
|
|
||||||
if validate_compose_file "$scratch/compose.yaml" >"$scratch/config.log" 2>&1; then
|
|
||||||
echo 'Full Compose validation accepted a missing variable' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
grep -q 'required for this regression' "$scratch/config.log"
|
|
||||||
HOMELAB_TEST_REQUIRED=present validate_compose_file "$scratch/compose.yaml"
|
|
||||||
|
|
||||||
cat >"$scratch/resources.json" <<'JSON'
|
|
||||||
{"kind":"List","items":[
|
|
||||||
{"kind":"Deployment","metadata":{"namespace":"app"},"spec":{"template":{"spec":{
|
|
||||||
"containers":[{"envFrom":[{"secretRef":{"name":"credentials"}},{"secretRef":{"name":"optional","optional":true}}],"env":[{"valueFrom":{"secretKeyRef":{"name":"credentials","key":"password"}}}]}],
|
|
||||||
"initContainers":[{"envFrom":[{"secretRef":{"name":"init"}}]}],
|
|
||||||
"imagePullSecrets":[{"name":"registry"}],
|
|
||||||
"volumes":[{"secret":{"secretName":"mounted"}},{"projected":{"sources":[{"secret":{"name":"projected"}},{"secret":{"name":"optional-projected","optional":true}}]}}]
|
|
||||||
}}}},
|
|
||||||
{"kind":"CronJob","metadata":{},"spec":{"jobTemplate":{"spec":{"template":{"spec":{"containers":[{"envFrom":[{"secretRef":{"name":"cron"}}]}]}}}}}},
|
|
||||||
{"kind":"IngressRoute","metadata":{"namespace":"app"},"spec":{"tls":{"secretName":"controller-issued-tls"}}}
|
|
||||||
]}
|
|
||||||
JSON
|
|
||||||
actual="$(jq -r -f "$repo/.gitea/workflows/secret-references.jq" "$scratch/resources.json" | sort)"
|
|
||||||
expected=$'app credentials\napp init\napp mounted\napp projected\napp registry\ndefault cron'
|
|
||||||
[ "$actual" = "$expected" ] || { echo "Unexpected Secret references: $actual" >&2; exit 1; }
|
|
||||||
|
|
||||||
REPO="$repo"
|
|
||||||
# shellcheck source=../workflows/deploy-lib.sh
|
|
||||||
source "$repo/.gitea/workflows/deploy-lib.sh"
|
|
||||||
K8S_MANIFESTS=("$scratch/resources.json")
|
|
||||||
KUSTOMIZE_APPS=()
|
|
||||||
# No live cluster access. Reject credentials in app even if they exist elsewhere.
|
|
||||||
kubectl() {
|
|
||||||
case "$1" in
|
|
||||||
create) cat "$scratch/resources.json" ;;
|
|
||||||
get)
|
|
||||||
if [ "$3" = credentials ] && [ "$5" = app ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*) echo "Unexpected kubectl invocation: $*" >&2; return 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
if check_referenced_secrets >"$scratch/secrets.log"; then
|
|
||||||
echo 'Namespace-scoped Secret check accepted a missing Secret' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
grep -q 'MISSING OR UNREADABLE: app/credentials' "$scratch/secrets.log"
|
|
||||||
# API/rendering errors must not produce an empty reference list and pass.
|
|
||||||
kubectl() { return 1; }
|
|
||||||
if check_referenced_secrets >"$scratch/secrets.log"; then
|
|
||||||
echo 'Secret check accepted a failed manifest render' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
printf '%s\n' 'Deploy validation regressions passed.'
|
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
tools_dir="$(bash .gitea/workflows/install-ci-tools.sh shellcheck jq)"
|
tools_dir="$(bash .gitea/workflows/install-ci-tools.sh shellcheck)"
|
||||||
export PATH="$tools_dir:$PATH"
|
export PATH="$tools_dir:$PATH"
|
||||||
mapfile -t scripts < <(
|
mapfile -t scripts < <(
|
||||||
git ls-files '*.sh' ':(glob)**/*.bash'
|
git ls-files '*.sh' ':(glob)**/*.bash'
|
||||||
@@ -98,7 +98,6 @@ jobs:
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
shellcheck --external-sources --source-path=SCRIPTDIR --severity=style "${scripts[@]}"
|
shellcheck --external-sources --source-path=SCRIPTDIR --severity=style "${scripts[@]}"
|
||||||
bash .gitea/tests/deploy-validation.sh
|
|
||||||
|
|
||||||
lint-prettier:
|
lint-prettier:
|
||||||
runs-on: [self-hosted, linux, arch, homelab]
|
runs-on: [self-hosted, linux, arch, homelab]
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
# All committed Compose files, including the ones deploy never starts.
|
# All committed Compose files, including the ones deploy never starts.
|
||||||
compose_files() {
|
compose_files() {
|
||||||
git ls-files \
|
git ls-files \
|
||||||
'*compose.yaml' '*compose.yml'
|
'*/compose.yaml' '*/compose.yml' 'compose.yaml' 'compose.yml' \
|
||||||
|
'*/docker-compose.yaml' '*/docker-compose.yml'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prints the flags that turn `docker compose config` into the general check.
|
# Prints the flags that turn `docker compose config` into the general check.
|
||||||
|
|||||||
@@ -31,16 +31,6 @@ warn() {
|
|||||||
echo "WARNING: $*" >&2
|
echo "WARNING: $*" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prune needs the complete desired set in one invocation. Per-file pruning
|
|
||||||
# treats resources from the other files as absent and can delete them.
|
|
||||||
check_prune_mode() {
|
|
||||||
if [ "$APPLY_PRUNE" = "true" ]; then
|
|
||||||
echo "ERROR: APPLY_PRUNE=true is unsupported by the per-file deploy loop." >&2
|
|
||||||
echo "Disable it; remove obsolete resources explicitly after review." >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
collect_k8s() {
|
collect_k8s() {
|
||||||
git -C "$REPO" ls-files -- "$1" \
|
git -C "$REPO" ls-files -- "$1" \
|
||||||
| grep -E '\.ya?ml$' \
|
| grep -E '\.ya?ml$' \
|
||||||
@@ -696,53 +686,27 @@ stage_preflight() {
|
|||||||
git -C "$REPO" reset --hard "$target"
|
git -C "$REPO" reset --hard "$target"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Required pod Secrets, scoped to the resource namespace. TLS route Secrets are
|
|
||||||
# created by cert-manager and are not prerequisites for applying a Certificate.
|
|
||||||
check_referenced_secrets() {
|
|
||||||
local m k objects refs extracted ns name
|
|
||||||
local missing=()
|
|
||||||
refs=""
|
|
||||||
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
|
|
||||||
objects="$(kubectl create --dry-run=client --validate=false -f "$m" -o json)" || return 1
|
|
||||||
extracted="$(printf '%s' "$objects" | jq -r -f "$REPO/.gitea/workflows/secret-references.jq")" || return 1
|
|
||||||
refs+="$extracted"$'\n'
|
|
||||||
done
|
|
||||||
for k in ${KUSTOMIZE_APPS[@]+"${KUSTOMIZE_APPS[@]}"}; do
|
|
||||||
objects="$(kubectl kustomize "$k" | kubectl create --dry-run=client --validate=false -f - -o json)" || return 1
|
|
||||||
extracted="$(printf '%s' "$objects" | jq -r -f "$REPO/.gitea/workflows/secret-references.jq")" || return 1
|
|
||||||
refs+="$extracted"$'\n'
|
|
||||||
done
|
|
||||||
while read -r ns name; do
|
|
||||||
[ -n "${name:-}" ] || continue
|
|
||||||
if kubectl get secret "$name" -n "$ns" -o name >/dev/null 2>&1; then
|
|
||||||
echo " ok: $ns/$name"
|
|
||||||
else
|
|
||||||
echo " MISSING OR UNREADABLE: $ns/$name"
|
|
||||||
missing+=("$ns/$name")
|
|
||||||
fi
|
|
||||||
done < <(printf '%s' "$refs" | sort -u)
|
|
||||||
if [ "${#missing[@]}" -gt 0 ]; then
|
|
||||||
echo "ERROR: required pod Secrets are missing or unreadable:"
|
|
||||||
printf ' - %s\n' "${missing[@]}"
|
|
||||||
echo "Create them in the listed namespaces from the service's secret example."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stage_validate() {
|
stage_validate() {
|
||||||
check_prune_mode || return 1
|
|
||||||
cd "$REPO"
|
cd "$REPO"
|
||||||
select_manifests
|
select_manifests
|
||||||
local m k cf
|
local m k cf
|
||||||
# The deploy host has the local .env and secret files. Resolve them here so
|
# Compose .env files and secret files are gitignored by design, so the
|
||||||
# missing configuration fails before either apply job changes workloads.
|
# workstation never has real values for the inactive stacks. This stage only
|
||||||
# CI keeps the structure-only check for inactive stacks.
|
# runs the full check on active stacks; the general structure check for every
|
||||||
|
# committed Compose file (active or not) lives in the ci workflow, which has no
|
||||||
|
# .env at all.
|
||||||
|
#
|
||||||
|
# Active stacks are still validated with interpolation and env-file resolution
|
||||||
|
# off, so required-variable guards (:?) and missing local files do not fail the
|
||||||
|
# deploy. Normalization and consistency checks stay enabled.
|
||||||
# shellcheck source=compose-lint.sh
|
# shellcheck source=compose-lint.sh
|
||||||
source "$REPO/.gitea/workflows/compose-lint.sh"
|
source "$REPO/.gitea/workflows/compose-lint.sh"
|
||||||
|
local compose_validate_flags=()
|
||||||
|
mapfile -t compose_validate_flags < <(compose_safe_flags)
|
||||||
log "Validate compose stacks"
|
log "Validate compose stacks"
|
||||||
for cf in ${COMPOSE_STACKS[@]+"${COMPOSE_STACKS[@]}"}; do
|
for cf in ${COMPOSE_STACKS[@]+"${COMPOSE_STACKS[@]}"}; do
|
||||||
echo " config: $cf"
|
echo " config: $cf"
|
||||||
validate_compose_file "$cf"
|
validate_compose_file "$cf" ${compose_validate_flags[@]+"${compose_validate_flags[@]}"}
|
||||||
done
|
done
|
||||||
log "Validate k8s manifests (kubectl dry-run=client)"
|
log "Validate k8s manifests (kubectl dry-run=client)"
|
||||||
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
|
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
|
||||||
@@ -760,20 +724,48 @@ stage_validate() {
|
|||||||
done
|
done
|
||||||
log "Checking referenced Secrets exist"
|
log "Checking referenced Secrets exist"
|
||||||
echo " (deploy never applies *secret*.yaml; create missing ones manually)"
|
echo " (deploy never applies *secret*.yaml; create missing ones manually)"
|
||||||
check_referenced_secrets
|
local ref_secrets=() missing_secrets=() all_secrets s
|
||||||
|
if [ "${#K8S_MANIFESTS[@]}" -gt 0 ]; then
|
||||||
|
while IFS= read -r s; do
|
||||||
|
[ -n "$s" ] && ref_secrets+=("$s")
|
||||||
|
done < <(
|
||||||
|
{
|
||||||
|
grep -h -A1 -E 'secretRef:|secretKeyRef:' "${K8S_MANIFESTS[@]}" 2>/dev/null || true
|
||||||
|
grep -h -E 'secretName:' "${K8S_MANIFESTS[@]}" 2>/dev/null || true
|
||||||
|
} | grep -E 'name:' | sed -E 's/.*name:[[:space:]]*//' | tr -d '"'"'"' "'"'" | sed -E 's/[[:space:]]*#.*//' | awk 'NF' | sort -u || true
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
all_secrets="$(kubectl get secrets -A --no-headers -o custom-columns=:metadata.name 2>/dev/null || true)"
|
||||||
|
for s in ${ref_secrets[@]+"${ref_secrets[@]}"}; do
|
||||||
|
if printf '%s\n' "$all_secrets" | grep -qx "$s"; then
|
||||||
|
echo " ok: $s"
|
||||||
|
else
|
||||||
|
echo " MISSING: $s"
|
||||||
|
missing_secrets+=("$s")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "${#missing_secrets[@]}" -gt 0 ]; then
|
||||||
|
echo "ERROR: ${#missing_secrets[@]} referenced Secret(s) not found in the cluster:"
|
||||||
|
printf ' - %s\n' "${missing_secrets[@]}"
|
||||||
|
echo "Create them manually from the laptop, e.g.:"
|
||||||
|
echo " kubectl apply -f SERVICE/k8s/secrets.yaml # see SERVICE/k8s/secrets.yaml.example"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
stage_apply_k8s() {
|
stage_apply_k8s() {
|
||||||
check_prune_mode || return 1
|
|
||||||
cd "$REPO"
|
cd "$REPO"
|
||||||
select_manifests >/dev/null
|
select_manifests >/dev/null
|
||||||
local ns_files=() other_files=() m k
|
local ns_files=() other_files=() m k prune_opts=()
|
||||||
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
|
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
|
||||||
case "$m" in
|
case "$m" in
|
||||||
*/namespace.y?ml) ns_files+=("$m") ;;
|
*/namespace.y?ml) ns_files+=("$m") ;;
|
||||||
*) other_files+=("$m") ;;
|
*) other_files+=("$m") ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
if [ "$APPLY_PRUNE" = "true" ]; then
|
||||||
|
prune_opts=(--prune -l app.kubernetes.io/managed-by=homelab-deploy)
|
||||||
|
fi
|
||||||
|
|
||||||
# Record what is about to change, and publish it for the verify job, before
|
# Record what is about to change, and publish it for the verify job, before
|
||||||
# the first apply. Both are fatal on failure: see snapshot_dir.
|
# the first apply. Both are fatal on failure: see snapshot_dir.
|
||||||
@@ -798,7 +790,7 @@ stage_apply_k8s() {
|
|||||||
if [ "${#other_files[@]}" -gt 0 ]; then
|
if [ "${#other_files[@]}" -gt 0 ]; then
|
||||||
log "Applying resources (${#other_files[@]} files, our images pinned to digests)"
|
log "Applying resources (${#other_files[@]} files, our images pinned to digests)"
|
||||||
for m in "${other_files[@]}"; do
|
for m in "${other_files[@]}"; do
|
||||||
if ! render_pinned <"$m" | kubectl apply -f -; then
|
if ! render_pinned <"$m" | kubectl apply "${prune_opts[@]}" -f -; then
|
||||||
echo "ERROR: apply failed for ${m#"$REPO"/}" >&2
|
echo "ERROR: apply failed for ${m#"$REPO"/}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -120,15 +120,6 @@ install_shellcheck() {
|
|||||||
rm -rf "$tmp"
|
rm -rf "$tmp"
|
||||||
}
|
}
|
||||||
|
|
||||||
install_jq() {
|
|
||||||
if at_version jq "${JQ_VERSION}"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fetch "https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/jq-linux-${goarch}" \
|
|
||||||
"$BIN_DIR/jq"
|
|
||||||
chmod 0755 "$BIN_DIR/jq"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_uv() {
|
install_uv() {
|
||||||
if at_version uv "${UV_VERSION}"; then
|
if at_version uv "${UV_VERSION}"; then
|
||||||
return 0
|
return 0
|
||||||
@@ -245,7 +236,6 @@ for tool in "${wanted[@]}"; do
|
|||||||
case "$tool" in
|
case "$tool" in
|
||||||
kubeconform) install_kubeconform ;;
|
kubeconform) install_kubeconform ;;
|
||||||
shellcheck) install_shellcheck ;;
|
shellcheck) install_shellcheck ;;
|
||||||
jq) install_jq ;;
|
|
||||||
actionlint) install_actionlint ;;
|
actionlint) install_actionlint ;;
|
||||||
prettier) install_prettier ;;
|
prettier) install_prettier ;;
|
||||||
ruff) install_ruff ;;
|
ruff) install_ruff ;;
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# kubectl emits a List for files containing multiple resources.
|
|
||||||
(if .kind == "List" then .items[] else . end)
|
|
||||||
| (.metadata.namespace // "default") as $ns
|
|
||||||
| [
|
|
||||||
(.. | objects
|
|
||||||
| (.secretRef? // empty), (.secretKeyRef? // empty), (.secret? // empty)
|
|
||||||
| select(.optional != true)
|
|
||||||
| .name // .secretName // empty),
|
|
||||||
(.. | objects | .imagePullSecrets[]?.name)
|
|
||||||
]
|
|
||||||
| unique[]
|
|
||||||
| select(. != null and . != "")
|
|
||||||
| "\($ns) \(.)"
|
|
||||||
@@ -31,6 +31,3 @@ UV_VERSION="0.12.17"
|
|||||||
# so the tree that gets tested is the tree that gets built. Renovate keeps this
|
# so the tree that gets tested is the tree that gets built. Renovate keeps this
|
||||||
# in step with the Dockerfile's node: tag via the "node runtime" group.
|
# in step with the Dockerfile's node: tag via the "node runtime" group.
|
||||||
NODE_VERSION="22.23.3"
|
NODE_VERSION="22.23.3"
|
||||||
|
|
||||||
# Secret-reference regression tests parse rendered Kubernetes objects.
|
|
||||||
JQ_VERSION="1.8.1"
|
|
||||||
@@ -51,8 +51,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: adguard-deployment
|
name: adguard-deployment
|
||||||
namespace: adguard
|
namespace: adguard
|
||||||
spec:
|
spec:
|
||||||
@@ -66,6 +64,8 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: adguard
|
app: adguard
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: adguard
|
- name: adguard
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: authentik-server-deployment
|
name: authentik-server-deployment
|
||||||
namespace: authentik
|
namespace: authentik
|
||||||
spec:
|
spec:
|
||||||
@@ -65,8 +63,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: authentik-worker-deployment
|
name: authentik-worker-deployment
|
||||||
namespace: authentik
|
namespace: authentik
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: cfddns
|
name: cfddns
|
||||||
labels:
|
labels:
|
||||||
app: cfddns
|
app: cfddns
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: checkmk-deployment
|
name: checkmk-deployment
|
||||||
namespace: checkmk
|
namespace: checkmk
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: cloudflared
|
name: cloudflared
|
||||||
labels:
|
labels:
|
||||||
app: cloudflared
|
app: cloudflared
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: convertx-deployment
|
name: convertx-deployment
|
||||||
namespace: converters
|
namespace: converters
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: session-keeper
|
name: session-keeper
|
||||||
namespace: edu-master
|
namespace: edu-master
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: webinar-checker
|
name: webinar-checker
|
||||||
namespace: edu-master
|
namespace: edu-master
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: gitea-deployment
|
name: gitea-deployment
|
||||||
namespace: gitea
|
namespace: gitea
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: glance-deployment
|
name: glance-deployment
|
||||||
namespace: glance
|
namespace: glance
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
SECRET_ENCRYPTION_KEY="REPLACE_ME"
|
|
||||||
TZ="Europe/Bratislava"
|
|
||||||
PUID="1000"
|
|
||||||
PGID="1000"
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
services:
|
|
||||||
homarr:
|
|
||||||
container_name: homarr
|
|
||||||
image: ghcr.io/homarr-labs/homarr:v2.1.2
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ./appdata:/appdata
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
- ./kubeconfig:/app/config/kubeconfig:ro
|
|
||||||
env_file: .env
|
|
||||||
ports:
|
|
||||||
- 80:7575
|
|
||||||
- 81:3000
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ:-Europe/Bratislava}
|
|
||||||
- TURBO_TELEMETRY_DISABLED=1
|
|
||||||
- KUBECONFIG=/app/config/kubeconfig
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.services.homarr.loadbalancer.server.port=7575"
|
|
||||||
|
|
||||||
# Prod Router
|
|
||||||
- "traefik.http.routers.homarr.rule=Host(`homarr.forust.xyz`)"
|
|
||||||
- "traefik.http.routers.homarr.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.homarr.tls.certresolver=letsencrypt"
|
|
||||||
# Local Router
|
|
||||||
- "traefik.http.routers.homarr-local.rule=Host(`homarr.workstation.internal`)"
|
|
||||||
- "traefik.http.routers.homarr-local.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.homarr-local.tls=true"
|
|
||||||
# Dev Router
|
|
||||||
- "traefik.http.routers.homarr-dev.rule=Host(`homarr.gigaforust.internal`)"
|
|
||||||
- "traefik.http.routers.homarr-dev.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.homarr-dev.tls=true"
|
|
||||||
networks:
|
|
||||||
- proxy
|
|
||||||
networks:
|
|
||||||
proxy:
|
|
||||||
external: true
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# apiVersion: cert-manager.io/v1
|
|
||||||
# kind: Certificate
|
|
||||||
# metadata:
|
|
||||||
# name: home-prod-tls
|
|
||||||
# namespace: homarr
|
|
||||||
# spec:
|
|
||||||
# secretName: home-prod-tls
|
|
||||||
# dnsNames:
|
|
||||||
# - home.forust.xyz
|
|
||||||
# issuerRef:
|
|
||||||
# name: letsencrypt-prod
|
|
||||||
# kind: ClusterIssuer
|
|
||||||
# ---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: internal-wildcard-tls
|
|
||||||
namespace: homarr
|
|
||||||
spec:
|
|
||||||
secretName: internal-wildcard-tls
|
|
||||||
dnsNames:
|
|
||||||
- "*.workstation.internal"
|
|
||||||
- "*.gigaforust.internal"
|
|
||||||
- workstation.internal
|
|
||||||
- gigaforust.internal
|
|
||||||
issuerRef:
|
|
||||||
name: internal-ca
|
|
||||||
kind: ClusterIssuer
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: homarr-config
|
|
||||||
namespace: homarr
|
|
||||||
data:
|
|
||||||
TZ: "Europe/Bratislava"
|
|
||||||
TURBO_TELEMETRY_DISABLED: "1"
|
|
||||||
ENABLE_KUBERNETES: "true"
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: homarr-service
|
|
||||||
namespace: homarr
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: homarr
|
|
||||||
ports:
|
|
||||||
- port: 7575
|
|
||||||
targetPort: 7575
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: homarr-deployment
|
|
||||||
namespace: homarr
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: homarr
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: homarr
|
|
||||||
spec:
|
|
||||||
serviceAccountName: homarr
|
|
||||||
containers:
|
|
||||||
- name: homarr
|
|
||||||
image: ghcr.io/homarr-labs/homarr:v2.1.2
|
|
||||||
envFrom:
|
|
||||||
- configMapRef:
|
|
||||||
name: homarr-config
|
|
||||||
- secretRef:
|
|
||||||
name: homarr-secrets
|
|
||||||
ports:
|
|
||||||
- containerPort: 7575
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: 7575
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 6
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: 7575
|
|
||||||
initialDelaySeconds: 60
|
|
||||||
periodSeconds: 30
|
|
||||||
failureThreshold: 3
|
|
||||||
volumeMounts:
|
|
||||||
- name: homarr-data
|
|
||||||
mountPath: /appdata
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: "250m"
|
|
||||||
memory: "350Mi"
|
|
||||||
limits:
|
|
||||||
cpu: "500m"
|
|
||||||
memory: "700Mi"
|
|
||||||
volumes:
|
|
||||||
- name: homarr-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: homarr-pvc
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: homarr-pvc
|
|
||||||
namespace: homarr
|
|
||||||
spec:
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 2Gi
|
|
||||||
volumeMode: Filesystem
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# apiVersion: traefik.io/v1alpha1
|
|
||||||
# kind: IngressRoute
|
|
||||||
# metadata:
|
|
||||||
# name: homarr-prod
|
|
||||||
# namespace: homarr
|
|
||||||
# spec:
|
|
||||||
# entryPoints:
|
|
||||||
# - websecure
|
|
||||||
# routes:
|
|
||||||
# - match: Host(`home.forust.xyz`)
|
|
||||||
# kind: Rule
|
|
||||||
# services:
|
|
||||||
# - name: homarr-service
|
|
||||||
# port: 7575
|
|
||||||
# tls:
|
|
||||||
# secretName: home-prod-tls
|
|
||||||
# ---
|
|
||||||
apiVersion: traefik.io/v1alpha1
|
|
||||||
kind: IngressRoute
|
|
||||||
metadata:
|
|
||||||
name: homarr-local
|
|
||||||
namespace: homarr
|
|
||||||
spec:
|
|
||||||
entryPoints:
|
|
||||||
- websecure
|
|
||||||
routes:
|
|
||||||
- match: Host(`home.workstation.internal`) || Host(`home.gigaforust.internal`)
|
|
||||||
kind: Rule
|
|
||||||
services:
|
|
||||||
- name: homarr-service
|
|
||||||
port: 7575
|
|
||||||
tls:
|
|
||||||
secretName: internal-wildcard-tls
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: homarr
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: homarr
|
|
||||||
namespace: homarr
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: homarr-readonly
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
- services
|
|
||||||
- endpoints
|
|
||||||
- namespaces
|
|
||||||
- nodes
|
|
||||||
- configmaps
|
|
||||||
- persistentvolumeclaims
|
|
||||||
- events
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources:
|
|
||||||
- deployments
|
|
||||||
- statefulsets
|
|
||||||
- daemonsets
|
|
||||||
- replicasets
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["networking.k8s.io"]
|
|
||||||
resources:
|
|
||||||
- ingresses
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["traefik.io"]
|
|
||||||
resources:
|
|
||||||
- ingressroutes
|
|
||||||
- ingressroutetcps
|
|
||||||
- ingressrouteudps
|
|
||||||
- middlewares
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["metrics.k8s.io"]
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
- nodes
|
|
||||||
verbs: ["get", "list"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: homarr-readonly
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: homarr-readonly
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: homarr
|
|
||||||
namespace: homarr
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: homarr-secrets
|
|
||||||
namespace: homarr
|
|
||||||
type: Opaque
|
|
||||||
stringData:
|
|
||||||
# openssl rand -hex 32
|
|
||||||
SECRET_ENCRYPTION_KEY: "REPLACE_ME"
|
|
||||||
@@ -14,8 +14,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: immich-deployment
|
name: immich-deployment
|
||||||
namespace: immich
|
namespace: immich
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: immich-machine-learning-deployment
|
name: immich-machine-learning-deployment
|
||||||
namespace: immich
|
namespace: immich
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: immich-valkey
|
name: immich-valkey
|
||||||
namespace: immich
|
namespace: immich
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: kener-deployment
|
name: kener-deployment
|
||||||
namespace: kener
|
namespace: kener
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: metube-deployment
|
name: metube-deployment
|
||||||
namespace: metube
|
namespace: metube
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
n8n:
|
n8n:
|
||||||
image: docker.n8n.io/n8nio/n8n:2.42.3
|
image: docker.n8n.io/n8nio/n8n:2.42.2
|
||||||
container_name: n8n
|
container_name: n8n
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
+1
-3
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: n8n-deployment
|
name: n8n-deployment
|
||||||
namespace: n8n
|
namespace: n8n
|
||||||
spec:
|
spec:
|
||||||
@@ -31,7 +29,7 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: n8n
|
- name: n8n
|
||||||
image: docker.n8n.io/n8nio/n8n:2.42.3
|
image: docker.n8n.io/n8nio/n8n:2.42.2
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: n8n-config
|
name: n8n-config
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netbird-server-deployment
|
name: netbird-server-deployment
|
||||||
namespace: netbird
|
namespace: netbird
|
||||||
spec:
|
spec:
|
||||||
@@ -128,8 +126,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netbird-dashboard-deployment
|
name: netbird-dashboard-deployment
|
||||||
namespace: netbird
|
namespace: netbird
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netbox-deployment
|
name: netbox-deployment
|
||||||
namespace: netbox
|
namespace: netbox
|
||||||
labels:
|
labels:
|
||||||
@@ -120,8 +118,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netbox-worker-deployment
|
name: netbox-worker-deployment
|
||||||
namespace: netbox
|
namespace: netbox
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netbox-valkey
|
name: netbox-valkey
|
||||||
namespace: netbox
|
namespace: netbox
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: netronome-deployment
|
name: netronome-deployment
|
||||||
namespace: netronome
|
namespace: netronome
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
Whitespace-only changes.
@@ -1,17 +1,11 @@
|
|||||||
# Pinned chart: stakater/reloader 2.2.17 (app v1.4.22).
|
# Pinned chart: stakater/reloader 2.2.17 (app v1.4.22).
|
||||||
# Deployed by the deploy workflow, namespace reloader.
|
# Deployed by the deploy workflow, namespace reloader.
|
||||||
# Restarts pods when a ConfigMap or Secret they consume changes. Opt-in per workload
|
# Restarts pods when a ConfigMap or Secret they consume changes. Opt-in per workload
|
||||||
# via the reloader.stakater.com/auto: "true" workload annotation; watchGlobally because
|
# via the reloader.stakater.com/auto: "true" pod annotation; watchGlobally because
|
||||||
# the workloads that need it are spread across a few dozen namespaces.
|
# the workloads that need it are spread across a few dozen namespaces.
|
||||||
|
|
||||||
reloader:
|
reloader:
|
||||||
watchGlobally: true
|
watchGlobally: true
|
||||||
# Only opted-in workloads are restarted. Keep scheduled jobs on their schedule.
|
|
||||||
autoReloadAll: false
|
|
||||||
ignoreJobs: true
|
|
||||||
ignoreCronJobs: true
|
|
||||||
# Change pod-template annotations rather than injecting STAKATER_* env vars.
|
|
||||||
reloadStrategy: annotations
|
|
||||||
|
|
||||||
deployment:
|
deployment:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
|||||||
@@ -218,34 +218,6 @@ data:
|
|||||||
"matchUpdateTypes": ["patch"],
|
"matchUpdateTypes": ["patch"],
|
||||||
"groupName": "all patch updates",
|
"groupName": "all patch updates",
|
||||||
"groupSlug": "all-patch"
|
"groupSlug": "all-patch"
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.",
|
|
||||||
"matchDatasources": ["docker"],
|
|
||||||
"matchPackageNames": ["python"],
|
|
||||||
"groupName": "python base image",
|
|
||||||
"groupSlug": "python",
|
|
||||||
"automerge": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Rolling/floating tags (streaming stack, nextcloud beta, kubectl latest) - never automerge, every bump is a manual review. Placed last so automerge:false wins over the shared digest/patch rule.",
|
|
||||||
"matchDatasources": ["docker"],
|
|
||||||
"matchPackageNames": [
|
|
||||||
"lscr.io/linuxserver/jellyfin",
|
|
||||||
"lscr.io/linuxserver/qbittorrent",
|
|
||||||
"lscr.io/linuxserver/sonarr",
|
|
||||||
"lscr.io/linuxserver/radarr",
|
|
||||||
"lscr.io/linuxserver/prowlarr",
|
|
||||||
"lscr.io/linuxserver/bazarr",
|
|
||||||
"ghcr.io/seerr-team/seerr",
|
|
||||||
"fallenbagel/jellyseerr",
|
|
||||||
"ghcr.io/lampac-nextgen/lampac",
|
|
||||||
"ghcr.io/nextcloud-releases/all-in-one",
|
|
||||||
"alpine/kubectl"
|
|
||||||
],
|
|
||||||
"groupName": "floating images - manual",
|
|
||||||
"groupSlug": "floating-manual",
|
|
||||||
"automerge": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ spec:
|
|||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
containers:
|
containers:
|
||||||
- name: renovate
|
- name: renovate
|
||||||
image: renovate/renovate:44.136.0
|
image: renovate/renovate:44.132.2
|
||||||
env:
|
env:
|
||||||
- name: RENOVATE_PLATFORM
|
- name: RENOVATE_PLATFORM
|
||||||
value: gitea
|
value: gitea
|
||||||
|
|||||||
@@ -207,34 +207,6 @@
|
|||||||
"matchUpdateTypes": ["patch"],
|
"matchUpdateTypes": ["patch"],
|
||||||
"groupName": "all patch updates",
|
"groupName": "all patch updates",
|
||||||
"groupSlug": "all-patch"
|
"groupSlug": "all-patch"
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.",
|
|
||||||
"matchDatasources": ["docker"],
|
|
||||||
"matchPackageNames": ["python"],
|
|
||||||
"groupName": "python base image",
|
|
||||||
"groupSlug": "python",
|
|
||||||
"automerge": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Rolling/floating tags (streaming stack, nextcloud beta, kubectl latest) - never automerge, every bump is a manual review. Placed last so automerge:false wins over the shared digest/patch rule.",
|
|
||||||
"matchDatasources": ["docker"],
|
|
||||||
"matchPackageNames": [
|
|
||||||
"lscr.io/linuxserver/jellyfin",
|
|
||||||
"lscr.io/linuxserver/qbittorrent",
|
|
||||||
"lscr.io/linuxserver/sonarr",
|
|
||||||
"lscr.io/linuxserver/radarr",
|
|
||||||
"lscr.io/linuxserver/prowlarr",
|
|
||||||
"lscr.io/linuxserver/bazarr",
|
|
||||||
"ghcr.io/seerr-team/seerr",
|
|
||||||
"fallenbagel/jellyseerr",
|
|
||||||
"ghcr.io/lampac-nextgen/lampac",
|
|
||||||
"ghcr.io/nextcloud-releases/all-in-one",
|
|
||||||
"alpine/kubectl"
|
|
||||||
],
|
|
||||||
"groupName": "floating images - manual",
|
|
||||||
"groupSlug": "floating-manual",
|
|
||||||
"automerge": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: searxng-deployment
|
name: searxng-deployment
|
||||||
namespace: searxng
|
namespace: searxng
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
+36
-7
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
jellyfin:
|
jellyfin:
|
||||||
image: lscr.io/linuxserver/jellyfin:version-12.1ubu2604
|
image: lscr.io/linuxserver/jellyfin:latest
|
||||||
container_name: jellyfin
|
container_name: jellyfin
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -19,7 +19,7 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
qbittorrent:
|
qbittorrent:
|
||||||
image: lscr.io/linuxserver/qbittorrent:5.2.4
|
image: lscr.io/linuxserver/qbittorrent:latest
|
||||||
container_name: qbittorrent
|
container_name: qbittorrent
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -38,7 +38,7 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
sonarr:
|
sonarr:
|
||||||
image: lscr.io/linuxserver/sonarr:4.0.20
|
image: lscr.io/linuxserver/sonarr:latest
|
||||||
container_name: sonarr
|
container_name: sonarr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -55,7 +55,7 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
radarr:
|
radarr:
|
||||||
image: lscr.io/linuxserver/radarr:6.4.4
|
image: lscr.io/linuxserver/radarr:latest
|
||||||
container_name: radarr
|
container_name: radarr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -72,7 +72,7 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
prowlarr:
|
prowlarr:
|
||||||
image: lscr.io/linuxserver/prowlarr:2.6.5
|
image: lscr.io/linuxserver/prowlarr:latest
|
||||||
container_name: prowlarr
|
container_name: prowlarr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -87,8 +87,9 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
jellyseerr:
|
jellyseerr:
|
||||||
image: fallenbagel/jellyseerr:latest
|
image: ghcr.io/seerr-team/seerr:latest
|
||||||
container_name: jellyseerr
|
container_name: jellyseerr
|
||||||
|
init: true
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- TZ=${TZ:-Europe/Berlin}
|
- TZ=${TZ:-Europe/Berlin}
|
||||||
@@ -100,7 +101,7 @@ services:
|
|||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
bazarr:
|
bazarr:
|
||||||
image: lscr.io/linuxserver/bazarr:1.6.2
|
image: lscr.io/linuxserver/bazarr:latest
|
||||||
container_name: bazarr
|
container_name: bazarr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -116,6 +117,31 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- streaming
|
- streaming
|
||||||
|
|
||||||
|
lampac:
|
||||||
|
image: ghcr.io/lampac-nextgen/lampac:latest
|
||||||
|
container_name: lampac
|
||||||
|
restart: unless-stopped
|
||||||
|
shm_size: 1024mb
|
||||||
|
# Restore persisted passwd/init.conf from seed volume before start,
|
||||||
|
# so config survives container recreation (upstream entrypoint is
|
||||||
|
# ENTRYPOINT ["dotnet", "Core.dll"], WORKDIR /lampac, USER lampac).
|
||||||
|
entrypoint:
|
||||||
|
[
|
||||||
|
"/bin/sh",
|
||||||
|
"-c",
|
||||||
|
"if [ -f /seed/passwd ] && [ ! -f /lampac/passwd ]; then cp /seed/passwd /lampac/passwd; fi; if [ -f /seed/init.conf ] && [ ! -f /lampac/init.conf ]; then cp /seed/init.conf /lampac/init.conf; fi; exec /usr/share/dotnet/dotnet Core.dll",
|
||||||
|
]
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ:-Europe/Berlin}
|
||||||
|
volumes:
|
||||||
|
- lampac-seed:/seed
|
||||||
|
- lampac-cache:/lampac/cache
|
||||||
|
- lampac-db:/lampac/database
|
||||||
|
ports:
|
||||||
|
- "19118:9118"
|
||||||
|
networks:
|
||||||
|
- streaming
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
jellyfin-cfg:
|
jellyfin-cfg:
|
||||||
qbittorrent-cfg:
|
qbittorrent-cfg:
|
||||||
@@ -124,6 +150,9 @@ volumes:
|
|||||||
prowlarr-cfg:
|
prowlarr-cfg:
|
||||||
jellyseerr-cfg:
|
jellyseerr-cfg:
|
||||||
bazarr-cfg:
|
bazarr-cfg:
|
||||||
|
lampac-seed:
|
||||||
|
lampac-cache:
|
||||||
|
lampac-db:
|
||||||
downloads:
|
downloads:
|
||||||
movies:
|
movies:
|
||||||
tv:
|
tv:
|
||||||
|
|||||||
@@ -13,19 +13,32 @@ spec:
|
|||||||
issuerRef:
|
issuerRef:
|
||||||
name: internal-ca
|
name: internal-ca
|
||||||
kind: ClusterIssuer
|
kind: ClusterIssuer
|
||||||
# ---
|
---
|
||||||
# apiVersion: cert-manager.io/v1
|
apiVersion: cert-manager.io/v1
|
||||||
# kind: Certificate
|
kind: Certificate
|
||||||
# metadata:
|
metadata:
|
||||||
# name: jellyfin-prod-tls
|
name: jelly-prod-tls
|
||||||
# namespace: streaming
|
namespace: streaming
|
||||||
# spec:
|
spec:
|
||||||
# secretName: jellyfin-prod-tls
|
secretName: jelly-prod-tls
|
||||||
# dnsNames:
|
dnsNames:
|
||||||
# - jellyfin.forust.xyz
|
- jelly.forust.xyz
|
||||||
# issuerRef:
|
issuerRef:
|
||||||
# name: letsencrypt-prod
|
name: letsencrypt-prod
|
||||||
# kind: ClusterIssuer
|
kind: ClusterIssuer
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: seerr-prod-tls
|
||||||
|
namespace: streaming
|
||||||
|
spec:
|
||||||
|
secretName: seerr-prod-tls
|
||||||
|
dnsNames:
|
||||||
|
- seerr.forust.xyz
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
kind: ClusterIssuer
|
||||||
# ---
|
# ---
|
||||||
# apiVersion: cert-manager.io/v1
|
# apiVersion: cert-manager.io/v1
|
||||||
# kind: Certificate
|
# kind: Certificate
|
||||||
@@ -78,16 +91,3 @@ spec:
|
|||||||
# issuerRef:
|
# issuerRef:
|
||||||
# name: letsencrypt-prod
|
# name: letsencrypt-prod
|
||||||
# kind: ClusterIssuer
|
# kind: ClusterIssuer
|
||||||
# ---
|
|
||||||
# apiVersion: cert-manager.io/v1
|
|
||||||
# kind: Certificate
|
|
||||||
# metadata:
|
|
||||||
# name: jellyseerr-prod-tls
|
|
||||||
# namespace: streaming
|
|
||||||
# spec:
|
|
||||||
# secretName: jellyseerr-prod-tls
|
|
||||||
# dnsNames:
|
|
||||||
# - jellyseerr.forust.xyz
|
|
||||||
# issuerRef:
|
|
||||||
# name: letsencrypt-prod
|
|
||||||
# kind: ClusterIssuer
|
|
||||||
@@ -186,3 +186,30 @@ endpoints:
|
|||||||
- "192.168.88.100"
|
- "192.168.88.100"
|
||||||
conditions:
|
conditions:
|
||||||
ready: true
|
ready: true
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: lampac
|
||||||
|
namespace: streaming
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 19118
|
||||||
|
targetPort: 19118
|
||||||
|
---
|
||||||
|
apiVersion: discovery.k8s.io/v1
|
||||||
|
kind: EndpointSlice
|
||||||
|
metadata:
|
||||||
|
name: lampac
|
||||||
|
namespace: streaming
|
||||||
|
labels:
|
||||||
|
kubernetes.io/service-name: lampac
|
||||||
|
addressType: IPv4
|
||||||
|
ports:
|
||||||
|
- port: 19118
|
||||||
|
protocol: TCP
|
||||||
|
endpoints:
|
||||||
|
- addresses:
|
||||||
|
- "192.168.88.100"
|
||||||
|
conditions:
|
||||||
|
ready: true
|
||||||
@@ -116,3 +116,54 @@ spec:
|
|||||||
port: 16767
|
port: 16767
|
||||||
tls:
|
tls:
|
||||||
secretName: internal-wildcard-tls
|
secretName: internal-wildcard-tls
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: lampac-local
|
||||||
|
namespace: streaming
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`lampac.workstation.internal`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: lampac
|
||||||
|
port: 19118
|
||||||
|
tls:
|
||||||
|
secretName: internal-wildcard-tls
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: jellyfin-prod
|
||||||
|
namespace: streaming
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`jelly.forust.xyz`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: jellyfin
|
||||||
|
port: 18096
|
||||||
|
tls:
|
||||||
|
secretName: jelly-prod-tls
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: seerr-prod
|
||||||
|
namespace: streaming
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`seerr.forust.xyz`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: jellyseerr
|
||||||
|
port: 15055
|
||||||
|
tls:
|
||||||
|
secretName: seerr-prod-tls
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
termix:
|
termix:
|
||||||
image: ghcr.io/lukegus/termix:2.9.1
|
image: ghcr.io/lukegus/termix:2.9.0
|
||||||
container_name: termix
|
container_name: termix
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# ports:
|
# ports:
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: termix-deployment
|
name: termix-deployment
|
||||||
namespace: termix
|
namespace: termix
|
||||||
spec:
|
spec:
|
||||||
@@ -31,7 +29,7 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: termix
|
- name: termix
|
||||||
image: ghcr.io/lukegus/termix:2.9.1
|
image: ghcr.io/lukegus/termix:2.9.0
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: termix-config
|
name: termix-config
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ ports:
|
|||||||
exposedPort: 8080
|
exposedPort: 8080
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
expose:
|
expose:
|
||||||
default: true
|
default: false
|
||||||
http:
|
http:
|
||||||
aliasHeadersStrategy: delete
|
aliasHeadersStrategy: delete
|
||||||
ssh:
|
ssh:
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: vaultwarden-deployment
|
name: vaultwarden-deployment
|
||||||
namespace: vaultwarden
|
namespace: vaultwarden
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ spec:
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
reloader.stakater.com/auto: "true"
|
|
||||||
name: xui-deployment
|
name: xui-deployment
|
||||||
namespace: xui
|
namespace: xui
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
Reference in new issue
Block a user