在这里插入图片描述

###############################################################################
# Author: Winson Li
# Email: mail@winson.dev
# 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

# 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

---
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:
      serviceAccountName: dify-postgres
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: dify-postgres
        image: 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
        - name: PGDATA
          value: /var/lib/postgresql/data
        # command:
        # - "postgres"
        # - "-c"
        # - "max_connections=100"
        # - "-c"
        # - "shared_buffers=128MB"
        # - "-c"
        # - "work_mem=4MB"
        # - "-c"
        # - "maintenance_work_mem=64MB"
        # - "-c"
        # - "effective_cache_size=4096MB"

        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: postgres-data
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-data
        hostPath:
          path: /root/k8s/dify/db/postgres/data
          type: DirectoryOrCreate

---
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

---
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:
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: dify-redis
      containers:
      - name: dify-redis
        image: 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
      volumes:
      - name: redis-data
        hostPath:
          path: /root/k8s/dify/db/redis/data
          type: DirectoryOrCreate

---
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

---
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:
      terminationGracePeriodSeconds: 10
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: dify-weaviate
      volumes:
      - name: weaviate-data
        hostPath:
          path: /root/k8s/dify/db/weaviate/data
          type: DirectoryOrCreate
      containers:
      - name: dify-weaviate
        image: 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

---
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:
      automountServiceAccountToken: false
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: dify-sandbox
        image: langgenius/dify-sandbox:0.2.12
        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
        livenessProbe:
          exec:
            command:
            - "curl"
            - "-f"
            - "http://localhost:8194/health"
        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 SSL_ports port 1025-65535   # Enable the configuration to resolve this issue: https://github.com/langgenius/dify/issues/12792
    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:
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: dify-ssrf
        image: 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
---
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:
      nodeSelector:
        kubernetes.io/os: linux
      volumes:
      - name: dify-api-storage
        hostPath:
          path: /root/k8s/dify/app/api/storage
          type: DirectoryOrCreate
      containers:
      - name: dify-api
        image: langgenius/dify-api:1.4.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: opendal
        - name: OPENDAL_SCHEME
          value: fs
        - name: OPENDAL_FS_ROOT
          value: storage
        - 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'
        - name: SENTRY_DSN
          value: ''
        - name: SENTRY_TRACES_SAMPLE_RATE
          value: '1.0'
        - name: SENTRY_PROFILES_SAMPLE_RATE
          value: '1.0'
          # plugin settings
        - name: 'PLUGIN_MAX_PACKAGE_SIZE'
          value: '52428800'
        - name: 'INNER_API_KEY_FOR_PLUGIN'
          value: 'QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1'
        - name: 'PLUGIN_DAEMON_KEY'
          value: 'lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi'
        - name: 'PLUGIN_DAEMON_URL'
          value: 'http://dify-plugin-daemon:5002'
        - name: 'MARKETPLACE_ENABLED'
          value: 'true'
        - name: 'MARKETPLACE_API_URL'
          value: 'https://marketplace.dify.ai'
        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
