25 Commits

Author SHA1 Message Date
8ed24361bf Removed invisible chars and printing of signing key in workflows file
All checks were successful
Package & Sign Helm Chart / build (release) Successful in 1m24s
2025-06-12 19:50:18 +02:00
c4fae1e2d8 Update Chart.yaml and CHANGELOG for BookStack v25.5.0 release 2025-06-12 19:49:29 +02:00
25707b7f89 Fixed some formating issues 2025-05-15 22:58:04 +02:00
61d3bc4aba Update description in Chart.yaml to clarify deployment details for BookStack 2025-05-15 22:57:23 +02:00
bc5138ef84 Merge remote-tracking branch 'origin/renovate/ubuntu-24.x' 2025-05-15 22:56:30 +02:00
fe12222722 Update GPG key reference in Helm package command to use specific signing key
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 14s
2025-05-12 23:04:25 +02:00
be91c9677a Add step to display GPG keys in CI environment
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 12s
2025-05-12 23:02:48 +02:00
33fbe9e443 Add error handling to legacy secret-keyring build step
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 13s
2025-05-12 22:50:14 +02:00
c09e1a2978 Update PGP public key block with new key data
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 29s
2025-05-12 22:41:15 +02:00
337b9e9f0b Fix GPG command to include passphrase for secret key export in package-and-deploy workflow
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 20s
2025-05-12 22:21:31 +02:00
91bb7a4fd1 Enhance GPG command in secret-keyring build step with additional flags for improved functionality
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 28s
2025-05-12 22:19:21 +02:00
005aab7ec9 Fix GPG command to use batch mode for secret-keyring build step
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 36s
2025-05-12 22:16:55 +02:00
c2ccd5e27f Fix GPG command to remove unnecessary batch flag in secret-keyring build step
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 25s
2025-05-12 22:12:50 +02:00
7cf5f43299 Fix output redirection syntax for GPG secret key export in package-and-deploy workflow
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 22s
2025-05-12 22:08:58 +02:00
3eaa7e6b60 Add initial changelog for BookStack Helm chart version 0.1.0+up25.2.3
Some checks failed
Package & Sign Helm Chart / build (release) Failing after 2m4s
2025-05-08 17:20:44 +02:00
fac90514e4 Add script to generate CHANGELOG.md from Chart.yaml annotations 2025-05-08 17:20:36 +02:00
f22cdaa818 Add annotations for license, links, maintainers, and changes in Chart.yaml 2025-05-08 17:20:28 +02:00
55ca2b3af4 Update dependency ubuntu to v24 2025-05-08 13:16:00 +00:00
79877d8eae Update README.md to enhance documentation for BookStack Helm Chart 2025-05-08 15:05:28 +02:00
c01965b45f Update Helm chart workflow to include signing process and add PGP public key 2025-05-08 14:49:54 +02:00
a55853f4ab Add JSON schema for BookStack configuration and settings 2025-05-08 14:16:33 +02:00
9eaaf4a8cc Add support for additional authentication secrets in deployment template 2025-05-08 14:16:15 +02:00
e0e2e10fd1 Enhance secret management by adding additionalSecrets and mail credentials checks in the Helm template 2025-05-08 13:30:04 +02:00
0f14ad0329 Refactor BookStack configuration by removing unused view settings and simplifying additional settings structure 2025-05-08 13:29:11 +02:00
99637a0932 Fix GPG passphrase secret reference and update curl command for chart upload 2025-05-08 08:53:58 +02:00
11 changed files with 956 additions and 29 deletions

View File

