Migrate repository Gitea to another Gitea server

Hello community,

OLD SERVER debian 11 gitea 1.19.4 → gitea 1.21.7 mariadb Ver 15.1 Distrib 10.5.19-MariaDB nginx
NEW SERVER debian 12 gitea 1.21.7 mariadb Ver 15.1 Distrib 10.11.6-MariaDB

My two systems communicate PING and SSH in both directions, and they are both self-hosted.

As part of a proof of concept I set up a Gitea server.
Due to availability issues, this POC had to be functional.

Today I was able to configure a new Gitea server.
I therefore want to transfer part of the deposits to the new server while maintaining the pull-request issues.

I see that in “new migration” the choice of gitea is available.
I made several attempts without success, I tried with or without access token, mirror, LFS…

For the token I created it using the web interface of the old server
profile → configuration → application
I put a name and check all the permissions

Here is my installation procedure:
So I use the migration tools
selection Gitea.
I put the URL of the repository that I want imported
I fill in with an access token that I created
I check the element labels tickets requests for addition, publication, milestone
I select the new owner
fill in the name of the repository
and press migrate

and I get the following message

You cannot import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings.

The configuration of the app.ini file is similar for both servers, I tried several configurations

; [migrations]
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; ; Max attempts per http/https request on migrations.
; MAX_ATTEMPTS = 3
; ;
; ; Backoff time per http/https request retry (seconds)
; RETRY_BACKOFF = 3
; ;
; ; Allowed domains for migrating, default is blank. Blank means everything will be allowed.
; ; Multiple domains could be separated by commas.
; ; Wildcard is supported: "github.com, *.github.com"
; ALLOWED_DOMAINS =
ALLOWED_DOMAINS = *.MY.DOMAIN*
; ;
; ; Blocklist for migrating, default is blank. Multiple domains could be separated by commas.
; ; When ALLOWED_DOMAINS is not blank, this option has a higher priority to deny domains.
; ; Wildcard is supported.
BLOCKED_DOMAINS =
; ;
; ; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default)
; ; If a domain is allowed by ALLOWED_DOMAINS, this option will be ignored.
; ALLOW_LOCALNETWORKS = false
ALLOW_LOCALNETWORKS = true

New server log

mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...eb/routing/logger.go:102:func1() [I] router: completed GET /user/events for MY_IP:PORT, 200 OK in 223873.0ms @ events/events.go:18(events.Events)
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...s/process/manager.go:231:remove() [T] Done 65f19cb2-2: GET: /user/events
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...s/process/manager.go:188:Add() [T] Start 65f19d92: POST: /repo/migrate (request)
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...eb/routing/logger.go:47:func1() [T] router: started   POST /repo/migrate for IP:63909
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...ices/auth/session.go:50:SessionUser() [T] Session Authorization: Found user[3]
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...ices/auth/session.go:66:SessionUser() [T] Session Authorization: Logged in user <User 3:MYUSER>
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 .../context_response.go:68:HTML() [D] Template: repo/migrate/gitea
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...eb/routing/logger.go:102:func1() [I] router: completed POST /repo/migrate for MY_IP:PORT, 200 OK in 18.2ms @ repo/migrate.go:151(repo.MigratePost)
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...s/process/manager.go:231:remove() [T] Done 65f19d92: POST: /repo/migrate
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...s/process/manager.go:188:Add() [T] Start 65f19d92-2: GET: /user/events (request)
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...eb/routing/logger.go:47:func1() [T] router: started   GET /user/events for IP:63909
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...ices/auth/session.go:50:SessionUser() [T] Session Authorization: Found user[3]
mars 13 13:35:30 NEW_SERVER gitea[62215]: 2024/03/13 13:35:30 ...ices/auth/session.go:66:SessionUser() [T] Session Authorization: Logged in user <User 3:MYUSER>
mars 13 13:35:34 NEW_SERVER gitea[62215]: 2024/03/13 13:35:34 ...eb/routing/logger.go:68:func1() [I] router: polling   GET /user/events for MY_IP:PORT, elapsed 3931.3ms @ events/events.go:18(events.Events)
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:188:Add() [T] Start 65f19d9f: Cron: Stop zombie tasks (normal)
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:188:Add() [T] Start 65f19d9f-2: Cron: Update Mirrors (normal)
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...ces/mirror/mirror.go:41:Update() [T] Doing: Update
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:188:Add() [T] Start 65f19d9f-3: Cron: Start schedule tasks (normal)
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:231:remove() [T] Done 65f19d9f: Cron: Stop zombie tasks
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...ces/mirror/mirror.go:118:Update() [T] Finished: Update: 0 pull mirrors and 0 push mirrors queued
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:231:remove() [T] Done 65f19d9f-2: Cron: Update Mirrors
mars 13 13:35:43 NEW_SERVER gitea[62215]: 2024/03/13 13:35:43 ...s/process/manager.go:231:remove() [T] Done 65f19d9f-3: Cron: Start schedule tasks

While searching on the net I came across solutions consisting of dumping the database and copying the directory /var/lib/gitea

if possible I would prefer to be able to migrate the repositories

1 Like

What if you clear ALLOWED_DOMAINS?

Hello
I tried with ALLOWED_DOMAINS comment and uncomment, with my domain, with *, and empty

BLOCKED_DOMAINS comment and uncommented

