Compare commits
10 commits
d6eda322de
...
7b9eea3229
Author | SHA1 | Date | |
---|---|---|---|
|
7b9eea3229 | ||
|
5ee8e81372 | ||
|
6e645c6abf | ||
|
65049a09b5 | ||
|
0ac0a6eeb2 | ||
|
29ea18b2a2 | ||
|
cd226ea065 | ||
|
40523875f0 | ||
|
3d8d3e5724 | ||
|
e9204a27ba |
20 changed files with 138 additions and 89 deletions
97
README.md
97
README.md
|
@ -10,49 +10,6 @@ with a double-digit user number,
|
|||
so all experiments happen carefully.
|
||||
Still, it is an experimental offering.
|
||||
|
||||
## Tools
|
||||
|
||||
Useful tools for administration:
|
||||
- my `stack` CLI helper, currently part of my dotfiles:
|
||||
https://git.jfischer.org/xeruf/dotfiles/src/branch/main/.config/shell/server#L11
|
||||
- stackspin docs:
|
||||
https://docs.stackspin.net/en/v2/system_administration/customizing.html
|
||||
|
||||
## Explanation - Typical App Deployment in Stackspout with Flux on Kubernetes
|
||||
|
||||
The diagram illustrates generically how continuous app deployment works in our Kubernetes cluster
|
||||
from Infrastructure-as-Code using flux.
|
||||
Not every app has database, backend and frontend,
|
||||
but in the end the deployments all work very similarly
|
||||
so there is no point showing it for each individual app.
|
||||
Except for the Single-Sign On,
|
||||
apps also do not really depend on each other.
|
||||
|
||||
Explanations:
|
||||
- deploy :: creates a resource on the cluster from a file in the GitRepository
|
||||
- create :: creates a resource on the cluster using Kubernetes logic
|
||||
- ... all :: creates multiple independent resources
|
||||
|
||||
All Flux Kustomizations refer to a directory in the GitRepository,
|
||||
but for clarity I omitted it beyond the initial one.
|
||||
|
||||
Clouds are created not via Flux GitOps,
|
||||
but through one-time scripts.
|
||||
|
||||

