You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fabric在DigitalOcean部署Mezzanine站点遇rsync错误求助

解决Mezzanine部署中rsync的「源和目标不能都是远程」错误

我正在尝试部署Mezzanine站点,遵循官方教程的CASE1(部署至新服务器)操作:

  • 步骤1-3执行正常;
  • 执行步骤4「Run fab all」时,流程完成了virtualenv的安装并创建了项目目录,随后出现以下错误:

[1xx.xx.xxx.xx] out: New python executable in /home/~/.virtualenvs/blog_iq/bin/python
[1xx.xx.xxx.xx] out: Installing setuptools, pip, wheel...done.
[1xx.xx.xxx.xx]] out:
[1xx.xx.xxx.xx]] rsync_project: rsync --exclude ".pyc" --exclude ".pyo" --exclude "*.db" --exclude ".DS_Store" --exclude ".coverage" --exclude "local_settings.py" --exclude "/static" --exclude "/.git" --exclude "/.hg" -pthrvz --rsh='ssh -p 22 ' C:\Users~\Root\2blog\blog_iq\ user@1xx.xxx.xx:/home/user/mezzanine/blog_iq

[localhost] local: rsync --exclude ".pyc" --exclude ".pyo" --exclude "*.db" --exclude ".DS_Store" --exclude ".coverage" --exclude "local_settings.py" --exclude "/static" --exclude ".git" --exclude "/.hg" -pthrvz --rsh='ssh -p 22 ' C:\Users~\Root\2blog\blog_iq\ user@1xx.xxx.xx:/home/user/mezzanine/blog_iq

The source and destination cannot both be remote. rsync error: syntax or usage error (code 1) at main.c(1292) [Receiver=3.1.2]

Fatal error: local() encountered an error (return code 1) while executing 'rsync --exclude ".pyc" --exclude ".pyo" --exclude "*.db" --exclude ".DS_Store" --exclude ".coverage" --exclude "local_settings.py" --exclude "/static" --exclude ".git" --exclude ".hg" -pthrvz --rsh='ssh -p 22 ' C:\Users~\Root\2blog\blog_iq\ user@1xx.xxx.xx:/home/user/mezzanine/blog_iq

Aborting. Disconnecting from 1xx.xxx.xx... done.

我找到了fabfile.py中生成该错误的相关代码片段:

################
# Config setup #
################
if not hasattr(env, "proj_app"):
    env.proj_app = real_project_name("blog_iq")
conf = {}
if sys.argv[0].split(os.sep)[-1] in ("fab", "fab-script.py"):
    # Ensure we import settings from the current dir
    try:
        conf = import_module("%s.settings" % env.proj_app).FABRIC
        try:
            conf["HOSTS"][0]
        except (KeyError, ValueError):
            raise ImportError
    except (ImportError, AttributeError):
        print("Aborting, no hosts defined.")
        exit()
env.db_pass = conf.get("DB_PASS", None)
env.admin_pass = conf.get("ADMIN_PASS", None)
env.user = conf.get("SSH_USER", getuser())
env.password = conf.get("SSH_PASS", None)
env.key_filename = conf.get("SSH_KEY_PATH", None)
env.hosts = conf.get("HOSTS", [""])
env.proj_name = conf.get("PROJECT_NAME", env.proj_app)
env.venv_home = conf.get("VIRTUALENV_HOME", "/home/%s/.virtualenvs" % env.user)
env.venv_path = join(env.venv_home, env.proj_name)
env.proj_path = "/home/%s/mezzanine/%s" % (env.user, env.proj_name)
env.manage = "%s/bin/python %s/manage.py" % (env.venv_path, env.proj_path)
env.domains = conf.get("DOMAINS", [conf.get("LIVE_HOSTNAME", env.hosts[0])])
env.domains_nginx = " ".join(env.domains)
env.domains_regex = "|".join(env.domains)
env.domains_python = ", ".join(["'%s'" % s for s in env.domains])
env.ssl_disabled = "#" if len(env.domains) > 1 else ""
env.vcs_tools = ["git", "hg"]
env.deploy_tool = conf.get("DEPLOY_TOOL", "rsync")
env.reqs_path = conf.get("REQUIREMENTS_PATH", None)
env.locale = conf.get("LOCALE", "en_US.UTF-8")
env.num_workers = conf.get("NUM_WORKERS", "multiprocessing.cpu_count() * 2 + 1")
env.secret_key = conf.get("SECRET_KEY", "")
env.nevercache_key = conf.get("NEVERCACHE_KEY", "")
if not env.secret_key:
    print("Aborting, no SECRET_KEY setting defined.")
    exit()
