###############################################################################
# Author: Winson Li
# Email: a623719265@gmail.com
# Github: @Winson-030
###############################################################################
# Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: dify

# Dify Credentials
# apiVersion: v1
# kind: Secret
# metadata:
#   name: dify-credentials
#   namespace: dify
# data:
#   # Base64 encoded postgres username, default is postgres
#   pg-username: cG9zdGdyZXM=
#   # Base64 encoded postgres password, default is difyai123456
#   pg-password: ZGlmeWFpMTIzNDU2
#   # Base64 encoded postgres host, default is dify-postgres
#   pg-host: ZGlmeS1wb3N0Z3Jlcw==
#   # Base64 encoded postgres port 5432
#   pg-port: NTQzMg==
#   # Base64 encoded redis username, default is empty
#   redis-username: ""
#   # Base64 encoded redis password, default is difyai123456
#   redis-password: ZGlmeWFpMTIzNDU2
#   # Base64 encoded redis host, default is dify-redis
#   redis-host: ZGlmeS1yZWRpcw==
#   # Base64 encoded redis port 6379
#   redis-port: NjM3OQ==
#   # Base64 encoded weaviate host, default is dify-weaviate
#   weaviate-host: ZGlmeS13ZWF2aWF0ZQ==
#   # Base64 encoded weaviate port 8080
#   weaviate-port: ODA4MA==
# type: Opaque

---
apiVersion: v1
kind: Secret
metadata:
  name: dify-harbor-secret
  namespace: dify
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ew0KICAgICJhdXRocyI6IHsNCiAgICAgICJyZWdpc3RyeS5oZC0wMS5hbGF5YW5ldy5jb206ODQ0MyI6IHsNCiAgICAgICAgInVzZXJuYW1lIjogInZjLWFwcC1tYXJrZXQtdmlldyIsDQogICAgICAgICJwYXNzd29yZCI6ICJIS3NlNTYz77yBIg0KICAgICAgfSwNCiAgICAgICJyZWdpc3RyeS5oZC0wMi5hbGF5YW5ldy5jb206ODQ0MyI6IHsNCiAgICAgICAgInVzZXJuYW1lIjogInZjLWFwcC1tYXJrZXQtdmlldyIsDQogICAgICAgICJwYXNzd29yZCI6ICJBbGF5YU5lVzFBcHBNYXJrZXQyVjFldzNQYXNzdzByZDQiDQogICAgICB9LA0KICAgICAgInJlZ2lzdHJ5LmhkLTAzLmFsYXlhbmV3LmNvbTo4NDQzIjogew0KICAgICAgICAidXNlcm5hbWUiOiAidmMtYXBwLW1hcmtldC12aWV3IiwNCiAgICAgICAgInBhc3N3b3JkIjogIkFsYXlhTmVXMUFwcE1hcmtldDJWMWV3M1Bhc3N3MHJkNCINCiAgICAgIH0NCiAgfQ0KfQ0KDQo=



# Postgres Server Start
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/instance: dify-postgres
  name: dify-postgres
  namespace: dify

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/instance: dify-postgres
  name: dify-postgres
  namespace: dify
rules:
- apiGroups:
  - "*"
  resources:
  - "*"
  verbs:
  - "*"

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/instance: dify-postgres
  name: dify-postgres
  namespace: dify
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: dify-postgres
subjects:
- kind: ServiceAccount
  name: dify-postgres

# ---
# kind: PersistentVolumeClaim
# apiVersion: v1
# metadata:
#   name: dify-postgres-pvc
#   namespace: dify
# spec:
#   storageClassName: mas-cephfs-hdd-vc2qofwoe524
#   accessModes:
#     - ReadWriteMany
#   resources:
#     requests:
#       storage: 5Gi

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dify-postgres
  namespace: dify
