惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
O
OpenAI News
V
V2EX
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - Franky
Security Latest
Security Latest
S
SegmentFault 最新的问题
Project Zero
Project Zero
Spread Privacy
Spread Privacy
K
Kaspersky official blog
J
Java Code Geeks
V
Vulnerabilities – Threatpost
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
Scott Helme
Scott Helme
WordPress大学
WordPress大学
量子位
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Simon Willison's Weblog
Simon Willison's Weblog
S
Secure Thoughts
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
Visual Studio Blog
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
腾讯CDC
Cyberwarzone
Cyberwarzone
IT之家
IT之家
GbyAI
GbyAI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
D
Docker

豆沙工作室

停止 Mac 上的时间机器备份 评论里的私信消息 记得清理你的日志文件 招魂 Annihilation [11ty] 使用 Pagefind 实现静态站点的搜索 直面死亡 [11ty] 修复 RSS 里的数学公式 看到了一个神奇的 UA PreFound:10B - 四次击键 一点小小的 AI 震撼 PreFound:10A - 文本之外,还有(绘)文字 PreFound:09 - 色彩运算子 计算机不予申辩 Re-Game 2.0 Addendum C - Press START PreFound:08 - 动效与仿射 PreFound:07 - 图片拼贴报 PreFound:06 - 漫游雪花海 PreFound:05 - 写出到屏幕 And Trek I Will PreFound:04 - 举起渲染器 PreFound:03 - 跨越比特面 PreFound:02 - 启动编码器 PreFound:01 - 新建文件夹 PreFound:00 - 梦开始的地方 向着无穷远跑去 如何打包一个 Python 项目 只能作为光盘手册存在的书籍 航天飞机和马屁股的关系 Get an iPod 从鸿蒙系统中拉取蓝牙 HCI 日志 第二类擦除 迁移 FreshRSS 的数据库
从 Gitea 迁移到 Forgejo
dousha · 2026-07-05 · via 豆沙工作室

这次我们就没有 FreshRSS 那般的好运咯。

::more::

如果你已经在生产环境中使用 Gitea 而且这个 Gitea 实例不仅仅是你自己在用,那么不要尝试通过这个方式迁移你的环境:你会丢失所有的 Gitea Runner 秘钥信息、所有的软件包(比如私有 npm 包、私有容器镜像等)、所有的用户配置(比如头像、SSH 公钥、GPG 公钥等)、提交热力图和 Gitea 实例配置。

如果你确实需要迁移到不同的实例,那么请让用户在新的实例中重建他们的账户、将仓库迁移到新的实例,并重新配置 Runner, 并在一切都尘埃落定后再停止旧的实例!

由于最早的时候装 Gitea 时为了省事选了 SQLite 数据库,现在它也开始报 504 Gateway Timeout 了。解决方案自然是迁移到 PostgreSQL, 当然 Gitea 也是没法点两下鼠标就能更换数据库后端的。

简单翻了翻资料,这回是实打实的得重装整个实例才能切换数据库后端了。既然反正都要重装了,那……也许我们可以试试 Forgejo? 反正这玩意也就我一个人在用,迁移 Git 托管后端应该不是一件困难的事情。

简单起一组容器:

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:15
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - forgejo
    volumes:
      - forgejo:/data
      - /etc/localtime:/etc/localtime:ro
    depends_on:
      - postgres
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    ports:
      - 3000:3000
      - 222:22
  postgres:
    image: m.daocloud.io/docker.io/postgres:16-alpine
    restart: always
    container_name: forgejo_postgres
    shm_size: 128mb
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: forgejo
      POSTGRES_HOST_AUTH_METHOD: password
    networks:
      - forgejo
networks:
  forgejo:
    external: false
volumes:
  forgejo: null

安装时选择对应的数据库后端、按计划填好表即可。

接下来就到了愉快的迁移时间!作为程序员,面对这种简单的重复性劳动的第一反应当然是直接用脚本自动化——虽然也许手动戳一戳会快很多。

那么,先召唤两个服务的命令行工具:

yay -S tea forgejo-cli

首先在 Gitea 中创建一个最高权限的应用程序 Token, 留给之后迁移数据使用。我们也可以用这个 Token 从命令行中登录 Gitea:

tea login add

选择已有 Access token 并粘贴进去即可。

同样的,我们也要在 Forgejo 中创建一个最高权限的应用程序 Token.

相比起 tea, fj 就更为……传统一些。它对于参数的顺序是十分在意的,而且报错信息也相对而言比较隐晦。它需要你按照顺序指定 Forgejo 的实例位置,然后是命令,再然后是命令自己的各项参数;这中间不能随意换序。所以添加登录令牌就得是这么一个节奏:

