Bạn dừng Gitea, cài Forgejo, sao chép app.ini và thư mục dữ liệu, rồi khởi động dịch vụ theo đúng cách mọi hướng dẫn di chuyển mô tả. Giao diện web hiện lên. Rồi việc di chuyển database thất bại, hoặc tệ hơn, Forgejo từ chối khởi động vì phiên bản schema của bạn quá mới để nó hiểu được. Bạn đang dùng Gitea 1.23 trở lên, và bản nâng cấp tại chỗ đơn giản mà mọi tài liệu mô tả không còn áp dụng được cho bạn nữa.
Forgejo trở thành một hard fork của Gitea vào đầu năm 2024, và từ đó hai dự án đã phân kỳ ở cấp độ schema cơ sở dữ liệu. Cách bạn di chuyển từ Gitea sang Forgejo hiện phụ thuộc hoàn toàn vào phiên bản Gitea của bạn. Hướng dẫn này cung cấp lộ trình chính xác cho phiên bản của bạn, các lệnh đầy đủ cho cả cài đặt native và Docker, các cách khắc phục cho Gitea 1.23+, và một danh sách kiểm tra xác minh, để bạn di chuyển mà không mất repository, issue hay người dùng.
Tóm tắt nhanh
- Vách ngăn phiên bản là có thật. Forgejo v10.0 là bản phát hành cuối cùng hỗ trợ nâng cấp trực tiếp từ Gitea. Gitea v1.22 là phiên bản cao nhất có thể đi theo lộ trình trực tiếp được hỗ trợ.
- Trên Gitea v1.22 trở về trước: trước tiên di chuyển sang Forgejo v10.0.x, sau đó nâng cấp Forgejo v10 lên bản phát hành hiện tại (v15). Hai bước, cả hai đều được hỗ trợ.
- Trên Gitea v1.23 trở lên: không có hướng đi trực tiếp nào được hỗ trợ chính thức. Bạn chọn giữa hạ cấp SQL/schema, script di chuyển của cộng đồng, di chuyển qua repo/API, hoặc dàn dựng trên server mới bằng một trong các phương pháp đó. Mỗi cách đều mang một mức đánh đổi mất dữ liệu khác nhau.
- Sao lưu thư mục dữ liệu và cơ sở dữ liệu của bạn trước khi động vào bất cứ thứ gì. Mỗi lộ trình dưới đây đều giả định bạn có bản sao lưu có thể khôi phục được. Các lộ trình không được hỗ trợ giả định điều đó gấp đôi.
- Một số việc luôn cần được chú ý sau khi di chuyển: lên kế hoạch tạo lại hoặc kiểm tra Personal Access Tokens, đăng ký lại Actions runner, và xóa rồi xây dựng lại chỉ mục tìm kiếm Bleve. Hãy lên kế hoạch cho những việc này bất kể bạn chọn hướng đi nào.
- Di chuyển không phải là bắt buộc. Gitea vẫn đang được duy trì tích cực. Quyết định "ở lại với Gitea" là hợp lý nếu rủi ro di chuyển lớn hơn lợi ích đối với tình huống của bạn.
Nằm ngoài phạm vi bài này: di chuyển từ Gogs, GitHub hoặc GitLab sang Forgejo, và thiết lập Forgejo Actions từ đầu.
Điều kiện tiên quyết / Những gì bạn cần
Trước khi chạy bất kỳ lệnh nào, hãy xác nhận bạn có bản sao lưu đầy đủ, có thể khôi phục được của hai thứ: thư mục dữ liệu Gitea (/var/lib/gitea trên bản cài đặt native mặc định) và cơ sở dữ liệu của bạn. Nếu cơ sở dữ liệu là SQLite, tệp đó nằm trong thư mục dữ liệu; nếu là PostgreSQL hoặc MySQL, hãy dump riêng bằng pg_dump hoặc mysqldump. Một cuộc di chuyển không có bản sao lưu đã kiểm chứng không phải là di chuyển, đó là đánh cược.
Bạn cũng sẽ cần:
- Phiên bản Gitea hiện tại của bạn. Chạy
gitea --version(hoặcdocker exec <container> gitea --version. Con số này quyết định toàn bộ lộ trình của bạn. - Loại database của bạn: SQLite, PostgreSQL, hoặc MySQL. Một số giải pháp tình thế chỉ áp dụng cho một loại database cụ thể.
- Quyền root hoặc sudo trên server.
- Cần nhận thức rằng lộ trình được hỗ trợ cài đặt Forgejo v10.0 như một bước trung gian. Forgejo v10.0 đã EOL từ ngày 16 tháng 4 năm 2025. Bạn chỉ cài nó trong thời gian di chuyển và nâng cấp ra khỏi nó ngay lập tức.
Vì sao hướng đi nâng cấp trực tiếp bị hỏng
Vào tháng 12 năm 2024, dự án Forgejo đã công bố một tuyên bố tương thích đã vạch ra một ranh giới rõ ràng: "Các phiên bản Forgejo trong tương lai sẽ không hỗ trợ nâng cấp từ các instance Gitea đang chạy phiên bản v1.23 trở lên." Câu đó chính là toàn bộ vấn đề gói gọn trong một dòng.
Khi Forgejo tách nhánh từ Gitea đầu năm 2024, hai codebase tiếp tục phân kỳ, và các database schema dần khác biệt nhau. Forgejo duy trì một khoảng thời gian tương thích để các nhà vận hành Gitea hiện tại có thể chuyển sang, nhưng khoảng thời gian đó có điểm kết thúc. Forgejo v10.0, phát hành ngày 16 tháng 1 năm 2025, là "the last version to allow a transparent upgrade from Gitea v1.22 or lower." Bất kỳ phiên bản nào mới hơn v10.0 sẽ không đọc trực tiếp được cơ sở dữ liệu Gitea.
Chính vấn đề thời điểm mới là điều khiến nhiều người bất ngờ. Gitea v1.23 phát hành cuối năm 2024, và bản phát hành Gitea hiện tại tính đến tháng 6 năm 2026 là v1.26.4. Nếu bạn giữ instance Gitea của mình tương đối cập nhật, bạn đã vượt qua ngưỡng này và các hướng dẫn tiêu chuẩn không còn mô tả đúng tình huống của bạn.
Điểm chính của phần này: hướng đi trực tiếp được hỗ trợ chỉ dừng ở Gitea v1.22. Mọi phiên bản mới hơn đều cần thêm một bước.
Tìm lộ trình di chuyển của bạn theo phiên bản Gitea
Chạy gitea --version, tìm hàng của bạn, và làm theo lộ trình ở cột thứ ba. Phần còn lại của hướng dẫn này là chi tiết đằng sau các hàng đó.
| Phiên bản Gitea | Đích Forgejo được hỗ trợ (trực tiếp) | Lộ trình di chuyển |
|---|---|---|
| ≤ 1.21 | Forgejo v7.0 - v10.0 | Chuyển sang Forgejo v10.0.x, sau đó nâng cấp lên phiên bản hiện tại (v15) |
| 1.22 | Forgejo v8.0 - v10.0 | Chuyển sang Forgejo v10.0.x, sau đó nâng cấp lên phiên bản hiện tại (v15) |
| 1.23 | Không có (không được hỗ trợ) | Vá phiên bản SQL (Phương án A), sau đó theo hướng đi được hỗ trợ chính thức |
| 1.24 - 1.25.2 | Không có (không được hỗ trợ) | Các script hạ cấp SQL tuần tự (Phương án B), sau đó theo hướng đi được hỗ trợ chính thức |
| 1.26+ | Không có (không được hỗ trợ) | Script thử nghiệm hoặc di chuyển API từng repo một (Phương án C) |
Các tuyên bố về tương thích phiên bản đến trực tiếp từ thông báo tương thích chính thức của Forgejo: Gitea đến v1.21 có thể chuyển sang Forgejo v7.0 đến v10.0, và Gitea v1.22 có thể chuyển sang Forgejo v8.0 đến v10.0. Cả hai đều dừng ở v10.0 như đích đến trực tiếp được hỗ trợ cuối cùng.
Đằng sau câu hỏi về phiên bản là ba chiến lược di chuyển, và sẽ hữu ích nếu bạn nắm được chúng trước khi đi vào từng bước cụ thể:
- Tại chỗ, cùng một máy chủ. Thay thế file nhị phân hoặc image container trên máy hiện có. Đây là cách tốn ít công sức nhất khi phiên bản của bạn hỗ trợ; yêu cầu bước trung gian qua v10.0.
- Dàn dựng trên máy chủ mới. Cấp một server mới và dùng nó làm đích an toàn cho phương pháp di chuyển phù hợp với phiên bản Gitea của bạn. Cách này bảo vệ máy chủ Gitea gốc và giúp việc quay lui dễ dàng hơn, nhưng không giúp bạn tránh được vấn đề database-schema của Gitea 1.23+.
- Di chuyển qua Repo/API. Dùng công cụ di chuyển của Forgejo để kéo repository từ instance Gitea cũ về. Lịch sử Git là phần đáng tin cậy nhất; các siêu dữ liệu như issue, PR, nhãn, bản phát hành, dữ liệu wiki, và bình luận nên được coi là nỗ lực tối đa và cần kiểm tra lại từng repo một.

Hướng đi được hỗ trợ: Gitea v1.22 trở về trước
Nếu bạn đang dùng Gitea v1.22 trở về trước, tài liệu di chuyển chính thức mô tả một hướng đi hai bước: di chuyển sang Forgejo v10.0.x, sau đó nâng cấp Forgejo v10 lên bản phát hành hiện tại. Bước đầu tiên là một thao tác thay thế trực tiếp vì Forgejo v10.x đọc được database của Gitea v1.22; bước thứ hai là một lần nâng cấp Forgejo bình thường.
Có hai cách để làm việc này tùy vào cách Gitea đang chạy trên server của bạn. Hãy chọn cách phù hợp với thiết lập hiện tại. Nếu Gitea chạy dưới dạng system service, hãy dùng hướng đi native. Nếu Gitea chạy trong container, hãy dùng hướng đi Docker. Forgejo v10.x đóng vai trò thay thế trực tiếp cho Gitea v1.22.x.
Lộ trình Native (systemd)
Sao lưu trước tiên. Sau đó cài Forgejo v10.0.x bằng gói của bản phân phối hoặc binary release được ghim ở v10.0. Dừng Gitea trước khi sao chép bất cứ thứ gì. Một dịch vụ đang chạy và ghi vào thư mục dữ liệu giữa lúc sao chép sẽ làm hỏng bản sao.
# Stop the running Gitea service before touching its data
systemctl stop gitea
Sao chép cấu hình và thư mục dữ liệu vào các vị trí của Forgejo, sau đó sửa quyền sở hữu. Tệp cấu hình phải cho phép nhóm forgejo đọc; dữ liệu phải thuộc quyền sở hữu của người dùng forgejo.
# Copy the existing Gitea config to Forgejo's config path
cp /etc/gitea/app.ini /etc/forgejo/app.ini
# Back up the copied config before rewriting paths
cp /etc/forgejo/app.ini /etc/forgejo/app.ini.bak
# Update old Gitea data paths to Forgejo data paths
sed -i 's#/var/lib/gitea#/var/lib/forgejo#g' /etc/forgejo/app.ini
# Forgejo reads its config as the forgejo group; grant group write
chown root:forgejo /etc/forgejo/app.ini && chmod g+w /etc/forgejo/app.ini
# Copy the data directory and hand ownership to the forgejo user
rsync -aHAX --numeric-ids /var/lib/gitea/ /var/lib/forgejo/
chown -R forgejo:forgejo /var/lib/forgejo
Khởi động Forgejo và bật chế độ tự chạy khi khởi động máy.
# Start Forgejo and enable it at boot
systemctl start forgejo && systemctl enable forgejo
Trước khi nâng cấp khỏi v10.0, hãy đẩy sạch các hàng đợi để không mất công việc đang xử lý dở trong lúc nhảy phiên bản.
# Flush pending queue items before the version upgrade
forgejo manager flush-queues
Bây giờ hãy nâng cấp Forgejo v10.0.x lên bản phát hành hiện tại bằng cách thay thế binary bằng v15 và khởi động lại dịch vụ, theo Hướng dẫn nâng cấp Forgejo. Sau cả hai bước chuyển tiếp, chạy doctor để kiểm tra cơ sở dữ liệu và sửa những gì có thể.
# Check everything; write a log you can read if something is wrong
forgejo doctor check --all --log-file /tmp/doctor.log
Đọc /tmp/doctor.log trước khi áp dụng bất kỳ bản sửa tự động nào. Dùng --fix chỉ khi kết quả của lệnh doctor chỉ ra một sửa chữa cụ thể mà bạn hiểu rõ, hoặc khi bạn đang làm theo một hướng xử lý sự cố chính thức.
Nếu doctor không báo lỗi nghiêm trọng nào và giao diện web liệt kê đầy đủ repository của bạn, bước di chuyển đầu tiên đã hoàn tất.
Lộ trình Docker / Container
Nếu Gitea chạy dưới dạng container, hãy chạy Forgejo theo cùng cách. Sử dụng image Forgejo v10.x để thay thế trực tiếp cho image Gitea v1.22.x của bạn, trỏ nó vào cùng volume dữ liệu và cơ sở dữ liệu. Trước tiên hãy xác nhận phiên bản Docker của bạn ít nhất là 20.10.6. Các phiên bản cũ hơn tạo ra hành vi không xác định với container Forgejo.
Một chi tiết riêng cho container hay khiến người dùng vấp phải: biến môi trường. Forgejo vẫn giữ tiền tố GITEA_ để tương thích ngược, nhưng tài liệu khuyến nghị truyền cả hai tiền tố để cấu hình của bạn không bị ảnh hưởng khi một phiên bản Forgejo tương lai loại bỏ tên cũ.
# docker-compose.yml (excerpt): pass both prefixes for forward compatibility
environment:
- GITEA__database__DB_TYPE=postgres
- FORGEJO__database__DB_TYPE=postgres
# ...repeat the dual-prefix pattern for every config override you pass
Với container rootless, dữ liệu phải thuộc quyền sở hữu của user 1000 và group 1000, khớp với người dùng runtime của image rootless. Sau khi container khởi động trên v10.x, chạy lại forgejo doctor check --all từ bên trong container, sau đó nâng cấp tag image lên bản phát hành v15 hiện tại và khởi động lại.
Nếu bạn đang dùng Gitea v1.23 trở lên

Đây là nơi các hướng dẫn tiêu chuẩn dừng lại, và cũng là nơi phần lớn các bản cài hiện tại đang đứng. Không có hướng đi trực tiếp nào được hỗ trợ chính thức từ Gitea v1.23+, nên mọi phương án dưới đây đều hoặc do cộng đồng cung cấp hoặc gây mất dữ liệu. Trước khi chạy bất kỳ phương án nào, hãy sao lưu toàn bộ thư mục dữ liệu và database, và xác nhận bạn có thể khôi phục được. Các cách này sẽ thay đổi dữ liệu production; bản sao lưu là cách duy nhất để bạn hoàn tác.
Ba phương án khác nhau về mức độ rủi ro và lượng dữ liệu giữ lại được. Hãy chọn phương án có sự đánh đổi mà bạn chấp nhận được.
Phương án A: Hạ cấp SQL Schema / Vá phiên bản
Giải pháp tình thế hẹp nhất là hạ cấp phiên bản database schema để Forgejo v10 coi nó như một database v1.22.
Lưu ý: Đừng coi việc cập nhật phiên bản tự nó là một lần hạ cấp hoàn chỉnh. Phiên bản di chuyển được ghi nhận và schema thực tế phải khớp nhau. Trên Gitea 1.23.x, hãy kiểm tra việc hạ cấp toàn bộ trên một bản sao trước, và so sánh schema trước khi trỏ Forgejo vào đó.
Một maintainer của Forgejo đã mô tả đoạn SQL trong Codeberg issue #7638:
-- Downgrade the recorded schema version to the v1.22 baseline (PostgreSQL/MySQL)
UPDATE version SET version=305 WHERE id=1;
Sau bước này, bạn làm theo lộ trình được hỗ trợ như thể đang ở v1.22. Lưu ý quan trọng: maintainer chỉ xác nhận điều này cho riêng Gitea v1.23.1, không phải toàn bộ v1.23.x. Số phiên bản schema phải chính xác; áp dụng sai giá trị đích cho sai phiên bản Gitea có thể khiến cơ sở dữ liệu rơi vào trạng thái không thể khôi phục bằng bất kỳ cách di chuyển nào. Đây là PostgreSQL/MySQL, nó không được hỗ trợ chính thức và không được kiểm thử như một quy trình chung.
Mẹo nhỏ: đặt trực tiếp version=305 sẽ bỏ qua bước di chuyển 304 sang 305, vốn đã thay đổi cách mã hóa TOTP secrets. Codeberg issue #8210 ghi nhận rằng điều này làm hỏng xác thực hai yếu tố đối với những người dùng bị ảnh hưởng. Cách khắc phục là đặt version về 304, để quá trình di chuyển chạy, hoặc xóa các dòng trong bảng two_factor để người dùng đăng ký lại. Đừng bỏ qua bước này nếu có bất kỳ tài khoản nào dùng TOTP.
Phương án B: Các script hạ cấp SQL tuần tự (Gitea 1.24-1.25.2)
Đối với các phiên bản từ 1.24 đến 1.25.2, một bản vá phiên bản đơn lẻ là chưa đủ: schema đã trải qua nhiều trạng thái trung gian. Các script cộng đồng tại xlrl/prepare-gitea-migration-to-forgejo đưa schema lùi dần qua các phiên bản trung gian về v1.22, sau đó bạn đi theo hướng được hỗ trợ chính thức. Các script này là công sức của cộng đồng, không phải một quy trình chính thống, và chúng nhắm chủ yếu vào SQLite. Chỉ chạy chúng trên một database mà bạn đã sao lưu từ trước.
Phương án C: Di chuyển qua API từng repo một (Gitea 1.26+ hoặc bất kỳ phiên bản nào)
Hướng đi qua repo/API giữ lại dữ liệu Git một cách đáng tin cậy nhất. Tùy vào nguồn, quyền truy cập, và phương pháp di chuyển, các siêu dữ liệu tùy chọn như issue, pull request, nhãn, milestone, bản phát hành, dữ liệu wiki, và bình luận cũng có thể được chuyển theo, nhưng hãy coi đó là nỗ lực tối đa chứ không đảm bảo, và kiểm tra lại từng repo một. Với một kho lưu trữ chỉ chứa code, cách này thường ổn; còn với một server mà issue tracker chính là bộ nhớ của cả nhóm, hãy kiểm thử việc chuyển siêu dữ liệu trước khi quyết định theo hướng này.
Hai công cụ thử nghiệm cố gắng di chuyển đầy đủ hơn cho phiên bản 1.23+ nhưng mỗi công cụ đều có những khoảng trống riêng. pacnpal/gitea2forgejo (GitHub) thực hiện dump toàn bộ dữ liệu cộng với đồng bộ API và yêu cầu SECRET_KEY khớp nhau để chuyển các trường đã mã hóa, nhưng nó không di chuyển Personal Access Tokens, Actions runners, webhook callback URLs, hoặc 2FA. nicoverbruggen/gitea-to-forgejo (GitHub) là một công cụ thử nghiệm dựa trên Podman, chuyển người dùng, khóa, tổ chức, repo, issue, PR, release và mirror, nhưng không chuyển 2FA tokens, dữ liệu runtime của Actions, hoặc các OCI package manifest bị treo. Hãy coi cả hai là thử nghiệm và kiểm tra kết quả theo bảng ma trận chuyển đổi bên dưới.
Điểm chính của phần này: không có hướng đi trực tiếp nào được hỗ trợ chính thức từ Gitea 1.23+. Hãy chọn phương án có mức đánh đổi mất dữ liệu mà bạn chấp nhận được, và sao lưu trước khi bắt đầu.
Di chuyển trên một máy chủ mới an toàn hơn, nhưng không bỏ qua được ngưỡng phiên bản
Một máy chủ mới là nơi an toàn nhất để dàn dựng và kiểm tra việc di chuyển, nhưng đó không phải là một lộ trình tương thích schema riêng biệt. Nếu nguồn của bạn là Gitea v1.22 trở về trước, hãy cài Forgejo v10.0.x trên máy đích trước, khôi phục hoặc sao chép dữ liệu Gitea vào đó, để Forgejo chạy các bước di chuyển cơ sở dữ liệu được hỗ trợ, sau đó nâng cấp instance Forgejo v10 đó lên phiên bản Forgejo hiện tại.
Nếu nguồn của bạn là Gitea v1.23 trở lên, đừng khôi phục cơ sở dữ liệu Gitea trực tiếp vào Forgejo hiện tại và mong nó chạy được. Bạn vẫn cần một trong các phương án 1.23+ không được hỗ trợ ở trên: hạ cấp hoặc revert SQL theo từng giai đoạn, một công cụ di chuyển cộng đồng, hoặc di chuyển qua repo/API. Máy chủ mới giúp giảm rủi ro rollback vì máy Gitea gốc vẫn không bị đụng đến; nhưng nó không loại bỏ nhu cầu xử lý sự không khớp phiên bản cơ sở dữ liệu.
Đây là lúc Forgejo một chạm của Cloudzy app có thể giúp ích: dùng nó làm instance đích sạch, sau đó chạy phương pháp di chuyển phù hợp với phiên bản Gitea của bạn. Image marketplace của Cloudzy mang đến cho bạn một đích Forgejo sẵn sàng trên VPS hiệu năng cao, để bạn có thể tập trung vào các bước khôi phục, kiểm tra và chuyển đổi thay vì cài đặt ban đầu. Kế hoạch di chuyển vẫn phụ thuộc vào việc bạn đang ở trước hay sau ngưỡng Gitea 1.22.
Cái gì chuyển được và cái gì bạn phải làm lại

Một phần dữ liệu của bạn sẽ tự động chuyển, một phần chỉ chuyển khi thỏa một điều kiện nào đó, và một phần không bao giờ chuyển mà phải tạo lại thủ công. Biết rõ phần nào thuộc loại nào trước khi bắt đầu chính là ranh giới giữa một lần chuyển đổi suôn sẻ và một tuần người dùng bối rối.
| Mục | Có chuyển được không? | Điều kiện |
|---|---|---|
| Tài khoản người dùng + mật khẩu | Có | Tự động |
| Khóa công khai SSH của người dùng | Có | Tự động |
| SSH host key (định danh server) | Không (thủ công) | Sao chép /etc/ssh/ssh_host_* nếu không mọi client sẽ gặp lỗi host-key không khớp |
| Repository + lịch sử git | Có | Bằng cách sao chép thư mục dữ liệu |
| Issue, PR, nhãn, milestone, bình luận | Có | Bằng cách thao tác trên database |
| Đối tượng LFS | Có | Kiểm tra số lượng object và tổng dung lượng khớp nhau |
| Webhook (cấu hình) | Có | Lịch sử gửi không được di chuyển |
| Bí mật CI/CD | Có điều kiện | Chỉ khi SECRET_KEY khớp; nếu không sẽ không đọc được mà không có cảnh báo nào |
| Ứng dụng OAuth | Có điều kiện | Chỉ khi SECRET_KEY khớp nhau; các callback URL có thể cần cập nhật |
| 2FA (TOTP seeds) | Có điều kiện | Chỉ khi SECRET_KEY khớp nhau |
| Personal Access Tokens | Lên kế hoạch tạo lại / kiểm tra | Thực hành an toàn nhất sau khi di chuyển; kiểm tra trước khi dựa vào token cũ |
| Đăng ký Actions runner | Không (phải đăng ký lại) | Token đăng ký được giới hạn theo hostname |
| Lịch sử chạy / log của Actions | No | Không được di chuyển bởi bất kỳ lộ trình nào |
| Chỉ mục tìm kiếm Bleve | Không (xóa và tạo lại) | Xóa /var/lib/gitea/data/indexers/ và để nó tự tạo lại |
| Thương hiệu tùy chỉnh / template | Có (file) | public/assets/img/ giờ đây phải nằm trong custom/ |
| Deploy key theo từng repo | Không (thêm lại thủ công) | Không được di chuyển bởi bất kỳ lộ trình nào |
Bốn mục bị ảnh hưởng nặng nhất vì chúng hỏng âm thầm hoặc tác động đến mọi người dùng, nên hãy xử lý một cách cẩn thận: người dùng nên tạo lại hoặc rà soát Personal Access Tokens của họ, bạn phải đăng ký lại các Actions runner với hostname mới, bạn phải xóa chỉ mục tìm kiếm Bleve để Forgejo tạo lại nó sạch sẽ, và bạn phải viết lại bất kỳ uses: các tham chiếu rút gọn trong workflow Actions của bạn sang URL GitHub đầy đủ, vì Forgejo và Gitea kéo action từ các mirror riêng biệt và một tham chiếu tương đối sẽ trỏ sai chỗ.
Mẹo nhỏ: nếu bạn chạy Gitea và Forgejo song song trong quá trình di chuyển và cả hai đều trỏ đến cùng một Redis instance, hãy đổi Forgejo sang Redis db=1 trước khi bắt đầu. Cả hai mặc định dùng db=0, và nếu dùng chung, Gitea sẽ tiêu thụ các sự kiện di chuyển của Forgejo và phá hỏng hàng đợi di chuyển. (blog.mei-home.net documents this exact failure.)
Điểm chính của phần này: Personal Access Tokens, Actions runner, deploy key theo từng repo, và chỉ mục tìm kiếm Bleve luôn phải xử lý thủ công. Hãy đưa chúng vào kế hoạch di chuyển, đừng để đến sau mới nghĩ tới.
Kiểm tra việc di chuyển đã thành công
Bắt đầu với lệnh doctor, sau đó kiểm tra các con số, rồi kiểm thử những gì người dùng thực sự làm. Lệnh doctor bắt được các vấn đề ở cấp database; kiểm tra thủ công bắt được các vấn đề mất dữ liệu và quyền truy cập mà doctor không thấy được.
- Chạy
forgejo doctor check --all --log-file /tmp/doctor.log, sau đó đọc log trước khi thực hiện thay đổi. Sử dụng--fixchỉ dành cho một sửa chữa cụ thể mà bạn hiểu rõ. - Xác nhận số lượng repository, số lượng issue và PR, số lượng đối tượng LFS cùng tổng dung lượng đều khớp với các con số trước khi di chuyển. Nếu có sai lệch ở đây nghĩa là có gì đó chưa được chuyển sang.
- Kiểm thử push và pull qua SSH. Nếu client báo lỗi host-key không khớp, tức là bạn chưa sao chép /etc/ssh/ssh_host_* sang server mới.
- Đăng nhập và xác nhận 2FA hoạt động đối với một tài khoản có sử dụng nó. Nếu TOTP bị hỏng, xem lưu ý ở Phương án A phía trên.
- Tạo lại Personal Access Tokens, đăng ký lại Actions runner, và chạy thử một workflow.
Một vài triệu chứng sau khi di chuyển có nguyên nhân đã biết. Thiếu favicon hoặc logo nghĩa là tài nguyên thương hiệu của bạn vẫn nằm trong public/assets/img/ thay vì custom/, nơi Forgejo hiện mong đợi chúng. Lỗi 404 trên các route package cho thấy đường dẫn lưu trữ bị cấu hình sai. Actions báo lỗi "repository not found" là uses: vấn đề mirror. Hãy chuyển sang dùng URL đầy đủ. Trang trắng hoặc lỗi 500 sau khi đăng nhập trên database SQLite nghĩa là bạn đang dưới mức tối thiểu, điều mà tài liệu nâng cấp đặt ở mức Forgejo v1.19.3-0.
Khi nào thì nên ở lại với Gitea
Di chuyển là một lựa chọn, không phải nghĩa vụ. Nếu bạn đã vượt qua ngưỡng và độ phức tạp của việc di chuyển vượt quá lợi ích về quản trị hay tính năng đối với tình huống của bạn, ở lại với Gitea là một lựa chọn chính đáng. Gitea vẫn đang được duy trì tích cực (nhiều bản phát hành mỗi tháng, hiện tại ở v1.26.4), và CommitGo cung cấp các tùy chọn thương mại bao gồm Gitea Enterprise, Gitea Cloud, và chứng nhận SOC 2 Type 2 cho các nhóm cần đến chúng.
Cũng cần cân nhắc thẳng thắn về mối lo phiên bản trung gian đã EOL. Hướng đi trực tiếp được hỗ trợ yêu cầu cài đặt tạm thời Forgejo v10.0, phiên bản đã EOL từ tháng 4 năm 2025. Điều này chấp nhận được như một bước di chuyển tạm thời mà bạn nâng cấp thoát ra ngay sau đó, nhưng một số nhà vận hành sẽ phản đối vì lý do chính sách. Với họ, di chuyển qua repo/API vào một instance Forgejo mới hoàn toàn có thể tránh được bước trung gian EOL này, trong khi việc dàn dựng trên server mới vẫn phụ thuộc vào phương pháp di chuyển bạn chọn.
Nếu lý do bạn chuyển đổi là hoạt động phát triển, dữ liệu cho thấy Forgejo là dự án năng động hơn: một phân tích bởi honeypot.net đếm được 3.039 commit Forgejo so với 1.228 commit Gitea trong giai đoạn tháng 7 năm 2024 đến tháng 5 năm 2025, và 232 contributor của Forgejo so với 153 của Gitea trong năm tính đến tháng 5 năm 2025. Đó là một tín hiệu trong số nhiều tín hiệu khác; hãy cân nhắc nó cùng với rủi ro di chuyển của bạn thay vì coi đó là yếu tố quyết định.
Điểm chính của phần này: di chuyển không phải là bắt buộc. Quyết định này là sự cân nhắc giữa sở thích về quản trị và mức độ hoạt động với rủi ro di chuyển, và cả hai lựa chọn đều có lý riêng.
Chọn hướng đi của bạn và sao lưu trước
Hướng đi di chuyển của bạn quy về một con số duy nhất: phiên bản Gitea của bạn. Với v1.22 trở về trước, bạn đi theo hướng hai bước được hỗ trợ chính thức qua Forgejo v10. Với v1.23 trở lên, bạn chọn một giải pháp tình thế dựa trên mức mất dữ liệu bạn chấp nhận được: hạ cấp SQL/schema, script cộng đồng, di chuyển qua repo/API, hoặc dàn dựng trên server mới. Dù chọn hướng nào, hãy sao lưu thư mục dữ liệu và database trước, chạy forgejo doctor sau đó, và xác nhận số lượng repository, issue, và LFS khớp với số liệu ban đầu của bạn.
Xác định phiên bản của bạn, lấy bản sao lưu, và làm theo hàng tương ứng. Lộ trình phức tạp hơn những gì các hướng dẫn cũ hứa hẹn, nhưng nó được xác định rõ ràng một khi bạn biết mình đang đứng ở đâu trên ngưỡng phiên bản.
Câu hỏi thường gặp
Tôi có thể nâng cấp trực tiếp từ Gitea sang Forgejo không?
Có, nếu bạn đang chạy Gitea v1.22 trở về trước: nâng cấp trực tiếp lên Forgejo v10.0, sau đó nâng cấp Forgejo v10 lên bản phát hành hiện tại. Không, nếu bạn đang chạy Gitea v1.23 trở lên. Forgejo v10.0 là bản phát hành cuối cùng hỗ trợ nâng cấp trực tiếp minh bạch, nên các phiên bản Gitea mới hơn cần một giải pháp tình thế khác.
Phiên bản Gitea nào tương thích với Forgejo?
Gitea v1.22 trở về trước có lộ trình nâng cấp trực tiếp được hỗ trợ sang Forgejo (đến Forgejo v10.0, sau đó tiếp tục lên phiên bản hiện tại). Gitea v1.23 trở lên không có lộ trình trực tiếp được hỗ trợ chính thức, vì Forgejo đã ngừng hỗ trợ nâng cấp trực tiếp từ Gitea v1.23+ kể từ các bản phát hành sau v10.0.
Tôi có thể di chuyển từ Gitea 1.26 sang Forgejo không?
Có, nhưng không qua nâng cấp trực tiếp được hỗ trợ. Các lựa chọn của bạn là di chuyển qua repo/API, trong đó lịch sử Git là phần đáng tin cậy còn siêu dữ liệu phải kiểm tra từng repo một, một script di chuyển thử nghiệm, hoặc dàn dựng trên server mới bằng một trong các phương pháp không được hỗ trợ cho 1.23+ nêu trên. Không có hướng đi tại chỗ nào được hỗ trợ chính thức từ Gitea 1.26.
Personal Access Tokens của tôi có được chuyển sang không?
Lên kế hoạch tạo lại hoặc xoay vòng Personal Access Tokens sau khi di chuyển. Một số phương án di chuyển không giữ lại chúng, và ngay cả khi token vẫn còn, người dùng nên kiểm tra lại phạm vi quyền trước khi sử dụng lại. Mọi script hoặc tích hợp dùng token cũ cần được kiểm thử và cập nhật sau khi chuyển đổi.
Các workflow Gitea Actions của tôi có hoạt động trong Forgejo không?
Phần lớn là có, với hai điều chỉnh bắt buộc. Workflow uses: các tham chiếu rút gọn sẽ hỏng vì Forgejo và Gitea kéo action từ các mirror riêng biệt. Hãy chuyển chúng sang URL GitHub đầy đủ (ví dụ, uses: https://github.com/sammcj/dotenv-output-action@main. Bạn cũng phải đăng ký lại các Actions runner, vì token đăng ký của chúng gắn với hostname cũ.
Còn việc di chuyển từ Gogs sang Forgejo thì sao?
Đó là một quá trình di chuyển khác với hướng đi khác và nằm ngoài phạm vi bài này. Bài viết này chỉ nói riêng về việc chuyển từ Gitea sang Forgejo; nếu nguồn của bạn là Gogs, hãy tham khảo tài liệu di chuyển chính thức của Forgejo dành riêng cho Gogs.