@@ -1,4 +1,4 @@
name: Packaging Chart name: Package & Sign Helm Chart
on: on:
release: release:
@@ -6,30 +6,77 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
env:
CHART_DIR: bookstack/
CHART_VERSION: ${{ github.event.release.tag_name }}
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
steps: steps:
- name: Checkout
uses: actions/checkout@v4 # 1) Code auschecken
- name: Setup latest Helm - uses: actions/checkout@v4
uses: azure/setup-helm@v4.3.0
# 2) Helm installieren
- uses: azure/setup-helm@v4.3.0
with: with:
version: latest version: latest
id: install id: install
- name: Import GPG key - name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6 uses: crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }} passphrase: ${{ secrets.GPG_PASSPHRASE }}
trust_level: 5 trust_level: 5
- name: Export GPG key in legacy format
# 3) "Generation-1"-Secret-Ring für Helm erzeugen (TMP, 600 Rechte)
- name: Build legacy secret-keyring
run: | run: |
gpg --export-secret-keys --output /tmp/keyring.gpg ${{ secrets.GPG_KEY_ID }} set -euo pipefail
- name: Package Chart install -m 700 -d /tmp/gpgring
gpg --batch --yes --pinentry-mode loopback \
--passphrase "$PASSPHRASE" \
--export-secret-keys "$GPG_KEY_ID" \
>/tmp/gpgring/secring.gpg
chmod 600 /tmp/gpgring/secring.gpg
echo "$PASSPHRASE" > /tmp/gpgring/passphrase.txt
chmod 600 /tmp/gpgring/passphrase.txt
# 4) Chart bauen & signieren
- name: Package & sign chart
run: | run: |
cp README.md ./charts/bookstack/. cp README.md "$CHART_DIR"/
helm dependency build ./charts/bookstack helm dependency build "$CHART_DIR"
helm package --version $CHART_VERSION --sign --keyring /tmp/keyring.gpg ./bookstack --dependency-update helm package "$CHART_DIR" \
curl -u $REPO_CREDENTIALS -F "chart=@bookstack-$CHART_VERSION.tgz" -F "prov=@bookstack-$CHART_VERSION.tgz.prov" https://charts.morlana.net/api/charts --version "$CHART_VERSION" \
--sign \
--key "Morlana Signing" \
--keyring /tmp/gpgring/secring.gpg \
--passphrase-file /tmp/gpgring/passphrase.txt
# 5) In dein internes Chart-Repo hochladen
- name: Upload to ChartMuseum
env: env:
REPO_CREDENTIALS: ${{ secrets.REPO_CREDENTIALS }} REPO_CREDENTIALS: ${{ secrets.REPO_CREDENTIALS }}
CHART_VERSION: ${{ github.event.release.tag_name }} run: |
curl -H "Authorization: Basic $REPO_CREDENTIALS" \
-F "chart=@bookstack-$CHART_VERSION.tgz" \
-F "prov=@bookstack-$CHART_VERSION.tgz.prov" \
https://charts.morlana.net/api/charts
# 6) Public-Key aus Repo beilegen und als Release-Asset anhängen
- name: Attach release assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event.release.tag_name }}
files: |
bookstack-${{ env.CHART_VERSION }}.tgz
bookstack-${{ env.CHART_VERSION }}.tgz.prov
pubkeys/morlana.asc
# 7) Aufräumen (optional, Runner ist ohnehin kurzlebig)
- name: Cleanup sensitive files
if: ${{ always() }}
run: rm -rf /tmp/gpgring

9
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"github.copilot.enable": {
"*": true,
"plaintext": false,
"markdown": false,
"scminput": false,
"yaml": true
}
}

15
CHANGELOG.md Normal file
View File