# Remote git repos need to be "bare" and reside separated from the project
if env.deploy_tool == "git":
    env.repo_path = "/home/%s/git/%s.git" % (env.user, env.proj_name)
else:
    env.repo_path = env.proj_path

以及rsync上传的代码:

def rsync_upload():
    """ Uploads the project with rsync excluding some files and folders. """
    excludes = ["*.pyc", "*.pyo", "*.db", ".DS_Store", ".coverage", "local_settings.py", "/static", "/.git", "/.hg"]
    local_dir = os.getcwd() + os.sep
    return rsync_project(remote_dir=env.proj_path, local_dir=local_dir, exclude=excludes)

问题原因分析

这个错误的核心是rsync被错误地当作本地命令执行了,而不是通过Fabric的rsync_project函数正确处理远程目标。从错误输出的[localhost] local:前缀能看出,Fabric在本地机器上运行了rsync命令,但命令里同时指定了Windows格式的本地路径和远程服务器路径,这违反了rsync的规则——rsync不允许在本地执行时同时使用远程路径作为目标(它会误把远程路径识别成另一个远程源)。

本质问题出在Windows环境的路径格式(盘符、反斜杠)和Fabric的rsync处理逻辑不兼容,导致rsync_project没有正确识别远程目标,退化成了本地执行命令。

解决方案

方案1:修改rsync_upload函数,显式指定远程主机

修改rsync_upload函数,给rsync_project明确指定远程主机,避免Fabric在本地执行rsync:

def rsync_upload():
    """ Uploads the project with rsync excluding some files and folders. """
    excludes = ["*.pyc", "*.pyo", "*.db", ".DS_Store", ".coverage", "local_settings.py", "/static", "/.git", "/.hg"]
    local_dir = os.getcwd() + os.sep
    # 显式指定远程主机,确保rsync_project知道目标是远程服务器
    return rsync_project(
        remote_dir=env.proj_path,
        local_dir=local_dir,
        exclude=excludes,
        host=env.hosts[0]
    )

方案2:调整本地路径格式,适配Windows环境

Windows的反斜杠路径会被rsync识别为转义字符,导致路径解析错误,把反斜杠替换成正斜杠即可:

def rsync_upload():
    """ Uploads the project with rsync excluding some files and folders. """
    excludes = ["*.pyc", "*.pyo", "*.db", ".DS_Store", ".coverage", "local_settings.py", "/static", "/.git", "/.hg"]
    # 将Windows路径的反斜杠替换为正斜杠,避免rsync解析错误
    local_dir = os.getcwd().replace("\\", "/") + "/"
    return rsync_project(remote_dir=env.proj_path, local_dir=local_dir, exclude=excludes)

方案3:改用git作为部署工具(推荐)

如果rsync的Windows兼容性问题难以彻底解决,切换到git部署会更稳定。修改项目settings中的FABRIC配置,把DEPLOY_TOOL改成git:

# 在你的项目settings.py中找到FABRIC配置段
FABRIC = {
    "DEPLOY_TOOL": "git",  # 替换原有的"rsync"
    # 其他配置保持不变...
}

确保本地项目已经初始化git仓库并commit所有更改,Fabric的fab all会自动在远程服务器创建对应的bare仓库并完成部署。

验证步骤

修改完成后,保存文件并重新执行:

fab all

如果是修改了rsync_upload函数,确认fabfile.py保存后再执行;如果切换到git部署,先确保本地git仓库状态正常。

内容的提问来源于stack exchange,提问作者J. Khoury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:08:41