EPrints 配置参数详解(cfg.d 分层体系与关键项)

EPrints 3.4.7 配置体系实测详解:SystemSettings.pm 与 lib/syscfg.d 站点层、lib/cfg.d 默认层(64 件)、flavours/pub_lib/cfg.d 口味层、archives/<id>/cfg/cfg.d 档案层的四层加载语义;源码级证据 + 覆写实测揭示文件名交错排序陷阱,misc/indexing/document_upload/branding/eprint_fields 关键项逐项解读,改配置生效方式速查。

EPrints配置参数详解Perl知识库2026/11/01

EPrints 配置参数详解(cfg.d 分层体系与关键项)

目标:以实测环境(Ubuntu 22.04.5 + EPrints 3.4.7,archive 为 demo/demo2)为样本,讲透 EPrints 的 Perl 配置体系——站点级 SystemSettings.pm 与 lib/syscfg.d、默认层 lib/cfg.d、口味层 flavours/pub_lib/cfg.d、档案层 archives/<id>/cfg/cfg.d 的四层结构;用源码级证据 + 覆写实测(含一个反直觉的文件名排序陷阱)验证"后者覆盖前者"的真实语义;逐项详解 10_core.pl、database.pl、misc.pl、indexing.pl、document_upload.pl、branding.pl、eprint_fields.pl 等关键配置。部署过程见 《EPrints 3.4.7 Ubuntu 22.04 安装部署指南》,选型背景见 《EPrints 介绍与选型指南》。

一、环境信息与配置体系总览

项目值(实测)
EPrints 版本epadmin 3.4.7 [Schema 3.3.4]
安装路径/opt/eprints3(SystemSettings base_path)
运行用户eprints(uid=106,getent passwd eprints 实测)
archivedemo(pub 口味,127.0.0.1:8141)、demo2(pub 口味,demo2.eprints.qzuo.local:8141)
配置语言Perl 片段:$c->{键} = 值;(不是 YAML/properties)

EPrints 配置分四层,加载时后层同名文件覆盖前层:

① 站点级  /opt/eprints3/perl_lib/EPrints/SystemSettings.pm   (user/group/base_path/smtp 等"装机级"参数)
② 站点层  /opt/eprints3/lib/syscfg.d/                        (core/executables/invocations/repositories/settings 5 件)
③ 默认层  /opt/eprints3/lib/cfg.d/                           (发行默认,实测 64 个 .pl)
   口味层 /opt/eprints3/flavours/pub_lib/cfg.d/              (pub 口味,实测 23 件:eprint_fields.pl、views.pl、oai.pl 等)
④ 档案层  /opt/eprints3/archives/<id>/cfg/cfg.d/             (每库独立,epadmin create 生成 6 件)

③ 内部再细分:默认层之后按口味声明的 lib 顺序叠加口味层,最后叠加档案层——所以每个 archive 的本地配置只出现在自己的 cfg/cfg.d 内,多库互不干扰。

💡 技术拓展:与 DSpace(Spring Boot dspace.cfg/Ant 属性文件)、InvenioRDM(Python invenio.cfg)不同,EPrints 的配置本身就是可执行 Perl——可以写条件、引用变量、调函数(document_upload.pl 里就有探测逻辑)。灵活度极高,代价是配置错误会直接抛 Perl 编译错,且无 schema 校验。

二、站点级配置:SystemSettings.pm 与 lib/syscfg.d

perl_lib/EPrints/SystemSettings.pm 是装机级系统设置(实测节选):

