使用Docker+Apache2+WebSVN搭建SVN服务器

1. 背景

虽然现在的SVN已经用的越来越少,很多人都切换到了Git上。但是以前的一些历史项目还是需要SVN支持的。
之前的SVN服务器是直接搭建在一台Ubuntu服务器上的。当时一起搭建了WebSVN。也曾经研究过怎么搭建WebSVN,但是现在也不能够工作了,时间长久了也忘了怎么搭建了。所以想研究一下怎么使用Docker来完成一样的工作。

2. 构建过程

SVN搭建需要Apache配合。而WebSVN需要PHP的配合。这次构建镜像是以Ubuntu 14.04.5为基础的。然后在镜像基础上安装Apache2,Subversion,WebSVN等内容。

2.1 Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FROM ubuntu:14.04.5
RUN sed -i "s/archive/cn.archive/g" /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y apache2 subversion libapache2-svn websvn \
&& sed -i "s/'UTF-8', 'ISO/'GBK', 'UTF-8', 'ISO/g" /usr/share/websvn/include/command.php \
&& apt-get autoclean && apt-get clean && apt-get autoremove \
&& a2enmod auth_digest
ENV SERVER_NAME=localhost \
APACHE_RUN_USER=www-data \
APACHE_RUN_GROUP=www-data \
APACHE_PID_FILE=/var/run/apache2/apache2.pid \
APACHE_RUN_DIR=/var/run/apache2 \
APACHE_LOCK_DIR=/var/lock/apache2 \
APACHE_LOG_DIR=/var/log/apache2 \
APACHE_LOG_LEVEL=warn
COPY buildtime/apache2-foreground /usr/local/bin/
COPY buildtime/default.conf /etc/apache2/sites-available/000-default.conf
CMD ["apache2-foreground"]

构建命令:docker build . -t svnbase

2.2 解读

  • FROM 指定了基础镜像
  • RUN 指定了构建过程中需要执行的指令
  • ENV 设置了运行Apache所需要的一些环境变量
  • COPY 将一些预先写好的配置文件复制到镜像中;
  • CMD 指定了镜像的启动命令。

其中的RUN命令最复杂,完成了最重要的一部分工作。我们逐条解读。

2.2.1 修改Ubuntu源地址

国内的网络环境导致了直接使用基础镜像中的源下载包会非常慢,因此有必要切换到国内的镜像地址。这个是通过编辑/etc/apt/sources.list文件完成的。使用命令:

1
sed -i "s/archive/cn.archive/g" /etc/apt/sources.list

完成了对这个文件的修改。其做法就是将archive.ubuntu.com这个域名替换为:cn.archive.ubuntu.com

2.2.2 安装相关组件

这部分包含如下几条指令,这部分比较基础,不做过多解读。

1
2
apt-get update \
&& apt-get install -y apache2 subversion libapache2-svn websvn

2.2.3 修复WebSVN的中文编码问题

默认情况下,WebSVN只支持UTF-8编码的源文件。如果源码中有GBK编码的,会显示为乱码。通过网上查找,可以通过修改源码解决。参考资料:中文解决办法^Appendix1

1
sed -i "s/'UTF-8', 'ISO/'GBK', 'UTF-8', 'ISO/g" /usr/share/websvn/include/command.php

2.2.4 清理缓存,减小镜像体积

下面的命令清理apt-get生成的缓存,从而减小镜像的体积。

1
apt-get autoclean && apt-get clean && apt-get autoremove

2.3 其他文件

2.3.1 apache2-foreground

使用下面的脚本启动Apache服务,并显示log文件内容。注意:单纯的使用service start会导致镜像很快退出。

1
2
3
4
5
#!/bin/bash
set -e

# Apache gets grumpy about PID files pre-existing
rm -f /var/run/apache2/apache2.pid && service apache2 start && tail -f /var/log/apache2/access.log && service apache2 stop

2.3.2 default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<VirtualHost *:80>
ServerName 127.0.0.1

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

<Location /svnrep>
DAV svn
SVNParentPath /opt/scmroot/svn/svnrep
SVNListParentPath on
AuthType Digest
AuthName "SVN Access"
AuthUserFile /opt/scmroot/svndigest
Require valid-user
</Location>