spec:
  selector:
    matchLabels:
      app: dify-postgres
  serviceName: "dify-postgres"
  replicas: 1
  template:
    metadata:
      labels:
        app: dify-postgres
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      serviceAccountName: dify-postgres
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: dify-postgres
        image: registry.hd-02.alayanew.com:8443/vc-app_market/postgres:15-alpine
        env:
        - name: PGUSER
          value: postgres
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-username
        - name: POSTGRES_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-password
        - name: POSTGRES_DB
          value: dify
        livenessProbe:
          exec:
            command:
            - "pg_isready"
            - "-U"
            - "$(PGUSER)"
            - "-d"
            - "$(POSTGRES_DB)"
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 2
          successThreshold: 1
          failureThreshold: 10
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 100m
            memory: 128Mi
        ports:
        - containerPort: 5432
          name: postgres-port
        volumeMounts:
        - name: data-volume
          mountPath: /var/lib/postgresql/data
          subPath: apps/dify/postgresql/data
      volumes:
      - name: data-volume
        persistentVolumeClaim:
          claimName: pvc-capacity-userdata

---
apiVersion: v1
kind: Service
metadata:
  name: dify-postgres
  namespace: dify
spec:
  selector:
    app: dify-postgres
  type: ClusterIP
  clusterIP: None
  ports:
  - name: postgres
    protocol: TCP
    port: 5432
    targetPort: 5432

# Postgres Server End
# Redis Server Start
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/instance: dify-redis
  name: dify-redis
  namespace: dify

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/instance: dify-redis
  name: dify-redis
  namespace: dify
rules:
- apiGroups:
  - "*"
  resources:
  - "*"
  verbs:
  - "*"

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/instance: dify-redis
  name: dify-redis
  namespace: dify
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: dify-redis
subjects:
- kind: ServiceAccount
  name: dify-redis

# ---
# kind: PersistentVolumeClaim
# apiVersion: v1
# metadata:
#   name: dify-redis-pvc
#   namespace: dify
# spec:
#   storageClassName: mas-cephfs-hdd-vc2qofwoe524
#   accessModes:
#     - ReadWriteMany
#   resources:
#     requests:
#       storage: 5Gi

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dify-redis
  namespace: dify
spec:
  selector:
    matchLabels:
      app: dify-redis
  serviceName: "dify-redis"
  replicas: 1
  template:
    metadata:
      labels:
        app: dify-redis
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: dify-redis
      containers:
      - name: dify-redis
        image: registry.hd-02.alayanew.com:8443/vc-app_market/redis:6-alpine
        ports:
        - containerPort: 6379
          name: redis-p
        command: ["redis-server", "--save", "20", "1", "--loglevel", "warning", "--requirepass", "$(REDIS_PASSWORD)"]
        resources:
          limits:
            cpu: 500m
            memory: 1024Mi
          requests:
            cpu: 100m
            memory: 102Mi
        env:
        - name: REDIS_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-password
        livenessProbe:
          exec:
            command:
            - redis-cli
            - ping
        volumeMounts:
        - name: redis-data
          mountPath: /data
          subPath: apps/dify/redis/data
      volumes:
      - name: redis-data
        persistentVolumeClaim:
          claimName: pvc-capacity-userdata

---
apiVersion: v1
kind: Service
metadata:
  name: dify-redis
  namespace: dify
spec:
  selector:
    app: dify-redis
  type: ClusterIP
  clusterIP: None
  ports:
  - name: redis
    protocol: TCP
    port: 6379
    targetPort: 6379

# Redis Server End

# Weaviate Server Start
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/instance: dify-weaviate
  name: dify-weaviate
  namespace: dify

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/instance: dify-weaviate
  name: dify-weaviate
  namespace: dify
rules:
- apiGroups:
  - "*"
  resources:
  - "*"
  verbs:
  - "*"

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/instance: dify-weaviate
  name: dify-weaviate
  namespace: dify
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: dify-weaviate
subjects:
- kind: ServiceAccount
  name: dify-weaviate

# ---
# kind: PersistentVolumeClaim
# apiVersion: v1
# metadata:
#   name: dify-weaviate-pvc
#   namespace: dify
# spec:
#   storageClassName: mas-cephfs-hdd-vc2qofwoe524
#   accessModes:
#     - ReadWriteMany
#   resources:
#     requests:
#       storage: 5Gi
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dify-weaviate
  namespace: dify
