diff --git a/.github/workflows/chart-ci.yml b/.github/workflows/chart-ci.yml new file mode 100644 index 00000000..73501a3b --- /dev/null +++ b/.github/workflows/chart-ci.yml @@ -0,0 +1,56 @@ +name: Chart CI + +on: + pull_request: + paths: + - charts/** + - .github/workflows/chart-ci.yml + - .github/workflows/chart-release.yml + - .kube-linter.yaml + push: + branches: + - dev + paths: + - charts/** + - .github/workflows/chart-ci.yml + - .github/workflows/chart-release.yml + - .kube-linter.yaml + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: azure/setup-helm@v4 + + - name: Lint chart + run: helm lint charts/explo --strict + + - name: Render chart + run: | + helm template test charts/explo + helm template test charts/explo \ + --set auth.username=admin \ + --set auth.password=ci-only + helm template test charts/explo \ + --set persistence.media.existingClaim=media-pvc \ + --set persistence.media.subPath=explo + helm template test charts/explo \ + --set ingress.enabled=true \ + --set ingress.className=traefik \ + --set-json 'ingress.hosts=[{"host":"explo.example.com","paths":[{"path":"/","pathType":"Prefix"}]}]' + helm template test charts/explo \ + --set ingress.enabled=true \ + --set ingress.className=nginx \ + --set-json 'ingress.hosts=[{"host":"explo.example.com","paths":[{"path":"/","pathType":"Prefix"}]}]' + helm template test charts/explo \ + --set httpRoute.enabled=true \ + --set-json 'httpRoute.parentRefs=[{"name":"traefik-gateway","namespace":"traefik","sectionName":"websecure"}]' \ + --set-json 'httpRoute.hostnames=["explo.example.com"]' + + - name: Lint manifests + uses: stackrox/kube-linter-action@v1 + with: + directory: charts/explo + config: .kube-linter.yaml diff --git a/.github/workflows/chart-release.yml b/.github/workflows/chart-release.yml new file mode 100644 index 00000000..522df3b5 --- /dev/null +++ b/.github/workflows/chart-release.yml @@ -0,0 +1,112 @@ +name: Chart Release + +on: + workflow_run: + workflows: + - Latest Release + types: + - completed + +permissions: + contents: write + +jobs: + publish: + if: github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.workflow_run.head_sha }} + + - name: Resolve release tag + id: tag + run: | + SHA="${{ github.event.workflow_run.head_sha }}" + TAG=$(git tag -l 'v*' --points-at "$SHA" | sort -V | tail -1) + if [ -z "$TAG" ]; then + echo "No v* tag found for ${SHA}; skipping chart publish" + echo "skip=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + VERSION="${TAG#v}" + echo "skip=false" >> "$GITHUB_OUTPUT" + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + + - name: Skip when chart is missing + id: chart + if: steps.tag.outputs.skip != 'true' + run: | + if [ ! -f charts/explo/Chart.yaml ]; then + echo "present=false" >> "$GITHUB_OUTPUT" + echo "No chart at this tag" + exit 0 + fi + echo "present=true" >> "$GITHUB_OUTPUT" + + - uses: azure/setup-helm@v4 + if: steps.tag.outputs.skip != 'true' && steps.chart.outputs.present == 'true' + + - name: Package chart + if: steps.tag.outputs.skip != 'true' && steps.chart.outputs.present == 'true' + run: | + mkdir -p dist + helm package charts/explo \ + --version "${{ steps.tag.outputs.version }}" \ + --app-version "${{ steps.tag.outputs.tag }}" \ + --destination dist + echo "package=${GITHUB_WORKSPACE}/dist/$(ls dist)" >> "$GITHUB_ENV" + + - name: Upload release asset + if: steps.tag.outputs.skip != 'true' && steps.chart.outputs.present == 'true' + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release upload "${{ steps.tag.outputs.tag }}" "$package" --clobber + + - name: Publish gh-pages + if: steps.tag.outputs.skip != 'true' && steps.chart.outputs.present == 'true' + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + PAGES_DIR="${RUNNER_TEMP}/gh-pages" + REPO="${{ github.repository }}" + PAGES_URL="https://lumepart.github.io/Explo" + TAG="${{ steps.tag.outputs.tag }}" + + if git ls-remote --exit-code --heads "https://github.com/${REPO}.git" gh-pages >/dev/null 2>&1; then + git clone --branch gh-pages \ + "https://x-access-token:${GH_TOKEN}@github.com/${REPO}.git" \ + "$PAGES_DIR" + else + mkdir -p "$PAGES_DIR" + cd "$PAGES_DIR" + git init + git checkout -b gh-pages + git remote add origin "https://x-access-token:${GH_TOKEN}@github.com/${REPO}.git" + fi + + cp "$package" "$PAGES_DIR/" + if [ -f pages/index.html ]; then + cp pages/index.html "$PAGES_DIR/index.html" + fi + + if [ -f "$PAGES_DIR/index.yaml" ]; then + helm repo index "$PAGES_DIR" --url "$PAGES_URL" --merge "$PAGES_DIR/index.yaml" + else + helm repo index "$PAGES_DIR" --url "$PAGES_URL" + fi + + cd "$PAGES_DIR" + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + if git diff --staged --quiet; then + echo "No gh-pages changes for ${TAG}" + exit 0 + fi + git commit -m "chore(chart): publish ${TAG}" + git push origin gh-pages diff --git a/.gitignore b/.gitignore index 28a16e55..7ff4abc0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ tmp/ .air.toml logs/ -explo +/explo src/web/dist/ src/web/frontend/node_modules/ /cache diff --git a/.kube-linter.yaml b/.kube-linter.yaml new file mode 100644 index 00000000..3423daef --- /dev/null +++ b/.kube-linter.yaml @@ -0,0 +1,6 @@ +checks: + exclude: + - no-read-only-root-fs + - run-as-non-root + - unset-cpu-requirements + - unset-memory-requirements diff --git a/README.md b/README.md index 33092061..e39a438a 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,17 @@ Or jump directly to: - [System Notes](https://github.com/LumePart/Explo/wiki/6.-System-Notes) – Known issues and system-specific tips - [FAQ](https://github.com/LumePart/Explo/wiki/8.-FAQ) – Common questions +## Kubernetes + +Install from the Helm repository: + +```bash +helm repo add explo https://lumepart.github.io/Explo +helm repo update +helm install explo explo/explo --namespace explo --create-namespace +``` + +See [charts/explo/README.md](charts/explo/README.md) for values, examples, and upgrades. ## Acknowledgements diff --git a/charts/explo/.helmignore b/charts/explo/.helmignore new file mode 100644 index 00000000..0dddfab2 --- /dev/null +++ b/charts/explo/.helmignore @@ -0,0 +1,13 @@ +.DS_Store +*.swp +*.bak +*.tmp +*.orig +*~ +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ diff --git a/charts/explo/Chart.yaml b/charts/explo/Chart.yaml new file mode 100644 index 00000000..ebd90b06 --- /dev/null +++ b/charts/explo/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: explo +description: Helm chart for Explo music discovery +type: application +version: 0.0.0 +appVersion: dev +home: https://github.com/LumePart/Explo +sources: + - https://github.com/LumePart/Explo +maintainers: + - name: LumePart + url: https://github.com/LumePart +keywords: + - explo + - music + - listenbrainz + - jellyfin diff --git a/charts/explo/README.md b/charts/explo/README.md new file mode 100644 index 00000000..76b0a55b --- /dev/null +++ b/charts/explo/README.md @@ -0,0 +1,233 @@ +# explo + +Helm chart for [Explo](https://github.com/LumePart/Explo). + +## Install + +```bash +helm repo add explo https://lumepart.github.io/Explo +helm repo update +helm install explo explo/explo \ + --namespace explo \ + --create-namespace +``` + +Helm uses the latest chart version from the repo. The chart pins the matching app image by default. + +## Local development + +```bash +helm install explo ./charts/explo \ + --namespace explo \ + --create-namespace +``` + +## Web UI exposure + +Use one of Ingress or HTTPRoute. Both work with common controllers. + +### Ingress (Traefik or ingress-nginx) + +Standard `networking.k8s.io/v1` Ingress. Set `ingress.className` to your controller. + +Traefik: + +```yaml +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt + hosts: + - host: explo.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: explo-tls + hosts: + - explo.example.com +``` + +ingress-nginx: + +```yaml +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt + hosts: + - host: explo.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: explo-tls + hosts: + - explo.example.com +``` + +### Gateway API (HTTPRoute) + +For Traefik Gateway, Envoy Gateway, Cilium, or other Gateway API implementations: + +```yaml +httpRoute: + enabled: true + parentRefs: + - name: traefik-gateway + namespace: traefik + sectionName: websecure + hostnames: + - explo.example.com +``` + +TLS is usually terminated on the Gateway. Point `parentRefs` at your Gateway and listener. + +## Minimal values + +```yaml +ingress: + enabled: true + className: traefik + hosts: + - host: explo.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: explo-tls + hosts: + - explo.example.com + +persistence: + config: + enabled: true + size: 2Gi + storageClass: longhorn + media: + enabled: true + existingClaim: music-library + subPath: explo + +auth: + existingSecret: explo-auth +``` + +## Music server examples + +Jellyfin: + +```yaml +extraEnv: + EXPLO_SYSTEM: jellyfin + SYSTEM_URL: http://jellyfin.jellyfin.svc.cluster.local:8096 + API_KEY: your-api-key + LIBRARY_NAME: Music +``` + +Navidrome or another Subsonic-compatible server: + +```yaml +extraEnv: + EXPLO_SYSTEM: subsonic + SYSTEM_URL: http://navidrome.navidrome.svc.cluster.local:4533 + SYSTEM_USERNAME: explo + SYSTEM_PASSWORD: your-password +``` + +Optional slskd downloads: + +```yaml +extraEnv: + DOWNLOAD_SERVICES: youtube,slskd + SLSKD_URL: http://slskd.servarr.svc.cluster.local:5030 + SLSKD_API_KEY: your-api-key +``` + +## Persistence + +- `/opt/explo/config` stores wizard config, cache, logs, and `.env` +- `/data` should be on a path your music server can scan +- `WEB_ENV_PATH=/opt/explo/config/.env` lets the wizard write config to the PVC + +## Auth + +UI credentials can be set in the setup wizard after install. + +Optional install-time shortcuts: + +```yaml +auth: + username: admin + password: change-me +``` + +Or: + +```yaml +auth: + existingSecret: explo-auth +``` + +## Image version + +The chart `appVersion` matches the app release tag. The default image tag uses `.Chart.AppVersion`. + +Override only when needed: + +```yaml +image: + tag: latest + pullPolicy: Always +``` + +## Upgrade + +```bash +helm repo update +helm upgrade explo explo/explo --namespace explo +``` + +## Values + +| Key | Default | Description | +|-----|---------|-------------| +| `image.repository` | `ghcr.io/lumepart/explo` | Container image | +| `image.tag` | `""` | Image tag. Defaults to chart `appVersion` | +| `image.pullPolicy` | `IfNotPresent` | Image pull policy | +| `replicaCount` | `1` | Pod count. Keep at 1 | +| `deploymentStrategy.type` | `Recreate` | Deployment strategy | +| `service.type` | `ClusterIP` | Service type | +| `service.port` | `7288` | Service port | +| `ingress.enabled` | `false` | Enable Ingress | +| `ingress.className` | `""` | Ingress class (`traefik`, `nginx`, etc.) | +| `ingress.annotations` | `{}` | Ingress annotations | +| `ingress.hosts` | `[]` | Ingress host rules | +| `ingress.tls` | `[]` | Ingress TLS config | +| `httpRoute.enabled` | `false` | Enable Gateway API HTTPRoute | +| `httpRoute.parentRefs` | `[]` | Gateway parent references | +| `httpRoute.hostnames` | `[]` | HTTPRoute hostnames | +| `httpRoute.path` | `/` | Path prefix for the route | +| `env.TZ` | `UTC` | Container timezone | +| `env.WEB_ENV_PATH` | `/opt/explo/config/.env` | Writable config file path | +| `auth.existingSecret` | `""` | Secret with UI credentials | +| `auth.username` | `""` | Inline UI username | +| `auth.password` | `""` | Inline UI password | +| `persistence.config.enabled` | `true` | Enable config PVC | +| `persistence.config.size` | `2Gi` | Config PVC size | +| `persistence.media.enabled` | `true` | Enable media volume | +| `persistence.media.mountPath` | `/data` | Download directory | +| `persistence.media.subPath` | `""` | Subpath on existing claim | +| `extraEnv` | `{}` | Extra environment variables | +| `extraVolumes` | `[]` | Extra pod volumes | +| `extraVolumeMounts` | `[]` | Extra volume mounts | + +## Troubleshooting + +- Pod not ready: check `kubectl logs` and confirm port 7288 responds on `/api/ui/setup-status` +- Wizard cannot save config: confirm the config PVC is writable and `WEB_ENV_PATH` points inside it +- Music server cannot see downloads: align `/data` with your library PVC or subpath +- Ingress not routing: confirm `ingress.className` matches your controller +- HTTPRoute not routing: confirm `parentRefs` point at an existing Gateway listener diff --git a/charts/explo/templates/NOTES.txt b/charts/explo/templates/NOTES.txt new file mode 100644 index 00000000..093a1b17 --- /dev/null +++ b/charts/explo/templates/NOTES.txt @@ -0,0 +1,13 @@ +Explo is installed in namespace {{ .Release.Namespace }}. + +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http{{- if $.Values.ingress.tls }}s{{- end }}://{{ .host }} +{{- end }} +{{- else if .Values.httpRoute.enabled }} +{{- range .Values.httpRoute.hostnames }} + https://{{ . }} +{{- end }} +{{- else }} + kubectl port-forward -n {{ .Release.Namespace }} svc/{{ include "explo.fullname" . }} 7288:{{ .Values.service.port }} +{{- end }} diff --git a/charts/explo/templates/_helpers.tpl b/charts/explo/templates/_helpers.tpl new file mode 100644 index 00000000..1c639fe7 --- /dev/null +++ b/charts/explo/templates/_helpers.tpl @@ -0,0 +1,95 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "explo.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "explo.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "explo.labels" -}} +helm.sh/chart: {{ include "explo.name" . }}-{{ .Chart.Version | replace "+" "_" }} +{{ include "explo.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "explo.selectorLabels" -}} +app.kubernetes.io/name: {{ include "explo.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Image tag defaults to Chart appVersion. +*/}} +{{- define "explo.imageTag" -}} +{{- .Values.image.tag | default .Chart.AppVersion }} +{{- end }} + +{{/* +Auth secret name when using inline credentials. +*/}} +{{- define "explo.authSecretName" -}} +{{- if .Values.auth.existingSecret }} +{{- .Values.auth.existingSecret }} +{{- else }} +{{- include "explo.fullname" . }}-auth +{{- end }} +{{- end }} + +{{/* +True when UI credentials are injected at install time. +*/}} +{{- define "explo.authConfigured" -}} +{{- if .Values.auth.existingSecret -}} +true +{{- else if and .Values.auth.username .Values.auth.password -}} +true +{{- else -}} +false +{{- end }} +{{- end }} + +{{/* +Config PVC claim name. +*/}} +{{- define "explo.configClaimName" -}} +{{- if .Values.persistence.config.existingClaim }} +{{- .Values.persistence.config.existingClaim }} +{{- else }} +{{- include "explo.fullname" . }}-config +{{- end }} +{{- end }} + +{{/* +Media PVC claim name. +*/}} +{{- define "explo.mediaClaimName" -}} +{{- if .Values.persistence.media.existingClaim }} +{{- .Values.persistence.media.existingClaim }} +{{- else }} +{{- include "explo.fullname" . }}-media +{{- end }} +{{- end }} diff --git a/charts/explo/templates/deployment.yaml b/charts/explo/templates/deployment.yaml new file mode 100644 index 00000000..b7d3632e --- /dev/null +++ b/charts/explo/templates/deployment.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "explo.fullname" . }} + labels: + {{- include "explo.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: {{ .Values.deploymentStrategy.type }} + selector: + matchLabels: + {{- include "explo.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "explo.selectorLabels" . | nindent 8 }} + {{- if eq (include "explo.authConfigured" .) "true" }} + annotations: + checksum/auth: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- end }} + spec: + containers: + - name: explo + image: "{{ .Values.image.repository }}:{{ include "explo.imageTag" . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 7288 + protocol: TCP + env: + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if eq (include "explo.authConfigured" .) "true" }} + - name: UI_USERNAME + valueFrom: + secretKeyRef: + name: {{ include "explo.authSecretName" . }} + key: {{ .Values.auth.usernameKey }} + - name: UI_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "explo.authSecretName" . }} + key: {{ .Values.auth.passwordKey }} + {{- end }} + {{- range $key, $value := .Values.extraEnv }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /api/ui/setup-status + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.persistence.config.enabled }} + - name: config + mountPath: /opt/explo/config + {{- end }} + {{- if .Values.persistence.media.enabled }} + - name: media + mountPath: {{ .Values.persistence.media.mountPath }} + {{- with .Values.persistence.media.subPath }} + subPath: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + {{- if .Values.persistence.config.enabled }} + - name: config + persistentVolumeClaim: + claimName: {{ include "explo.configClaimName" . }} + {{- end }} + {{- if .Values.persistence.media.enabled }} + - name: media + persistentVolumeClaim: + claimName: {{ include "explo.mediaClaimName" . }} + {{- end }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/explo/templates/httproute.yaml b/charts/explo/templates/httproute.yaml new file mode 100644 index 00000000..7f11f411 --- /dev/null +++ b/charts/explo/templates/httproute.yaml @@ -0,0 +1,27 @@ +{{- if .Values.httpRoute.enabled }} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ include "explo.fullname" . }} + labels: + {{- include "explo.labels" . | nindent 4 }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- toYaml .Values.httpRoute.parentRefs | nindent 4 }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + - matches: + - path: + type: PathPrefix + value: {{ .Values.httpRoute.path | default "/" | quote }} + backendRefs: + - name: {{ include "explo.fullname" . }} + port: {{ .Values.service.port }} +{{- end }} diff --git a/charts/explo/templates/ingress.yaml b/charts/explo/templates/ingress.yaml new file mode 100644 index 00000000..be0f2ebe --- /dev/null +++ b/charts/explo/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "explo.fullname" . }} + labels: + {{- include "explo.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName | quote }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path | quote }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "explo.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/explo/templates/pvc-config.yaml b/charts/explo/templates/pvc-config.yaml new file mode 100644 index 00000000..d435cbdb --- /dev/null +++ b/charts/explo/templates/pvc-config.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.persistence.config.enabled (not .Values.persistence.config.existingClaim) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "explo.fullname" . }}-config + labels: + {{- include "explo.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.persistence.config.accessMode }} + {{- if .Values.persistence.config.storageClass }} + storageClassName: {{ .Values.persistence.config.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.config.size | quote }} +{{- end }} diff --git a/charts/explo/templates/pvc-media.yaml b/charts/explo/templates/pvc-media.yaml new file mode 100644 index 00000000..2f666792 --- /dev/null +++ b/charts/explo/templates/pvc-media.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.persistence.media.enabled (not .Values.persistence.media.existingClaim) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "explo.fullname" . }}-media + labels: + {{- include "explo.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.persistence.media.accessMode }} + {{- if .Values.persistence.media.storageClass }} + storageClassName: {{ .Values.persistence.media.storageClass | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.media.size | quote }} +{{- end }} diff --git a/charts/explo/templates/secret.yaml b/charts/explo/templates/secret.yaml new file mode 100644 index 00000000..2b97c17c --- /dev/null +++ b/charts/explo/templates/secret.yaml @@ -0,0 +1,12 @@ +{{- if and (not .Values.auth.existingSecret) .Values.auth.username .Values.auth.password }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "explo.fullname" . }}-auth + labels: + {{- include "explo.labels" . | nindent 4 }} +type: Opaque +stringData: + {{ .Values.auth.usernameKey }}: {{ .Values.auth.username | quote }} + {{ .Values.auth.passwordKey }}: {{ .Values.auth.password | quote }} +{{- end }} diff --git a/charts/explo/templates/service.yaml b/charts/explo/templates/service.yaml new file mode 100644 index 00000000..233bd9e4 --- /dev/null +++ b/charts/explo/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "explo.fullname" . }} + labels: + {{- include "explo.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "explo.selectorLabels" . | nindent 4 }} diff --git a/charts/explo/values.yaml b/charts/explo/values.yaml new file mode 100644 index 00000000..142d24e4 --- /dev/null +++ b/charts/explo/values.yaml @@ -0,0 +1,66 @@ +nameOverride: "" +fullnameOverride: "" + +image: + repository: ghcr.io/lumepart/explo + tag: "" + pullPolicy: IfNotPresent + +replicaCount: 1 + +deploymentStrategy: + type: Recreate + +service: + type: ClusterIP + port: 7288 + +ingress: + enabled: false + className: "" + annotations: {} + hosts: [] + tls: [] + +httpRoute: + enabled: false + annotations: {} + parentRefs: [] + hostnames: [] + path: / + +env: + TZ: UTC + WEB_UI: "true" + WEB_ADDR: ":7288" + WEB_DATA_PATH: /opt/explo/config/ + WEB_ENV_PATH: /opt/explo/config/.env + +auth: + existingSecret: "" + username: "" + password: "" + usernameKey: username + passwordKey: password + +persistence: + config: + enabled: true + existingClaim: "" + size: 2Gi + storageClass: "" + accessMode: ReadWriteOnce + media: + enabled: true + existingClaim: "" + mountPath: /data + subPath: "" + size: 10Gi + storageClass: "" + accessMode: ReadWriteOnce + +extraEnv: {} +extraVolumes: [] +extraVolumeMounts: [] + +resources: {} diff --git a/pages/index.html b/pages/index.html new file mode 100644 index 00000000..c2e937ba --- /dev/null +++ b/pages/index.html @@ -0,0 +1,16 @@ + + +
+ ++helm repo add explo https://lumepart.github.io/Explo +helm repo update +helm install explo explo/explo --namespace explo --create-namespace ++ + +