@@ -0,0 +1,15 @@
# Changelog
## 0.1.0+up25.5.0 - 2025-06-12
- **Changed** ✦ Packages upstream BookStack v25.5.0
- [Release Notes](https://github.com/solidnerd/docker-bookstack/releases/tag/25.5.0)
- [Project homepage](https://www.bookstackapp.com/)
## 0.1.0+up25.2.3 2025-05-08
- **Added** Initial Helm chart for BookStack.
- ✦ Packages upstream BookStack v25.2.3
- [Project homepage](https://www.bookstackapp.com/)
- **Added** ✦ Ingress, persistence, TLS and SMTP settings readymade
- **Added** ✦ Includes optional MariaDB and Redis subcharts
- [MariaDB subchart](https://artifacthub.io/packages/helm/bitnami/mariadb)
- [Redis subchart](https://artifacthub.io/packages/helm/bitnami/redis)

143
README.md
View File

@@ -1,3 +1,142 @@
# bookstack-chart # BookStack Helm Chart
This is an unofficial Helm Chart for bookstackapp.com Deploys the BookStack wiki platform on Kubernetes with optional MariaDB and Redis sub-charts.
---
## Versioning
The chart uses **dual semantic versioning**:
```
<chart semver>+<upstream BookStack semver>
# example: 1.2.3+25.2.3
```
This allows Helm to track compatibility changes independently from upstream BookStack releases.
---
## Prerequisites
* Helm 3
* Kubernetes 1.24+
* (Optional) External MariaDB 10.5+ and/or Redis 6+ instances if you disable the bundled subcharts
---
## Quick start
```bash
helm repo add morlana https://charts.morlana.net
helm repo update
helm install bookstack morlana/bookstack \
--namespace bookstack --create-namespace
```
The first run generates a **Laravel APP\_KEY** secret. The deployment automatically restarts once the key is present.
---
## Upgrading
```bash
helm upgrade bookstack morlana/bookstack -n bookstack --reuse-values
```
Helm recognises new chart versions that follow the `x.y.z+<bookstack>` scheme. Check the upstream projects release notes as well as the charts `CHANGELOG.md` before upgrading across major versions.
---
## Uninstalling
```bash
helm uninstall bookstack -n bookstack
```
PersistentVolumeClaims and One-Time generated secrets are **not** removed automatically.
---
## Configuration (excerpt)
| Key | Description | Default |
| ------------------------------- | --------------------------------------------------- | --------------------- |
| `bookstack.image.repository` | Container image repository | `solidnerd` |
| `bookstack.image.name` | Image name | `bookstack` |
| `bookstack.image.tag` | Image tag (defaults to upstream version when empty) | `""` |
| `bookstack.replicaCount` | Number of pods | `1` |
| `bookstack.config.app.url` | Public URL users will access | `https://example.com` |
| `bookstack.config.app.key` | Laravel APP\_KEY (autogenerated if empty) | `""` |
| `bookstack.mail.host` | SMTP host (set to enable email) | `""` |
| `bookstack.mail.port` | SMTP port | `1025` |
| `bookstack.persistence.enabled` | Persist uploads and storage | `true` |
| `bookstack.persistence.size` | PVC size | `10Gi` |
| `service.type` | Kubernetes Service type | `ClusterIP` |
| `ingress.enabled` | Create an Ingress | `false` |
| `db.enabled` | Deploy bundled MariaDB | `true` |
| `redis.enabled` | Deploy bundled Redis | `true` |
Override values with `--set key=value` or put them in `my-values.yaml` and pass `-f`.
---
## Persistence
A single ReadWriteMany PVC is created by default so all replicas share the same data. Customise size, StorageClass or accessMode via `bookstack.persistence.*`.
---
## Ingress example
```yaml
ingress:
enabled: true
class: nginx
hostname: wiki.example.com
tls:
- hosts: [wiki.example.com]
secretName: wiki-tls
```
---
## Using external services
Disable the subcharts and point BookStack at existing database/redis servers:
```yaml
db:
enabled: false
bookstack:
externalDatabase:
host: mariadb.example.com
database: bookstack
username: bookstack
password: supersecret
redis:
enabled: false
bookstack:
externalRedis:
servers: redis://:password@redis.example.com:6379/0
```
---
## Backup & restore
* **Database**: use `mysqldump` / `mysql` against the MariaDB service (or your external DB).
* **Application data**: back up the BookStack PVC with your preferred tool (Velero, restic, etc.).
---
## Contributing
Bug reports and pull requests are welcome in the [chart repository](https://git.morlana.online/f.weber/bookstack-chart).
For issues specific to BookStack itself, please use the [upstream projects tracker](https://github.com/BookStackApp/BookStack/issues).
Happy documenting! 📚

View File

@@ -1,12 +1,13 @@
apiVersion: v2 apiVersion: v2
name: bookstack name: bookstack
description: A Helm chart for Kubernetes description: |
Deploys the BookStack wiki platform on Kubernetes with optional MariaDB and Redis sub-charts.
type: application type: application
version: "0.1.0+up25.2.3" version: "0.1.0+up25.5.0"
appVersion: "25.2.3" appVersion: "25.5.0"
dependencies: dependencies:
- name: mariadb - name: mariadb
@@ -18,3 +19,27 @@ dependencies:
version: ">=21.0.0 <22.0.0" version: ">=21.0.0 <22.0.0"
repository: "oci://registry-1.docker.io/bitnamicharts" repository: "oci://registry-1.docker.io/bitnamicharts"
condition: redis.enabled condition: redis.enabled
annotations:
artifacthub.io/license: MIT
artifacthub.io/links: |
- name: Git Repository
url: https://git.morlana.online/f.weber/bookstack-chart
- name: Issues
url: https://github.com/flweber/helm-bookstack/issues
- name: GitHub Mirror
url: https://github.com/flweber/helm-bookstack
artifacthub.io/maintainers: |
- name: Florian Weber
email: kosmos@morlana.net
artifacthub.io/signKey: |
fingerprint: 8975 6E20 1E4C 99B1 A2E9 5712 DF7D F259 CD8F CAAA
url: https://raw.githubusercontent.com/flweber/helm-bookstack/refs/heads/main/pubkeys/morlana.asc
artifacthub.io/changes: |
- kind: changed
description: ✦ Packages upstream BookStack v25.5.0
links:
- name: Release Notes
url: https://github.com/solidnerd/docker-bookstack/releases/tag/25.5.0
- name: Project homepage
url: https://www.bookstackapp.com/

View File

@@ -84,6 +84,12 @@ spec:
- secretRef: - secretRef:
name: {{ include "bookstack.secret" . }} name: {{ include "bookstack.secret" . }}
{{- end }} {{- end }}
{{- range $key, $conf := .Values.bookstack.auth }}
{{- if and (ne $key "method") (ne $key "auto.initiate") ($conf.enabled) $conf.existingSecret }}
- secretRef:
name: {{ $conf.existingSecret }}
{{- end }}
{{- end }}
ports: ports:
- containerPort: 8080 - containerPort: 8080
name: bookstack-http name: bookstack-http

View File

@@ -1,4 +1,4 @@
{{- if or (not .Values.db.enabled) (not (.Values.bookstack.auth | default dict | len | eq 0)) }} {{- if or (not .Values.db.enabled) (not (.Values.bookstack.auth | default dict | len | eq 0)) .Values.bookstack.config.additionalSecrets .Values.bookstack.mail.username .Values.bookstack.config.additionalSecrets .Values.bookstack.mail.password }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
type: Opaque type: Opaque
@@ -32,7 +32,7 @@ data:
$conf.clientSecret | b64enc | quote }} $conf.clientSecret | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.bookstack.auth.ldap.enabled }} {{- if and .Values.bookstack.auth.ldap.enabled (not .Values.bookstack.auth.ldap.existingSecret) }}
LDAP_SERVER: {{ required LDAP_SERVER: {{ required
"You have to define a bookstack.auth.ldap.server" "You have to define a bookstack.auth.ldap.server"
.Values.bookstack.auth.ldap.server | b64enc | quote }} .Values.bookstack.auth.ldap.server | b64enc | quote }}
@@ -40,7 +40,16 @@ data:
"You have to define a bookstack.auth.ldap.dn" "You have to define a bookstack.auth.ldap.dn"
.Values.bookstack.auth.ldap.dn | b64enc | quote }} .Values.bookstack.auth.ldap.dn | b64enc | quote }}
LDAP_PASS: {{ required LDAP_PASS: {{ required
"You have to define a bookstack.auth.ldap.passw" "You have to define a bookstack.auth.ldap.pass"
.Values.bookstack.auth.ldap.pass | b64enc | quote }} .Values.bookstack.auth.ldap.pass | b64enc | quote }}
{{- end }} {{- end }}
{{- if .Values.bookstack.mail.username }}
MAIL_USERNAME: {{ .Values.bookstack.mail.username | b64enc | quote }}
{{- end }}
{{- if .Values.bookstack.mail.password }}
MAIL_PASSWORD: {{ .Values.bookstack.mail.password | b64enc | quote }}
{{- end }}
{{- range $key, $value := .Values.bookstack.config.additionalSecrets }}
{{ $key | snakecase | upper }}: {{ $value | b64enc | quote }}
{{- end }}
{{- end }} {{- end }}

