- 后端
- 企业应用
【免费下载链接】zenodo
Research. Shared.
本指南围绕 Zenodo(CERN 开发的开源科研数据共享平台)的 INSTALL.rst 展开,系统讲解两种落地方式:一条是基于docker-compose的"全栈容器化"快速部署路径,适合只想本地运行验证的用户;另一条是"容器只跑依赖服务、代码跑在本机虚拟环境"的开发安装路径,适合后续要修改 Zenodo 源码的开发者。读完本文,你将掌握从零搭建 Zenodo 本地实例、初始化数据库与搜索索引、构建前端资源、启动 Celery 异步任务队列以及加载许可证等数据全过程的完整操作。
一、安装前必读:Zenodo 的运行时依赖
Zenodo 建立在 Invenio 框架之上,是一个典型的微服务化 Web 应用,运行它至少需要四类基础服务:
| 服务 | 用途 | 对应 docker-compose 服务名 |
|---|---|---|
| PostgreSQL | 主数据库,存储记录、用户、元数据 | db |
| Elasticsearch | 全文检索与索引 | search/es |
| Redis | 缓存与 Celery 结果后端 | cache |
| RabbitMQ | 异步任务消息队列 | mq |
INSTALL.rst 开头将依赖描述为 PostgreSQL、Elasticsearch 2.x、Redis 和 RabbitMQ;而在后文"运行服务"一节中又要求 Elasticsearch 7.x。结合当前仓库 docker-services.yml 的实际配置可以看到,搜索服务实际使用的是opensearchproject/opensearch:2.2.1镜像,并启用了compatibility.override_main_response_version=true以兼容 Elasticsearch 7.x 的响应格式。因此读者在搭建时应以仓库当前锁定的镜像为准,避免被文档中不一致的版本描述误导。
两种安装路径的差异在于"应用代码跑在哪里":
- Docker 安装:应用、前端、负载均衡、监控全部容器化,一条命令拉起完整栈;
- 开发安装:只把 PostgreSQL、Elasticsearch、Redis、RabbitMQ 跑在 Docker 里,Zenodo 应用代码与 Celery worker 跑在你自己创建的 Python 虚拟环境中,方便直接编辑代码、即时调试。
提示:若无法使用 Docker,也可以直接在本机系统安装这四个服务。此时应参照 docker-compose.yml 与 docker-services.yml 中声明的环境变量(如
INVENIO_SQLALCHEMY_DATABASE_URI、INVENIO_BROKER_URL、INVENIO_SEARCH_ELASTIC_HOSTS等)来手动配置连接参数。
二、方式一:Docker 全栈安装(快速体验)
2.1 克隆代码并构建完整栈
全栈安装需要 Docker 与 docker-compose 工具。假设所有代码仓库都检出在~/src/目录下(下文均以此为前提),首先克隆 Zenodo 源码并切换到 master 分支:
$ cd ~/src/ $ git clone https://gitcode.com/gh_mirrors/ze/zenodo.git $ cd ~/src/zenodo $ git checkout master接着使用完整栈配置文件 docker-compose.full.yml 构建镜像并后台启动:
$ docker-compose -f docker-compose.full.yml build $ docker-compose -f docker-compose.full.yml up -d2.2 docker-compose.full.yml 的完整栈结构
从 docker-compose.full.yml 可以清晰看到 Zenodo 生产级部署的容器编排,全部服务均通过extends继承 docker-services.yml 中的基础定义:
| 容器 | 角色 | 关键配置 |
|---|---|---|
lb | HAProxy 负载均衡 | 映射宿主80/443/8080端口,前端链路指向frontend |
frontend | Nginx 反向代理 | 映射宿主81/444端口,代理到web,共享static容器的静态卷 |
web | uWSGI 应用服务器 | 命令uwsgi /code/zenodo/docker/uwsgi/uwsgi.ini,暴露5000端口,链接cache/search/mq/db四个基础服务 |
worker | Celery 异步 worker | 命令celery worker -A zenodo.celery --loglevel=INFO,常驻运行(restart: "always") |
static | 静态资源数据卷容器 | 挂载static、site-packages、data与源码目录/code/zenodo |
flower | Celery 任务监控 | 暴露5555端口,链接mq |
search-dashboards | OpenSearch Dashboards | 暴露5601端口,OPENSEARCH_HOSTS=http://search:9200 |
其中app基础服务的环境变量(见 docker-services.yml)揭示了 Zenodo 的配置注入方式——所有 Invenio 配置均可通过INVENIO_*环境变量覆盖,例如:
INVENIO_SQLALCHEMY_DATABASE_URI=postgresql://zenodo:zenodo@db/zenodo:数据库连接串,对应db容器中POSTGRES_USER=zenodo、POSTGRES_PASSWORD=zenodo、POSTGRES_DB=zenodo;INVENIO_BROKER_URL=amqp://guest:guest@mq:5672//与INVENIO_CELERY_BROKER_URL:RabbitMQ 消息代理地址;INVENIO_CACHE_REDIS_URL=redis://cache:6379/0与INVENIO_CELERY_RESULT_BACKEND=redis://cache:6379/2:Redis 缓存与 Celery 结果后端;INVENIO_SEARCH_ELASTIC_HOSTS=['es:9200']:搜索服务地址;INVENIO_SESSION_COOKIE_SECURE=True、INVENIO_WSGI_PROXIES=2、INVENIO_SECRET_KEY=CHANGE_ME(部署时务必替换密钥)。
2.3 初始化数据库、索引与演示数据
保持 docker-compose 会话存活,另开一个新终端,在web容器内运行仓库自带的初始化脚本 scripts/init.sh:
$ cd ~/src/zenodo $ docker-compose -f docker-compose.full.yml run --rm web bash /code/zenodo/scripts/init.shscripts/init.sh 的核心逻辑值得拆解——它依次执行了一整套 Zenodo CLI 命令:
zenodo db create # 创建数据库表结构 zenodo index queue init # 初始化索引队列 zenodo index init # 创建 Elasticsearch/OpenSearch 索引 zenodo queues declare # 声明 RabbitMQ 队列 zenodo fixtures init loadlicenses loadfunders loadfp6grants \ loadsipmetadatatypes loadusers loadcommunities # 加载许可证、资助方、FP6 资助项目、SIP 元数据类型、用户、社区等数据 zenodo index reindex -t od_lic -t frdoi -t grant --yes-i-know # 重建许可证/资助项目/资助方索引 zenodo index run # 消费索引队列这也解释了为什么"初始化"这一步是异步、多阶段的:数据库建表与索引创建相互独立,而许可证(od_lic)、资助项目(frdoi)、资助方(grant)等索引需要先有数据再重建。
2.4 浏览器访问、监控界面与端口总览
初始化完成后,在浏览器访问:
https://<docker ip>- 在 Linux 以及较新的 macOS 上,
<docker ip>通常就是localhost; - 在通过
docker-machine运行 Docker 的旧版 macOS / Windows 上,用docker-machine ip <machine-name>查出实际 IP。
全栈部署还自带了三个监控/管理界面:
- Elasticsearch 插件界面:
http://<docker ip>:9200/_plugin/hq/ - RabbitMQ 管理控制台:
http://<docker ip>:15672/(默认账号guest/guest) - HAProxy 统计页:
http://<docker ip>:8080/(默认账号guest/guest)
同时,Docker 宿主机上暴露了以下端口,可用于排查各组件连通性:
| 端口 | 服务 |
|---|---|
80/443 | HAProxy(HTTP / HTTPS 入口) |
81/444 | Nginx |
5000 | Zenodo 应用 |
5432 | PostgreSQL |
5672 | RabbitMQ |
6379 | Redis |
8080 | HAProxy stats |
9200/9300 | Elasticsearch(HTTP / 传输层) |
15672 | RabbitMQ management console |
三、方式二:开发安装(容器跑依赖、本机跑代码)
开发安装的核心思路是复用 docker-compose.yml 只拉起四个基础服务(PostgreSQL、Elasticsearch、Redis、RabbitMQ),把 Zenodo 应用代码装进自己的 Python 虚拟环境,便于随时编辑与调试。
注意:由于 Docker 会把服务映射到本机
localhost的默认端口,请确保系统里没有同端口占用——即本机不能同时运行 PostgreSQL、Redis、RabbitMQ 或 Elasticsearch。
3.1 仅启动四个基础服务
$ cd ~/src/zenodo $ docker-compose up -d # "-d" 表示后台运行docker-compose.yml 中只声明了cache、db、mq、search四个服务(分别继承自 docker-services.yml),其中search额外挂载了名为search的本地数据卷以持久化搜索索引数据。
3.2 创建虚拟环境并安装依赖
使用 virtualenvwrapper 创建独立虚拟环境(注意仓库 Dockerfile 基于python:2.7,文档也以 Python 2.7 为例):
$ mkvirtualenv -p python2.7 zenodo (zenodo)$关于 Python 版本:Zenodo 同时支持 Python 2.7 与 3.5+,但如果你需要用到 XRootD 存储接口,则必须使用 Python 2.7——因为底层 XRootD 库尚不支持 Python 3.5+。这一点同样反映在 Dockerfile 中:
FROM python:2.7。
进入源码目录,安装 Python 依赖与 Zenodo 本体:
(zenodo)$ cd ~/src/zenodo (zenodo)$ pip install -r requirements.txt (zenodo)$ pip install -e ".[all]"其中pip install -e ".[all]"以可编辑模式安装 Zenodo 及其全部可选依赖;Dockerfile 中对应的镜像内安装命令是pip install -e .[postgresql,elasticsearch2,all],可据此了解依赖分组(postgresql、elasticsearch2为不同的后端扩展组)。
3.3 前端资源构建(NodeJS / NPM 工具链)
Zenodo 前端资源不是预编译产物,而是由 SASS、JavaScript 等源文件经一系列构建工具现场编译生成,因此需要先安装 NodeJS 工具链。
版本要求
文档明确要求的工具版本如下:
| 工具 | 版本 |
|---|---|
| NodeJS | 7.4 |
| NPM | 4.0.5 |
| SASS(node-sass) | 3.8.0 |
| CleanCSS | 3.4.19 |
| UglifyJS | 2.7.3 |
| RequireJS | 2.2.0 |
建议用 NVM(Node Version Manager,作用类似 Python 的 pyenv)安装并切换 Node 版本:
(zenodo)$ nvm install 7.4 (zenodo)$ nvm use 7.4 Now using node v7.4.0 (npm v4.0.5)如果想长期使用 Node v7.4,可以设为默认版本,省去每次nvm use的麻烦:
(zenodo)$ nvm alias default 7.4安装 npm 依赖
运行仓库提供的 scripts/setup-npm.sh,包会安装到当前用户的 NVM 环境中:
(zenodo)$ ./scripts/setup-npm.sh该脚本的源码实现印证了版本约束的严谨性:它先检查node --version,只有匹配v7*或v6*才继续,否则直接报错退出;随后通过npm install --silent -g全局安装四个精确锁定版本的构建工具:node-sass@3.8.0、clean-css@3.4.19、uglify-js@2.7.3、requirejs@2.2.0。顺带说明,脚本开头还内嵌了一段"修复 npm 未安装"的兼容逻辑(对应历史 issue #2154),会直接下载 Node v7.4.0 的二进制包解压到/usr/local,这也是 Dockerfile 中镜像构建时直接执行该脚本的原因。
下载并编译前端资源
接下来运行 scripts/setup-assets.sh 完成前端资源的下载与编译:
(zenodo)$ ./scripts/setup-assets.sh从脚本源码可以看到它做的事情远不止"编译":先再次校验 node 版本与四个构建工具二进制(cleancss、node-sass、uglifyjs、r_js)是否就位,然后依次执行:
zenodo npm --pinned-file package.pinned.json # 依据 package.pinned.json 生成实例静态目录下的 package.json cd ${VIRTUAL_ENV}/var/instance/static npm install # 安装前端 npm 依赖 zenodo collect -v # 收集各模块静态资源 zenodo assets build # 编译 SASS/JS,产出最终静态资源其中package.pinned.json(仓库根目录)是前端依赖的锁定清单;zenodo assets build则调用 Invenio 的 webassets 机制把theme、records、deposit、search_ui等模块的scss与js编译为可对外服务的静态文件。
3.4 运行基础服务与初始化
在开发模式下同样需要四个基础服务在线,执行:
$ cd ~/src/zenodo $ docker-compose up -d这会拉起 PostgreSQL(db)、Elasticsearch(es)、RabbitMQ(mq)、Redis(cache)四个容器,保持该终端会话存活。
接着在新的终端会话中激活虚拟环境并初始化数据库、搜索索引、消息队列及各类 fixtures(许可证、资助项目、社区、用户等):
$ cd ~/src/zenodo $ workon zenodo (zenodo)$ ./scripts/init.sh关于./scripts/init.sh内部各条命令的含义,可回看本文 2.3 节的逐行拆解——开发安装与 Docker 安装走的是同一套初始化流程。
3.5 启动 Celery worker
Zenodo 的许多操作(索引、异步任务、外部数据收割)依赖 Celery,需要在另一个终端会话启动 worker:
$ cd ~/src/zenodo $ workon zenodo (zenodo)$ celery worker -A zenodo.celery -l INFO --purge-A zenodo.celery指定 Celery 应用入口,即 zenodo/celery.py——它直接复用了 Invenio 提供的invenio_app.celery应用对象(from invenio_app.celery import celery),因此 Zenodo 的所有异步任务都注册在这同一个应用上;--purge会在启动前清空积压的过期任务消息。
3.6 加载外部数据(许可证等)
接下来加载演示数据——目前阶段只有许可证。由于加载过程需要向外部的 OAI-PMH 或 REST API 发起收割,因此依赖互联网,且必须保持 Celery worker 会话存活,然后在另一个终端执行:
$ cd ~/src/zenodo $ workon zenodo (zenodo)$ zenodo opendefinition loadlicenses -s opendefinition (zenodo)$ zenodo opendefinition loadlicenses -s spdx (zenodo)$ ./scripts/index.sh- 两条
loadlicenses命令分别从 OpenDefinition 与 SPDX 两个来源收割许可证数据,由 Celery 异步执行; - scripts/index.sh 则承担索引重建任务,其内部逻辑为:
zenodo index destroy --force --yes-i-know # 删除旧索引 zenodo index init --force # 重新创建索引 zenodo index reindex -t od_lic -t frdoi -t grant -t recid -t depid --yes-i-know zenodo index run -c 4 -d # 以 4 个并发 worker 消费索引队列注意开发安装的index.sh比 Docker 安装的init.sh多重建了recid(记录)与depid(deposit)两类索引,因为此时需要把已入库的记录数据也索引进搜索。
3.7 启动开发服务器
最后,以调试模式启动 Zenodo 开发服务器:
(zenodo)$ export FLASK_DEBUG=True (zenodo)$ zenodo run访问http://localhost:5000,即可看到与生产环境(zenodo.org)同源同构的 Zenodo 实例页面。FLASK_DEBUG=True让 Flask 进入调试模式,代码改动会自动重载、出错时展示交互式调试页,极大方便源码开发调试。
四、DOI 徽章(Badges)的系统依赖
如果希望记录详情页上的 DOI 徽章(badge)正常工作,宿主系统还需要具备两个底层组件:
- Cairo SVG 库:用于将 SVG 徽章渲染为图片;
- DejaVu Sans 字体:徽章文本渲染所需的默认字体。
这正是 Dockerfile 在系统依赖安装阶段显式加入libcairo2-dev fonts-dejavu的原因——容器镜像在构建时就预置了这两项依赖。对本机开发安装而言,请确保你的操作系统装有libcairo2-dev(或对应发行版名称)与fonts-dejavu后再验证徽章功能。
五、小结:两种安装路径的选型建议
- 只想本地体验 / 验证功能:选 Docker 全栈安装,
docker-compose -f docker-compose.full.yml build && up -d加上一次init.sh即可拥有包含负载均衡、反向代理、Celery worker、监控面板的完整 Zenodo; - 打算二次开发 Zenodo 源码:选开发安装,用
docker-compose.yml只跑四个基础服务,代码跑在 virtualenv 中,配合FLASK_DEBUG=True与 Celery worker 获得即时反馈的开发循环; - 无论哪种方式,都必须完整经历"启动依赖服务 →
scripts/init.sh初始化 → 构建前端资源(开发模式)→ 加载许可证数据 → 重建索引"这几个阶段,任一环节缺失都会导致页面、搜索或异步任务异常。
上述所有命令与配置均取自当前仓库的 INSTALL.rst、docker-compose.full.yml、docker-compose.yml、docker-services.yml、Dockerfile 以及 scripts/init.sh、scripts/setup-npm.sh、scripts/setup-assets.sh、scripts/index.sh 等文件,可按需深入阅读以理解各环节的底层实现。
- 后端
- 企业应用
【免费下载链接】zenodo
Research. Shared.
相关推荐
SPlayer 安装部署与本地开发环境搭建完整指南
SPlayer 安装部署与本地开发环境搭建完整指南 本指南系统讲解 SPlayer 这款跨平台音乐播放器的全部安装与开发方式:涵盖 Windows / macO
音视频桌面应用前端GM_script与Docker部署:如何搭建本地开发环境
想要快速搭建GM_script项目的本地开发环境吗?Docker部署方案为你提供了一种简单高效的解决方案!本文将详细介绍如何使用Docker容器化技术来快速部署
前端Karakeep 开发环境搭建全指南:一键脚本、手动安装与 Docker Compose 开发栈
Karakeep 开发环境搭建全指南:一键脚本、手动安装与 Docker Compose 开发栈 本文是 Karakeep(自托管书签管理应用)的本地开发环境搭
后端前端移动开发AI 应用知识管理全文检索MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考