当你在执行 docker-compose up -d 后发现 Dify 服务根本没启动,或者容器反复重启、根本无响应,这时候千万别傻盯着 Web 界面——那个界面大概率还没起来。正确的第一反应是:从日志源头下手。
具体操作就两步:先跑 docker-compose ps 确认容器状态,再用 docker-compose logs --tail=50 dify-api 揪出第一条错误日志。如果日志里冒出“数据库连接拒绝”“环境变量缺失”或“迁移异常”,下一步就得挨个核对 .env 配置、PostgreSQL 数据目录权限、Redis 连通性以及 DNS 解析设置。

确认容器是否真实运行
运行 docker-compose ps,重点检查 dify-api、dify-web、postgresql、redis 这四个核心服务的状态。但凡看到某个容器显示 Exit 1 或 Restarting,都说明启动流程在初始化阶段就已经卡壳了。
特别要盯紧 postgres 和 redis:它们俩是 Dify 的前置依赖,一旦挂掉,dify-api 会因为连接超时直接退出。可别以为只有数据库容器里才有错误日志——真正报错的地方往往藏在 api 容器自己的日志里。
快速获取首个失败容器的原始日志
执行 docker-compose logs --tail=50 dify-api,这是最高效的起点。90% 的启动失败根源——包括数据库连接拒绝、环境变量缺失、迁移脚本报错——都会在输出的首条错误行里露馅。
如果返回空或者提示 No such service,说明 docker-compose.yml 里的服务名对不上,或者你当前目录压根不在部署根路径下。这时候必须 cd 到 docker-compose.yml 所在目录再执行。
要是看到类似 psycopg2.OperationalError: FATAL: password authentication failed 的字眼,立马去比对 .env 文件里的 POSTGRES_PASSWORD 是否和 docker-compose.yml 中 postgres 服务定义的完全一致——大小写和特殊字符一个都不能差。
定位 PostgreSQL 初始化失败
方法一:直查数据库容器日志
执行 docker-compose logs postgres。重点搜 initdb: error、permission denied 或 data directory has wrong ownership——这些信号指向挂载卷权限异常。
方法二:检查数据目录权限
如果用的是 ./volumes/postgresql:/var/lib/postgresql/data 这类挂载方式,宿主机上的 ./volumes/postgresql 目录必须允许 UID 999(PostgreSQL 最新镜像默认用户)写入。执行 sudo chown -R 999:999 ./volumes/postgresql 可以强制修复。
方法三:跳过初始化重试
临时把 docker-compose.yml 中 postgres 服务的 command: ["postgres", "-c", "log_statement=all"] 这一行注释掉,避免自定义命令干扰初始化流程。
排查 Redis 连接超时
第一步:确认 redis 容器状态正常且端口暴露正确
docker-compose port redis 6379 应该返回类似 0.0.0.0:6379 的结果。如果报错或返回空,去检查 docker-compose.yml 中 redis 服务是否遗漏了 ports 块,或者被防火墙拦住了。
第二步:手动测试连通性
进入 api 容器内部:docker-compose exec dify-api sh,然后执行 redis-cli -h redis -p 6379 ping。返回 PONG 说明网络通;要是卡住或者报 Connection refused,意味着 redis 服务还没就绪,或者配置了密码但 .env 里没设 REDIS_PASSWORD。
第三步:验证环境变量注入
还在 dify-api 容器内,运行 echo $REDIS_URL。正确的值应该是 redis://:yourpass@redis:6379/0 这种格式;如果为空或者不含密码字段,说明 .env 没被正确加载,需要检查 docker-compose.yml 中该服务是否声明了 env_file: .env。
解析 dify-api 启动日志中的关键错误模式
① 出现 django.core.exceptions.ImproperlyConfigured: Set the DATABASE_URL environment variable:
说明 .env 文件根本没被读取,或者里面的 DATABASE_URL 字段被注释、拼写成 DB_URL 这类错误写法,又或者混进了不可见 Unicode 字符。用 cat -A .env 看一眼就能发现。
② 出现 Migration files not found 或 django.db.migrations.exceptions.InconsistentMigrationHistory:
这是数据库迁移状态乱套了。先备份 ./volumes/postgresql 目录,再执行 docker-compose run --rm dify-api python manage.py migrate --fake-initial 强制同步初始状态。
③ 出现 Failed to load API key from environment 且紧跟一段 ValueError: Cannot find token:
说明 .env 中的 SECRET_KEY 是空的或者只有空格。Dify 看到这个直接罢工。必须设置至少 50 位随机字符串,比如用 openssl rand -base64 64 | tr '+/' '-_' | tr -d '\n' 生成一个。
④ 日志末尾反复打印 Waiting for postgres... 超过 60 秒后退出:
这不是网络问题,而是 dify-api 容器里的 DNS 解析挂了。检查宿主机 /etc/resolv.conf 是不是包含 127.0.0.1——Docker 不支持本地 DNS 转发。替换成 8.8.8.8,然后重启 Docker 服务就解决了。