View File

@@ -0,0 +1,569 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"global": {
"type": "object",
"description": "Global settings for all applications.",
"additionalProperties": false,
"properties": {
"imageRegistry": {
"type": "string",
"description": "The image registry to use for all applications. This is used to pull the images from the registry.",
"default": ""
},
"imagePullSecrets": {
"type": "array",
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod",
"items": {
"$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.31.6/_definitions.json#/definitions/io.k8s.api.core.v1.LocalObjectReference"
},
"x-kubernetes-patch-merge-key": "name",
"x-kubernetes-patch-strategy": "merge",
"default": []
},
"defaultStorageClass": {
"type": "string",
"description": "The default storage class to use for all applications. This is used to create persistent volumes for the applications.",
"default": ""
},
"clusterDomain": {
"type": "string",
"description": "The domain name of the cluster. This is used to resolve services within the cluster.",
"default": "cluster.local"
}
}
},
"bookstack": {
"type": "object",
"description": "",
"additionalProperties": false,
"properties": {
"image": {
"type": "object",
"description": "",
"additionalProperties": false,
"properties": {
"registry": {
"type": "string",
"description": "The image registry to use for all applications. This is used to pull the images from the registry.",
"default": ""
},
"repository": {
"type": "string",
"description": "The repository of the image.",
"default": "solidnerd"
},
"name": {
"type": "string",
"description": "The name of the image.",
"default": "bookstack"
},
"tag": {
"type": "string",
"description": "Tag of the application you want to deploy. Could be a version number, commit sha or bad practice like \"latest\", \"dev\", \"qs\", \"prd\"",
"default": ""
},
"imagePullSecrets": {
"type": "array",
"description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod",
"items": {
"$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.31.6/_definitions.json#/definitions/io.k8s.api.core.v1.LocalObjectReference"
},
"x-kubernetes-patch-merge-key": "name",
"x-kubernetes-patch-strategy": "merge",
"default": []
},
"pullPolicy": {
"type": "string",
"description": "",
"default": "Always"
}
}
},
"replicaCount": {
"type": "integer",
"description": "The number of replicas to run.",
"default": 1
},
"updateStrategy": {
"description": "The update strategy to use for the deployment.",
"$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.31.6/_definitions.json#/definitions/io.k8s.api.apps.v1.DeploymentStrategy"
},
"externalDatabase": {
"type": "object",
"description": "If you want to use an external database, set this to true and provide the connection details.",
"additionalProperties": false,
"properties": {
"host": {
"type": "string",
"description": "The host (including port) of the external database."
},
"database": {
"type": "string",
"description": "The name of the database."
},
"username": {
"type": "string",
"description": "The username for the external database."
},
"password": {
"type": "string",
"description": "The password for the external database."
}
},
"required": [
"host",
"database",
"username",
"password"
]
},
"externalRedis": {
"type": "object",
"description": "If you want to use an external redis, set this to true and provide the connection details.",
"additionalProperties": false,
"properties": {
"servers": {
"type": "string",
"description": "One or more redis servers. See bookstack documentation for more details."
}
},
"required": [
"servers"
]
},
"config": {
"type": "object",
"description": "Bookstack application configuration section.",
"properties": {
"app": {
"type": "object",
"additionalProperties": true,
"description": "These settings will be provided as environment variables to bookstack. All of them will be automatically prefixed with \"APP_\" and the upper-case version of the provided key. e.g. \"url\" will be \"APP_URL\". If you have variables like \"APP_DEFAULT_DARK_MODE\" replace underscores with \".\" e.g. \"default.dark.mode\".",
"properties": {
"key": {
"type": [
"string",
"null"
],
"description": "If not provided a random key will be generated on the first deployment",
"default": null
},
"url": {
"type": "string",
"description": ""
}
},
"required": [
"url"
]
},
"additional": {
"type": "object",
"additionalProperties": true,
"description": "Here you can define environment variables by yourself which don't have a specific prefix e.g. \"STORAGE_TYPE\". Set it like key-value yaml pairs. For example: \"STORAGE_TYPE\": \"local\". Don't replace \"_\" with \".\"!"
},
"additionalSecrets": {
"type": "object",
"additionalProperties": true,
"description": "It's like \"additional\" section but the values will be stored in a Kubernetes secret. Base64 encoding will be done by the chart, so you have to input the clear values."
}
},
"required": [
"app"
]
},
"mail": {
"type": "object",
"description": "Bookstack mail settings. If your needed values are not listed here, you can also set them if the values are prefixed with \"MAIL_\". If you need \"MAIL_VERIFY_SSL\" write it as \"verify.ssl\".",
"additionalProperties": true,
"properties": {
"driver": {
"type": "string",
"description": "",
"default": "smtp",
"enum": [
"smtp",
"sendmail"
]
},
"host": {
"type": "string",
"description": "",
"default": ""
},
"from": {
"type": "string",
"description": "",
"default": "bookstack@cluster.local"
},
"from.name": {
"type": "string",
"description": "",
"default": "BookStack"
},
"username": {
"type": "string",
"description": "",
"default": "changeme"
},
"password": {
"type": "string",
"description": "",
"default": "changeme"
},
"port": {
"type": "integer",
"description": "",
"default": 1025
},
"encryption": {
"type": "string",
"description": "",
"default": "null",
"enum": [
"tls",
"null"
]
},
"verify.ssl": {
"type": "boolean",
"description": "",
"default": true
},
"sendmail.command": {
"type": "string"
}
},
"required": [
"driver"
]
},
"auth": {
"type": "object",
"description": "",
"additionalProperties": false,
"properties": {
"method": {
"type": "string",
"description": "See for more information: https://github.com/BookStackApp/BookStack/blob/development/.env.example.complete#L149"
},
"auto.initiate": {
"type": "boolean",
"default": false,
"description": "See for more information: https://github.com/BookStackApp/BookStack/blob/development/.env.example.complete#L153"
},
"oidc": {
"type": "object",
"description": "Here you can define BookStack OIDC settings. To set additional values not listed here define them in lowercase and replace \"_\" with \".\" in variable names. E.g. \"OIDC_ISSUER_DISCOVER\" as \"issuer.discover\"",
"required": ["enabled"],
"additionalProperties": true,
"properties": {
"name": {
"type": "string",
"description": "",
"default": "Open ID Connect"
},
"clientId": {
"type": "string",
"description": "",
"default": ""
},
"clientSecret": {
"type": "string",
"description": "",
"default": ""
},
"issuer": {
"type": "string",
"description": "",
"default": ""
}
}
},
"azure": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"AZURE_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"discord": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"DISCORD_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"facebook": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"FACEBOOK_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"github": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"GITHUB_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"gitlab": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"GITLAB_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"google": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"GOOGLE_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"okta": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"OKTA_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"slack": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"SLACK_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"twitch": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"TWITCH_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"twitter": {
"description": "Enable or disable social auth option. You can set additional values like auto registration by replacing \"_\" with \".\" and in lowercase e.g. \"TWITTER_AUTO_REGISTER\" as \"auto.register\". You don't need the social auth key as a prefix.",
"$ref": "#/definitions/socialAuth"
},
"ldap": {
"type": "object",
"description": "Enable or disable social auth option. You can set additional values like email attribute by replacing \"_\" with \".\" and in lowercase e.g. \"LDAP_EMAIL_ATTRIBUTE\" as \"email.attribute\". You don't need the \"LDAP_\" key as a prefix.",
"additionalProperties": true,
"properties": {
"enabled": {
"type": "boolean",
"default": "false",
"description": "Wether LDAP auth is enabled"
},
"server": {
"type": "string",
"default": "",
"description": "The LDAP server to connect to."
},
"dn": {
"type": "string",
"default": "",
"description": "User DN used for authentication"
},
"pass": {
"type": "string",
"default": "",
"description": "Password used for authentication"
},
"base.dn": {
"type": "string",
"default": "",
"description": "LDAP Base search dn"
}
},
"required": ["enabled"]
}
}
},
"extraEnv": {
"type": "object",
"additionalProperties": {
"type": ["string", "object"],
"description": "Extra environment variables for bookstack. Could be a simple string or a valueFrom..."
}
},
"persistence": {
"type": "object",
"description": "Defines volume settings for data persistence in bookstack",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Wether volume will be created"
},
"size": {
"type": "string",
"default": "10Gi",
"description": "The size of the volume which will be created. Be careful some storage interfaces don't support resizing."
},
"storageClass": {
"type": "string",
"description": "",
"default": ""
},
"accessMode": {
"type": "string",
"default": "ReadWriteMany",
"description": "Access mode to define how many times the volume could be mounted."
}
},
"required": ["enabled", "size", "accessMode"]
}
}
},
"ingress": {
"type": "object",
"description": "Here you can define the ingress settings for your application. This is only needed if you want to expose your application to the outside world.",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable the ingress",
"default": false
},
"annotations": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"description": "You can add these Kubernetes annotations to specific Ingress objects to customize their behavior.\n!!! tip Annotation keys and values can only be strings. Other types, such as boolean or numeric values must be quoted, i.e. \"true\", \"false\", \"100\". More info: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md",
"type": "object"
}
},
"tls": {
"description": "tls represents the TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.",
"items": {
"$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.31.6/_definitions.json#/definitions/io.k8s.api.networking.v1.IngressTLS"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"class": {
"type": "string",
"description": "The class of the ingress. This is used to select the ingress controller that should handle this ingress. If not set, the default ingress class will be used."
},
"hostname": {
"type": "string",
"description": "The hostname for the ingress. This is used to route traffic to the correct service."
},
"path": {
"type": "string",
"description": "The path for the ingress. This is used to route traffic to the correct service.",
"default": "/"
},
"pathType": {
"type": "string",
"description": "The path type for the ingress. This is used to route traffic to the correct service.",
"enum": [
"Exact",
"Prefix",
"ImplementationSpecific"
],
"default": "Prefix"
}
},
"required": [
"enabled",
"hostname",
"path",
"pathType"
]
},
"service": {
"type": "object",
"description": "Here you can define the service settings for your application.",
"additionalProperties": false,
"properties": {
"port": {
"type": "integer",
"description": "The port that the service should listen on.",
"default": 8080
},
"type": {
"type": "string",
"enum": [
"ClusterIP",
"NodePort",
"LoadBalancer",
"Headless"
],
"description": "The type of the service. This defines how the service is exposed or not.",
"default": "ClusterIP"
},
"loadBalancerIP": {
"type": [
"string",
"null"
],
"description": "LoadBalancerIP is the IP address that will be assigned to the service when it is created. This is only used if the service type is LoadBalancer.",
"default": ""
},
"nodePort": {
"type": [
"integer",
"string",
"null"
],
"description": "NodePort is the port that will be assigned to the service when it is created. This is only used if the service type is NodePort.",
"default": ""
},
"clusterIP": {
"type": [
"string",
"null"
],
"description": "ClusterIP is the IP address that will be assigned to the service when it is created. This is only used if the service type is ClusterIP.",
"default": ""
}
},
"required": [
"port",
"type"
]
},
"db": {
"type": "object",
"description": "Here you can define the database settings for your application.",
"additionalProperties": true,
"properties": {
"enabled": {
"type": "boolean",
"description": "Whether this deployment is enabled",
"default": true
}
},
"required": [
"enabled"
]
},
"redis": {
"type": "object",
"description": "Here you can define the redis settings for your application.",
"additionalProperties": true,
"properties": {
"enabled": {
"type": "boolean",
"description": "Whether this deployment is enabled",
"default": true
}
},
"required": [
"enabled"
]
}
},
"required": [
"global",
"bookstack",
"db",
"redis",
"service",
"ingress"
],
"definitions": {
"socialAuth": {
"type": "object",
"additionalProperties": true,
"properties": {
"enabled": {
"type": "boolean",
"description": "Whether this auth option is enabled",
"default": false
},
"appId": {
"type": "string",
"description": "",
"default": ""
},
"appSecret": {
"type": "string",
"description": "",
"default": ""
}
}
}
}
}