fj -H http://forgejo.home.arpa auth add-key USERNAME_HERE forgejo-access-token

两边登录成功后就可以开始着手迁移了。设置好变量:

export GITEA_BASE_URL="https://gitea.home.arpa"
export FORGEJO_BASE_URL="http://USERNAME_HERE@forgejo.home.arpa"
export GITEA_ACCESS_TOKEN="access-token"

首先,创建所有的组织账号:

tea organizations ls --limit 99999 --page 1 |
tail -n +4 |
head -n -1 |
awk '{print $2}' |
xargs -L 1 fj -H ${FORGEJO_BASE_URL} org create

这个做法只创建了组织账号本身,组织账号剩下的属性,比如头像、描述等等东西如果仅通过 Shell 自带的能力非常容易搞炸,所以还是留给手动迁移或者正经的脚本吧。

然后仓库直接一把梭:

tea repos ls --limit 999999 --page 1 |
tail -n +4 |
head -n -1 |
awk "{print \"echo ${GITEA_ACCESS_TOKEN} | fj -H ${FORGEJO_BASE_URL} repo migrate -s gitea -t --include lfs,wiki,issues,prs,milestones,labels,releases ${GITEA_BASE_URL}\" $2 \"/\" $4 \" \" $2 \"/\" $4 }" |
xargs -I {} sh -c '{}'

这么做会有一个很头大的问题:有些仓库在迁移时会报 500 Internal Server Error, 直觉上是因为源站响应时间过长导致的。所以脚本跑完了之后,还得再比对一下哪些仓库没能正确迁移成功,滤出之后再跑一遍——或者也可以选择反复执行这个命令,已经存在的仓库会报 409 Conflict.

完成仓库迁移后,就可以修改 Nginx 反代配置将 Git 托管服务指向 Forgejo 了。之前给 Gitea 的写的反代配置可以直接拿来用,只替换 upstream 就可以。

接下来就是 Runner 的迁移。

Runner 迁移没有方便的脚本,只能一个个去登录服务器、下载 Runner 程序并重新注册 Runner.

如果你不太喜欢搞 Docker in Docker 的话,推荐使用 Forgejo Runner 的独立程序版。以及这玩意的 Runner 配置需要手动操作的东西有点多,所以用独立程序版会相对而言更好操作一些。参考如下脚本下载独立程序:

export ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
export RUNNER_VERSION=$(curl -X 'GET' https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | jq .name -r | cut -c 2-)
export FORGEJO_URL="https://code.forgejo.org/forgejo/runner/releases/download/v${RUNNER_VERSION}/forgejo-runner-${RUNNER_VERSION}-linux-${ARCH}"
wget -O forgejo-runner ${FORGEJO_URL}
chmod +x forgejo-runner

创建一个专门的应用程序用户:

sudo useradd --create-home forgejo
sudo usermod -aG docker forgejo
sudo cp forgejo-runner /home/forgejo/

只要不通过 passwd 指定这个用户的密码,那么它就无法远程登录。不过,我们可以 sudo 进去:

sudo -u forgejo -i
cd ~

生成一份配置文件:

./forgejo-runner generate-config > config.yml

Forgejo 的 Runner 支持各种容器环境;同样的,这也需要你指定需要使用的容器的运行环境以及每个标签对应使用什么镜像。如果需要使用 Docker, 那么需要修改配置文件中以下键值:

container:
  docker_host: "automount"

然后指定使用以下镜像:

runner:
  labels:
    - ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest
    - ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04
    - ubuntu-24.04:docker://ghcr.io/catthehacker/ubuntu:act-24.04

在 Forgejo 后台添加新的 Runner 后,后端会生成一段形如以下的配置文件片段:

server:
  connections:
    forgejo:
      url: https://forgejo.home.arpa/
      uuid: 1df4e318-9eda-4a2e-a6d7-8a905d2cc9f6
      token: aaaabbbbccccddddeeeeffff000011112222

我们只需要将它合并到对应 Runner 的配置文件中即可,不需要通过 forgejo-runner register 指令进行注册。

简单写一个 systemd 服务,使能即可:

[Unit]
Description=Forgejo Runner
After=network-online.target

[Service]
Type=simple
Restart=always
ExecStart=/home/forgejo/forgejo-runner -c /home/forgejo/config.yml daemon
User=forgejo
Group=forgejo
WorkingDirectory=/home/forgejo

[Install]
WantedBy=multi-user.target

也许该抽时间做一下性能剖析:我知道现在磁盘阵列的访问很慢,可是究竟有多慢?有没有优化的方法?