DokuWiki容器化实践

DokuWiki 使用 Docker 做容器化,主要解决以下问题。

  • 插件和模板的安装
  • 插件和模板的默认配置和配置文件的传递
  • 持久化存储

插件模板安装

使用容器之后就不能在使用插件管理器来安装插件了,否则容器重启后插件将丢失。需要将插件代码打包到镜像里。基本思路是使用多段构建,在 builder 过程中下载并解压插件和模板代码,然后复制到运行镜像中。以下是示例 Dockerfile,完整 Dockerfile 请看参考资料。

FROM alpine:3.8 as builder
RUN	sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache wget unzip
WORKDIR /wiki
RUN wget https://github.com/splitbrain/dokuwiki/archive/release_stable_2018-04-22b.tar.gz -O stable.tar.gz
RUN tar zxvf stable.tar.gz
RUN rm -f dokuwiki-release_stable_2018-04-22b/install.php
# data目录需要挂载volume
RUN mv dokuwiki-release_stable_2018-04-22b/data /tmp/

RUN mkdir plugins tpl

# markdowku插件
RUN wget https://komkon2.de/markdowku/markdowku.tgz
RUN tar zxvf markdowku.tgz
RUN mv markdowku plugins

# php7镜像
FROM registry.cn-beijing.aliyuncs.com/kubebase/php7-nginx:1.3

RUN apk add --no-cache git openssh-client
RUN apk add --no-cache php7-xml php7-zip
COPY conf/default.conf /etc/nginx/conf.d/default.conf
COPY conf/dokuwiki_rewrite.conf /etc/nginx/dokuwiki_rewrite.conf

COPY --from=builder /wiki/dokuwiki-release_stable_2018-04-22b/ /home/wwwroot/default/
COPY --from=builder /wiki/tpl/ /home/wwwroot/default/lib/tpl/
COPY --from=builder /wiki/plugins/ /home/wwwroot/default/lib/plugins/

COPY app.sh /app.sh
WORKDIR /home/wwwroot/default

Dockerfile 中使用的 PHP 镜像参考 制作PHP7基础镜像

插件模板配置

基础镜像支持在 app.sh 中自定义启动脚本。可以在启动脚本中定义如何将插件及模板的配置应用到容器中的 DokuWiki 实例。基本思路是以 ConfigMap 名称为配置文件名称(不带 php 后缀),举例来说,设置 ConfigMap local, 则 cp $APP_CONFIG_PATH/local /home/wwwroot/default/conf/local.php,这样就可以在运行时修改 Dokuwiki 的配置。实现代码如下。

function stepPreConf() {
	for item in `ls $APP_CONFIG_PATH`; do 
		echo $item | grep -E '[A-Z]' && continue          # 跳过普通环境变量
		cp $APP_CONFIG_PATH/$item $WIKIROOT/conf/${item}".php"
		chown nobody.nobody $WIKIROOT/conf/${item}".php"   # 允许通过配置工具修改配置,但是重部之后会失效
	done

	# default acl and account
	AUTH="$WIKIROOT/conf/users.auth.php"
	ACL="$WIKIROOT/conf/acl.auth.php"
	if [ ! -f $AUTH ]; then
		echo 'admin:$1$lgH1ByTw$3agbZNBd7/JrVrUflGVNp/:annProg:admin@admin.com:admin,user' > $AUTH
	fi

	if [ ! -f $ACL ]; then
		echo -e "* @ALL 1\n* @user 8" > $ACL
	fi

	# default template
	echo "\$conf['template'] = 'bootstrap3';" >> $MAINCONF
}

有一些必要的配置,通过 app.sh 来设置默认值,比如,为 Bootstrap3 模板设置默认值。

function setConf() {
	# $1 type eg. plugin or tpl
	# $2 plugin or tpl name
	# $3 config item
	# $4 config value
	grep "\['$1'\]\['$2'\]\['$3'\]" $MAINCONF &>/dev/null|| echo "\$conf['$1']['$2']['$3'] = '$4';" >> $MAINCONF
}