View File

@@ -18,12 +18,8 @@ bookstack:
app: app:
key: "" key: ""
url: "https://example.com" url: "https://example.com"
views.books: list additional: {}
views.bookshelves: grid additionalSecrets: {}
views.bookshelf: grid
default.dark.mode: true
additional:
DISABLE_EXTERNAL_SERVICES: false
mail: mail:
driver: "smtp" driver: "smtp"
host: "" host: ""

83
generate_changelog.py Normal file
View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""
generate_changelog.py - Wandelt den Artifact Hub-Changelog in Chart.yaml
in eine Markdown-Datei (CHANGELOG.md) um.
Aufruf:
python generate_changelog.py # takes ./Chart.yaml
python generate_changelog.py path/to/Chart.yaml
"""
import argparse
import datetime as dt
import pathlib
import sys
import textwrap
import yaml
MD_HEADER = "# Changelog\n\n"
def read_chart(path: pathlib.Path) -> dict:
if not path.exists():
sys.exit(f"❌ Chart.yaml not found: {path}")
with path.open() as f:
return yaml.safe_load(f)
def extract_changes(chart: dict) -> list[dict]:
try:
raw = chart["annotations"]["artifacthub.io/changes"]
except KeyError:
sys.exit("❌ No 'artifacthub.io/changes' annotations found.")
try:
return yaml.safe_load(raw) or []
except yaml.YAMLError as e:
sys.exit(f"❌ Changelog annotations are not in a valid YAML format:\n{e}")
def render_markdown(chart: dict, changes: list[dict]) -> str:
version = chart.get("version", "Unversioniert")
today = dt.date.today().isoformat()
heading = f"## {version} - {today}\n"
bullets = []
for item in changes:
kind = item.get("kind", "").capitalize()
desc = item.get("description", "").strip()
links = item.get("links", [])
link_md = ""
if links:
link_md = " " + " ".join(f"[{l['name']}]({l['url']})" for l in links)
bullets.append(f"- **{kind}** {desc}{link_md}")
return MD_HEADER + heading + "\n".join(bullets) + "\n"
def main() -> None:
parser = argparse.ArgumentParser(
description="Generates CHANGELOG.md from Chart.yaml annotations."
)
parser.add_argument(
"chart_yaml",
nargs="?",
default="Chart.yaml",
help="Pfad zur Chart.yaml (Standard: ./Chart.yaml)",
)
args = parser.parse_args()
chart_path = pathlib.Path(args.chart_yaml)
chart = read_chart(chart_path)
changes = extract_changes(chart)
changelog_md = render_markdown(chart, changes)
outfile = chart_path.parent / "CHANGELOG.md"
outfile.write_text(changelog_md, encoding="utf-8")
print(f"✅ CHANGELOG.md generated under {outfile.resolve()}.")
if __name__ == "__main__":
main()

29
pubkeys/morlana.asc Normal file
View File

@@ -0,0 +1,29 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGgiWykBEACtiiNGno+ZL99rI0qP98Ei+HNcs/MgBWqjPa3/nYv6wK1FVEhu
95w/4Oh/EBEP7vuq5lDfC2JQHiif6AHu4tBB6V2Hx3XLyZE9HY+7SuqIWzeGGr2F
GlD8GkEQ4/HtdHDK+htFUgTPrzW7f/ax5pgvvzAXQcXnC6fIOGsd2IJO0LoEjhTn
KJQqEOgPqGjyfND9+3bfscLJi2CSK23pWz30f1sTzqLM4eMN7poXGqjwjtyKwGog
j66t6Na6A/B3AU9QPP5BB1/Qj09FVsd/InLsyelULG1fZmY0wx2/wiE0VNhenjGa
EejCp8oHieZ++x811ux6wROdJc38HC5lJfXhyob3yJ2OXeGBYnZG8PrT2CqJpTXz
W/5kDVYAyKOh2iiPGADGlMOajnyCgtRI9YEsKYybxlRW7vuvh7ItHb7/iplbamgx
RUrxiJGDMTEENsePTQq4pGOblXptw6PiIogGv9kWJ9WaEIbbAlFJmAIOh2JXRF+Y
JgaCzUjUNRv/z3P5Ymwd2qYxp+RO8QVCPs+/PAqL0BgwCFQXhOC5Yez3/89D5tKy
UOMBxK+xP3i7mj5C6BZa+1ChMdN9yUYpGKVfm16xLVrGBbwWZI6YB4qF+3n4qUtp
Ld7CVEzPVarftb8UpIaqAO/R/MYPUAJeKCykHrlaaOqkj3Dhacqgl+h9FQARAQAB
tDFNb3JsYW5hIFNpZ25pbmcgPGNvbnRhY3QrZGV2ZWxvcG1lbnRAbW9ybGFuYS5u
ZXQ+iQJOBBMBCgA4FiEEiXVuIB5MmbGi6VcS333yWc2PyqoFAmgiWykCGwMFCwkI
BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ333yWc2PyqrhXA//SnEa+hG0hIAB4Ua/
qgqv/7nzpRIFAA5tqSoOPZ0p4YvtsSywc7zJ+ZH7IClvlewOo0Omeo4XiYQCLYSL
LnYv/yqrWVNU35TI29k2RTE4pmcHB9hMdG8heI2c5O3vd9C4yQCWwWKMSD3pEPrq
aLkHkQvLyXZukBeMzNFaVK4wOjPB02MadQLIu9rbUbKW9DvUmt/x8uBVmm/Pq4Ds
HBgxdnOifEhzMG2gG+4UJYt2jfibMwCJpM4d/drs28Qf9dhjj1UHzhhwBW3OpJkJ
E+hHVMObzolefh4eR3gPctIkxuVjYC91FVZkqVV3TgrLKhfgro5ML7IFgCnzHVuZ
PKJsssNZds+2Sv/nf2QtXcGvQgZ3xjNlaQUxE0WTGe+DKx4pMyxx4s+eNYGhA5Yo
rrb9on8TfDNaexU0BDUyt3DLQVxk8niqQPmj9jmD+BrsjWnj7Dn1yCgjre/viZjH
Ys8AHwxSu4qh3XBtjUQ9YDhUMmNqIOtJHiVp97kWbLbQ7CiCI+/7IT6Pk50+GzXV
KaTRfEp6zxpMx2wgsw4CP7aKukLrIFWxDNyQ+030c8TQW8WuL1W3oTzh0iu7DCgR
XVmgS6+YAbxjX/gAD0Dx3jLftQ2Y3PGMWPXtZmtZucIFhg1ArmYb2v1n8sWMi+cK
k/0Bxc8p29/H9s7dv5pVyrx2fcM=
=o6F8
-----END PGP PUBLIC KEY BLOCK-----