首先是现象,按照官方文档部署成功并修改EXPOSE_NGINX_PORT端口后,访问对应的url可能会出现卡在登陆界面的现象,F12查看网络请求发现有个请求报502错误,一看就是nginx有问题。
官方QA里有这个问题的解决方法20.502 Bad Gateway
这是因为Nginx将服务转发到了错误的位置导致的,首先确保容器正在运行,然后以Root权限运行以下命令:
docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }}: {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
在输出内容中找到这两行:
/docker-web-1: 172.19.0.5
/docker-api-1: 172.19.0.7
记住后面的IP地址。然后打开你存放dify源代码的地方,打开dify/docker/nginx/conf.d
,将http://api:5001
替换为http://172.19.0.7:5001
,将http://web:3000
替换为http://172.19.0.5:3000
,随后重启Nginx容器或者重载配置。 这些IP地址是_示例性_ 的,你必须执行命令获取你自己的IP地址,不要直接填入。 你可能在重新启动相关容器时需要再次根据IP进行配置。
不过每次重启docker都要手动修改有些麻烦,我在这篇文章里看到了更便利的方法,用python脚本自动获取ip并重启:Docker部署dify访问时502 Bad Gateway的问题
我对这个脚本做了一些修改,用default.conf.template来生成文件。首先安装依赖:
pip install docker
创建一个python文件dify-nginx.py放在docker目录下
具体代码:
# coding=utf-8
# pip install docker
import os
import docker
client = docker.from_env()
# 获取当前 Python 脚本所在的文件夹的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 读取文件
def file_get_contents(file_path):
with open(file_path, "r", encoding="utf-8") as file:
return file.read()
# 写入文件
def file_put_contents(file_path, content):
with open(file_path, "w", encoding="utf-8") as file:
file.write(content)
# 获取容器 IP
def get_container_ip(container_name):
container = client.containers.get(container_name)
return container.attrs['NetworkSettings']['Networks']['docker_default']['IPAddress']
# 重启容器
def restart_container(container_name):
container = client.containers.get(container_name)
container.restart()
def main():
# 获取 API 和 Web 容器的 IP 地址
api_container_ip = get_container_ip('docker-api-1')
web_container_ip = get_container_ip('docker-web-1')
print(f'api_container_ip: {api_container_ip}')
print(f'web_container_ip: {web_container_ip}')
# 拼接模板文件路径和目标文件路径
template_path = os.path.join(current_dir, 'nginx/conf.d/default.conf.template')
target_path = os.path.join(current_dir, 'nginx/conf.d/default.conf')
# 读取模板文件内容并替换 IP 地址
tpl_contents = file_get_contents(template_path)
tpl_contents = tpl_contents.replace('http://api', f'http://{api_container_ip}')
tpl_contents = tpl_contents.replace('http://web', f'http://{web_container_ip}')
# 将修改后的内容写入目标配置文件
file_put_contents(target_path, tpl_contents)
# 重启 Nginx 容器
restart_container('docker-nginx-1')
print("Nginx container restarted with updated configuration.")
if __name__ == '__main__':
main()
如果你其他步骤没问题,那就docker compose正常启动然后运行这个程序就行了:
docker compose up -d
python3 dify-nginx.py
这个就是正常启动的页面
补充1:
注意,如果遇到default.conf无法被修改的情况,试着把docker-entrypoint.sh里面的:
envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
改成:
if [ ! -f /etc/nginx/conf.d/default.conf ]; then
envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
fi
改完以后应该就不会每次启动都覆盖了
补充2:
在wsl的ubuntu上部署时又碰上了新的情况:
db容器报错:
data directory "/var/lib/postgresql/data" has invalid permissions
Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).
在知乎上查到了解决方法(原文链接:Windows上用Docker Desktop部署Progres数据库提示invalid permissions问题解决 - 知乎):
就是在volumes映射后面加入“&& sudo chmod 0700 /var/lib/postgresql/data”。具体在Dify就是在docker目录下的“docker-compose.yaml”文件里面的:
volumes:
- ./volumes/db/data:/var/lib/postgresql/data
修改为:
volumes:
- ./volumes/db/data:/var/lib/postgresql/data && sudo chmod 0700 /var/lib/postgresql/data
或者
volumes:
- ./volumes/db/data:/var/lib/postgresql/data && sudo chmod 0750 /var/lib/postgresql/data