spec:
  selector:
    matchLabels:
      app: dify-weaviate
  serviceName: "dify-weaviate"
  replicas: 1
  template:
    metadata:
      labels:
        app: dify-weaviate
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: dify-weaviate
      containers:
      - name: dify-weaviate
        image: registry.hd-02.alayanew.com:8443/vc-app_market/semitechnologies/weaviate:1.19.0
        ports:
        - containerPort: 8080
          name: weaviate-p
        resources:
          limits:
            cpu: 500m
            memory: 1024Mi
          requests:
            cpu: 100m
            memory: 102Mi
        env:
        - name: QUERY_DEFAULTS_LIMIT
          value: "25"
        - name: AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED
          value: "false"
        - name: PERSISTENCE_DATA_PATH
          value: "/var/lib/weaviate"
        - name: "DEFAULT_VECTORIZER_MODULE"
          value: "none"
        - name: "AUTHENTICATION_APIKEY_ENABLED"
          value: "true"
        - name: "AUTHENTICATION_APIKEY_ALLOWED_KEYS"
          value: "WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih"
        - name: "AUTHENTICATION_APIKEY_USERS"
          value: "hello@dify.ai"
        - name: "AUTHORIZATION_ADMINLIST_ENABLED"
          value: "true"
        - name: "AUTHORIZATION_ADMINLIST_USERS"
          value: "hello@dify.ai"
        volumeMounts:
        - name: weaviate-data
          mountPath: /var/lib/weaviate
          subPath: apps/dify/weaviate/data
      volumes:
      - name: weaviate-data
        persistentVolumeClaim:
          claimName: pvc-capacity-userdata 
---
apiVersion: v1
kind: Service
metadata:
  name: dify-weaviate
  namespace: dify
spec:
  selector:
    app: dify-weaviate
  type: ClusterIP
  clusterIP: None
  ports:
  - name: weaviate
    protocol: TCP
    port: 8080
    targetPort: 8080

# Weaviate Server End

# Dify Sandbox Server Start
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dify-sandbox
  namespace: dify
  labels:
    app: dify-sandbox
spec:
  replicas: 1
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: dify-sandbox
  template:
    metadata:
      labels:
        app: dify-sandbox
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      automountServiceAccountToken: false
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: dify-sandbox
        image: registry.hd-02.alayanew.com:8443/vc-app_market/langgenius/dify-sandbox:0.2.10
        env:
        - name: API_KEY
          value: "dify-sandbox"
        - name: GIN_MODE
          value: "release"
        - name: WORKER_TIMEOUT
          value: "15"
        - name: ENABLE_NETWORK
          value: "true"
        - name: SANDBOX_PORT
          value: "8194"
          # uncomment if you want to use proxy
        - name: HTTP_PROXY
          value: 'http://dify-ssrf:3128'
        - name: HTTPS_PROXY
          value: 'http://dify-ssrf:3128'
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 1Gi
        ports:
        - containerPort: 8194
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata:
  name: dify-sandbox
  namespace: dify
spec:
  ports:
  - port: 8194
    targetPort: 8194
    protocol: TCP
    name: dify-sandbox
  type: ClusterIP
  clusterIP: None
  selector:
    app: dify-sandbox

# Dify Sandbox Server End

# Dify SSRF Proxy Start
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: ssrf-proxy-config
  namespace: dify