function stepTplBootstrap3() {
	setConf tpl bootstrap3 showThemeSwitcher "1"
	setConf tpl bootstrap3 showPageIcons "1"
	setConf tpl bootstrap3 showPurgePageCache "logged"
	setConf tpl bootstrap3 pageIcons "feed,send-mail,permalink,print,help"
}

持久化存储

推荐使用 git 仓库来存储,需要插件 gitbacked。在 app.sh 中设置 gitbackend 插件。

# app.sh是以root用户运行的,php程序以nobody用户运行,因此git相关命令也应用nobody运行,否则会有权限问题
# 需要设置HOME 参见 https://stackoverflow.com/a/27151021 解决  unable to access '/root/.config/git/attributes' 报错
function gitCmd() {
	su - nobody -s /bin/sh -c "HOME=/home/nobody;cd $DATADIR;git $1"
}

# 设置SSH KEY
function sshKey() {
	SSHDIR=/home/nobody/.ssh/
	echo "SSHDIR: $SSHDIR"
	[ ! -d $SSHDIR ] && mkdir -p $SSHDIR
	[ -f "$APP_CONFIG_PATH/ID_RSA" ] && cp $APP_CONFIG_PATH/ID_RSA $SSHDIR/id_rsa
	[ -f "$APP_CONFIG_PATH/ID_RSA_PUB" ] && cp $APP_CONFIG_PATH/ID_RSA_PUB $SSHDIR/id_rsa.pub
	echo "I am `whoami`"
	echo "StrictHostKeyChecking no" >> $SSHDIR/config
	chown -R nobody.nobody /home/nobody
}

# gitbacked设置,忽略cache tmp目录
# 将git作为默认存储,容器更新后拉取远程仓库
# 为了提高git pull速度,需要有持久化存储。如果用hostPath,需要固定机器
function stepPluginGitbacked() {
	sshKey
	# 设置默认值
	setConf plugin gitbacked ignorePaths "cache,tmp,index,locks"
	setConf plugin gitbacked periodicPull "1"
	setConf plugin gitbacked pushAfterCommit "1"

	# 需要设置HOME 参见 https://stackoverflow.com/a/27151021 解决  unable to access '/root/.config/git/attributes' 报错
	export HOME=/home/nobody

	# 需要设置权限
	chown -R nobody.nobody $DATADIR
	cd $DATADIR

	isEmpty=`ls $DATADIR |wc -l`
	[ $isEmpty -eq 0 ] && gitCmd "clone $GITREPO $DATADIR"
	if [ ! -d $DATADIR/.git ];then
		gitCmd init
		gitCmd "remote add origin $GITREPO"
	fi

	# 设置
	gitCmd 'config user.name "nobody"'
	gitCmd 'config user.email "dokuwiki@k8s.cluster"'

	gitCmd "pull origin master"

	for item in attic cache index locks media media_attic media_meta meta pages tmp; do
		[ ! -d $DATADIR/$item ] && mkdir $DATADIR/$item
	done

	for item in cache tmp index locks;do
		grep "$item/" .gitignore|| echo "$item/" >> .gitignore
	done

	chown -R nobody.nobody $DATADIR

	changes=`git status --short |wc -l`
	if [ $changes -gt 0 ];then
		gitCmd "add -A"
		gitCmd 'commit -m "commit"'
		gitCmd "push -u origin master"
	fi
}

管理员密码

请看参考资料,通过tools/smd5.php设置。

# php smd5.php mypasswd
$1$R8JFGQ1J$WEbAwCMI2RLKjkGQRgEWG.

推荐插件

plot
catlist
csv
dw2pdf
imgpaste
mathjax
move
todo
epub
wrap
bookcreator
gitbacked
tag

参考资料

1. https://github.com/annProg/kubernetes-practice/tree/master/dokuwiki

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注