|
||||
|
||||
### Guide: Creating OAuth Credentials for an external service
|
||||
- push an OAuth2Client definition like for the apps,
|
||||
adjusting `metadata.name` and `spec.secretName` as well as `spec.redirectUris`
|
||||
- obtain the generated `client_secret` for your application from kubernetes:
|
||||
|
||||
kubectl get secret -n flux-system stackspin-APP-oauth-variables --template '{{.data.client_secret}}' | base64 -d
|
||||
|
||||
with client_id:
|
||||
|
||||
kubectl get secret -n flux-system stackspin-APP-oauth-variables --template '{{.data.client_id}}{{"\n"}}{{.data.client_secret}}{{"\n"}}' | while read in; do echo $in | base64 -d; echo; done
|
||||
|
||||
|
||||
## Customizations
|
||||
|
||||
### Overrides
|
||||
|
@ -60,7 +17,12 @@ but through one-time scripts.
|
|||
-> most notably `external` to add Applications into Nextcloud as hub
|
||||
|
||||
### New Applications
|
||||
below list is formatted as:
|
||||
|
||||
Following are the applications Stackspout adds beyond Stackspin.
|
||||
Unlike Stackspin, there is currently no mechanism to add those individually,
|
||||
they come in one package with the repository.
|
||||
|
||||
Below list is formatted as:
|
||||
> subdomain: Service (helmrepo, if not provided by the service authors)
|
||||
|
||||
#### Stable including Single-Sign-On
|
||||
|
@ -98,7 +60,7 @@ First [install Stackspin](https://docs.stackspin.net/en/latest/installation/inst
|
|||
Then apply the configuration to your cluster:
|
||||
|
||||
```sh
|
||||
install.sh
|
||||
./install.sh
|
||||
```
|
||||
|
||||
Done!
|
||||
|
@ -114,3 +76,48 @@ kubectl -n stackspout get pods
|
|||
```
|
||||
|
||||
But there are also ConfigMaps, Secrets, StatefulSets, PVCs, Helmrepos and more...
|
||||
|
||||
### Tools
|
||||
|
||||
Useful tools for administration:
|
||||
- my `stack` CLI helper, currently part of my dotfiles:
|
||||
https://git.jfischer.org/xeruf/dotfiles/src/branch/main/.config/shell/server#L11
|
||||
- stackspin docs:
|
||||
https://docs.stackspin.net/en/v2/system_administration/customizing.html
|
||||
|
||||
### Guide: Creating OAuth Credentials for an external service
|
||||
- push an OAuth2Client definition like for the apps,
|
||||
adjusting `metadata.name` and `spec.secretName` as well as `spec.redirectUris`
|
||||
- obtain the generated `client_secret` for your application from kubernetes:
|
||||
|
||||
kubectl get secret -n flux-system stackspin-APP-oauth-variables --template '{{.data.client_secret}}' | base64 -d
|
||||
|
||||
with client_id:
|
||||
|
||||
kubectl get secret -n flux-system stackspin-APP-oauth-variables --template '{{.data.client_id}}{{"\n"}}{{.data.client_secret}}{{"\n"}}' | while read in; do echo $in | base64 -d; echo; done
|
||||
|
||||
|
||||
## Explanation - Typical App Deployment in Stackspout with Flux on Kubernetes
|
||||
|
||||
The diagram illustrates generically how continuous app deployment works in our Kubernetes cluster
|
||||
from Infrastructure-as-Code using flux.
|
||||
Not every app has database, backend and frontend,
|
||||
but in the end the deployments all work very similarly
|
||||
so there is no point showing it for each individual app.
|
||||
Except for the Single-Sign On,
|
||||
apps also do not really depend on each other.
|
||||
|
||||
Explanations:
|
||||
- deploy :: creates a resource on the cluster from a file in the GitRepository
|
||||
- create :: creates a resource on the cluster using Kubernetes logic
|
||||
- ... all :: creates multiple independent resources
|
||||
|
||||
All Flux Kustomizations refer to a directory in the GitRepository,
|
||||
but for clarity I omitted it beyond the initial one.
|
||||
|
||||
Clouds are created not via Flux GitOps,
|
||||
but through one-time scripts.
|
||||
|
||||

|
||||
|
||||
See also https://about.ftt.gmbh/projects/polygon.html#state-of-stackspout-2022
|
||||
|
|
|
@ -25,6 +25,8 @@ data:
|
|||
enabled: true
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
hosts:
|
||||
- host: "${n8n_domain}"
|
||||
paths: [ "/" ]
|
||||
|
|
|
@ -7,5 +7,6 @@ metadata:
|
|||
spec:
|
||||
fields:
|
||||
- fieldName: forgejo_admin_password
|
||||
- fieldName: lfs_jwt
|
||||
- fieldName: postgresql_password
|
||||
- fieldName: postgresql_admin_password
|
||||
|
|
|
@ -9,7 +9,9 @@ data:
|
|||
enabled: true
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "1g"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
hosts:
|
||||
- host: "${forgejo_domain}"
|
||||
paths:
|
||||
|
@ -59,8 +61,8 @@ data:
|
|||
server:
|
||||
LANDING_PAGE: login
|
||||
ROOT_URL: "https://${forgejo_domain}"
|
||||
# PROTOCOL: "https"
|
||||
# DOMAIN:
|
||||
LFS_START_SERVER: true
|
||||
LFS_JWT_SECRET: "${lfs_jwt}"
|
||||
openid:
|
||||
ENABLE_OPENID_SIGNUP: true
|
||||
service:
|
||||
|
@ -84,7 +86,7 @@ data:
|
|||
cors:
|
||||
ENABLED: true
|
||||
SCHEME: "https"
|
||||
ALLOW_DOMAIN: "files.ftt.gmbh"
|
||||
ALLOW_DOMAIN: "files.${domain}"
|
||||
ALLOW_CREDENTIALS: true
|
||||
# log:
|
||||
# LEVEL: "Debug"
|
||||
|
|
|
@ -8,3 +8,9 @@ stringData:
|
|||
NEXT_PUBLIC_WEBAPP_URL: "https://${calcom_domain}"
|
||||
NEXTAUTH_SECRET: "${nextauth_secret}"
|
||||
CALENDSO_ENCRYPTION_KEY: "${calendso_key}"
|
||||
EMAIL_FROM: "${outgoing_mail_from_address}"
|
||||
EMAIL_SERVER_HOST: "${outgoing_mail_smtp_host}"
|
||||
EMAIL_SERVER_PORT: "!!str ${outgoing_mail_smtp_port}"
|
||||
EMAIL_SERVER_USER: "${outgoing_mail_smtp_user}"
|
||||
EMAIL_SERVER_PASSWORD: "${outgoing_mail_smtp_password}"
|
||||
# email_enabled: "${outgoing_mail_enabled}"
|
||||
|
|
|
@ -33,6 +33,8 @@ data:
|
|||
enabled: true
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
hosts:
|
||||
- host: "${calcom_domain}"
|
||||
paths:
|
||||
|
@ -42,17 +44,3 @@ data:
|
|||
- secretName: calcom-tls
|
||||
hosts:
|
||||
- "${calcom_domain}"
|
||||
|
||||
# TODO Adjust calcom Mailing config
|
||||
# mailer:
|
||||
# enabled: "${outgoing_mail_enabled}"
|
||||
# host: "${outgoing_mail_smtp_host}"
|
||||
# port: "${outgoing_mail_smtp_port}"
|
||||
# username: "${outgoing_mail_smtp_user}"
|
||||
# password: "${outgoing_mail_smtp_password}"
|
||||
# fromemail: "${outgoing_mail_from_address}"
|
||||
# TODO Adjust calcom OpenID Connect Single Sign-On Configuration
|
||||
# - name: Stackspin
|
||||
# key: "${client_id}"
|
||||
# secret: "${client_secret}"
|
||||
# autoDiscoverUrl: 'https://${hydra_domain}/.well-known/openid-configuration'
|
||||
|
|
|
@ -17,7 +17,7 @@ data:
|
|||
certManager: true
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' ${nextcloud_domain}";
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
commonLabels:
|
||||
stackspin.net/backupSet: "invoiceninja"
|
||||
podLabels:
|
||||
|
|
|
@ -23,6 +23,8 @@ data:
|
|||
enabled: true
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
hosts:
|
||||
- host: "${taiga_domain}"
|
||||
paths:
|
||||
|
|
|
@ -16,6 +16,10 @@ data:
|
|||
hosts:
|
||||
- "${gatus_domain}"
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
existingClaim: "gatus-data"
|
||||
|
||||
security:
|
||||
oidc:
|
||||
issuer-url: "https://${hydra_domain}"
|
||||
|
@ -89,6 +93,14 @@ data:
|
|||
url: "https://forge.${domain}"
|
||||
<<: *defaults
|
||||
group: "Stackspout"
|
||||
- name: "Cal.com Appointment Booking"
|
||||
url: "https://meet.${domain}"
|
||||
<<: *defaults
|
||||
group: "Stackspout"
|
||||
- name: "Gatus Health Dashboard"
|
||||
url: "https://status.${domain}"
|
||||
<<: *defaults
|
||||
group: "Stackspout"
|
||||
|
||||
- name: "Mailserver STARTTLS"
|
||||
url: "starttls://${outgoing_mail_smtp_host}:587"
|
||||
|
|
|
@ -18,6 +18,8 @@ data:
|
|||
enabled: true
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: "true"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
hosts:
|
||||
- host: "${zammad_domain}"
|
||||
paths:
|
||||
|
|
|
@ -14,3 +14,8 @@ flux create kustomization stackspout \
|
|||
--path="./infrastructure/kustomizations/" \
|
||||
--prune=true \
|
||||
--interval=5m
|
||||
|
||||
flux bootstrap git \
|
||||
--url=https://open.greenhost.net/xeruf/stackspout.git \
|
||||
--branch=main \
|
||||
--path=util/flux
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
#- stackspin-zulip-override.yaml # no push notifications for now
|
||||
- stackspin-nextcloud-override.yaml
|
||||
- stackspin-nginx-ingress-override.yaml
|
||||
- stackspin-apps-custom.yaml
|
||||
- storageclass-retain.yaml
|
||||
- source-controller-patch.yaml
|
|
@ -1,13 +0,0 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: source-controller-patch
|
||||
namespace: flux-system
|
||||
patches:
|
||||
- patch: |
|
||||
- op: add
|
||||
path: /spec/template/spec/containers/0/args/-
|
||||
value: --helm-index-max-size=80000000
|
||||
target:
|
||||
kind: Deployment
|
||||
name: "source-controller"
|
|
@ -5,6 +5,30 @@ metadata:
|
|||
name: stackspin-zulip-override
|
||||
data:
|
||||
values.yaml: |
|
||||
zulip:
|
||||
environment:
|
||||
SETTING_PUSH_NOTIFICATION_BOUNCER_URL: 'https://push.zulipchat.com'
|
||||
ingress:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Content-Security-Policy: frame-ancestors 'self' files.${domain}";
|
||||
|
||||
#zulip:
|
||||
# environment:
|
||||
# SETTING_PUSH_NOTIFICATION_BOUNCER_URL: 'https://push.zulipchat.com'
|
||||
## https://github.com/zulip/docker-zulip/blob/main/kubernetes/chart/zulip/values.yaml
|
||||
#ingress:
|
||||
# enabled: true
|
||||
# annotations:
|
||||
# # Tell cert-manager to automatically get a TLS certificate
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
# # Allow bigger uploads, for image and file attaching.
|
||||
# # 25M is the default limit of Zulip itself, so we just follow that
|
||||
# # suggestion here. If you want to increase this further, you'd have to
|
||||
# # configure that limit in Zulip as well.
|
||||
# nginx.ingress.kubernetes.io/proxy-body-size: "25m"
|
||||
# hosts:
|
||||
# - host: "${zulip_domain}"
|
||||
# paths:
|
||||
# - path: "/"
|
||||
# tls:
|
||||
# - hosts:
|
||||
# - "${zulip_domain}"
|
||||
# secretName: stackspin-zulip
|
||||
|
|
0
util/flux/gotk-components.yaml
Normal file
0
util/flux/gotk-components.yaml
Normal file
0
util/flux/gotk-sync.yaml
Normal file
0
util/flux/gotk-sync.yaml
Normal file
20
util/flux/source-controller-patch.yaml
Normal file
20
util/flux/source-controller-patch.yaml
Normal file
|
@ -0,0 +1,20 @@
|
|||
# https://fluxcd.io/flux/installation/configuration/boostrap-customization/
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources: # manifests generated during bootstrap
|
||||
- gotk-components.yaml
|
||||
- gotk-sync.yaml
|
||||
patches:
|
||||
- patch: |
|
||||
- op: add
|
||||
path: /spec/template/spec/containers/0/args/-
|
||||
value: --helm-index-max-size=80000000
|
||||
- op: replace
|
||||
path: /spec/template/spec/volumes/0
|
||||
value:
|
||||
name: temp
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
target:
|
||||
kind: Deployment
|
||||
name: "source-controller"
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Loading…
Add table
Reference in a new issue