$EPrints::SystemSettings::conf = {
	'version' => 'EPrints 3.4.7',
	'base_path' => '/opt/eprints3',
	'group' => 'eprints',
	'user' => 'eprints',
	'file_perms' => '0664',
	'show_ids_in_log' => 0,
	'smtp_server' => '127.0.0.1',
	'invocation' => {},
	'executables' => { ... },

lib/syscfg.d/ 五个文件(实测内容):

文件关键项(实测原文)
core.pl$c->{show_ids_in_log} = 0;、$c->{file_perms} = '0664';、$c->{dir_perms} = '02775';、$c->{apache} = 2;(mod_perl 版本)、$c->{virtualhost} = '';(VirtualHost 指令字符串)
settings.pl#$c->{user} = 'eprint';、#$c->{group} = 'eprint';、#$c->{smtp_server} = 'smtp';(均注释态,实际值由 SystemSettings 提供)
repositories.pl# $c->{repository}->{epapers}->{disabled} = 1;——按站禁用某 archive 的开关位
executables.pl外部程序路径自动探测表:convert/tar/rm/dvips/gunzip/sendmail/unzip/html2text/cp/latex/perl/pdftotext/wget/antiword/ffmpeg/file/doc2txt/unoconv/txt2refs/ffprobe/cal/ncal,逐个 -x 探测后写入 $c->{executables}
invocations.pl调用模板串:pdftotext => '$(pdftotext) -q -enc UTF-8 -layout $(SOURCE) $(TARGET)'、antiwordpdf、targz、zip、wget、ffmpeg_video_mp4/ogg/webm、unoconv 等——全文抽取与转码的命令行拼装

executables/invocations 两层解耦(程序在哪 + 怎么调)意味着:换 pdftotext 路径改前者,改抽取参数改后者,都可在档案层用同名文件覆写。

三、档案层 cfg.d:epadmin create 生成的 6 个文件逐项实测

archives/demo/cfg/cfg.d/ 实测清单与内容:

10_core.pl(站点寻址,epadmin config_core demo 可重新生成):

# This file was created by bin/epadmin
# You can regenerate this file by doing ./bin/epadmin config_core demo
$c->{host} = '127.0.0.1';
$c->{port} = '8141';
$c->{aliases} = [];
$c->{securehost} = '';
$c->{secureport} = 443;
$c->{http_root} = undef;

host/port 决定该 archive 归属哪个 VirtualHost(Apache 侧 PerlSetVar EPrints_ArchiveID 双保险);aliases 可列多域名并生成 Redirect;securehost 为空即纯 HTTP 部署。对比 demo2 的实测值:$c->{host} = 'demo2.eprints.qzuo.local';——同端口 8141 按 Host 头路由到不同 archive,多库单实例的机制核心。

database.pl(库连接):

$c->{dbname} = 'demo';
$c->{dbhost} = 'localhost';
$c->{dbport} = undef;
$c->{dbsock} = undef;
$c->{dbuser} = 'demo';
$c->{dbpass} = 'q1w2e3r4';
$c->{dbengine} = 'InnoDB';

每个 archive 一个独立 MySQL 库、独立库用户(epadmin create_db/config_db 可重建)。注意 dbpass 为明文存储,档案目录权限必须收紧(属组 eprints、600/640)。

adminemail.pl:$c->{adminemail} = 'admin@eprints.qzuo.local';——OAI Identify 的 <adminEmail>、报错邮件收件人(第六节将用它做覆写生效的端到端验证)。可选 $c->{senderemail} 单独设定发件地址。

00_flavour.pl:$c->{flavour} = 'pub';——口味声明,加载器首先读取此文件决定叠加哪个口味层(源码实测:open (my $fh, "$repcfgd/00_flavour.pl") or die ...),建库后不可随意改。

csrf_protection.pl:$c->{csrf_token_salt} = "CHANGEME";——CSRF 令牌盐值,3.4.7 建库向导原样写入默认值 CHANGEME(实测),生产必须更换。

citationcaches.pl(引用缓存开关与范围):

$c->{datasets}->{citationcache} = {
        class => "EPrints::DataObj::CitationCache",
        sqlname => "citationcache",
        index => 0,
};
$c->{citation_caching}->{enabled} = 0;
$c->{citation_caching}->{excluded_dataobjs} = [ 'epm', 'eventqueue', 'loginticket', 'subject' ];
$c->{citation_caching}->{excluded_styles} = [ 'result', ... ];

默认关闭(enabled=0);开启后记录间引用关系(citations)缓存入库,大库慎用(缓存表膨胀)。

四、加载顺序与覆写语义(源码实测 + 一个反直觉陷阱)

perl_lib/EPrints/Config.pm 的 load_repository_config_module 实测逻辑(源码注释原文):

##cfg folder loaded latest takes priority. (latter overwrite earlier.)
my $libcfgd = $SYSTEMCONF->{"lib_path"}."/cfg.d";
my $repcfgd = $info->{archiveroot}."/cfg/cfg.d";
my %files_map = ();
...
my @libpaths = ($libcfgd);
my $lib_order = $SYSTEMCONF->{"flavours"}->{$flavour};   # 由 00_flavour.pl 决定
foreach (@$lib_order) { push @libpaths, $SYSTEMCONF->{"base_path"}."/$_/cfg.d"; }
push @libpaths, $repcfgd;
# 每个目录的文件以"文件名"为键放进 %files_map —— 后目录(档案层)的同名文件胜出
$files_map{$file} = "$dir/$file";
...
# we want to sort by filename because we interleave files from default and custom locations
foreach my $file (sort keys %files_map) { ... }           # 最终按文件名字典序交错加载

拆解成两条规则:

  1. 同名文件:档案层 > 口味层 > 默认层(%files_map 后写覆盖);
  2. 不同名文件:全部合并,按文件名字典序交错执行——排序是跨目录全局的!

第 2 条埋着一个实测踩中的陷阱:想覆写默认层 misc.pl 里的 $c->{skip_buffer},新建 archives/demo/cfg/cfg.d/99_c1test.pl 不生效——因为 ASCII 序 9 < 字母,99_c1test.pl 排在 misc.pl 之前加载,随后被默认层 misc.pl 的 $c->{skip_buffer} = 0; 覆盖回去。实测对照(验证脚本见第五节):

覆写文件 99_c1test.pl(skip_buffer=1, csrf=S9C1SALT2026, adminemail=c1test@..., 新键 c1_probe_key):
skip_buffer = 0            ← 被默认层 misc.pl 覆盖回 0
csrf_token_salt = CHANGEME ← 被档案层 csrf_protection.pl(字典序在后)覆盖
adminemail = admin@eprints.qzuo.local ← 被档案层 adminemail.pl 覆盖
c1_probe_key = archive-layer-wins     ← 无同名竞争者,存活

改名 zz_c1test.pl 后(zz 排所有文件之后):
skip_buffer = 1
csrf_token_salt = S9C1SALT2026
adminemail = c1test@eprints.qzuo.local
c1_probe_key = archive-layer-wins

正确姿势:覆写某默认项,首选编辑档案层同名文件(如直接改 archives/demo/cfg/cfg.d/csrf_protection.pl,规则 1 保证档案层胜出且不受排序影响);若用新文件做覆写,文件名必须排在被覆写文件之后(惯例 zz_ 前缀)。另外注意:同名覆写是整文件遮蔽而非按键合并——档案层放一个只含一行 $c->{theme}=... 的 branding.pl,默认层 branding.pl 的其余键将全部丢失。

五、覆写生效端到端实测

验证脚本 /work/c1_dump.pl(实测):

#!/usr/bin/perl -w
use strict;
use lib "/opt/eprints3/perl_lib";
use EPrints;
my $repo = EPrints->new->repository("demo");
for my $k (qw(skip_buffer csrf_token_salt adminemail theme c1_probe_key)) {
    my $v = $repo->config($k);
    print "$k = ", (defined $v ? $v : "(undef)"), "\n";
}

基线回显(覆写前):

skip_buffer = 0
csrf_token_salt = CHANGEME
adminemail = admin@eprints.qzuo.local
theme = (undef)
c1_probe_key = (undef)

写入 archives/demo/cfg/cfg.d/zz_c1test.pl(四项覆写,内容见第四节)后 dump 全部生效(第四节实测回显)。再看Web 端到端——adminemail 直接渲染进 OAI Identify,重启 Apache 后实测:

# curl -s "http://127.0.0.1:8141/cgi/oai2?verb=Identify" | grep adminEmail
    <adminEmail>c1test@eprints.qzuo.local</adminEmail>

删除 zz_c1test.pl、重启 Apache,dump 与 OAI 双双恢复原值(admin@eprints.qzuo.local),实测闭环。这同时证明了:档案层 cfg.d 改动 → 进程重启后即时生效,无需重建索引或静态页。

六、默认层 lib/cfg.d 关键项详解

lib/cfg.d/ 实测 64 个文件,按主题分组:paths.pl/20_baseurls.pl(路径与 URL 基)、security.pl/session.pl/user_auth_limits.pl/user_login.pl(安全与会话)、search.pl/search_xapian.pl/indexing.pl(检索)、eprint_search_*.pl/document_fields*.pl/user_fields*.pl(字段与搜索表单)、email.pl/registration.pl(邮件与注册)、rdf*.pl/signposting.pl(语义输出)、languages.pl/template_*.pl/homepage.pl(界面)、log.pl/misc.pl/vlit.pl 等。以下逐项实测关键文件:

misc.pl(杂项行为开关):

$c->{use_mimetex} = 0;
$c->{cookie_auth} = 1;
$c->{skip_buffer} = 0;
$c->{skip_buffer_owners} = [];
$c->{cookie_domain} = defined $c->{host} ? $c->{host} : $c->{securehost};
$c->{cookie_auth_set_user} = 0;
$c->{pin_timeout} = 24*7; # a week
$c->{cache_timeout} = 10;
$c->{cache_maxlife} = 12;
$c->{cache_max} = 100;

要点:cookie_auth=1 启用 Cookie 记住登录;skip_buffer=0 提交进 buffer 待审(改 1 则直接发布,测试库常用);skip_buffer_owners 可按用户组豁免缓冲;cache_* 三项控制页面片段缓存(超时 10 秒、最长存活 12 小时、容量 100)。

indexing.pl(索引词法):

$c->{indexing}->{freetext_stop_words} = { ... };   # 停用词表(不进倒排)
$c->{indexing}->{freetext_always_words} = { ... }; # 强制收录词
# Chars which separate words. Pretty much anything except ... 分字符集
# extract_words( $repository, $text )  索引与查询共用切词

切词逻辑(extract_words)索引与检索共用,改分字符号或停用词后需 epadmin reindex 重建才对新旧记录一致生效。中文分词默认按非字母数字切分,效果有限,需换分词方案时改此文件。

document_upload.pl(上传与磁盘):

$c->{diskspace_error_threshold} = 64*1024;    # 剩余空间低于 64KB 拒收上传
$c->{diskspace_warn_threshold} = 512*1024;    # 低于 512KB 告警
# $c->{mimemap}->{html} = "text/html";        # MIME 映射扩展位
# $c->{archive_max_files} = 100;              # 压缩包展开文件数上限(防 zip bomb)

branding.pl(品牌与模板):

$c->{site_logo} = "/images/sitelogo.png";
# $c->{theme} = "green";                      # 主题需在 lib/themes/ 下有同名目录
$c->{user_area_template} = 'default_internal';

实测本发行 lib/themes/ 仅带 example 主题目录——theme 注释默认值 green 并无实体,直接启用会找不到主题资源;换 logo 的正规做法是替换 cfg/static/images 下文件后跑 bin/generate_static(文件头注释原文如此)。

eprint_fields.pl(口味层,记录字段集):flavours/pub_lib/cfg.d/eprint_fields.pl 实测字段序列(节选):

creators(子字段 name, id) / contributors(type[set_name=contributor_type], name, id) /
corp_creators / title / ispublished / subjects / divisions / keywords / note /
suggestions / abstract / date / date_type / publisher / official_url / id_number /
data_type / copyright_holders ...

字段以 $c->{eprint_fields} 数组声明,每项含 name/type/multiple/optional 等属性;配套 eprint_fields_default.pl(默认值)、eprint_fields_automatic.pl(自动值)、eprint_fields_pub.pl(口味差异)、eprint_validate.pl(校验)。增删字段后必须 epadmin update <id> 同步数据库表结构(详见本专栏 CLI 篇)。

csrf_protection.pl / citationcaches.pl:见第三节(档案层实测)。

七、改配置后的生效方式速查

改动内容生效动作(实测/源码依据)
档案层 cfg.d 一般项epadmin reload <id>(回显实测:The repository config will be reloaded, but you should still restart apache as soon as possible.)→ 择机重启 Apache
host/port/aliases(10_core.pl)epadmin config_core <id> 重生成 + generate_apacheconf --replace + 重启 Apache
页面模板/静态资源(logo 等)bin/generate_static <id> 重刷 archives/<id>/html
导航视图(views.pl)epadmin refresh_views <id> 或 bin/generate_views <id>
字段集(eprint_fields.pl)epadmin update <id>(只加不删);删表用 erase_eprints/erase_data(危险,见 CLI 篇)
索引词法(indexing.pl)epadmin reindex <id> eprint 重建
全库禁用某 archivelib/syscfg.d/repositories.pl 设 disabled=1
开发期免重启epadmin set_developer_mode <id> on(每请求重载配置,源码明示生产禁用)

八、常见问题

  1. 覆写不生效——九成是第四节陷阱:新文件名字典序排在被覆写文件之前。优先改同名档案层文件,或 zz_ 前缀。
  2. 启动报 Error in configuration: Global symbol "@xxx" requires explicit package name——配置值里的 @(邮箱!)在双引号串中被 Perl 插值。实测写法:$c->{adminemail} = "c1test\@eprints.qzuo.local"; 转义 @,或单引号串。
  3. could not open file flavour config file——档案层 00_flavour.pl 缺失/不可读,加载器第一步就 die(源码实测),从模板补回即可。
  4. csrf 盐值 CHANGEME——3.4.7 建库向导不自动生成随机盐(实测),上线前务必手改档案层 csrf_protection.pl。
  5. dbpass 明文——database.pl 明文存密码属设计如此,靠文件权限兜底:档案目录须 eprints 属组、禁 world 读。
  6. 多库路由错乱——检查两处一致性:档案层 10_core.pl 的 host/port 与 Apache VirtualHost 的 ServerName/端口、PerlSetVar EPrints_ArchiveID;三者任一错配都会串库或 404。

九、参考链接

  1. EPrints GitHub 仓库(lib/cfg.d、lib/syscfg.d、flavours/pub_lib/cfg.d 配置源):https://github.com/eprints/eprints (查询日期 2026-11-01)
  2. EPrints wiki 配置文档:https://wiki.eprints.org/w/Configuration (查询日期 2026-11-01)
  3. EPrints wiki CSRF 说明:https://wiki.eprints.org/w/CSRF_Protection (查询日期 2026-11-01)
  4. Perl 配置文件插值语义(perlop,双引号串 @ 插值):https://perldoc.perl.org/perlop (查询日期 2026-11-01)
  5. 站内姊妹篇:《EPrints 介绍与选型指南》、《EPrints 3.4.7 Ubuntu 22.04 安装部署指南》;命令行管理见本专栏 CLI 篇《EPrints 常用 CLI 命令详解》
EPrints 配置参数详解(cfg.d 分层体系与关键项) - Quzuo