ALLOW_LOCALNETWORKS = false or true and comment and uncomment

I never succeeded.

I ended up making a backup of gitea and the database
and delete repositories to make room for backups

1 Like

Hello mlebon,

have you succeeded solving your problem, please?
I am facing the same issue - can’t migrate from a git host to the gitea server.

My settings are following:
[security]

ALLOWED_DOMAINS =
ALLOW_LOCALNETWORKS = true

Both, gitea and git hosts are in the same subnet.

Hello HappyFrog,

Unfortunately no, I did not find a solution for the migration.

In my case, I moved from one Gitea server to another.

So I made a backup of the database and directories.
After a database restore, and a configuration correction.

My new server was online.

I got the expected result, but it was long and tedious.

To come back to your problem, to be sure, you have a local git server instance (github, gitlab, kallithea, …) and you want to migrate to Gitea?
I have no solution to offer you, except a tedious method.

$ git clone old_repos
# after having previously created a new repository on Gitea
$ git add remote gitea new_repository
$ git push gitea --all
$ git push gitea --tags

RE,
i remembered that i got answers on the GitHub request Migrate repository Gitea to another Gitea server · Issue #29819 · go-gitea/gitea · GitHub

the answer given is this:

[migrations]
ALLOWED_DOMAINS = *
ALLOW_LOCALNETWORKS = true
SKIP_TLS_VERIFY = true
BLOCKED_DOMAINS =

ALLOWED_DOMAINS must be set

1 Like

Hi mlebon,

Thanks to your tip and the setup of git-daemon on the source Git server, I successfully managed to perform the migration directly from the Gitea web interface. :slight_smile:

1. Adding the section you mentioned to /etc/gitea/app.ini (the path to the configuration file may vary depending on the implementation or type of Gitea installation) on the Gitea server:

[migrations]
ALLOWED_DOMAINS =
ALLOW_LOCALNETWORKS = true
SKIP_TLS_VERIFY = true
BLOCKED_DOMAINS =

The only difference is that I left the ALLOWED_DOMAINS directive empty, as per the Gitea documentation. Now, some directives are duplicated in the [security] section of my Gitea config, but this doesn’t concern me at the moment. :slight_smile:

2. Install git-daemon on the original Git server.

The git-daemon enables the git:// protocol on your source git server.

The process was generated with the help of ChatGPT:
If Git is already installed on your server but you don’t have git-daemon, which allows repositories to be served over the git:// protocol, install git-daemon:

sudo apt update
sudo apt install git-daemon-run

3. Enabling chosen git repositories to be served with git-daemon

Now we’ll configure git-daemon to serve the repositories that you already have in the /var/git directory.

3.1. Ensure that the repositories have the correct permissions:

Ensure that the /var/git folder and all repositories inside it belong to the git user and group, so that git-daemon can access them.

sudo chown -R git:git /var/git

3.2. Allow access via the git:// protocol:

To make a repository accessible via git://, each migrated repository inside its folder (e.g., /var/git/repository-name.git) must contain the git-daemon-export-ok file (e.g., /var/git/repository-name.git/git-daemon-export-ok). This file indicates that the repository can be exported.

For each repository in /var/git that you want to make accessible, create this file:
cd /var/git/repository-name.git
sudo touch git-daemon-export-ok

For example, if you have a repository named repository-name.git, use:

cd /var/git/repository-name.git
sudo touch git-daemon-export-ok

I personally used this set of commands to set up all repositories:

bash
sudo -u git -s
cd /var/git
for i in ls; do [ -d “$i” ] && touch “$i/git-daemon-export-ok”; done
exit

4. Starting git-daemon temprorarily:

I decided to run git-daemon only temporarily because
a) it is an anonymous service and anyone can pull your repositories
b) this way seemed sufficient for the migration
c) running it permanently as a systemd service is considered unsafe as per a)

Start git-daemon with the appropriate parameters—this is a one-time run of the daemon, so it will stop when you close the terminal or press CTRL+C:

sudo git daemon --reuseaddr --base-path=/var/git/ --export-all --verbose --enable=receive-pack --port=9418

This command does the following:
--reuseaddr: Ensures that the socket can be reused when the daemon restarts.
--base-path=/var/git/: Sets /var/git/ as the root directory where repositories are searched for.
--export-all: Exports all repositories that have the git-daemon-export-ok file.
--verbose: Ensures that the daemon logs detailed information.
--enable=receive-pack: Allows receiving git push (this is optional if you only want read-only access) - perhaps this one is not necessary for migration purposes.
--port=9418: This is the port where Gitea expects the git:// protocol to run.

5. Once git-daemon is running…

Perform the migration from the Gitea web interface using the Migrate / Clone From URL: parameter with git://server.ip.or.known.hostname/repository-name.git.
Since git-daemon doesn’t support/require authorization, I left the username and password fields empty.
In the Git URL for the migration, I only entered the repository name (the repo name only including .git), as the rest of the path is set by the --base-path=/var/git/ above.

That’s it. Now, while git-daemon is running, I’m gradually migrating all repositories to the Gitea server.

After the migration is complete, be sure to exit git-daemon, otherwise the repositories will remain accessible to anyone.

P.S.: Even though I’m responding to the Gitea to Gitea migration topic and my post describes a Git to Gitea migration, I assume that with the right git-daemon setup, the procedure could work for a Gitea migration as well.

3 Likes