Dify 実際の導入を追体験する

公式ダウンロードからPowerShellでの展開、Ubuntuでの起動まで。

公開版の使い方

ここは教材を読む・動画を見るためのサイトです。サイトへアクセスしただけで、閲覧者のPCへソフトがインストールされることはありません。

Dify本体の約43MBのZIPはサイトへ同梱せず、公式配布先から別に取得します。補助ファイルを使う場合は、保存した教材の「導入ファイル」フォルダーへZIPと補助ファイルを一緒に置き、下の保存先入力欄を自分の場所へ修正してください。

公開版とPC保存版の違いを読む

動画で場所を確認 → 動画を止める → 自分のPCで操作 → 成功を確かめてチェック。ひとつずつ進めます。

このPCはDifyの導入済みです。まず第2章の新しいフォルダーへの展開練習を行い、第5章では起動状態の確認だけを実行します。初回導入の命令は、新しいPC向けの折りたたみ欄に分けています。

MP4を別に開く

音声なし。カーソルや進行表示を含む実録を編集し、長い待ち時間を省略しています。章ごとに録画日と範囲を表示しています。

WSL Ubuntu Docker Difyは何をするのか

具体的にできること集・意外とできないこと集 全30例

何ができて何ができないかを、質問への回答、報告文、画像・動画の具体例で説明します。コンテナーなどの言葉も読み方・意味・たとえから解説します。導入前の予習にも、説明するときの復習にも使えます。

4つのソフトの詳しい解説を読む

講師用の虎の巻 6ページ / 説明用の解説資料 24ページ

虎の巻 Word / 解説資料 Word

動画と同じ操作を進める

「この場面へ」で動画をその位置に移動して止めます。コードは一つの枠ずつ実行してください。

初回導入で使う教材フォルダー

ZIP教材は先に「すべて展開」します。下は01_教材を開く.htmlが入っているフォルダーです。別の場所へ移した場合だけ修正してください。初回導入用コードのパスに反映されます。

※ Windowsで展開した練習フォルダーと、実行するUbuntu側の保存先は別です。実際に動かすDifyはUbuntuの /home/ユーザー名/dify-training/dify-1.19.0 に置きます。

導入補助ファイルが行う処理を見る

Dockerの確認、公式ZIPの整合性確認、Ubuntuへの展開、設定の作成、部品の取得、起動と確認を順に行います。既存の導入先があれば停止し、既存Dockerのログイン設定は変更しません。

このZIP対応の改訂版は、ZIPの整合性・独立フォルダーへの展開・内部Python処理の構文を検査済みです。改訂版による別のDifyの新規起動は行っていません。サーバー起動の映像は、このPCで以前に実行した導入の記録です。

#!/usr/bin/env bash
# Dify 1.19.0: one-time, local learning installation for the current Ubuntu user.
# No Windows settings changes, administrator elevation, accounts, or API keys.
set -Eeuo pipefail
trap 'printf "\nSTOP: step failed at line %s. Keep this window open.\n" "$LINENO"' ERR
umask 077
printf '\n[1/5] Checking Ubuntu and Docker...\n'
test "$(id -un)" != root || { echo 'Run as your normal Ubuntu user.'; exit 1; }
command -v python3 >/dev/null
command -v docker >/dev/null || { echo 'Docker is not available. Check Docker Desktop WSL integration.'; exit 1; }
docker info --format 'Docker server: {{.ServerVersion}}'
docker compose version
python3 - <<'PY'
import re, subprocess
v=subprocess.check_output(['docker','compose','version','--short'],text=True).strip()
m=re.search(r'(\d+)\.(\d+)\.(\d+)',v)
if not m or tuple(map(int,m.groups())) < (2,35,0):
    raise SystemExit('Docker Compose 2.35.0 or newer is required.')
PY
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ARCHIVE="$SCRIPT_DIR/dify-1.19.0.zip"
TARGET="$HOME/dify-training/dify-1.19.0"
export ARCHIVE TARGET
printf '\n[2/5] Verifying the official release and copying it into Ubuntu...\n'
python3 - <<'PY'
import hashlib, os, pathlib, zipfile, stat
archive=pathlib.Path(os.environ['ARCHIVE'])
target=pathlib.Path(os.environ['TARGET'])
if target.exists():
    raise SystemExit('Installation folder already exists; stopped without overwriting it: '+str(target))
expected='a13a974657ced6c146b12459eb0ba9c0deea9b407d5c099fe1108355d53f5e40'
if hashlib.sha256(archive.read_bytes()).hexdigest()!=expected:
    raise SystemExit('Archive verification failed.')
target.parent.mkdir(parents=True,exist_ok=True)
with zipfile.ZipFile(archive) as z:
    for info in z.infolist():
        name=info.filename
        resolved=(target.parent/name).resolve()
        if not name.startswith('dify-1.19.0/') or not resolved.is_relative_to(target.resolve()):
            raise SystemExit('Unexpected archive path. Nothing extracted.')
        if stat.S_ISLNK(info.external_attr >> 16):
            link=z.read(info).decode('utf-8')
            if not (resolved.parent/link).resolve().is_relative_to(target.resolve()):
                raise SystemExit('Unexpected symbolic-link target. Nothing extracted.')
    for info in z.infolist():
        destination=target.parent/info.filename
        if stat.S_ISLNK(info.external_attr >> 16):
            destination.parent.mkdir(parents=True,exist_ok=True)
            destination.symlink_to(z.read(info).decode('utf-8'))
        else:
            z.extract(info,target.parent)
            mode=(info.external_attr >> 16) & 0o777
            if mode:
                destination.chmod(mode)
