14 Commits

Author SHA1 Message Date
578d35d55f switch from cronjob to scheduler service 2026-04-03 15:43:11 +03:00
6bdd590d1a Merge pull request 'Remove-Bitnami-Dependencies' (#7) from Remove-Bitnami-Dependencies into 2.0.0
Reviewed-on: #7
2025-12-08 11:15:42 +00:00
35a52529ff Clean up secret-values. 2025-12-08 14:13:26 +03:00
61be0e0405 Enable cronjobs. 2025-12-08 14:10:03 +03:00
6ee15ba226 Update the README 2025-12-08 09:19:18 +03:00
03d9b1156d Refactor the chart for ease of use. 2025-12-05 16:03:34 +03:00
5adbdbdcee . 2025-12-05 09:56:49 +03:00
a9f9703eaa Minio bucket and user policy fixes. 2025-12-05 09:55:47 +03:00
854ed6da5f Bitnami removed. 2025-12-04 11:43:13 +03:00
214f94f8b5 Chart version 2.0.0 - no Bitnami 2025-12-03 13:14:37 +03:00
0a7499c373 . 2025-12-02 08:29:58 +03:00
23ad2174ab work in progress 2025-11-25 11:29:04 +03:00
ce2e8543cf Replace Bitnami Charts and images. 2025-10-16 16:26:38 +03:00
artem.drozdov
f3f0c36b6b remove mono 2024-10-07 13:56:01 +03:00
19 changed files with 413 additions and 1371 deletions

View File

@@ -1,10 +1,19 @@
# Yonote Helm Chart
**Критическое изменение**
Данный чарт предназначен только для новых развертываний!
Версия 2.x.x не совместима с предыдущими версиями 1.x.x данного чарта. Если вы попытаетесь использовать этот чарт для обновления существующего развертывания Yonote, это приведет к потере данных.
Руководство по миграции будет предоставлено в ближайшее время.
## Обзор
Этот Helm chart позволяет развернуть **Yonote** в Kubernetes. Он предоставляет быстрый и простой способ установки, настройки и управления приложением с помощью Helm.
В нашем проекте используются два подхода для управления сервисами с помощью Helm chart'ов: "mono" и "service". В варианте "mono" все сервисы запускаются в одном pod'е, что позволяет снизить использование ресурсов. В подходе "service" каждый сервис запускается в отдельном pod'е, что улучшает отказоустойчивость и стабильность системы, но требует больше ресурсов.
Мы запускаем сервисы Yonote в отдельных подах, что улучшает отказоустойчивость и стабильность системы. Такой подход позволяет каждому сервису иметь свою собственную среду выполнения и управлять ресурсами более эффективно.
## Требования
@@ -48,6 +57,26 @@ helm install app -f values.yaml -f secret-values.yaml -n yonote-onprem .
```
После выполнения команды начнётся установка приложения и всех дополнительных сервисов к нему. Остаётся только подождать, пока все сервисы запустятся.
### 5. Keycloak
Перед первым входом в Yonote необходимо обновить поле **Valid redirect URIs** клиента yonote в области (realm) Yonote в системе Keycloak.
Уже существуют две записи, поэтому достаточно просто скопировать их и отредактировать.
Например:
Существующие записи:
* http://example.com/*
* https://example.com/*
Добавить следующие:
* http://app.example.com/*
* https://app.example.com/*
* https://app.example.com/auth/oidc.callback/*
* https://team.example.com/*
Примечание: символы * в URL-адресах являются подстановочными знаками и обозначают любые дополнительные пути после указанного базового URL.
### Обратная связь
Если у вас есть вопросы или вам нужна помощь, пишите на email: hello@yonote.ru

View File

@@ -1,18 +0,0 @@
dependencies:
- name: app
repository: https://dysnix.github.io/charts
version: 0.3.15
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 11.6.6
- name: redis
repository: https://charts.bitnami.com/bitnami
version: 16.12.1
- name: minio
repository: https://charts.bitnami.com/bitnami
version: 12.7.0
- name: keycloak
repository: https://charts.bitnami.com/bitnami
version: 14.0.0
digest: sha256:b12099844193a7a06a5d15b80774592b1cf73af191b654154a9c7a6e8d51a2e0
generated: "2024-08-25T04:02:50.20628049+03:00"

View File

@@ -1,40 +0,0 @@
apiVersion: v2
name: yonote-chart
version: 1.2.0
description:
Generic application Helm chart.
This chart includes multiple dependencies. The base of this chart is derived from the Dynix app chart.
maintainers:
- name: Dysnix
email: support@dysnix.com
url: https://github.com/dysnix/charts/tree/main/dysnix/app
dependencies:
- name: app
version: "0.3.15"
repository: https://dysnix.github.io/charts
alias: yonote-web
- name: postgresql
version: "11.6.6"
repository: https://charts.bitnami.com/bitnami
condition: yonoteDatabase.enabled
alias: yonoteDatabase
- name: redis
version: "16.12.1"
repository: https://charts.bitnami.com/bitnami
condition: yonote-redis.enabled
alias: yonote-redis
- name: minio
version: "12.7.0"
repository: https://charts.bitnami.com/bitnami
condition: minio.enabled
alias: minio
- name: keycloak
version: "14.0.0"
repository: https://charts.bitnami.com/bitnami
condition: keycloak.enabled
alias: keycloak

View File

@@ -1,45 +0,0 @@
global:
yonote:
config:
secret:
stringData:
DATABASE_URL: 'postgres://{{ .Values.yonoteDatabase.global.postgresql.auth.username }}:{{ .Values.yonoteDatabase.global.postgresql.auth.password }}@yonote-database:5432/{{ .Values.yonoteDatabase.global.postgresql.auth.database }}'
POSTGRES_PASSWORD: "{{ .Values.yonoteDatabase.global.postgresql.auth.password }}"
AWS_ACCESS_KEY_ID: "{{ .Values.minio.auth.rootUser }}" # Ваш идентификатор ключа доступа к AWS. Поведение в SelfHosted: устанавливает логин сервис аккаунта для доступа приложения к Minio S3 хранилищу
AWS_SECRET_ACCESS_KEY: "{{ .Values.minio.auth.rootPassword }}" # Ваш секретный ключ доступа AWS. Поведение в SelfHosted: устанавливает пароль сервис аккаунта для доступа приложения к Minio S3 хранилищу
OIDC_CLIENT_SECRET: "Kdq8rk5Pv5RW1c5kHXpnyfrmMRzI9xSD" # Секретный ключ клиента для аутентификации по OpenID Connect (OIDC).
SECRET_KEY: "659a8881b186198c3146e316f6dab67df25496534d1fa156d624b037260df688" # Сгенерируйте 32-байтовый случайный ключ в шестнадцатеричном коде. Вам следует использовать `openssl rand -hex 32` в вашем терминале для генерации случайного значения.
SMTP_PASSWORD: "1234"
UTILS_SECRET: "7bd5e9ac4415dd0dbf6b7721e2a21e9427b268cd0140c7516d13dece5024d479" # Сгенерируйте уникальный случайный ключ. Формат не важен, но вы все равно можете использовать`openssl rand -hex 32` в вашем терминале, чтобы создать это.
TELEGRAM_BOT_TOKEN: "1234"
UNSPLASH_API_ACCESS_KEY: "a-yGo6HpRP6jNfravx4Bz-oiPrRnH_5-24Xa9ZPlePE"
LICENSE_KEY: "qwerty-123456-zxcvb" # Обратитесь в отдел продаж для получения
SERVICE_WORKER_PUBLIC_KEY: "1234"
SERVICE_WORKER_PRIVATE_KEY: "1234"
# Генерация ключей (web-push) Service Worker
# 1) Установить Node.js и npm
# 2) Выполнить команду для генерации ключей
# npx web-push generate-vapid-keys
# 3) Полученные значения ввести в .env файл (SERVICE_WORKER_PUBLIC_KEY, SERVICE_WORKER_PRIVATE_KEY)
yonoteDatabase:
global:
postgresql:
auth:
password: "wsGZ6kXhr5"
postgresPassword: "QQYw4UjOU"
# yonote-redis: # Если используете пароль для redis
# auth:
# password: "12345678"
minio:
auth:
rootPassword: "12345678"
keycloak:
auth:
adminPassword: "root"
postgresql:
auth:
password: "tT9BqYdNyd"

View File

@@ -1,10 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: yonote-configs
labels:
{{- include "common.labels.standard" $ | nindent 4 }}
{{- with .Values.global.yonote.config.plain.data }}
data:
{{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 2 }}
{{- end }}

View File

@@ -1,69 +0,0 @@
{{- if eq ($.Values.global.yonote_cron_calendar_events.cron_enabled | toString) "true" }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: cron-calendar-events
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-calendar-events
image: curlimages/curl
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: yonote-secrets
command:
- /bin/sh
- -c
- >-
date;
curl
-X POST
{{ .Values.global.yonote_cron_calendar_events.url }}
-H "Content-Type: application/json"
-d '
{
"token": "$(UTILS_SECRET)"
}
'
restartPolicy: OnFailure
{{- end }}
---
{{- if eq ($.Values.global.yonote_cron_task_scheduler.cron_enabled | toString) "true" }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: cron-task-scheduler
spec:
schedule: "0 */1 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-task-scheduler
image: curlimages/curl
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: yonote-secrets
command:
- /bin/sh
- -c
- >-
date;
curl
-X POST
{{ .Values.global.yonote_cron_task_scheduler.url }}
-H "Content-Type: application/json"
-d '
{
"token":"$(UTILS_SECRET)", "limit":"200"
}
'
restartPolicy: OnFailure
{{- end }}

View File

@@ -1,34 +0,0 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.ingress.name }}
namespace: {{ .Values.ingress.namespace }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.ingressClassName }}
tls:
- secretName: "{{ .Values.ingress.tls.secretName }}"
hosts:
{{- range .Values.ingress.tls.hosts }}
- "{{ . }}"
{{- end }}
rules:
{{- range .Values.ingress.rules }}
- host: "{{ .host }}"
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ .service.name }}
port:
number: {{ .service.port | int }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,39 +0,0 @@
{{- if .Values.mcJob.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: yonote-minio-mc-job
labels:
app: yonote-minio
spec:
template:
metadata:
labels:
app: yonote-minio
spec:
containers:
- name: mc-client
image: "docker.io/bitnami/minio-client:2024.8.13-debian-12-r0"
command: ["/bin/sh", "-c"]
args:
- |
until mc alias set myminio http://yonote-minio:9000 {{ .Values.minio.auth.rootUser }} {{ .Values.minio.auth.rootPassword }}; do
echo "Waiting for MinIO to be ready..."
sleep 5
done
if ! mc ls myminio/yonote-bucket; then
mc mb myminio/yonote-bucket
else
echo "Bucket yonote-bucket already exists."
fi
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
restartPolicy: OnFailure
backoffLimit: 5
ttlSecondsAfterFinished: 100
{{- end }}

View File

@@ -1,169 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: realm-export
data:
realm-export.json: |
{
"realm": "yonote",
"enabled": true,
"notBefore": 1647809856,
"defaultSignatureAlgorithm": "RS256",
"revokeRefreshToken": false,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 300,
"accessTokenLifespanForImplicitFlow": 900,
"ssoSessionIdleTimeout": 1800,
"ssoSessionMaxLifespan": 36000,
"ssoSessionIdleTimeoutRememberMe": 0,
"ssoSessionMaxLifespanRememberMe": 0,
"offlineSessionIdleTimeout": 2592000,
"offlineSessionMaxLifespanEnabled": false,
"offlineSessionMaxLifespan": 5184000,
"clientSessionIdleTimeout": 0,
"clientSessionMaxLifespan": 0,
"clientOfflineSessionIdleTimeout": 0,
"clientOfflineSessionMaxLifespan": 0,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"accessCodeLifespanLogin": 1800,
"actionTokenGeneratedByAdminLifespan": 43200,
"actionTokenGeneratedByUserLifespan": 300,
"oauth2DeviceCodeLifespan": 600,
"oauth2DevicePollingInterval": 5,
"sslRequired": "external",
"registrationAllowed": true,
"registrationEmailAsUsername": true,
"rememberMe": true,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": true,
"editUsernameAllowed": false,
"bruteForceProtected": false,
"permanentLockout": false,
"maxFailureWaitSeconds": 900,
"minimumQuickLoginWaitSeconds": 60,
"waitIncrementSeconds": 60,
"quickLoginCheckMilliSeconds": 1000,
"maxDeltaTimeSeconds": 43200,
"failureFactor": 30,
"clients": [
{
"clientId": "{{ .Values.global.yonote.config.plain.data.OIDC_CLIENT_ID }}",
"secret": "{{ .Values.global.yonote.config.secret.stringData.OIDC_CLIENT_SECRET }}",
"redirectUris": [
"https://*.{{ .Values.global.yonote.baseListenAddress }}/*",
"http://*.{{ .Values.global.yonote.baseListenAddress }}/*",
"http://app.{{ .Values.global.yonote.baseListenAddress }}/*",
"https://app.{{ .Values.global.yonote.baseListenAddress }}/*",
"https://app.{{ .Values.global.yonote.baseListenAddress }}/auth/oidc.callback/*"
],
"baseUrl": "https://app.{{ .Values.global.yonote.baseListenAddress }}",
"enabled": true,
"publicClient": false,
"protocol": "openid-connect",
"attributes": {
"client.secret": "{{ .Values.global.yonote.config.secret.stringData.OIDC_CLIENT_SECRET }}",
"display.on.consent.screen": "true"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"protocolMappers": [
{
"name": "oidc-display-name",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}",
"jsonType.label": "String"
}
}
],
"defaultClientScopes": ["openid", "email"]
}
],
"identityProviders": [],
"internationalizationEnabled": true,
"clientScopes": [
{
"name": "openid",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}"
},
"protocolMappers": []
},
{
"name": "email",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true"
},
"protocolMappers": [
{
"id": "56fe6d23-690a-465c-bc36-99bff8fef6eb",
"name": "email verified",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-property-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "emailVerified",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email_verified",
"jsonType.label": "boolean"
}
},
{
"id": "2c6acd0e-b776-48f5-9c3b-7bfdbbe712dc",
"name": "email",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-property-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "email",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email",
"jsonType.label": "String"
}
}
]
}
],
"browserSecurityHeaders": {
"contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';"
},
"webAuthnPolicyRpEntityName": "keycloak",
"webAuthnPolicySignatureAlgorithms": ["ES256"],
"webAuthnPolicyRpId": "",
"webAuthnPolicyAttestationConveyancePreference": "not specified",
"webAuthnPolicyAuthenticatorAttachment": "not specified",
"webAuthnPolicyRequireResidentKey": "not specified",
"webAuthnPolicyUserVerificationRequirement": "not specified",
"webAuthnPolicyCreateTimeout": 0,
"webAuthnPolicyAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyAcceptableAaguids": [],
"webAuthnPolicyPasswordlessRpEntityName": "keycloak",
"webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"],
"webAuthnPolicyPasswordlessRpId": "",
"webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
"webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
"webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
"webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
"webAuthnPolicyPasswordlessCreateTimeout": 0,
"webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyPasswordlessAcceptableAaguids": [],
"smtpServer": {}
}

View File

@@ -1,14 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: yonote-secrets
labels:
{{- include "common.labels.standard" $ | nindent 4 }}
type: Opaque
{{- with .Values.global.yonote.config.secret.data }}
data:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.global.yonote.config.secret.stringData }}
stringData: {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 2 }}
{{- end }}

View File

@@ -1,389 +0,0 @@
global:
name: yonote-app
yonote:
dbMigrationEnv: production-ssl-disabled # Режим подключения к базе данных при выполнении миграций. При использовании SSL подключения, установите значение `production`
baseListenAddress: example.com # Доменный адрес для yonote
config:
plain:
data:
NODE_ENV: production
FORCE_HTTPS: "false"
PGSSLMODE: disable # Отключает SSL подключение к базе данных. Уберите эту строку, если вы используете SSL подключение к PostgreSQL
WEB_CONCURRENCY: "1"
BIND_HOST: 0.0.0.0 # Хост по умолчанию
PORT: "3000" # Порт по умолчанию
REDIS_URL: redis://yonote-redis-master:6379
DEFAULT_LANGUAGE: ru_RU # Язык по умолчанию
ENABLE_UPDATES: "false"
AI_URL: "1234"
AI_API_KEY: "1234"
URL: 'https://app.{{ .Values.global.yonote.baseListenAddress }}' # Базовый url приложения
COLLABORATION_URL: 'wss://app.{{ .Values.global.yonote.baseListenAddress }}' # Cервер, для нормальной работы это не нужно устанавливать
OIDC_DISPLAY_NAME: email
OIDC_SCOPES: openid email
OIDC_CLIENT_ID: yonote
OIDC_AUTH_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/auth' # URL для авторизации пользователей через OpenID Connect (OIDC). Пользователь перенаправляется на этот адрес для входа в систему.
OIDC_LOGOUT_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/logout' # URL для выхода из системы через OIDC. Пользователь перенаправляется на этот адрес для завершения сессии и выхода.
OIDC_TOKEN_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/token' # URL для получения токенов доступа и обновления. Этот адрес используется для обмена авторизационным кодом на токены
OIDC_USERINFO_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/userinfo' # URL для получения информации о пользователе. Используется для получения данных профиля пользователя на основе его токена.
AWS_S3_ACL: private
AWS_S3_UPLOAD_BUCKET_URL: yonote-minio:9000 # Адрес S3 хранилища
AWS_S3_UPLOAD_BUCKET_NAME: yonote-bucket # Имя хранилища
AWS_REGION: "ru_RU"
AWS_S3_UPLOAD_MAX_SIZE: "226214400" # Максимальный размер хранилища
AWS_S3_FORCE_PATH_STYLE: "false" # Следует ли принудительно использовать URL-адреса стиля пути для объектов S3
S3_PROXY_ENABLED: "false" # Включает или выключает проксирование загрузки/выгрузки файлов на S3 через бэкенд, принимает boolean
S3_MULTIPART_PART_SIZE: "1000" # Настройка размера частей для multipart загрузки на S3 хранилище, принимает число, по умолчанию 1000 (1GB), значение в мегабайтах.
SUBDOMAINS_ENABLED: "true" # Поддержка поддоменов для команд
BASENAME_FOR_SUBDOMAIN: '{{ .Values.global.yonote.baseListenAddress }}' # Имя хоста
NOT_ALLOWED_SUBDOMAINS: app,collaboration,auth,api,dev,docs,doc,admin,test,quota,billing,i,storage,host,updates # Запрещенные поддомены
TELEGRAM_API_URL: https://api.telegram.org
UNSPLASH_API_BASENAME: https://api.unsplash.com
RESERVED_SUBDOMAINS: about,account,admin,advertising,api,app,assets,archive,beta,billing,blog,cache,cdn,code,community,dashboard,developer,developers,forum,help,home,http,https,imap,localhost,mail,marketing,mobile,multiplayer,new,news,newsletter,ns1,ns2,ns3,ns4,password,profile,realtime,sandbox,script,scripts,setup,signin,signup,site,smtp,support,status,static,stats,test,update,updates,ws,wss,web,websockets,www,www1,www2,www3,www4
SMTP_HOST: ""
SMTP_USERNAME: ""
SMTP_FROM_EMAIL: ""
SMTP_REPLY_EMAIL: ""
SMTP_PORT: ""
SMTP_SECURE: "" # connection will be upgraded: https://nodemailer.com/smtp/
SMTP_REQUIRE_TLS: ""
yonote_cron_calendar_events:
cron_enabled: "true"
url: http://yonote-web/api/cron.calendar_events
yonote_cron_task_scheduler:
cron_enabled: "true"
url: http://yonote-web/api/cron.schedule
yonote-web:
fullnameOverride: yonote-web
nameOverride: yonote-web
name: web
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.5
pullPolicy: IfNotPresent
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: 250m
memory: 256Mi
ingress:
enabled: true
name: yonote-ingress
namespace: yonote-onprem
ingressClassName: nginx
tls:
- secretName: "you_tls_secret"
hosts:
- "app.example.com"
- "team.example.com"
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/server-snippets: |
location /realtime {
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
}
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Host $http_host";
more_set_headers "X-Real-IP $remote_addr";
more_set_headers "X-Forwarded-Proto $scheme";
more_set_headers "X-Forwarded-For $proxy_add_x_forwarded_for";
cert-manager.io/cluster-issuer: ""
rules:
- host: "app.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: yonote-web
port:
number: 80
- path: /realtime
pathType: Prefix
backend:
service:
name: yonote-websockets
port:
number: 80
- path: /whiteboard
pathType: Prefix
backend:
service:
name: yonote-whiteboard
port:
number: 80
- path: /collaboration
pathType: Prefix
backend:
service:
name: yonote-collaboration
port:
number: 80
- host: "team.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: yonote-web
port:
number: 80
- path: /realtime
pathType: Prefix
backend:
service:
name: yonote-websockets
port:
number: 80
- path: /whiteboard
pathType: Prefix
backend:
service:
name: yonote-whiteboard
port:
number: 80
- path: /collaboration
pathType: Prefix
backend:
service:
name: yonote-collaboration
port:
number: 80
containerPorts:
- containerPort: 3000
name: app
protocol: TCP
service:
type: ClusterIP
port: 80
targetPort: app
envFrom:
- configMapRef:
name: yonote-configs
- secretRef:
name: yonote-secrets
podLabels:
redis-client: 'true'
podAnnotations:
checksum/configmap: "{{ toJson .Values.global.yonote.config.plain | sha256sum }}"
checksum/secret: "{{ toJson .Values.global.yonote.config.secret | sha256sum }}"
readinessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
httpGet:
path: /_health
port: app
livenessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
httpGet:
path: /_health
port: app
yonoteDatabase:
enabled: true
global:
postgresql:
auth:
database: "yonote"
username: "yonote"
name: yonote-database
fullnameOverride: yonote-database
nameOverride: yonote-database
primary:
persistence:
size: 500Mi
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 50m
memory: 256Mi
yonote-redis:
enabled: true
fullnameOverride: yonote-redis
nameOverride: redis
architecture: standalone
auth:
enabled: false
master:
persistence:
size: 200Mi
resources:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 50m
memory: 128Mi
minio:
enabled: true
name: minio
fullnameOverride: yonote-minio
nameOverride: yonote-minio
auth:
rootUser: admin
persistence:
enabled: true
size: 500Mi
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Host $http_host";
more_set_headers "X-Real-IP $remote_addr";
more_set_headers "X-Forwarded-Proto $scheme";
more_set_headers "X-Forwarded-For $proxy_add_x_forwarded_for";
hosts:
- host: s3.example.com
paths:
- path: /
pathType: ImplementationSpecific
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 500m
buckets:
- name: yonote-bucket
policy: none
mcJob:
enabled: true
keycloak:
auth:
adminUser: root
fullnameOverride: yonote-keycloak
nameOverride: yonote-keycloak
command:
- /bin/bash
- -c
- |
/opt/bitnami/keycloak/bin/kc.sh import --file=/opt/bitnami/keycloak/data/import/realm-export.json && \
/opt/bitnami/keycloak/bin/kc.sh start-dev
extraEnvVars:
- name: KC_DB_PASSWORD
value: "tT9BqYdNyd"
- name: KEYCLOAK_PRODUCTION
value: "true"
- name: KC_HOSTNAME_URL
value: "https://auth.example.com"
- name: KC_HOSTNAME_ADMIN_URL
value: "https://auth.example.com"
extraVolumes:
- name: realm-export
configMap:
name: realm-export
extraVolumeMounts:
- name: realm-export
mountPath: /opt/bitnami/keycloak/data/import/realm-export.json
subPath: realm-export.json
ingress:
enabled: true
hostname: auth.example.com
ingressClassName: traefik
tls: true
annotations:
kubernetes.io/ingress.class: traefik
# cert-manager.io/cluster-issuer: letsencrypt.example.com # Если используете
extraTls:
- hosts:
- "auth.example.com"
secretName: "you_tls_secret"
rules:
- host: "auth.example.com"
paths:
- path: /
pathType: Prefix
service:
name: yonote-keycloak
port: http
- path: /admin
pathType: Prefix
service:
name: yonote-keycloak
port: http
proxy: "edge"
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 150m
memory: 128Mi
postgresql:
enabled: true
auth:
database: keycloak
username: keycloak
name: keycloak-database
fullnameOverride: keycloak-database
nameOverride: keycloak-database
primary:
persistence:
size: 512Mi

View File

@@ -14,17 +14,20 @@ dependencies:
- name: app
repository: https://dysnix.github.io/charts
version: 0.3.15
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 11.6.6
- name: app
repository: https://dysnix.github.io/charts
version: 0.3.15
- name: postgres
repository: https://groundhog2k.github.io/helm-charts/
version: 0.3.9
- name: redis
repository: https://charts.bitnami.com/bitnami
version: 16.12.1
repository: https://groundhog2k.github.io/helm-charts/
version: 0.7.0
- name: minio
repository: https://charts.bitnami.com/bitnami
version: 12.7.0
- name: keycloak
repository: https://charts.bitnami.com/bitnami
version: 14.0.0
digest: sha256:928723e189de54fafe19316743b8f9d08d7c74f9728b0c4afb1f5cd3ee1e83dc
generated: "2024-08-25T00:46:01.648512702+03:00"
repository: https://charts.min.io/
version: 5.4.0
- name: keycloakx
repository: https://codecentric.github.io/helm-charts
version: 1.3.2
digest: sha256:ad0128ad6d526a8946d659481ec5dc19d1faf785919efbcc689a37ae80bc820e
generated: "2025-10-30T14:17:59.001901626+03:00"

View File

@@ -1,9 +1,9 @@
apiVersion: v2
name: yonote-chart
version: 1.2.0
version: 2.0.0
description:
Generic application Helm chart.
This chart includes multiple dependencies. The base of this chart is derived from the Dynix app chart.
This chart includes multiple dependencies. The base of this chart is derived from the Dysnix app chart.
maintainers:
- name: Dysnix
email: support@dysnix.com
@@ -35,26 +35,31 @@ dependencies:
repository: https://dysnix.github.io/charts
alias: yonote-collaboration
- name: postgresql
version: "11.6.6"
repository: https://charts.bitnami.com/bitnami
condition: yonoteDatabase.enabled
alias: yonoteDatabase
- name: app
version: "0.3.15"
repository: https://dysnix.github.io/charts
alias: yonote-scheduler
- name: postgres
version: "0.3.9"
repository: https://groundhog2k.github.io/helm-charts/
condition: postgres.enabled
alias: postgres
- name: redis
version: "16.12.1"
repository: https://charts.bitnami.com/bitnami
condition: yonote-redis.enabled
alias: yonote-redis
version: "0.7.0"
repository: https://groundhog2k.github.io/helm-charts/
condition: redis.enabled
alias: redis
- name: minio
version: "12.7.0"
repository: https://charts.bitnami.com/bitnami
version: "5.4.0"
repository: https://charts.min.io/
condition: minio.enabled
alias: minio
- name: keycloak
version: "14.0.0"
repository: https://charts.bitnami.com/bitnami
- name: keycloakx
version: "1.3.2"
repository: https://codecentric.github.io/helm-charts
condition: keycloak.enabled
alias: keycloak

View File

@@ -3,17 +3,17 @@ global:
config:
secret:
stringData:
DATABASE_URL: 'postgres://{{ .Values.yonoteDatabase.global.postgresql.auth.username }}:{{ .Values.yonoteDatabase.global.postgresql.auth.password }}@yonote-database:5432/{{ .Values.yonoteDatabase.global.postgresql.auth.database }}'
POSTGRES_PASSWORD: "{{ .Values.yonoteDatabase.global.postgresql.auth.password }}"
AWS_ACCESS_KEY_ID: "{{ .Values.minio.customUser }}" # Ваш идентификатор ключа доступа к AWS.
AWS_SECRET_ACCESS_KEY: "{{ .Values.minio.customAccessKey }}" # Ваш секретный ключ доступа AWS.
OIDC_CLIENT_SECRET: "Kdq8rk5Pv5RW1c5kHXpnyfrmMRzI9xSD" # Секретный ключ клиента для аутентификации по OpenID Connect (OIDC).
DATABASE_URL: 'postgres://{{ .Values.postgres.userDatabase.user }}:{{ .Values.postgres.userDatabase.password }}@yonote-database:5432/{{ .Values.postgres.userDatabase.name }}'
POSTGRES_PASSWORD: "{{ .Values.postgres.userDatabase.password }}"
AWS_ACCESS_KEY_ID: "qwer12314q" # Ваш идентификатор ключа доступа к AWS.
AWS_SECRET_ACCESS_KEY: "qwer-12314q-qwersa" # Ваш секретный ключ доступа AWS.
OIDC_CLIENT_SECRET: "{{ .Values.keycloak.secrets.secrets.stringData.OIDC_CLIENT_SECRET }}" # Секретный ключ клиента для аутентификации по OpenID Connect (OIDC).
SECRET_KEY: "659a8881b186198c3146e316f6dab67df25496534d1fa156d624b037260df688" # Сгенерируйте 32-байтовый случайный ключ в шестнадцатеричном коде. Вам следует использовать `openssl rand -hex 32` в вашем терминале для генерации случайного значения.
SMTP_PASSWORD: "1234"
UTILS_SECRET: "7bd5e9ac4415dd0dbf6b7721e2a21e9427b268cd0140c7516d13dece5024d479" # Сгенерируйте уникальный случайный ключ. Формат не важен, но вы все равно можете использовать`openssl rand -hex 32` в вашем терминале, чтобы создать это.
TELEGRAM_BOT_TOKEN: "1234"
UNSPLASH_API_ACCESS_KEY: "a-yGo6HpRP6jNfravx4Bz-oiPrRnH_5-24Xa9ZPlePE"
LICENSE_KEY: "qwerty-123456-zxcvb" # Обратитесь в отдел продаж для получения
LICENSE_KEY: "" # Обратитесь в отдел продаж для получения
SERVICE_WORKER_PUBLIC_KEY: "1234"
SERVICE_WORKER_PRIVATE_KEY: "1234"
# Генерация ключей (web-push) Service Worker
@@ -22,22 +22,24 @@ global:
# npx web-push generate-vapid-keys
# 3) Полученные значения ввести в .env файл (SERVICE_WORKER_PUBLIC_KEY, SERVICE_WORKER_PRIVATE_KEY)
yonoteDatabase:
global:
postgresql:
auth:
password: "wsGZ6kXhr5"
postgresPassword: "QQYw4UjOU"
postgres:
settings:
superuserPassword: "QQYw4UjOU"
userDatabase:
password: "wsGZ6kXhr5"
# yonote-redis: # Если используете auth для redis
# auth:
# password: "12345678"
redis:
args:
- "--user redis:redis"
minio:
customAccessKey: "qwer-12314q-qwersa"
auth:
rootPassword: "qwettaas"
rootPassword: "qwettaas"
keycloak:
auth:
adminPassword: "root"
database:
password: keycloakdbpassword
secrets:
secrets:
stringData:
KEYCLOAK_ADMIN_PASSWORD: secret
OIDC_CLIENT_SECRET: "iS3jOA3Z7zXBwSN8EzJm36ybz57JNgpR"

View File

@@ -3,5 +3,12 @@ kind: ConfigMap
metadata:
name: postgres-init-scripts
data:
init.sql: |
CREATE DATABASE "{{ .Values.keycloak.externalDatabase.database }}";
init-keycloak-db.sh: |
!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE DATABASE {{ .Values.keycloak.database.database }};
CREATE USER {{ .Values.keycloak.database.username }} WITH PASSWORD '{{ .Values.keycloak.database.password }}';
GRANT ALL PRIVILEGES ON DATABASE keycloak TO {{ .Values.keycloak.database.username }};
EOSQL

View File

@@ -1,69 +0,0 @@
{{- if eq ($.Values.global.yonote_cron_calendar_events.cron_enabled | toString) "true" }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: cron-calendar-events
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-calendar-events
image: curlimages/curl
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: yonote-secrets
command:
- /bin/sh
- -c
- >-
date;
curl
-X POST
{{ .Values.global.yonote_cron_calendar_events.url }}
-H "Content-Type: application/json"
-d '
{
"token": "$(UTILS_SECRET)"
}
'
restartPolicy: OnFailure
{{- end }}
---
{{- if eq ($.Values.global.yonote_cron_task_scheduler.cron_enabled | toString) "true" }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: cron-task-scheduler
spec:
schedule: "0 */1 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-task-scheduler
image: curlimages/curl
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: yonote-secrets
command:
- /bin/sh
- -c
- >-
date;
curl
-X POST
{{ .Values.global.yonote_cron_task_scheduler.url }}
-H "Content-Type: application/json"
-d '
{
"token":"$(UTILS_SECRET)", "limit":"200"
}
'
restartPolicy: OnFailure
{{- end }}

View File

@@ -13,54 +13,22 @@ spec:
spec:
containers:
- name: mc-client
image: "docker.io/bitnami/minio-client:2024.8.13-debian-12-r0"
image: "minio/mc:RELEASE.2025-01-17T23-25-50Z"
command: ["/bin/sh", "-c"]
args:
- |
until mc alias set myminio http://yonote-minio:9000 {{ .Values.minio.auth.rootUser }} {{ .Values.minio.auth.rootPassword }}; do
until mc alias set myminio http://yonote-minio:9000 {{ .Values.minio.rootUser }} {{ .Values.minio.rootPassword }}; do
echo "Waiting for MinIO to be ready..."
sleep 5
done
echo "MinIO is ready and alias is set."
# Создание пользователя
if ! mc admin user add myminio {{ .Values.minio.customUser }} {{ .Values.minio.customAccessKey }}; then
echo "User {{ .Values.minio.customUser }} already exists or failed to create."
else
echo "User {{ .Values.minio.customUser }} created successfully."
fi
# Назначение политики для нового пользователя
cat <<EOF > /tmp/minio-user-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor",
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::yonote-bucket/*"
]
}
]
}
EOF
echo "User policy JSON file created."
mc admin policy create myminio yonote-policy /tmp/minio-user-policy.json
echo "User policy created and applied."
# Создание бакета
if ! mc ls myminio/yonote-bucket; then
mc mb myminio/yonote-bucket
echo "Bucket yonote-bucket created successfully."
if ! mc ls myminio/{{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }}; then
mc mb myminio/{{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }}
echo "Bucket {{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }} created successfully."
else
echo "Bucket yonote-bucket already exists."
echo "Bucket {{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }} already exists."
fi
# Установка политик для бакета
@@ -79,7 +47,7 @@ spec:
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::yonote-bucket"
"arn:aws:s3:::{{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }}"
]
},
{
@@ -93,7 +61,7 @@ spec:
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::yonote-bucket/*"
"arn:aws:s3:::{{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }}/*"
]
}
]
@@ -101,12 +69,9 @@ spec:
EOF
echo "Bucket policy JSON file created."
mc anonymous set-json /tmp/minio-bucket-policy.json myminio/yonote-bucket
mc anonymous set-json /tmp/minio-bucket-policy.json myminio/{{ .Values.global.yonote.config.plain.data.AWS_S3_UPLOAD_BUCKET_NAME }}
echo "Bucket policy applied."
mc admin policy attach myminio yonote-policy --user={{ .Values.minio.customUser }}
echo "Policy attached to user {{ .Values.minio.customUser }}."
resources:
requests:
memory: "128Mi"

View File

@@ -1,169 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: realm-export
data:
realm-export.json: |
{
"realm": "yonote",
"enabled": true,
"notBefore": 1647809856,
"defaultSignatureAlgorithm": "RS256",
"revokeRefreshToken": false,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 300,
"accessTokenLifespanForImplicitFlow": 900,
"ssoSessionIdleTimeout": 1800,
"ssoSessionMaxLifespan": 36000,
"ssoSessionIdleTimeoutRememberMe": 0,
"ssoSessionMaxLifespanRememberMe": 0,
"offlineSessionIdleTimeout": 2592000,
"offlineSessionMaxLifespanEnabled": false,
"offlineSessionMaxLifespan": 5184000,
"clientSessionIdleTimeout": 0,
"clientSessionMaxLifespan": 0,
"clientOfflineSessionIdleTimeout": 0,
"clientOfflineSessionMaxLifespan": 0,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"accessCodeLifespanLogin": 1800,
"actionTokenGeneratedByAdminLifespan": 43200,
"actionTokenGeneratedByUserLifespan": 300,
"oauth2DeviceCodeLifespan": 600,
"oauth2DevicePollingInterval": 5,
"sslRequired": "external",
"registrationAllowed": true,
"registrationEmailAsUsername": true,
"rememberMe": true,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": true,
"editUsernameAllowed": false,
"bruteForceProtected": false,
"permanentLockout": false,
"maxFailureWaitSeconds": 900,
"minimumQuickLoginWaitSeconds": 60,
"waitIncrementSeconds": 60,
"quickLoginCheckMilliSeconds": 1000,
"maxDeltaTimeSeconds": 43200,
"failureFactor": 30,
"clients": [
{
"clientId": "{{ .Values.global.yonote.config.plain.data.OIDC_CLIENT_ID }}",
"secret": "{{ .Values.global.yonote.config.secret.stringData.OIDC_CLIENT_SECRET }}",
"redirectUris": [
"https://*.{{ .Values.global.yonote.baseListenAddress }}/*",
"http://*.{{ .Values.global.yonote.baseListenAddress }}/*",
"http://app.{{ .Values.global.yonote.baseListenAddress }}/*",
"https://app.{{ .Values.global.yonote.baseListenAddress }}/*",
"https://app.{{ .Values.global.yonote.baseListenAddress }}/auth/oidc.callback/*"
],
"baseUrl": "https://app.{{ .Values.global.yonote.baseListenAddress }}",
"enabled": true,
"publicClient": false,
"protocol": "openid-connect",
"attributes": {
"client.secret": "{{ .Values.global.yonote.config.secret.stringData.OIDC_CLIENT_SECRET }}",
"display.on.consent.screen": "true"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"protocolMappers": [
{
"name": "oidc-display-name",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}",
"jsonType.label": "String"
}
}
],
"defaultClientScopes": ["openid", "email"]
}
],
"identityProviders": [],
"internationalizationEnabled": true,
"clientScopes": [
{
"name": "openid",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "{{ .Values.global.yonote.config.plain.data.OIDC_DISPLAY_NAME }}"
},
"protocolMappers": []
},
{
"name": "email",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true"
},
"protocolMappers": [
{
"id": "56fe6d23-690a-465c-bc36-99bff8fef6eb",
"name": "email verified",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-property-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "emailVerified",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email_verified",
"jsonType.label": "boolean"
}
},
{
"id": "2c6acd0e-b776-48f5-9c3b-7bfdbbe712dc",
"name": "email",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-property-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "email",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email",
"jsonType.label": "String"
}
}
]
}
],
"browserSecurityHeaders": {
"contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';"
},
"webAuthnPolicyRpEntityName": "keycloak",
"webAuthnPolicySignatureAlgorithms": ["ES256"],
"webAuthnPolicyRpId": "",
"webAuthnPolicyAttestationConveyancePreference": "not specified",
"webAuthnPolicyAuthenticatorAttachment": "not specified",
"webAuthnPolicyRequireResidentKey": "not specified",
"webAuthnPolicyUserVerificationRequirement": "not specified",
"webAuthnPolicyCreateTimeout": 0,
"webAuthnPolicyAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyAcceptableAaguids": [],
"webAuthnPolicyPasswordlessRpEntityName": "keycloak",
"webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"],
"webAuthnPolicyPasswordlessRpId": "",
"webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
"webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
"webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
"webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
"webAuthnPolicyPasswordlessCreateTimeout": 0,
"webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyPasswordlessAcceptableAaguids": [],
"smtpServer": {}
}

View File

@@ -7,6 +7,7 @@ global:
config:
plain:
data:
DEBUG: debug
NODE_ENV: production
FORCE_HTTPS: "false"
PGSSLMODE: disable # Отключает SSL подключение к базе данных. Уберите эту строку, если вы используете SSL подключение к PostgreSQL
@@ -15,7 +16,7 @@ global:
BIND_HOST: 0.0.0.0 # Хост по умолчанию
PORT: "3000" # Порт по умолчанию
REDIS_URL: redis://yonote-redis-master:6379
REDIS_URL: redis://yonote-redis:6379
DEFAULT_LANGUAGE: ru_RU # Язык по умолчанию
ENABLE_UPDATES: "false"
@@ -23,8 +24,10 @@ global:
AI_URL: "1234"
AI_API_KEY: "1234"
URL: 'https://app.{{ .Values.global.yonote.baseListenAddress }}' # Базовый url приложения
COLLABORATION_URL: 'wss://app.{{ .Values.global.yonote.baseListenAddress }}' # Cервер, для нормальной работы это не нужно устанавливать
URL: 'https://app.{{ .Values.global.yonote.baseListenAddress }}' # Базовый url приложения
COLLABORATION_URL: 'wss://app.{{ .Values.global.yonote.baseListenAddress }}' # Cервер, для нормальной работы это не нужно устанавливать
#DEPLOYMENT: 'hosted'
OIDC_DISPLAY_NAME: email
OIDC_SCOPES: openid email
@@ -35,7 +38,7 @@ global:
OIDC_USERINFO_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/userinfo' # URL для получения информации о пользователе. Используется для получения данных профиля пользователя на основе его токена.
AWS_S3_ACL: private
AWS_S3_UPLOAD_BUCKET_URL: 'https://api-s3.example.com' # Адрес API S3 хранилища
AWS_S3_UPLOAD_BUCKET_URL: 'https://s3.example.com' # Адрес API S3 хранилища
AWS_S3_UPLOAD_BUCKET_NAME: yonote-bucket # Имя хранилища
AWS_REGION: "RU"
AWS_S3_UPLOAD_MAX_SIZE: "226214400" # Максимальный размер хранилища
@@ -53,80 +56,72 @@ global:
RESERVED_SUBDOMAINS: about,account,admin,advertising,api,app,assets,archive,beta,billing,blog,cache,cdn,code,community,dashboard,developer,developers,forum,help,home,http,https,imap,localhost,mail,marketing,mobile,multiplayer,new,news,newsletter,ns1,ns2,ns3,ns4,password,profile,realtime,sandbox,script,scripts,setup,signin,signup,site,smtp,support,status,static,stats,test,update,updates,ws,wss,web,websockets,www,www1,www2,www3,www4
SMTP_HOST: ""
SMTP_HOST: "smtp.wilix.dev"
SMTP_USERNAME: ""
SMTP_FROM_EMAIL: ""
SMTP_REPLY_EMAIL: ""
SMTP_PORT: ""
SMTP_PORT: "456"
SMTP_SECURE: "" # connection will be upgraded: https://nodemailer.com/smtp/
SMTP_REQUIRE_TLS: ""
yonote_cron_calendar_events:
cron_enabled: "true"
url: http://yonote-web/api/cron.calendar_events
yonote_cron_task_scheduler:
cron_enabled: "true"
url: http://yonote-web/api/cron.schedule
ingress:
enabled: true
name: yonote-ingress
namespace: yonote-onprem
ingressClassName: traefik
tls:
secretName: "you_tls_secret"
secretName: "example.com-tls"
hosts:
- "app.example.com"
- "team.example.com"
rules:
- host: "app.example.com"
paths:
- path: /
pathType: Prefix
service:
name: yonote-web
port: 80
- path: /realtime
pathType: Prefix
service:
name: yonote-websockets
port: 80
- path: /whiteboard
pathType: Prefix
service:
name: yonote-whiteboard
port: 80
- path: /collaboration
pathType: Prefix
service:
name: yonote-collaboration
port: 80
- host: "team.example.com"
paths:
- path: /
pathType: Prefix
service:
name: yonote-web
port: 80
- path: /realtime
pathType: Prefix
service:
name: yonote-websockets
port: 80
- path: /whiteboard
pathType: Prefix
service:
name: yonote-whiteboard
port: 80
- path: /collaboration
pathType: Prefix
service:
name: yonote-collaboration
port: 80
- host: "app.example.com"
paths:
- path: /
pathType: Prefix
service:
name: yonote-web
port: 80
- path: /realtime
pathType: Prefix
service:
name: yonote-websockets
port: 80
- path: /whiteboard
pathType: Prefix
service:
name: yonote-whiteboard
port: 80
- path: /collaboration
pathType: Prefix
service:
name: yonote-collaboration
port: 80
- host: "team.example.com"
paths:
- path: /
pathType: Prefix
service:
name: yonote-web
port: 80
- path: /realtime
pathType: Prefix
service:
name: yonote-websockets
port: 80
- path: /whiteboard
pathType: Prefix
service:
name: yonote-whiteboard
port: 80
- path: /collaboration
pathType: Prefix
service:
name: yonote-collaboration
port: 80
annotations:
# cert-manager.io/cluster-issuer: letsencrypt.example.com # Если используете
#annotations:
# cert-manager.io/cluster-issuer: # Если используете
yonote-web:
fullnameOverride: yonote-web
@@ -136,7 +131,7 @@ yonote-web:
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.8
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
@@ -144,7 +139,7 @@ yonote-web:
initContainers:
- name: yonote-migration
image: images.updates.yonote.ru/yonote:1.19.8
image: images.updates.yonote.ru/yonote:1.22.11
imagePullPolicy: IfNotPresent
command:
- /bin/sh
@@ -220,7 +215,7 @@ yonote-websocket:
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.8
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
@@ -289,7 +284,7 @@ yonote-whiteboard:
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.8
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
@@ -358,7 +353,7 @@ yonote-worker:
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.8
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
@@ -427,7 +422,7 @@ yonote-collaboration:
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.19.8
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
@@ -488,104 +483,179 @@ yonote-collaboration:
path: /_health
port: app
yonoteDatabase:
yonote-scheduler:
fullnameOverride: yonote-scheduler
nameOverride: yonote-scheduler
name: scheduler
image:
registry: images.updates.yonote.ru
repository: yonote
tag: 1.22.11
pullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
args: ['IS_COMPILED=true yarn bytenode ./build/server/main.jsc --services=scheduler']
replicaCount: 1
maxReplicas: 1
minReplicas: 1
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 150m
memory: 128Mi
checksums: null
containerPorts:
- containerPort: 3000
name: app
protocol: TCP
service:
type: ClusterIP
port: 80
targetPort: app
envFrom:
- configMapRef:
name: yonote-configs
- secretRef:
name: yonote-secrets
podLabels:
redis-client: 'true'
podAnnotations:
checksum/configmap: "{{ toJson .Values.global.yonote.config.plain | sha256sum }}"
checksum/secret: "{{ toJson .Values.global.yonote.config.secret | sha256sum }}"
readinessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
httpGet:
path: /_health
port: app
livenessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
httpGet:
path: /_health
port: app
postgres:
enabled: true
global:
postgresql:
auth:
database: "yonote"
username: "yonote"
name: yonote-database
#settings:
# Default postgres
# superuser:
userDatabase:
name: yonote
user: yonote
fullnameOverride: yonote-database
nameOverride: yonote-database
primary:
persistence:
size: 5Gi
resources:
limits:
cpu: 2
memory: 8Gi
requests:
cpu: 500m
memory: 512Mi
storage:
requestedSize: 5Gi
className: ""
extraVolumes:
- name: init-scripts
configMap:
name: postgres-init-scripts
resources:
limits:
cpu: 2
memory: 5Gi
requests:
cpu: 500m
memory: 512Mi
extraVolumeMounts:
- name: init-scripts
mountPath: /docker-entrypoint-initdb.d
readOnly: true
extraScripts: postgres-init-scripts
yonote-redis:
redis:
enabled: true
fullnameOverride: yonote-redis
nameOverride: redis
architecture: standalone
image:
tag: 7.2.0-debian-11-r0
auth:
enabled: false
master:
persistence:
size: 5Gi
resources:
limits:
cpu: 1
memory: 4Gi
requests:
cpu: 500m
memory: 512Mi
storage:
requestedSize: 1Gi
className: ""
resources:
limits:
cpu: 1
memory: 4Gi
requests:
cpu: 500m
memory: 512Mi
minio:
enabled: true
name: minio
fullnameOverride: yonote-minio
customUser: yonote
nameOverride: yonote-minio
auth:
rootUser: admin
mode: standalone
rootUser: admin
image:
tag: 2024.8.3-debian-12-r1
policies:
- name: yonote_user_policy
statements:
- resources:
- 'arn:aws:s3:::yonote-bucket/*'
actions:
- "s3:GetObject"
- "s3:PutObject"
- "s3:DeleteObject"
users:
- accessKey: qwer12314q
secretKey: qwer-12314q-qwersa
policy: yonote_user_policy
persistence:
enabled: true
size: 5Gi
annotations:
helm.sh/resource-policy: keep
size: 1Gi
storageClass: ""
ingress:
enabled: true
hostname: 's3.example.com'
hosts:
- s3.example.com
ingressClassName: traefik
path: '/'
pathType: ImplementationSpecific
annotations:
kubernetes.io/ingress.class: traefik
# cert-manager.io/cluster-issuer: letsencrypt.example.com # Если используете
extraTls:
- hosts:
- "s3.example.com"
secretName: "you_tls_secret"
#cert-manager.io/cluster-issuer: letsencrypt.rancher.wilix.dev # Если используете
tls:
- hosts:
- "s3.example.com"
secretName: "example.com-tls"
apiIngress:
consoleIngress:
enabled: true
hostname: 'api-s3.example.com'
hosts:
- s3-console.example.com
ingressClassName: traefik
path: '/'
pathType: ImplementationSpecific
servicePort: minio-api
annotations:
kubernetes.io/ingress.class: traefik
# cert-manager.io/cluster-issuer: letsencrypt.example.com # Если используете
extraTls:
- hosts:
- "api-s3.example.com"
secretName: "api-s3.example.com"
#cert-manager.io/cluster-issuer: letsencrypt.rancher.wilix.dev # Если используете
tls:
- hosts:
- "s3-console.example.com"
secretName: "example.com-tls"
resources:
requests:
@@ -599,36 +669,53 @@ mcJob:
enabled: true
keycloak:
enabled: true
fullnameOverride: yonote-keycloak
nameOverride: yonote-keycloak
auth:
adminUser: root
image:
repository: images.updates.yonote.ru/yonote-keycloak
tag: latest
proxy: "edge"
args:
- start-dev --spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true --import-realm
command:
- /bin/bash
- -c
- |
/opt/bitnami/keycloak/bin/kc.sh start --import-realm --hostname={{ .Values.ingress.hostname }} --hostname-strict=true --hostname-strict-backchannel=true --https-protocols=TLSv1.2 --proxy=edge --db postgres --db-url-host yonote-database --db-username postgres --db-password="$(DB_PASSWORD)"
cache:
stack: custom
extraEnvVars:
- name: DB_PASSWORD
proxy:
enabled: "false"
extraEnv: |
- name: KEYCLOAK_ADMIN
value: root
- name: KEYCLOAK_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: yonote-database
key: postgres-password
name: {{ include "keycloak.fullname" . }}-secrets
key: KEYCLOAK_ADMIN_PASSWORD
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ include "keycloak.fullname" . }}-secrets
key: OIDC_CLIENT_SECRET
- name: BASENAME_FOR_SUBDOMAIN
value: example.com
- name: KC_HOSTNAME_STRICT
value: "false"
- name: KC_HOSTNAME
value: auth.example.com
- name: KC_HOSTNAME_STRICT_HTTPS
value: "false"
- name: KC_HOSTNAME_PATH
value: "/"
- name: KC_HTTP_ENABLED
value: "true"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
extraVolumes:
- name: realm-export
configMap:
name: realm-export
extraVolumeMounts:
- name: realm-export
mountPath: /opt/bitnami/keycloak/data/import/realm-export.json
subPath: realm-export.json
http:
relativePath: "/"
ingress:
enabled: true
@@ -637,20 +724,21 @@ keycloak:
tls:
- hosts:
- "auth.example.com"
secretName: "auth.example.com-tls"
secretName: "example.com-tls"
annotations:
kubernetes.io/ingress.class: traefik
# cert-manager.io/cluster-issuer: letsencrypt.example.com #Если используете
#cert-manager.io/cluster-issuer: #Если используете
rules:
- host: "auth.example.com"
paths:
- path: /
pathType: Prefix
pathType: ImplementationSpecific
service:
name: yonote-keycloak
port: http
- path: /admin
pathType: Prefix
pathType: ImplementationSpecific
service:
name: yonote-keycloak
port: http
@@ -663,19 +751,27 @@ keycloak:
cpu: 250m
memory: 256Mi
postgresql:
enabled: false
dbchecker:
enabled: "true"
externalDatabase:
host: jdbc:postgresql://yonote-database
database:
vendor: postgres
hostname: yonote-database
port: 5432
user: postgres
database: keycloak
username: keycloak
livenessProbe:
livenessProbe: |
httpGet:
path: '{{ trimSuffix "/" .Values.http.relativePath}}/'
port: http
initialDelaySeconds: 240
timeoutSeconds: 5
readinessProbe:
# Readiness probe configuration
readinessProbe: |
httpGet:
path: '{{ trimSuffix "/" .Values.http.relativePath}}/realms/master'
port: http
initialDelaySeconds: 120
timeoutSeconds: 5
timeoutSeconds: 1