data:
  squid.conf: |
    acl localnet src 0.0.0.1-0.255.255.255	# RFC 1122 "this" network (LAN)
    acl localnet src 10.0.0.0/8		# RFC 1918 local private network (LAN)
    acl localnet src 100.64.0.0/10		# RFC 6598 shared address space (CGN)
    acl localnet src 169.254.0.0/16 	# RFC 3927 link-local (directly plugged) machines
    acl localnet src 172.16.0.0/12		# RFC 1918 local private network (LAN)
    acl localnet src 192.168.0.0/16		# RFC 1918 local private network (LAN)
    acl localnet src fc00::/7       	# RFC 4193 local private network range
    acl localnet src fe80::/10      	# RFC 4291 link-local (directly plugged) machines
    acl SSL_ports port 443
    acl Safe_ports port 80		# http
    acl Safe_ports port 21		# ftp
    acl Safe_ports port 443		# https
    acl Safe_ports port 70		# gopher
    acl Safe_ports port 210		# wais
    acl Safe_ports port 1025-65535	# unregistered ports
    acl Safe_ports port 280		# http-mgmt
    acl Safe_ports port 488		# gss-http
    acl Safe_ports port 591		# filemaker
    acl Safe_ports port 777		# multiling http
    acl CONNECT method CONNECT
    http_access deny !Safe_ports
    http_access deny CONNECT !SSL_ports
    http_access allow localhost manager
    http_access deny manager
    http_access allow localhost
    http_access allow localnet
    http_access deny all

    ################################## Proxy Server ################################
    http_port 3128
    coredump_dir /var/spool/squid
    refresh_pattern ^ftp:		1440	20%	10080
    refresh_pattern ^gopher:	1440	0%	1440
    refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
    refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
    refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
    refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
    refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
    refresh_pattern .		0	20%	4320
    

    # upstream proxy, set to your own upstream proxy IP to avoid SSRF attacks
    # cache_peer 172.1.1.1 parent 3128 0 no-query no-digest no-netdb-exchange default 


    ################################## Reverse Proxy To Sandbox ################################
    http_port 8194 accel vhost
    # Notice:
    # default is 'sandbox' in dify's github repo, here is 'dify-sandbox' because the service name of sandbox is 'dify-sandbox'
    # you can change it to your own service name
    cache_peer dify-sandbox parent 8194 0 no-query originserver
    acl src_all src all
    http_access allow src_all

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: ssrf-proxy-entrypoint
  namespace: dify
data:
  docker-entrypoint-mount.sh: |
    #!/bin/bash

    # Modified based on Squid OCI image entrypoint
    
    # This entrypoint aims to forward the squid logs to stdout to assist users of
    # common container related tooling (e.g., kubernetes, docker-compose, etc) to
    # access the service logs.
    
    # Moreover, it invokes the squid binary, leaving all the desired parameters to
    # be provided by the "command" passed to the spawned container. If no command
    # is provided by the user, the default behavior (as per the CMD statement in
    # the Dockerfile) will be to use Ubuntu's default configuration [1] and run
    # squid with the "-NYC" options to mimic the behavior of the Ubuntu provided
    # systemd unit.
    
    # [1] The default configuration is changed in the Dockerfile to allow local
    # network connections. See the Dockerfile for further information.
    
    echo "[ENTRYPOINT] re-create snakeoil self-signed certificate removed in the build process"
    if [ ! -f /etc/ssl/private/ssl-cert-snakeoil.key ]; then
        /usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite > /dev/null 2>&1
    fi
    
    tail -F /var/log/squid/access.log 2>/dev/null &
    tail -F /var/log/squid/error.log 2>/dev/null &
    tail -F /var/log/squid/store.log 2>/dev/null &
    tail -F /var/log/squid/cache.log 2>/dev/null &
    
    # Replace environment variables in the template and output to the squid.conf
    echo "[ENTRYPOINT] replacing environment variables in the template"
    awk '{
        while(match($0, /\${[A-Za-z_][A-Za-z_0-9]*}/)) {
            var = substr($0, RSTART+2, RLENGTH-3)
            val = ENVIRON[var]
            $0 = substr($0, 1, RSTART-1) val substr($0, RSTART+RLENGTH)
        }
        print
    }' /etc/squid/squid.conf.template > /etc/squid/squid.conf
    
    /usr/sbin/squid -Nz
    echo "[ENTRYPOINT] starting squid"
    /usr/sbin/squid -f /etc/squid/squid.conf -NYC 1

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  dify-ssrf
  namespace: dify
  labels:
    app:  dify-ssrf
