diff --git a/yonote-chart/Chart.lock b/yonote-chart/Chart.lock new file mode 100644 index 0000000..6a6910e --- /dev/null +++ b/yonote-chart/Chart.lock @@ -0,0 +1,15 @@ +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: 14.6.20 +digest: sha256:dfaa7914dc55b5c305826ec1ed880af5c50904131aca19fe758d779719d35e99 +generated: "2024-07-17T16:05:55.571392551+03:00" diff --git a/yonote-chart/Chart.yaml b/yonote-chart/Chart.yaml new file mode 100644 index 0000000..6606fa7 --- /dev/null +++ b/yonote-chart/Chart.yaml @@ -0,0 +1,34 @@ +apiVersion: v2 +name: yonote-chart +version: 1.2.1 +description: + Generic application Helm 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 + 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: yonote-database.enabled + alias: yonote-database + + - name: redis + version: "16.12.1" + repository: https://charts.bitnami.com/bitnami + condition: yonote-redis.enabled + alias: yonote-redis + + - name: minio + version: "14.6.20" + repository: https://charts.bitnami.com/bitnami + condition: minio.enabled + alias: minio \ No newline at end of file diff --git a/yonote-chart/secret-values.yaml b/yonote-chart/secret-values.yaml new file mode 100644 index 0000000..3cbd5a8 --- /dev/null +++ b/yonote-chart/secret-values.yaml @@ -0,0 +1,31 @@ +global: + yonote: + config: + secret: + stringData: + DATABASE_URL: 'postgres://{{ .Values.global.postgresql.auth.username }}:{{ .Values.global.postgresql.auth.password }}@yonote-db:5432/{{ .Values.global.postgresql.auth.database }}' + POSTGRES_PASSWORD: wsGZ6kXhr5 + AWS_ACCESS_KEY_ID: "minioadmin" # Ваш идентификатор ключа доступа к AWS. Поведение в SelfHosted: устанавливает логин сервис аккаунта для доступа приложения к Minio S3 хранилищу + AWS_SECRET_ACCESS_KEY: "minioadminsecret" # Ваш секретный ключ доступа AWS. Поведение в SelfHosted: устанавливает пароль сервис аккаунта для доступа приложения к Minio S3 хранилищу + OIDC_CLIENT_SECRET: "" + 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: "" # Обратитесь в отдел продаж для получения + 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) + + postgresql: + auth: + password: "wsGZ6kXhr5" + postgresPassword: "QQYw4UjOU" + + + \ No newline at end of file diff --git a/yonote-chart/templates/configmap.yaml b/yonote-chart/templates/configmap.yaml new file mode 100644 index 0000000..52ca6f9 --- /dev/null +++ b/yonote-chart/templates/configmap.yaml @@ -0,0 +1,10 @@ +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 }} \ No newline at end of file diff --git a/yonote-chart/templates/cronjob.yaml b/yonote-chart/templates/cronjob.yaml new file mode 100644 index 0000000..21de386 --- /dev/null +++ b/yonote-chart/templates/cronjob.yaml @@ -0,0 +1,69 @@ +{{- 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 }} \ No newline at end of file diff --git a/yonote-chart/templates/secret.yaml b/yonote-chart/templates/secret.yaml new file mode 100644 index 0000000..96a343f --- /dev/null +++ b/yonote-chart/templates/secret.yaml @@ -0,0 +1,14 @@ +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 }} \ No newline at end of file diff --git a/yonote-chart/templates/traefic-http-to-https-redirect-middleware.yaml b/yonote-chart/templates/traefic-http-to-https-redirect-middleware.yaml new file mode 100644 index 0000000..93c470f --- /dev/null +++ b/yonote-chart/templates/traefic-http-to-https-redirect-middleware.yaml @@ -0,0 +1,10 @@ +{{- if eq $.Values.global.yonote.ingress.ingressClassName "traefik" }} +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: redirect-https +spec: + redirectScheme: + scheme: https + permanent: true +{{- end }} \ No newline at end of file diff --git a/yonote-chart/templates/traefik-wss-headers-middleware.yaml b/yonote-chart/templates/traefik-wss-headers-middleware.yaml new file mode 100644 index 0000000..c8fc1bd --- /dev/null +++ b/yonote-chart/templates/traefik-wss-headers-middleware.yaml @@ -0,0 +1,10 @@ +{{- if eq $.Values.global.yonote.ingress.ingressClassName "traefik" }} +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: wss-headers +spec: + headers: + customRequestHeaders: + X-Forwarded-Proto: https +{{- end }} \ No newline at end of file diff --git a/yonote-chart/values.yaml b/yonote-chart/values.yaml new file mode 100644 index 0000000..60aadd0 --- /dev/null +++ b/yonote-chart/values.yaml @@ -0,0 +1,265 @@ +global: + name: yonote-app + postgresql: + auth: + database: yonote + username: yonote + + yonote: + ingress: + ingressClassName: traefik + + dbMigrationEnv: production-ssl-disabled # Режим подключения к базе данных при выполнении миграций. При использовании SSL подключения, установите значение `production` + + baseListenAddress: example.com + + config: + plain: + data: + NODE_ENV: production + FORCE_HTTPS: "false" + PGSSLMODE: disable # Отключает SSL подключение к базе данных. Уберите эту строку, если вы используете SSL подключение к PostgreSQL + + 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' + OIDC_LOGOUT_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/logout' + OIDC_TOKEN_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/token' + OIDC_USERINFO_URI: 'https://auth.example.com/realms/yonote/protocol/openid-connect/userinfo' + + AWS_S3_ACL: private + AWS_S3_UPLOAD_BUCKET_URL: http://s3.example.com # Адрес 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 + # ingressClassName: traefik + # hosts: "'*.example.com'" + # annotations: + # cert-manager.io/cluster-issuer: "" + # traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-redirect-https@kubernetescrd,{{ .Release.Namespace }}-wss-headers@kubernetescrd,kube-system-wilix-office-ipwhitelist@kubernetescrd" + # extraTls: + # - hosts: + # - "'*.example.com'" + # secretName: "'*.example.com'" + + ingress: + enabled: true + hostname: "'*.example.com'" + ingressClassName: nginx + path: '/' + pathType: Prefix + 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: "" + extraTls: + - hosts: + - "'*.example.com'" + secretName: "'*.example.com'" + + 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 + +yonote-database: + enabled: true + fullnameOverride: yonote-db + nameOverride: db + + 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: minio + accessKey: "minioadmin" + secretKey: "minioadminsecret" + + persistence: + enabled: true + size: 500Mi + + # ingress: + # enabled: true + # hostname: '"s3.example.com"' + # annotations: + # cert-manager.io/cluster-issuer: letsencrypt.rancher.wilix.dev + # traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-redirect-https@kubernetescrd,{{ .Release.Namespace }}-wss-headers@kubernetescrd,kube-system-wilix-office-ipwhitelist@kubernetescrd" + # extraTls: + # - hosts: + # - s3.example.com + # secretName: s3.example.com + + 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.onprem-test.stands.wilix.dev + paths: + - path: / + pathType: ImplementationSpecific + + resources: + requests: + memory: 512Mi + cpu: 250m + limits: + memory: 1Gi + cpu: 500m + + buckets: + - name: yonote-bucket + policy: none \ No newline at end of file