---
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
---
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:
      nodeSelector:
        kubernetes.io/os: linux
      volumes:
      - name: dify-api-storage
        hostPath:
          path: /root/k8s/dify/app/api/storage
          type: DirectoryOrCreate
      containers:
      - name: dify-worker
        image: langgenius/dify-api:1.4.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: opendal
        - name: OPENDAL_SCHEME
          value: fs
        - name: OPENDAL_FS_ROOT
          value: storage
        - 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'
        - name: SENTRY_DSN
          value: ''
        - name: SENTRY_TRACES_SAMPLE_RATE
          value: '1.0'
        - name: SENTRY_PROFILES_SAMPLE_RATE
          value: '1.0'
          # plugin settings
        - name: 'PLUGIN_MAX_PACKAGE_SIZE'
          value: '52428800'
        - name: 'PLUGIN_DAEMON_URL'
          value: 'http://dify-plugin-daemon:5002'
        - name: 'PLUGIN_DAEMON_KEY'
          value: 'lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi'
        - name: 'INNER_API_KEY_FOR_PLUGIN'
          value: 'QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1'
        - name: 'MARKETPLACE_ENABLED'
          value: 'true'
        - name: 'MARKETPLACE_API_URL'
          value: 'https://marketplace.dify.ai'
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 2Gi
        volumeMounts:
        - name: dify-api-storage
          mountPath: /app/api/storage
        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:
      nodeSelector:
        kubernetes.io/os: linux
      automountServiceAccountToken: false
      containers:
      - name: dify-web
        image: langgenius/dify-web:1.4.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: ""
          # dify marketplace
        - name: 'MARKETPLACE_API_URL'
          value: 'https://marketplace.dify.ai'
        - name: 'MARKETPLACE_URL'
          value: 'https://marketplace.dify.ai'
        - name: 'TOP_K_MAX_VALUE'
          value: ''
        - name: 'INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH'
          value: ''
        - name: 'PM2_INSTANCES'
          value: '2'
        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 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_set_header X-Forwarded-Port $server_port;
          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_set_header X-Forwarded-Port $server_port;
          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_set_header X-Forwarded-Port $server_port;
          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_set_header X-Forwarded-Port $server_port;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }

        location /explore {
          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_set_header X-Forwarded-Port $server_port;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
        }
        
        location /e/ {
          proxy_pass http://dify-plugin-daemon:5002;
          proxy_set_header Dify-Hook-Url ://;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Port $server_port;
          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_set_header X-Forwarded-Port $server_port;
          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:
      nodeSelector:
        kubernetes.io/os: linux
      automountServiceAccountToken: false
      containers:
      - name: dify-nginx
        image: nginx:stable
        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

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

# Dify plugin daemon Start

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dify-plugin-daemon
  namespace: dify
  labels:
    app: dify-plugin-daemon
spec:
  replicas: 1
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: dify-plugin-daemon
  template:
    metadata:
      labels:
        app: dify-plugin-daemon
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      automountServiceAccountToken: false
      volumes:
      - name: dify-plugin-daemon-storage
        hostPath:
          path: /root/k8s/dify/app/plugin/storage
          type: DirectoryOrCreate
      containers:
      - name: dify-plugin-daemon
        image: langgenius/dify-plugin-daemon:0.1.1-local
        resources:
          limits:
            memory: "1024Mi"
            cpu: "2000m"
          requests:
            memory: "256Mi"
            cpu: "500m"
        ports:
        - containerPort: 5003
          protocol: TCP
          name: debug-port
          
        - containerPort: 5002
          protocol: TCP
          name: service-port
        env:
          - name: DB_USERNAME
            value: postgres

          - name: DB_PASSWORD
            value: difyai123456

          - name: DB_HOST
            value: dify-postgres

          - name: DB_PORT
            value: '5432'

          - name: REDIS_HOST
            value: dify-redis

          - name: REDIS_PORT
            value: '6379'

          - name: REDIS_USERNAME
            value: ''

          - name: REDIS_PASSWORD
            value: difyai123456
          - 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: 'DB_DATABASE'
            value: 'dify_plugin'
          - name: 'SERVER_PORT'
            value: '5002'
          - name: 'EXPOSE_PLUGIN_DAEMON_PORT'
            value: '5002'
          - name: 'SERVER_KEY'
            value: 'lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi'
          - name: 'MAX_PLUGIN_PACKAGE_SIZE'
            value: '52428800'
          - name: 'PPROF_ENABLED'
            value: 'false'
          - name: 'DIFY_INNER_API_URL'
            value: 'http://dify-api:5001'
          - name: 'DIFY_INNER_API_KEY'
            value: 'QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1'
          - name: 'PLUGIN_REMOTE_INSTALLING_HOST'
            value: '0.0.0.0'
          - name: 'PLUGIN_REMOTE_INSTALLING_PORT'
            value: '5003'
          - name: 'PLUGIN_WORKING_PATH'
            value: '/app/storage/cwd'
          - name: 'FORCE_VERIFYING_SIGNATURE'
            value: 'true'
          - name: 'EXPOSE_PLUGIN_DEBUGGING_HOST'
            value: 'localhost'
          - name: 'EXPOSE_PLUGIN_DEBUGGING_PORT'
            value: '5003'
          # - name: 'ENDPOINT_URL_TEMPLATE'
          #   value: 'http://localhost/e/{hook_id}'
        volumeMounts:
        - name: dify-plugin-daemon-storage
          mountPath: /app/storage

---
apiVersion: v1
kind: Service
metadata:
  name: dify-plugin-daemon
  namespace: dify
spec:
  type: ClusterIP
  selector:
    app: dify-plugin-daemon
  ports:
  - port: 5003
    targetPort: 5003
    protocol: TCP
    name: debug-port
  - port: 5002
    targetPort: 5002
    protocol: TCP
    name: service-port

# Dify Plugin Daemon End

访问http://服务器ip:30000,初始化密码是password

2025年5月27日,知名智能应用开发平台Dify发布了重磅版本——v1.4.1。本次更新不仅汇聚了多项令人惊喜的新功能,还针对老版本存在的问题进行了深度修复和性能优化。无论你是开发者、企业用户,还是技术爱好者,Dify 1.4.1都将带来全新的体验与更多可能。本文将以全面且深入的角度,为你详细解读本次版本更新的亮点内容和升级指南,一站式掌握Dify最新资讯,助力你在智能应用的浪潮中抢占先机!

一、Dify 1.4.1:重磅新功能盘点

  1. 可选请求日志记录——调试更便捷

在复杂的应用开发和运维过程中,调试与问题追踪尤为重要。Dify 1.4.1新增的“可选请求和响应日志记录”功能,为开发者定制化调试方案提供了有力保障。开发者可以针对API请求及响应数据进行灵活配置和记录,帮助迅速定位问题、优化接口调用流程,显著提升开发效率和系统稳定性。

  1. 全面支持Web多媒体元素——音视频嵌入更自由

本次版本同时增强了Web端多媒体支持,实现了对视频(video)及音频(audio)元素的src属性兼容。这意味着无论是动态演示、音频播报,还是多媒体内容展示,开发者都能以更灵活和高效的方式嵌入丰富的媒体资源,打造更具吸引力的用户界面和体验。

  1. 支持阿里云OSS存储——云端管理再升级

对阿里云生态系统有需求的用户福音来了!Dify的插件守护进程新增支持阿里云对象存储服务(OSS),缓解云存储接入的痛点。这种支持极大丰富了数据处理与存储的场景应用,使得在中国及全球阿里云用户使用Dify更加无缝和高效,满足企业级业务多样数据管理需求。

  1. Opik Tracer对话追踪支持——全链路追踪增强版

在智能应用的运维和数据分析层面,追踪用户会话数据往往是关键。Dify 1.4.1新增了通过Opik Tracer追踪对话功能,能够更精准地捕获和呈现多轮会话流程,便于用户行为分析和产品迭代优化。无论是客服智能机器人还是复杂交互型应用,均可从中受益。

  1. 应用创建体验简化——上手更快更直观

Dify大幅优化了应用创建流程,将基础应用类型进行了折叠,减少界面复杂性,帮助开发者快速定位所需应用模板和配置项。对初学者来说,这意味着门槛更低;对资深用户来说,节省更多时间投入到核心业务逻辑的设计。

  1. 文档解析器增强——多编码文本支持更灵活

针对多样化的文本数据源,Dify升级了文档提取器,内置字符编码自动检测(chardet)模块,极大提升对复杂文本文件的兼容性和解析准确率。它有效解决了在不同编码格式文档中出现的乱码问题,为数据集成和知识抽取工作打下了更坚实基础。

二、Dify 1.4.1:修复与性能优化详解

  1. 重大安全更新,升级qdrant-client至1.9.0

安全始终是技术平台的生命线。此次版本全面升级了qdrant-client库,补丁修复了潜在安全隐患,确保数据存储和检索环节的安全稳定。同时也兼容了新版本客户端的诸多性能改进,保障系统响应速度与可靠性。

  1. 布局优化与界面问题修复

针对页面中的元数据条件名溢出、机器人描述文本超长导致布局错乱等问题进行了细致修复。界面美学和交互体验被进一步提升,无论是PC端还是移动端,用户都能感受到顺滑且协调的视觉效果。

  1. 上传与导出流程全面打磨

修复了头像上传失败、自定义文件类型导出异常的问题。文件管理流程被深度优化,保证用户在素材管理上无后顾之忧,为应用形象塑造和数据处理提供强大支持。

  1. 工作流和知识检索核心模块调优

岗位执行验证、工作流节点执行逻辑以及知识检索相关功能中的变量初始化问题被彻底解决。此外,检索重排开关的多次调用错误得到纠正,使得系统运行更稳定,业务逻辑更精准。

  1. 流式内容图表渲染提升

针对流式数据在Markdown文档中图表(ECharts)闪烁与动画循环的bug,Dify进行了核心渲染引擎升级改造,显著提升图表绘制的流畅度和稳定性,打造更具视觉冲击力的动态数据展示效果。

  1. Redis及数据库配置完善

中间件Redis版本从6升级至7,数据库模型类型错误修正及配置参数清晰化,整个平台的后端基础设施更加稳健,响应速度更快,支撑大规模并发访问。

三、升级指南:适配多种部署环境一步到位

  1. Docker Compose方式升级
  • 备份已有docker-compose配置文件,避免配置丢失风险。
  • 从主分支拉取最新代码,确保基础代码同步。
  • 关闭现有服务,导出数据卷备份,确保数据安全。
  • 重新部署启动容器,完成版本切换。
  1. 源码环境升级
  • 停止API、Worker与前端服务,保证升级环境干净。
  • 切换到1.4.1发布分支,拉取完整代码。
  • 进入API目录,同步并升级Python依赖。
  • 使用数据库迁移脚本完成架构变更。
  • 重新启动全部服务,完成全流程更新。

四、推荐实践与落地场景

  1. 开发者调试利器:开启请求日志,快速定位接口异常与性能瓶颈,节省开发周期。

  2. 多媒体集成应用:通过新增视频与音频元素支持,轻松构建教学、娱乐及企业宣传应用。

  3. 云存储扩展场景:利用阿里云OSS插件,搭建跨境或多区域数据分发架构,提高访问速度与稳定性。

  4. 智能客服对话分析:结合Opik Tracer端到端会话追踪,提升客户服务满意度,精准运营分析。

  5. 低门槛快速搭建:优化后的应用创建流程,让新手零基础轻松搭建功能完善的智能应用。

  6. 数据抽取与知识管理:增强的文档编码识别让大批量异构数据导入及自动分类更加顺畅,高效完成知识库构建。

五、总结

Dify 1.4.1的发布,是一次功能与体验的双重进阶,也是对用户反馈的积极响应。全新日志机制、多媒体增强、云端存储支持以及追踪能力,配合核心修复和底层性能优化,系统运行更流畅、安全和智能。无论是初次尝试,还是长期投入Dify生态,升级到1.4.1版本都能帮你打开更多想象空间,实现更高效的应用创新。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