spec:
  selector:
    matchLabels:
      app: dify-ssrf
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app:  dify-ssrf
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name:  dify-ssrf
        image:  registry.hd-02.alayanew.com:8443/vc-app_market/ubuntu/squid:latest
        env:
        - name: HTTP_PORT
          value: "3128"
        - name: COREDUMP_DIR
          value: "/var/spool/squid"
        - name: REVERSE_PROXY_PORT
          value: "8194"
        - name: SANDBOX_HOST
          value: "dify-sandbox"
        - name: SANDBOX_PORT
          value: "8194"
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 300m
            memory: 300Mi
        ports:
        - containerPort:  3128
          name:  dify-ssrf
        volumeMounts:
        - name: ssrf-proxy-config
          mountPath: /etc/squid/
        - name: ssrf-proxy-entrypoint
          mountPath: /tmp/
        command: [ "sh", "-c", "cp /tmp/docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
      volumes:
        - name: ssrf-proxy-config
          configMap:
            name: ssrf-proxy-config
        - name: ssrf-proxy-entrypoint
          configMap:
            name: ssrf-proxy-entrypoint
      restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
  name: dify-ssrf
  namespace: dify
spec:
  selector:
    app: dify-ssrf
  ports:
  - protocol: TCP
    port: 3128
    targetPort: 3128
# Dify SSRF Proxy End

# Dify API Server End
# ---
# kind: PersistentVolumeClaim
# apiVersion: v1
# metadata:
#   name: dify-api-pvc
#   namespace: dify
# spec:
#   storageClassName: mas-cephfs-hdd-vc2qofwoe524
#   accessModes:
#     - ReadWriteMany
#   resources:
#     requests:
#       storage: 5Gi

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dify-api
  labels:
    app.kubernetes.io/instance: dify-api
    app: dify-api
  namespace: dify
spec:
  replicas: 1
  revisionHistoryLimit: 1
  minReadySeconds: 10
  serviceName: dify-api
  selector:
    matchLabels:
      app: dify-api
  template:
    metadata:
      labels:
        app: dify-api
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      nodeSelector:
        kubernetes.io/os: linux
      volumes:
      - name: dify-api-storage
        persistentVolumeClaim:
          claimName: pvc-capacity-userdata
          
      containers:
      - name: dify-api
        image: registry.hd-02.alayanew.com:8443/vc-app_market/langgenius/dify-api:0.12.1
        env:
        - name: MODE
          value: api
        - name: LOG_LEVEL
          value: DEBUG
        - name: SECRET_KEY
          value: "sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U"
        - name: CONSOLE_WEB_URL
          value: ""
        - name: INIT_PASSWORD
          value: password
        - name: CONSOLE_API_URL
          value: ""
        - name: SERVICE_API_URL
          value: ""
        - name: APP_WEB_URL
          value: ""
        - name: FILES_URL
          value: ""
        - name: MIGRATION_ENABLED
          value: "true"
        - name: DB_USERNAME
          value: postgres
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-username
        - name: DB_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-password
        - name: DB_HOST
          value: dify-postgres
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-host
        - name: DB_PORT
          value: '5432'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-port
        - name: DB_DATABASE
          value: dify
        - name: REDIS_HOST
          value: dify-redis
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-host
        - name: REDIS_PORT
          value: '6379'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-port
          # default redis username is empty
        - name: REDIS_USERNAME
          value: ''
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-username
        - name: REDIS_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-password
        - name: REDIS_USE_SSL
          value: "false"
        - name: REDIS_DB
          value: "0"
        - name: CELERY_BROKER_URL
          value: >-
            redis://$(REDIS_USERNAME):$(REDIS_PASSWORD)@$(REDIS_HOST):$(REDIS_PORT)/1
        - name: WEB_API_CORS_ALLOW_ORIGINS
          value: "*"
        - name: CONSOLE_CORS_ALLOW_ORIGINS
          value: "*"
        - name: STORAGE_TYPE
          value: "*"
        - name: STORAGE_LOCAL_PATH
          value: /app/api/storage
        - name: VECTOR_STORE
          value: weaviate
        - name: WEAVIATE_HOST
          value: dify-weaviate
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: weaviate-host
        - name: WEAVIATE_PORT
          value: '8080'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: weaviate-port
        - name: WEAVIATE_ENDPOINT
          value: http://$(WEAVIATE_HOST):$(WEAVIATE_PORT)
        - name: WEAVIATE_API_KEY
          value: "WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih"
        - name: CODE_EXECUTION_ENDPOINT
          value: http://dify-sandbox:8194
        - name: CODE_EXECUTION_API_KEY
          value: dify-sandbox
        - name: CODE_MAX_NUMBER
          value: "9223372036854775807"
        - name: CODE_MIN_NUMBER
          value: "-9223372036854775808"
        - name: CODE_MAX_STRING_LENGTH
          value: "80000"
        - name: TEMPLATE_TRANSFORM_MAX_LENGTH
          value: "80000"
        - name: CODE_MAX_STRING_ARRAY_LENGTH
          value: "30"
        - name: CODE_MAX_OBJECT_ARRAY_LENGTH
          value: "30"
        - name: CODE_MAX_NUMBER_ARRAY_LENGTH
          value: "1000"
        - name: INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH
          value: "1000"
          # uncommect to enable SSRF
        - name: SSRF_PROXY_HTTP_URL
          value: 'http://dify-ssrf:3128'
        - name: SSRF_PROXY_HTTPS_URL
          value: 'http://dify-ssrf:3128'
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 2Gi
        ports:
        - containerPort: 5001
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: dify-api-storage
          mountPath: /app/api/storage
          subPath: apps/dify/api
---
apiVersion: v1
kind: Service
metadata:
  name: dify-api
  namespace: dify
spec:
  ports:
  - port: 5001
    targetPort: 5001
    protocol: TCP
    name: dify-api
  type: ClusterIP
  selector:
    app: dify-api

# Dify API Server End

# Dify Worker Server Start
# ---
# kind: PersistentVolumeClaim
# apiVersion: v1
# metadata:
#   name: dify-worker-pvc
#   namespace: dify
# spec:
#   storageClassName: mas-cephfs-hdd-vc2qofwoe524
#   accessModes:
#     - ReadWriteMany
#   resources:
#     requests:
#       storage: 5Gi

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dify-worker
  namespace: dify
  labels:
    app: dify-worker
    app.kubernetes.io/instance: dify-worker
spec:
  serviceName: "dify-worker"
  replicas: 1
  selector:
    matchLabels:
      app: dify-worker
  template:
    metadata:
      labels:
        app: dify-worker
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      nodeSelector:
        kubernetes.io/os: linux
      volumes:
      - name: dify-worker-storage
        persistentVolumeClaim:
          claimName: pvc-capacity-userdata
      containers:
      - name: dify-worker
        image: registry.hd-02.alayanew.com:8443/vc-app_market/langgenius/dify-api:0.12.1
        ports:
        - containerPort: 5001
          protocol: TCP
        env:
        - name: CONSOLE_WEB_URL
          value: ""
        - name: MODE
          value: worker
        - name: LOG_LEVEL
          value: INFO
        - name: SECRET_KEY
          value: "sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U"
        - name: DB_USERNAME
          value: postgres
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-username
        - name: DB_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-password
        - name: DB_HOST
          value: dify-postgres
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-host
        - name: DB_PORT
          value: '5432'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: pg-port
        - name: DB_DATABASE
          value: dify
        - name: REDIS_HOST
          value: dify-redis
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-host
        - name: REDIS_PORT
          value: '6379'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-port
          # default redis username is empty
        - name: REDIS_USERNAME
          value: ''
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-username
        - name: REDIS_PASSWORD
          value: difyai123456
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: redis-password
        - name: REDIS_USE_SSL
          value: "false"
        - name: REDIS_DB
          value: "0"
        - name: CELERY_BROKER_URL
          value: >-
            redis://$(REDIS_USERNAME):$(REDIS_PASSWORD)@$(REDIS_HOST):$(REDIS_PORT)/1
        - name: WEB_API_CORS_ALLOW_ORIGINS
          value: "*"
        - name: CONSOLE_CORS_ALLOW_ORIGINS
          value: "*"
        - name: STORAGE_TYPE
          value: "*"
        - name: STORAGE_LOCAL_PATH
          value: /app/api/storage
        - name: VECTOR_STORE
          value: weaviate
        - name: WEAVIATE_HOST
          value: dify-weaviate
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: weaviate-host
        - name: WEAVIATE_PORT
          value: '8080'
          # valueFrom:
          #   secretKeyRef:
          #     name: dify-credentials
          #     key: weaviate-port
        - name: WEAVIATE_ENDPOINT
          value: http://$(WEAVIATE_HOST):$(WEAVIATE_PORT)
        - name: WEAVIATE_API_KEY
          value: "WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih"
        - name: SSRF_PROXY_HTTP_URL
          value: 'http://dify-ssrf:3128'
        - name: SSRF_PROXY_HTTPS_URL
          value: 'http://dify-ssrf:3128'
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 2Gi
        volumeMounts:
        - name: dify-worker-storage
          mountPath: /app/api/storage
          subPath: apps/dify/worker
        imagePullPolicy: IfNotPresent
      restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
  name: dify-worker
  namespace: dify
spec:
  ports:
  - protocol: TCP
    port: 5001
    targetPort: 5001
  selector:
    app: dify-worker
  type: ClusterIP

# Dify Worker Server End

# Dify Web Server Start
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dify-web
  namespace: dify
  labels:
    app: dify-web
spec:
  replicas: 1
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: dify-web
  template:
    metadata:
      labels:
        app: dify-web
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      nodeSelector:
        kubernetes.io/os: linux
      automountServiceAccountToken: false
      containers:
      - name: dify-web
        image: registry.hd-02.alayanew.com:8443/vc-app_market/langgenius/dify-web:0.12.1
        env:
        - name: EDITION
          value: SELF_HOSTED
        - name: CONSOLE_API_URL
          value: ""
        - name: APP_API_URL
          value: ""
        - name: SENTRY_DSN
          value: ""
        - name: NEXT_TELEMETRY_DISABLED
          value: "0"
        - name: TEXT_GENERATION_TIMEOUT_MS
          value: "60000"
        - name: CSP_WHITELIST
          value: ""
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 1Gi
        ports:
        - containerPort: 3000
        imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Service
metadata:
  name: dify-web
  namespace: dify
spec:
  ports:
  - port: 3000
    targetPort: 3000
    protocol: TCP
    name: dify-web
  type: ClusterIP
  selector:
    app: dify-web

# Dify Web Server End


# Dify Web Server End
# Dify Nginx Server Start
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: dify-nginx
  namespace: dify
data:
  nginx.conf: |-
    user  nginx;
    worker_processes  auto;

    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;


    events {
        worker_connections  1024;
    }


    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';

        access_log  /var/log/nginx/access.log  main;

        sendfile        on;
        #tcp_nopush     on;

        keepalive_timeout  65;

        #gzip  on;
        client_max_body_size 15M;

        server {
        listen 80;
        server_name _;

        location /console/api {
          proxy_pass http://dify-api:5001;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        location /api {
          proxy_pass http://dify-api:5001;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        location /v1 {
          proxy_pass http://dify-api:5001;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        location /files {
          proxy_pass http://dify-api:5001;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        location / {
          proxy_pass http://dify-web:3000;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        # If you want to support HTTPS, please uncomment the code snippet below
        #listen 443 ssl;
        #ssl_certificate ./../ssl/your_cert_file.cer;
        #ssl_certificate_key ./../ssl/your_cert_key.key;
        #ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        #ssl_prefer_server_ciphers on;
        #ssl_session_cache shared:SSL:10m;
        #ssl_session_timeout 10m;
    }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dify-nginx
  namespace: dify
  labels:
    app: dify-nginx
spec:
  replicas: 1
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: dify-nginx
  template:
    metadata:
      labels:
        app: dify-nginx
    spec:
      imagePullSecrets:
      - name: dify-harbor-secret
      nodeSelector:
        kubernetes.io/os: linux
      automountServiceAccountToken: false
      containers:
      - name: dify-nginx
        image: registry.hd-02.alayanew.com:8443/vc-app_market/nginx:latest
        resources:
          requests:
            cpu: 50m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 1Gi
        ports:
        - containerPort: 80
        volumeMounts:
        - name: dify-nginx
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: dify-nginx-config
          mountPath: /etc/nginx/conf.d
        imagePullPolicy: IfNotPresent
      volumes:
      - name: dify-nginx
        configMap:
          name: dify-nginx
      # Persistent volume could be better
      - name: dify-nginx-config
        emptyDir: {}

---
kind: Service
apiVersion: v1
metadata:
  name: dify-nginx
  namespace: dify
spec:
  selector:
    app: dify-nginx
  type: ClusterIP
  ports:
  - name: dify-nginx
    port: 80
    targetPort: 80
# Dify Nginx Server End

---
# vcluster export service
apiVersion: osm.datacanvas.com/v1alpha1
kind: ServiceExporter
metadata:
  name: dify-web-se # immutable
  namespace: dify
spec:
  serviceName: dify-nginx # required
  servicePort: 80