使用nginx代理多个Subversion Repos

时间:2012-05-04 16:36:16

标签: svn configuration nginx reverse-proxy

我目前有一个老化的subversion 1.4.2服务器,我想升级多个repos。我想做一些事情:

  • 转到更新版本(1.7+)的subversion
  • 将存储库拆分为不同的计算机
  • 更改主机名(我会在一秒钟内解释)
  • 更改为使用FQDN而不是URL上的路径(< - 这是我遇到的问题)

但是,我希望停机时间非常少,而且我希望能够逐步(并在很大程度上)与用户无缝连接。

因此,服务器目前由:svn.svr.mycompany.co.uk解决 我希望用户切换到使用:svn.mycompanyglobal.net

新名称将由DNS路由到适当的服务器,具体取决于用户所在的大陆。这很有效。

这指向使用svn DAV访问标准类型的Apache2安装:

<VirtualHost 10.11.22.33>
  Servername svn.svr.mycompany.co.uk

  <Location /main>
    DAV svn
    SVNPath /home/svnrepo/main
    [... Some regular auth stuff ...]
    SVNIndexXSLT /svnindex.xsl
  </Location>

  <Location /data>
    DAV svn
    SVNPath /home/svnrepo/data
    [... Some regular auth stuff ...]
    SVNIndexXSLT /svnindex.xsl
  </Location>
</VirtualHost>

通常有与文档根和模块相关的东西,但这是它的关键。

所以,目前我可以查看代码:http://svn.svr.mycompany.co.uk/data/Core/Blah

现在我已经在其前面加了一个 nginx 反向代理。它具有全局主机名,我可以通过以下网址浏览代码:http://data.svn.mycompanyglobal.net/Core/Blah注意我已移动“数据”从路径到主机名称)。我通过添加以下配置在 nginx 中实现了这一点:

server {
  listen 80;

  server_name data.svn.mycompanyglobal.net;

  proxy_set_header  Host svn.svr.mycompany.co.uk;

  location = /svnindex.xsl {
    proxy_pass http://svn.svr.mycompany.co.uk/svnindex.xsl;
  }

  location /data/ {
    proxy_pass http://svn.svr.mycompany.co.uk/data/;
  }

  location / {
    proxy_pass http://svn.svr.mycompany.co.uk/;
    rewrite ^(.*)$ /data$1 break;
  }
}

这一切都有效。我可以在Web浏览器中浏览代码,也可以通过TortoiseSVN中的repo浏览器或命令行“svn ls”浏览代码。所有这一切都通过代理。

然而,当我尝试检查代码时,我收到了错误

Unusable URI: it does not refer to this repository

我得出结论,这是客户做出这个决定(即提出错误)。看一下SVNKit源代码,很明显svn客户端将它请求的路径与服务器返回的路径进行比较 - 我不知道为什么,但这就是它的样子(见DavUtils)。

我可以通过将我结帐的URL更改为此来解决此问题(

http://data.svn.mycompanyglobal.net/data

[即我将存储库的名称添加到最后]

这可能有效,因为我在上面添加了“/ data /”路由。

有没有人设法做过这样的事情?我可以在Subversion服务器或代理上做些什么来改变subversion客户端路径的表示形式吗?

我知道,一旦我将它打开到单独的服务器上,它将不再是一个问题,因为每个服务器只会列出一个“位置”(根),但我现在没有这个的奢侈。

另外,你应该记住,这个盒子已经存在了驴子的年代,并且有很多硬编码的引用。这就是为什么我需要代理它以便我可以逐步将所有引用移动到新的URL格式。

我很欣赏这是一个很长的问题,但我希望我已经明确表达了我想要实现的目标。随意告诉我,我只是疯了 - 只是感觉我离工作太近了。)。

2 个答案:

答案 0 :(得分:0)

我可能正确理解你的背景。我确定你知道这一点,但SVN也运行在不同的端口上,所以你可能会遇到问题:)

关于nginx中的location参数,您必须记住它只定义您在配置中设置的服务器名称的位置。因此,对于您定义为data.svn.company.com的唯一服务器名称,您要定义该子域的每个位置。我认为你实际上是在尝试定义多个子域。

因此,如果是这种情况,您必须设置多个服务器名称,如main.svn.company.comdata.svn.company.com,而不是定义位置URI。

希望有所帮助:)

答案 1 :(得分:0)

所以我最终通过编辑端点服务器(即我正在离开的那个)在两个不同的位置拥有相同的存储库来实现这一点:

<VirtualHost 10.11.22.33>
  Servername svn.svr.mycompany.co.uk

  <Location /data>
    DAV svn
    SVNPath /home/svnrepo/data
    [... Some regular auth stuff ...]
  </Location>
</VirtualHost>

<VirtualHost 10.11.22.33>
  Servername data.svn.svr.mycompany.co.uk

  <Location />
    DAV svn
    SVNPath /home/svnrepo/data
    [... Some regular auth stuff ...]
  </Location>
</VirtualHost>

事实证明,subversion处理这个很好。我的代理变得微不足道。显然,我不需要这里的代理,但是当我开始打破终端服务器时,我会这样做。

现在我可以查看,浏览并登记:

http://data.svn.mycompanyglobal.net/
http://data.svn.svr.mycompany.co.uk/
http://svn.svr.mycompany.co.uk/data

第一个将路由到代理服务器并代理到第二个。第二个和第三个(如果直接连接)将直接路由到旧服务器。

作为参考,我的nginx代理条目现在看起来像这样:

server {
  listen 80;
  listen 443 ssl;

  server_name data.svn.mycompanyglobal.net;

  proxy_set_header     Host data.svn.svr.mycompany.co.uk;

  location / {
    proxy_pass http://data.svn.svr.mycompany.co.uk/;
  }
}

每个回购商都会有其中一个(上面例子中的“数据”和“主要”)。