1. 背景
虽然现在的SVN已经用的越来越少,很多人都切换到了Git上。但是以前的一些历史项目还是需要SVN支持的。 之前的SVN服务器是直接搭建在一台Ubuntu服务器上的。当时一起搭建了WebSVN。也曾经研究过怎么搭建WebSVN,但是现在也不能够工作了,时间长久了也忘了怎么搭建了。所以想研究一下怎么使用Docker来完成一样的工作。
2. 构建过程
SVN搭建需要Apache配合。而WebSVN需要PHP的配合。这次构建镜像是以Ubuntu 14.04.5为基础的。然后在镜像基础上安装Apache2
,Subversion
,WebSVN
等内容。
2.1 Dockerfile
1FROM ubuntu:14.04.5
2RUN sed -i "s/archive/cn.archive/g" /etc/apt/sources.list \
3 && apt-get update \
4 && apt-get install -y apache2 subversion libapache2-svn websvn \
5 && sed -i "s/'UTF-8', 'ISO/'GBK', 'UTF-8', 'ISO/g" /usr/share/websvn/include/command.php \
6 && apt-get autoclean && apt-get clean && apt-get autoremove \
7 && a2enmod auth_digest
8ENV SERVER_NAME=localhost \
9 APACHE_RUN_USER=www-data \
10 APACHE_RUN_GROUP=www-data \
11 APACHE_PID_FILE=/var/run/apache2/apache2.pid \
12 APACHE_RUN_DIR=/var/run/apache2 \
13 APACHE_LOCK_DIR=/var/lock/apache2 \
14 APACHE_LOG_DIR=/var/log/apache2 \
15 APACHE_LOG_LEVEL=warn
16COPY buildtime/apache2-foreground /usr/local/bin/
17COPY buildtime/default.conf /etc/apache2/sites-available/000-default.conf
18CMD ["apache2-foreground"]
构建命令:docker build . -t svnbase
2.2 解读
- FROM 指定了基础镜像
- RUN 指定了构建过程中需要执行的指令
- ENV 设置了运行Apache所需要的一些环境变量
- COPY 将一些预先写好的配置文件复制到镜像中;
- CMD 指定了镜像的启动命令。
其中的RUN命令最复杂,完成了最重要的一部分工作。我们逐条解读。
2.2.1 修改Ubuntu源地址
国内的网络环境导致了直接使用基础镜像中的源下载包会非常慢,因此有必要切换到国内的镜像地址。这个是通过编辑/etc/apt/sources.list
文件完成的。使用命令:
1sed -i "s/archive/cn.archive/g" /etc/apt/sources.list
完成了对这个文件的修改。其做法就是将archive.ubuntu.com
这个域名替换为:cn.archive.ubuntu.com
。
2.2.2 安装相关组件
这部分包含如下几条指令,这部分比较基础,不做过多解读。
1apt-get update \
2 && apt-get install -y apache2 subversion libapache2-svn websvn
2.2.3 修复WebSVN的中文编码问题
默认情况下,WebSVN只支持UTF-8编码的源文件。如果源码中有GBK编码的,会显示为乱码。通过网上查找,可以通过修改源码解决。参考资料:中文解决办法1
1sed -i "s/'UTF-8', 'ISO/'GBK', 'UTF-8', 'ISO/g" /usr/share/websvn/include/command.php
2.2.4 清理缓存,减小镜像体积
下面的命令清理apt-get生成的缓存,从而减小镜像的体积。
1apt-get autoclean && apt-get clean && apt-get autoremove
2.3 其他文件
2.3.1 apache2-foreground
使用下面的脚本启动Apache服务,并显示log文件内容。注意:单纯的使用service start会导致镜像很快退出。
1#!/bin/bash
2set -e
3
4# Apache gets grumpy about PID files pre-existing
5rm -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<VirtualHost *:80>
2 ServerName 127.0.0.1
3
4 ServerAdmin webmaster@localhost
5 DocumentRoot /var/www/html
6
7 <Location /svnrep>
8 DAV svn
9 SVNParentPath /opt/scmroot/svn/svnrep
10 SVNListParentPath on
11 AuthType Digest
12 AuthName "SVN Access"
13 AuthUserFile /opt/scmroot/svndigest
14 Require valid-user
15 </Location>
16
17 Alias /websvn /usr/share/websvn
18
19 <Directory /usr/share/websvn>
20 DirectoryIndex index.php
21 Options FollowSymLinks
22 Order allow,deny
23 Allow from all
24 <IfModule mod_php5.c>
25 php_flag magic_quotes_gpc Off
26 php_flag track_vars On
27 </IfModule>
28 AuthType Digest
29 AuthName "SVN Access"
30 AuthUserFile /opt/scmroot/svndigest
31 Require valid-user
32 </Directory>
33
34 ErrorLog ${APACHE_LOG_DIR}/error.log
35 CustomLog ${APACHE_LOG_DIR}/access.log combined
36</VirtualHost>
在这个配置文件中我们指定了几个特定的路径,这几个路径需要在运行镜像的时候挂载覆盖:
- /opt/scmroot/svnrep SVN仓库存放的路径;
- /opt/scmroot/svndigest 访问SVN仓库的用户配置文件。需要使用htdigest文件生成。
- AuthName 指定了Digest认证中的realm。在创建svndigest的时候需要使用同样的值“SVN Access”。
3. 使用
3.1 docker-compose.yaml
我们使用Docker-compose来使用这个镜像。
1version: '2'
2services:
3 apache:
4 image: svnbox
5 volumes:
6 # let container use same timezone as host
7 - /etc/localtime:/etc/localtime
8 - /opt/docker/svnbox/runtime/svnrep:/opt/scmroot/svnrep
9 - /opt/docker/svnbox/runtime/svndigest:/opt/scmroot/svndigest
10 - /opt/docker/svnbox/runtime/svn_deb_conf.inc:/etc/websvn/svn_deb_conf.inc
11 - /opt/docker/svnbox/runtime/index.html:/var/www/index.html
12 ports:
13 - "85:80"
14 restart: always
15 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<?php
2// 使用日志替代显示Age。缺省情况下WebSVN显示一个Age信息,包括修改人,修改时间(是距今多少天这种修改时间)
3$config->setShowAgeInsteadOfDate(false);
4// flatView 模式只显示当前目录的文件。而默认情况下是先是一个目录树,点击目录将在当前页面展开当前目录的内容。
5//$config->useFlatView();
6// 扩展Tab键为4个空格
7$config->expandTabsBy(4);
8// 在日志视图显示修改的内容(哪些文件被修改了)
9$config->setLogsShowChanges(true);
10// 添加要被WebSVN浏览的SVN仓库。不添加的就不显示。
11$config->addRepository("AuthServer", "file:///opt/scmroot/svn/svnrep/AuthServer");
12$config->addRepository("CodeConvert", "file:///opt/scmroot/svn/svnrep/CodeConvert");
13$config->addRepository("eCodeHSM", "file:///opt/scmroot/svn/svnrep/eCodeHSM");
14$config->addRepository("eCodeHSM_ezTokenPIN", "file:///opt/scmroot/svn/svnrep/eCodeHSM_ezTokenPIN");
15$config->addRepository("HSMCardManager", "file:///opt/scmroot/svn/svnrep/HSMCardManager");
16$config->addRepository("Software", "file:///opt/scmroot/svn/svnrep/Software");
17$config->addRepository("vcproj", "file:///opt/scmroot/svn/svnrep/vcproj");
18$config->setEnscriptPath("/usr/bin");
19$config->setSedPath("/bin");
20$config->useEnscript();
21?>
这个配置文件中对WebSVN进行了进一步的配置。其中最主要的是使用addRepository
添加本地SVN仓库(如果不添加,WebSVN是无法浏览SVN仓库的)。另外一些配置可以看源码中的注释。
3.3.2 index.html
这个是首页,可以随便编辑内容。
1<html>
2<head>
3</head>
4<body>
5</body>
6</html>
3.3.3 svndigest
使用htdigest命令创建。例如:
1$ htdigest -c svndigest "SVN Access" test
2Adding user test in realm SVN Access
3New password:
4Re-type new password:
4. 怎么访问
启动之后,使用:
- http://[server-ip]:85/svnre/… 访问SVN;
- http://[server-ip]:85/websvn 访问WebSVN。