从 Python 版迁移
本文介绍如何将运行 Python 版的现有 ProjectWikit 安装迁移至本版本。pwikit 会直接接管现有的 PostgreSQL 数据库,页面、历史记录、账号、密码、身份组和站点设置均保留在原处。上传的文件需复制到 pwikit 的数据目录中。
迁移需要安排停机时间。两个版本绝不能同时连接同一个数据库运行。
前提条件
- 旧安装运行的是 ProjectWikit 的最后一个 Python 版。本版本只能接管具有该版本数据库结构的数据库。如果数据库来自更早的 Python 版,pwikit 会应用一部分数据库变更,然后报错停止。
- PostgreSQL 14 或更高版本。
- pwikit 能够访问该 PostgreSQL 服务器,并以数据库所有者的账户连接,即旧安装所使用的账户。
- 迁移后的实例只包含旧安装的这一个站点,因为 pwikit 接管的是旧数据库本身。不支持把 Python 版的站点并入一个已有站点的实例;恢复备份同样会替换整个数据库,参见运维。
开始之前,请检查数据库结构。使用 psql 连接旧数据库,执行:
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'web_user' AND column_name = 'email_verified_at'
) AS ready;如果结果为 f,请停止操作:本版本无法接管该数据库。pwikit migrate status 无法代替此项检查,因为它对所有由 Python 版创建的数据库都给出相同的结果。
开始之前
提前告知用户站点的停机时间。
停止旧版本,但保持其 PostgreSQL 运行。如果使用 Python 版的 Docker Compose 部署,在其项目目录中执行:
shdocker compose stop web updater使用 PostgreSQL 自带的工具备份数据库:
shpg_dump -Fc -h <host> -U <user> -d <database> -f projwikit-before-pwikit.dump如果使用 Docker Compose 部署,用户名和数据库名取自其
.env文件中的DB_PG_USERNAME和DB_PG_DATABASE(默认为admin和projwikit):shdocker compose exec -T postgres pg_dump -Fc -U admin projwikit > projwikit-before-pwikit.dump保持旧的
files/目录不变。后续步骤只从中复制文件,因此回档时仍可使用。记录旧的设置:
SECRET_KEY、各项DB_PG_设置、各项EMAIL_设置、上传限制和GOOGLE_TAG_ID。使用 Docker Compose 部署时,这些设置位于.env中。按照部署安装 pwikit,但暂不启动
pwikit serve。
将 pwikit 连接到现有数据库
Python 版的 Compose 文件没有对外公开 PostgreSQL 的端口。为使同一台机器上的 pwikit 能够连接,请在 docker-compose.yaml 的 postgres 服务中添加端口映射:
postgres:
ports:
- "127.0.0.1:5432:5432"然后重新创建该容器。数据仍保存在 ./postgresql 中:
docker compose up -d postgres将连接字符串写入 pwikit 数据目录中的 pwikit.toml。该文件尚不存在时,请新建:
database = "postgres://admin:change-me-please@127.0.0.1:5432/projwikit"密码中的特殊字符必须进行百分号编码。使用数据库的 pwikit 命令以及系统服务都会读取此设置。也可以使用 DATABASE_URL 或 -database,但系统服务读取不到在 shell 中设置的环境变量。见配置。
在不更改数据库的前提下进行检查:
./pwikit migrate status如果没有设置 database、DATABASE_URL 或 -database,该命令会改用内置 PostgreSQL,并在 pgdata/ 中创建一个新的空数据库,而不会读取您的数据库。
来自 Python 版的数据库,第一行显示为 existing 0001_baseline.sql,其余各行为 pending:
STATUS MIGRATION
existing 0001_baseline.sql
pending 0002_admin_log_and_addresses.sql
...各状态的含义见命令行。
如果第一行显示 pending 0001_baseline.sql 而不是 existing,说明 pwikit 连接的不是由 Python 版创建的数据库。请先检查连接字符串,再继续操作。
应用数据库变更
./pwikit migrate up命令先输出 adopted 0001_baseline.sql,然后每应用一项变更输出一行 applied <name>。
除非以 -no-migrate 启动,pwikit serve 在启动时也会应用这些变更。先执行 migrate up,可以在站点上线之前看到结果。
每项变更要么完整应用,要么完全不应用。某项变更失败时,pwikit 会停止并指出是哪一项,此前的变更仍保持已应用状态。请先按照回档进行恢复,再重新尝试。
注意 本版本更改数据库之后,请勿再以旧版本连接该数据库启动。如需回到旧版本,请恢复迁移前制作的备份。
沿用密钥
密钥用于签署登录会话和通过邮件发送的链接,例如邀请链接、认领链接和密码重置链接。
- 沿用旧的
SECRET_KEY时,已发送但尚未使用的链接仍然有效。如果旧站点的登录 Cookie 名为pwikit_sessionid,已登录的用户保持登录状态;Cookie 为其他名称时,所有用户都需要重新登录。可在旧站点上通过浏览器的开发者工具查看 Cookie 名称。 - 使用不同的密钥时,所有用户都需要重新登录,已发送的链接也会失效。
- 如果旧安装从未设置
SECRET_KEY,或者仍在使用.env.example中的示例值,则其密钥是公开的。请勿沿用。pwikit 首次启动时会创建新密钥,所有用户都需要重新登录。
如需沿用密钥,请在启动 pwikit 之前将其写入数据目录中的 secrets/session-key:
mkdir -p secrets
printf '%s\n' 'old-secret-key' > secrets/session-key
chmod 600 secrets/session-key在 Windows 上,于 PowerShell 中执行:
New-Item -ItemType Directory -Force secrets | Out-Null
Set-Content -Path secrets\session-key -Value 'old-secret-key' -Encoding ascii该文件不能以字节顺序标记开头,因此上述命令以 ASCII 编码写入。pwikit 每次启动都会读取该文件,因此替换 pwikit 已创建的密钥后,重新启动即可生效。SECRET_KEY 与 -secret-key 的优先级高于该文件。见运维。
迁移上传的文件
Python 版将上传的文件保存在其项目目录的 files/ 中。本版本从数据目录的 files/ 中读取:
| 路径 | 内容 |
|---|---|
files/media/ | 页面附件 |
files/-/ | 站点图标、头像、身份组图标,以及在管理后台上传的文件 |
files/theme/<站点标识名>/ | 主题样式表,每个站点一个目录 |
从旧的
files/目录复制media、-和theme。本版本不使用旧的files/symlinks/目录,无需复制。shmkdir -p /opt/pwikit/files cp -a /opt/ProjectWikit/files/media /opt/ProjectWikit/files/- /opt/ProjectWikit/files/theme /opt/pwikit/files/在 Windows 上,于 PowerShell 中执行:
powershellCopy-Item -Recurse C:\ProjectWikit\files\media, C:\ProjectWikit\files\-, C:\ProjectWikit\files\theme -Destination C:\pwikit\files\将主题样式表移入以站点标识名命名的目录。
pwikit site list可列出标识名:sh./pwikit site list mkdir -p files/theme/wikit-wiki mv files/theme/*.css files/theme/wikit-wiki/也可以在管理后台的主题中逐一打开各主题并保存,以重新写入其样式表。
确认运行 pwikit 的账户可以读写
files/下的全部内容。Python 版的容器写入的文件可能属于root:shsudo chown -R <account>: /opt/pwikit/files
设置
请将设置写入 pwikit.toml。同名的环境变量也会被读取,但系统服务读取不到这些变量。
| Python 版 | 本版本 |
|---|---|
SECRET_KEY | secrets/session-key,见沿用密钥 |
DB_PG_HOST、DB_PG_PORT、DB_PG_DATABASE、DB_PG_USERNAME、DB_PG_PASSWORD | 不再读取。请将其合并为 database |
EMAIL_ENGINE | [mail] engine |
EMAIL_HOST | [mail] host |
EMAIL_PORT | [mail] port |
EMAIL_USERNAME | [mail] username |
EMAIL_PASSWORD | [mail] password |
EMAIL_USE_TLS | [mail] use_tls |
EMAIL_DEFAULT_FROM | [mail] from |
MEDIA_UPLOAD_LIMIT | [server] upload_limit |
ABSOLUTE_MEDIA_UPLOAD_LIMIT | [server] storage_limit |
GOOGLE_TAG_ID | [analytics] google_tag_id |
WEB_PORT | 无对应设置。见域名与 HTTPS |
MEDIA_HOST、ARTICLE_SOURCE_LIMIT、ARTICLE_REPLACE_CONFIG、ARTICLE_IMPORT_REPLACE_CONFIG、DEBUG、LOGLEVEL、COMPOSE_PROJECT_NAME、HOST_PROJECT_DIR、UPDATE_REPO、UPDATE_BRANCH、UPDATE_POLL_INTERVAL | 不再读取 |
邮件设置的默认值有所不同。未设置 host 时,pwikit 会将邮件写入日志而不发送,默认端口为 587。即使旧安装依赖默认值,也请明确设置 host 和 port。见配置。
域名与 HTTPS
各站点的域名与文件域名保存在数据库中,迁移后保持不变。需要重新决定的是由谁处理 HTTPS。
由 pwikit 处理 HTTPS。 当站点绑定了公网域名,且未配置
listen、trusted_proxies或 TLS 模式时,pwikit 会监听 80 与 443 端口,并从 Let's Encrypt 获取证书。请停止为旧版本处理 HTTPS 的 Web 服务器,以释放这两个端口。见自动 HTTPS。保留反向代理。 设置代理转发的目标地址以及代理自身的地址,这会关闭自动 HTTPS:
toml[server] listen = "127.0.0.1:8000" trusted_proxies = ["127.0.0.1"]将代理指向该地址。见置于反向代理之后。
启动 pwikit 并检查站点
按照部署在终端中或以系统服务方式启动 pwikit:
sh./pwikit serve登录并打开若干页面、附件和论坛主题,确认主题已生效。
在管理后台打开站点设置,检查站点语言与站点时区。站点时区的初始值为 UTC。
使用 pwikit 创建第一份备份:
./pwikit backup create。见运维。pwikit 的备份不包含secrets/,请另外保存该目录的副本。
管理员
- Python 版的管理界面由管理后台取代,访问地址仍为
/-/admin/。见站点管理。 - 超级管理员仍是超级管理员。所属身份组勾选了可进管理后台的成员仍可进入管理后台。
- 现有密码继续有效。
- 如需为账号授予全部权限,执行
./pwikit admin grant -name "<name>";如需收回,执行./pwikit admin revoke -name "<name>"。见命令行。
回档
停止 pwikit。
将转储文件恢复到一个空数据库:
shdropdb -h <host> -U <user> <database> createdb -h <host> -U <user> <database> pg_restore -h <host> -U <user> -d <database> projwikit-before-pwikit.dump如果使用 Docker Compose 部署:
shdocker compose exec -T postgres dropdb -U admin projwikit docker compose exec -T postgres createdb -U admin projwikit docker compose exec -T postgres pg_restore -U admin -d projwikit < projwikit-before-pwikit.dump旧的
files/目录只用于复制,因此保持不变。启动旧版本。使用 Docker Compose 部署时,执行
docker compose up -d。
迁移后在 pwikit 中发生的所有更改,例如新建的页面、账号和上传的文件,都会丢失。