print('Saved to:',target)
PY
cd -- "$TARGET/docker"
printf '\n[3/5] Creating the local learning configuration...\n'
python3 - <<'PY'
from pathlib import Path
import secrets
p=Path('.env')
if p.exists(): raise SystemExit('Existing .env found; stopped without overwriting it.')
text=Path('.env.example').read_text()
key='DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN='
if text.count(key)!=1: raise SystemExit('Unexpected configuration template.')
text=text.replace(key,key+secrets.token_hex(32))
text+='\n# Local learning HTTP/HTTPS ports\nEXPOSE_NGINX_PORT=8080\nEXPOSE_NGINX_SSL_PORT=8443\n'
p.write_text(text)
p.chmod(0o600)
PY
# Restrict every published service port in this selected stack to this PC.
# Compose's !override tag replaces the original port list completely.
python3 - <<'PY'
from pathlib import Path
import json, subprocess
config=json.loads(subprocess.check_output(['docker','compose','-f','docker-compose.yaml','config','--format','json'],text=True))
lines=['services:']
for name, service in config['services'].items():
    ports=service.get('ports',[])
    if not ports: continue
    lines += ['  '+name+':','    ports: !override']
    for port in ports:
        if not isinstance(port,dict): raise SystemExit('Unexpected port format.')
        port=dict(port)
        port['host_ip']='127.0.0.1'
        lines.append('      - '+json.dumps(port))
Path('docker-compose.override.yaml').write_text('\n'.join(lines)+'\n')
final=json.loads(subprocess.check_output(['docker','compose','config','--format','json'],text=True))
for service in final['services'].values():
    for port in service.get('ports',[]):
        if port.get('host_ip')!='127.0.0.1':
            raise SystemExit('Port binding verification failed. Nothing was started.')
print('All published ports verified as local to this PC.')
PY
docker compose config --quiet
printf '\n[4/5] Downloading and starting Dify components. This can take several minutes...\n'
python3 -u - <<'PY'
import json,os,pathlib,subprocess,tempfile
config=json.loads(subprocess.check_output(['docker','compose','config','--format','json'],text=True))
images=set()
profiles={'weaviate','postgresql','collaboration'}
for service in config['services'].values():
    selected=service.get('profiles',[])
    if selected and not profiles.intersection(selected):
        continue
    for port in service.get('ports',[]):
        if port.get('host_ip')!='127.0.0.1':
            raise SystemExit('STOP: unexpected non-local port binding. Nothing was started.')
    if service.get('image'): images.add(service['image'])
if not images: raise SystemExit('STOP: no images found in the existing configuration.')
print('Configuration verified. Existing Docker credentials will not be edited.',flush=True)
with tempfile.TemporaryDirectory(prefix='dify-public-pull-') as tmp:
    pathlib.Path(tmp,'config.json').write_text(json.dumps({'auths':{}}))
    env=os.environ.copy()
    env.pop('DOCKER_CONTEXT',None)
    for i,image in enumerate(sorted(images),1):
        print(f'\nImage {i}/{len(images)}: {image}',flush=True)
        result=subprocess.run(['docker','--config',tmp,'--host','unix:///var/run/docker.sock','image','pull',image],env=env)
        if result.returncode:
            raise SystemExit('STOP: image download failed. Keep the final error visible. Re-running this script can reuse completed downloads.')
print('\nAll public images downloaded.',flush=True)
PY

docker compose up -d --pull never --no-build
printf '\n[5/5] Checking containers...\n'
docker compose ps --all
printf '\nStartup command completed. The web application may need more time to become ready.\n'
printf 'Open: http://localhost:8080/install\n'
printf 'Folder: %s/docker\n' "$TARGET"
printf 'Keep this terminal open and report the last messages. Do not share passwords or .env.\n'

初回導入補助 / 再開用補助 / 入手先と検証範囲

最初のPowerShell実行で確認できたこと

2026年11月15日 13:09〜13:13に本人が実行しました。

公式ZIPの取得(42,900,252バイト)→ 新しい練習フォルダーへの展開 → dockerフォルダーの確認 → .envのコピーが完了しました。

提示された状態一覧では、Ubuntuとdocker-desktopはWSL 2で稼働し、Difyの常駐サービス15個はUpでした。init_permissionsのExited (0)は初期化処理の正常終了です。

※ この結果は実行記録と本人が提示した出力による確認です。13:09の操作は録画停止中でした。その後13:20から再実行し、第7章に新しい実録動画を追加しました。既存Difyの再インストールも行っていません。

今回の実行記録を読む

導入できたら次に進む

Difyが開いたら、AIモデルの接続とFAQの作成を行います。前の教材と同じ青いメニューで、一つずつ確認できます。

基礎解説と活用編 全9章を開く

Word説明書 / 編集できる全体スライド / 練習用FAQ

公式の参考資料

Dify 1.19.0の公式配布

MicrosoftのWSL導入手順

DockerとWSLの連携