2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Difyでフロントエンドをカスタムする

Last updated at Posted at 2025-04-14

はじめに

Difyをセルフホスティングで環境構築したけど、フロント部分をカスタムしたいと思い、設定をまとめました

セルフホスティングの環境構築方法はこちら

環境

  • サーバー: Ubuntu 24.04 LTS

変更箇所

  • 2025年4月10日現在、モバイル版でチャット履歴をタップしても、サイドバー外をタップしないとチャット画面に戻ることができない(バグっぽいけど)
    使いずらいので、チャット履歴をタップしたらサイドバーを閉じるように変更する
  • 複数のDifyを取りまとめるため、ダッシュボード画面を用意する

IMG_1915.jpg
タイトルを押したら、裏で画面は切り替わるがサイドバーは閉じない

手順

フロントを修正する

  1. dify/web/app/components/base/chat/chat-with-history/sidebar/index.tsxを以下に修正

    23行目付近~
    type Props = {
      isPanel?: boolean
    + onClose?: () => void
    }
    
    - const Sidebar = ({ isPanel }: Props) => {
    + const Sidebar = ({ isPanel, onClose }: Props) => {
      const { t } = useTranslation()
      const {
        appData,
        handleNewConversation,
        pinnedConversationList,
        conversationList,
        currentConversationId,
        handleChangeConversation,
        handlePinConversation,
        handleUnpinConversation,
        conversationRenaming,
        handleRenameConversation,
        handleDeleteConversation,
        sidebarCollapseState,
        handleSidebarCollapse,
        isMobile,
        isResponding,
      } = useChatWithHistoryContext()
    
    52行目付近~
    const handleOperate = useCallback((type: string, item: ConversationItem) => {
        if (type === 'pin')
          handlePinConversation(item.id)
    
        if (type === 'unpin')
          handleUnpinConversation(item.id)
    
        if (type === 'delete')
          setShowConfirm(item)
    
        if (type === 'rename')
          setShowRename(item)
      }, [handlePinConversation, handleUnpinConversation])
    + const handleChangeConversationWrapper = useCallback((conversationId: string) => {
    +    handleChangeConversation(conversationId)
    +    if (onClose)
    +      onClose()
    +  }, [handleChangeConversation, onClose])
      const handleCancelConfirm = useCallback(() => {
        setShowConfirm(null)
      }, [])
    
    114行目付近~
    <div className='h-0 grow space-y-2 overflow-y-auto px-3 pt-4'>
        {/* pinned list */}
        {!!pinnedConversationList.length && (
          <div className='mb-4'>
            <List
              isPin
              title={t('share.chat.pinnedTitle') || ''}
              list={pinnedConversationList}
    -         onChangeConversation={handleChangeConversation}
    +         onChangeConversation={handleChangeConversationWrapper}
              onOperate={handleOperate}
              currentConversationId={currentConversationId}
            />
          </div>
        )}
        {!!conversationList.length && (
          <List
            title={(pinnedConversationList.length && t('share.chat.unpinnedTitle')) || ''}
            list={conversationList}
    -       onChangeConversation={handleChangeConversation}
    +       onChangeConversation={handleChangeConversationWrapper}
            onOperate={handleOperate}
            currentConversationId={currentConversationId}
          />
        )}
    

  2. dify/web/app/components/base/chat/chat-with-history/header-in-mobile.tsxを修正

    104行目付近~
    {showSidebar && (
      <div className='fixed inset-0 z-50 flex bg-background-overlay p-1'
        onClick={() => setShowSidebar(false)}
      >
        <div className='flex h-full w-[calc(100vw_-_40px)] rounded-xl bg-components-panel-bg shadow-lg backdrop-blur-sm' onClick={e => e.stopPropagation()}>
    -     <Sidebar />
    +     <Sidebar isPanel onClose={() => setShowSidebar(false)} />
        </div>
      </div>
    )}
    

ダッシュボードの設置

  1. dify/docker/nginx ディレクトリに html ディレクトリを作成し、dashboard.html を設置する
    dify/docker/nginx#
    # htmlディレクトリの作成
    touch html/dashboard.html
    
    # dashboard.htmlの中身を作成
    nano html/dashboard.html
    

  2. ルーティングとBasic認証の追加
    dify/docker/nginx/conf.d#
    location / {
      proxy_pass http://web:3000;
      include proxy.conf;
    }
    
    + location /dashboard {
    +   auth_basic "Restricted Access";
    +   auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
    +   root /usr/share/nginx/html;
    +   index dashboard.html;
    +   try_files /dashboard.html $uri $uri/ =404;
    + }
    + 
    # placeholder for acme challenge location
    ${ACME_CHALLENGE_LOCATION}
    
    

Basic認証の追加

/dashboardにBasic認証をつけて、公開制限を行う

  1. apache2-utilsをインストール
    bash
    sudo apt update
    sudo apt install apache2-utils
    

  2. htpasswdコマンドでパスワードファイルを作成
    dify/docker/nginx/conf.d#
    sudo htpasswd -c ./.htpasswd <ユーザー名>
    

  3. パスワードの入力を求められるので、2回入力して設定完了

環境変更

  1. docker-compose-template.yamlを変更
    DifyはDocker Hubのイメージを使用しているため、これをdify/web/のディレクトリを見るように変更してあげないといけない

    dify/docker/docker-compose-template.yaml
    # Frontend web application.
      web:
    -  image: langgenius/dify-web:1.2.0
    +  build:
    +    context: ../web
    +    dockerfile: Dockerfile
        restart: always
        environment:
          CONSOLE_API_URL: ${CONSOLE_API_URL:-}
          APP_API_URL: ${APP_API_URL:-}
          SENTRY_DSN: ${WEB_SENTRY_DSN:-}
          NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
          TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
          CSP_WHITELIST: ${CSP_WHITELIST:-}
          MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
          MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
          TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
          INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
          PM2_INSTANCES: ${PM2_INSTANCES:-2}
          LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
          MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
          MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
          MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-5}
    

    ダッシュボードの設置先を指定する
    691行目付近~
    nginx:
      image: nginx:latest
      restart: always
      volumes:
        - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template
        - ./nginx/proxy.conf.template:/etc/nginx/proxy.conf.template
        - ./nginx/https.conf.template:/etc/nginx/https.conf.template
        - ./nginx/conf.d:/etc/nginx/conf.d
    +   - ./nginx/html:/usr/share/nginx/html
        - ./nginx/docker-entrypoint.sh:/docker-entrypoint-mount.sh
        - ./nginx/ssl:/etc/ssl # cert dir (legacy)
        - ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container)
        - ./volumes/certbot/conf:/etc/letsencrypt
        - ./volumes/certbot/www:/var/www/html
    

  2. docker-compose-template.yamldocker-compose.yaml に反映する

    ~dify/docker#
    python3 generate_docker_compose 
    

起動

  1. webをbuild形式にしたため、docker compose buildを実施後起動
    ~/dify/docker#
    docker compose up -d
    

確認

モバイル版でサイドバーを表示し、タイトルをタップしたらチャットが切り替わり、サイドバーが閉じるようになりました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?