はじめに
Difyをセルフホスティングで環境構築したけど、フロント部分をカスタムしたいと思い、設定をまとめました
環境
- サーバー: Ubuntu 24.04 LTS
変更箇所
- 2025年4月10日現在、モバイル版でチャット履歴をタップしても、サイドバー外をタップしないとチャット画面に戻ることができない(バグっぽいけど)
使いずらいので、チャット履歴をタップしたらサイドバーを閉じるように変更する - 複数のDifyを取りまとめるため、ダッシュボード画面を用意する
タイトルを押したら、裏で画面は切り替わるがサイドバーは閉じない
手順
フロントを修正する
-
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} /> )}
-
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> )}
ダッシュボードの設置
-
dify/docker/nginx
ディレクトリにhtml
ディレクトリを作成し、dashboard.html
を設置するdify/docker/nginx## htmlディレクトリの作成 touch html/dashboard.html # dashboard.htmlの中身を作成 nano html/dashboard.html
- ルーティングと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認証をつけて、公開制限を行う
- apache2-utilsをインストール
bash
sudo apt update sudo apt install apache2-utils
- htpasswdコマンドでパスワードファイルを作成
dify/docker/nginx/conf.d#
sudo htpasswd -c ./.htpasswd <ユーザー名>
- パスワードの入力を求められるので、2回入力して設定完了
環境変更
-
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
-
docker-compose-template.yaml
をdocker-compose.yaml
に反映する~dify/docker#python3 generate_docker_compose
起動
- webをbuild形式にしたため、
docker compose build
を実施後起動~/dify/docker#docker compose up -d
確認
モバイル版でサイドバーを表示し、タイトルをタップしたらチャットが切り替わり、サイドバーが閉じるようになりました。