Alias /websvn /usr/share/websvn

<Directory /usr/share/websvn>
DirectoryIndex index.php
Options FollowSymLinks
Order allow,deny
Allow from all
<IfModule mod_php5.c>
php_flag magic_quotes_gpc Off
php_flag track_vars On
</IfModule>
AuthType Digest
AuthName "SVN Access"
AuthUserFile /opt/scmroot/svndigest
Require valid-user
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

在这个配置文件中我们指定了几个特定的路径,这几个路径需要在运行镜像的时候挂载覆盖:

  • /opt/scmroot/svnrep SVN仓库存放的路径;
  • /opt/scmroot/svndigest 访问SVN仓库的用户配置文件。需要使用htdigest文件生成。
  • AuthName 指定了Digest认证中的realm。在创建svndigest的时候需要使用同样的值“SVN Access”。

3. 使用

3.1 docker-compose.yaml

我们使用Docker-compose来使用这个镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '2'
services:
apache:
image: svnbox
volumes:
# let container use same timezone as host
- /etc/localtime:/etc/localtime
- /opt/docker/svnbox/runtime/svnrep:/opt/scmroot/svnrep
- /opt/docker/svnbox/runtime/svndigest:/opt/scmroot/svndigest
- /opt/docker/svnbox/runtime/svn_deb_conf.inc:/etc/websvn/svn_deb_conf.inc
- /opt/docker/svnbox/runtime/index.html:/var/www/index.html
ports:
- "85:80"
restart: always
hostname: apache

3.2 解读

  • image 指定了镜像;
  • volumes 指定了要挂载的本地目录。其中:
    svnrep 是存放所有SVN仓库的目录;
    svndigest 是存放用户信息的文件。使用htdigest命令创建(考虑到安全性,选择了Digest认证,而不采用Basic认证)。
  • svn_deb_conf.inc WebSVN配置文件。主要可以用来添加SVN仓库,以供WebSVN访问。
  • index.html 是这个Apache需要的首页文件。

3.3 其他文件

3.3.1 svn_deb_conf.inc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
// 使用日志替代显示Age。缺省情况下WebSVN显示一个Age信息,包括修改人,修改时间(是距今多少天这种修改时间)
$config->setShowAgeInsteadOfDate(false);
// flatView 模式只显示当前目录的文件。而默认情况下是先是一个目录树,点击目录将在当前页面展开当前目录的内容。
//$config->useFlatView();
// 扩展Tab键为4个空格
$config->expandTabsBy(4);
// 在日志视图显示修改的内容(哪些文件被修改了)
$config->setLogsShowChanges(true);
// 添加要被WebSVN浏览的SVN仓库。不添加的就不显示。
$config->addRepository("AuthServer", "file:///opt/scmroot/svn/svnrep/AuthServer");
$config->addRepository("CodeConvert", "file:///opt/scmroot/svn/svnrep/CodeConvert");
$config->addRepository("eCodeHSM", "file:///opt/scmroot/svn/svnrep/eCodeHSM");
$config->addRepository("eCodeHSM_ezTokenPIN", "file:///opt/scmroot/svn/svnrep/eCodeHSM_ezTokenPIN");
$config->addRepository("HSMCardManager", "file:///opt/scmroot/svn/svnrep/HSMCardManager");
$config->addRepository("Software", "file:///opt/scmroot/svn/svnrep/Software");
$config->addRepository("vcproj", "file:///opt/scmroot/svn/svnrep/vcproj");
$config->setEnscriptPath("/usr/bin");
$config->setSedPath("/bin");
$config->useEnscript();
?>

这个配置文件中对WebSVN进行了进一步的配置。其中最主要的是使用addRepository添加本地SVN仓库(如果不添加,WebSVN是无法浏览SVN仓库的)。另外一些配置可以看源码中的注释。

3.3.2 index.html

这个是首页,可以随便编辑内容。

1
2
3
4
5
6
<html>
<head>
</head>
<body>
</body>
</html>

3.3.3 svndigest

使用htdigest命令创建。例如:

1
2
3
4
$ htdigest -c svndigest "SVN Access" test
Adding user test in realm SVN Access
New password:
Re-type new password:

4. 怎么访问

启动之后,使用:

附录. 参考资料

热评文章