Domestic mirrors for Fedora: dnf, pip, npm, Maven, Cargo, containers and Flatpak
The first thing to fix on a Fedora install in mainland China is the mirror. But F45 changed something that invalidates every older guide: the repository configuration files moved. That comes first, then the copy-paste setup.
Where the repository files live now
Section titled “Where the repository files live now”ls /usr/share/dnf5/repos.d/fedora.repo fedora-cisco-openh264.repo fedora-updates.repo ...Up to F44 they were in /etc/yum.repos.d/; F45 moved them to /usr/share/dnf5/repos.d/ (see repository configuration moves to /usr).
So:
| What you want | Where to edit |
|---|---|
| change an official repository URL | /usr/share/dnf5/repos.d/*.repo (overwritten on upgrade) |
| add your own repository | /etc/yum.repos.d/*.repo (higher priority, never overwritten) |
Prefer the second: create a file in /etc/yum.repos.d/ and disable the original with enabled=0.
Official mirrors: does yours have f45
Section titled “Official mirrors: does yours have f45”Fedora 45 is not released yet, so mirrors disagree. Measured 2026-10-28:
| Site | releases/45/ | releases/test/45_Beta/ |
|---|---|---|
| Aliyun | 404 | 200 |
| Tsinghua TUNA | 404 | 404 |
| USTC | 404 | 404 |
Only Aliyun carries the F45 Beta repository right now. After GA, releases/45/ appears everywhere and you switch the path.
Configuration:
sudo tee /etc/yum.repos.d/99-lab-cn.repo >/dev/null <<'EOF'[lab-cn-base]name=Aliyun Fedora 45 Beta (base)baseurl=https://mirrors.aliyun.com/fedora/releases/test/45_Beta/Everything/x86_64/os/enabled=1gpgcheck=0skip_if_unavailable=TrueEOFDisable the original metalink repositories (they cannot find fedora-45 and will error out):
sudo dnf config-manager setopt fedora.enabled=0 updates.enabled=0sudo dnf makecacheVerify:
dnf list --available nodejs | tail -2nodejs.x86_64 1:22.23.1-4.fc45 lab-cn-base
Third-party repositories: who supports f45
Section titled “Third-party repositories: who supports f45”| Repository | f45 status | Note |
|---|---|---|
| Remi | supported (base repo only) | https://mirrors.aliyun.com/remi/fedora/45/remi/x86_64/ works, but there is no remi-php83/84 versioned repository under f45 — it ships extensions and updates only |
| RPM Fusion | not yet | releases/45/ returns 404, 44 works. NVIDIA drivers and multimedia codecs have to wait |
Remi configuration:
sudo tee /etc/yum.repos.d/remi-cn.repo >/dev/null <<'EOF'[remi-cn]name=Remi's RPM repository (Aliyun)baseurl=https://mirrors.aliyun.com/remi/fedora/45/remi/x86_64/enabled=0gpgcheck=0EOFsudo dnf --enablerepo=remi-cn makecacheenabled=0 is deliberate: Remi replaces a large number of system packages, so enable it per-command with --enablerepo=remi-cn.
mkdir -p ~/.config/pipcat > ~/.config/pip/pip.conf <<'EOF'[global]index-url = https://pypi.tuna.tsinghua.edu.cn/simpletrusted-host = pypi.tuna.tsinghua.edu.cnEOFNote that this is not always faster; see the measurements below.
npm config set registry https://registry.npmmirror.comnpm config get registryhttps://registry.npmmirror.comRevert with npm config set registry https://registry.npmjs.org.
mkdir -p ~/.m2cat > ~/.m2/settings.xml <<'EOF'<settings> <mirrors> <mirror> <id>aliyun</id> <name>Aliyun Maven</name> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors></settings>Gradle takes an init script instead:
mkdir -p ~/.gradlecat > ~/.gradle/init.gradle <<'EOF'allprojects { repositories { maven { url 'https://maven.aliyun.com/repository/public' } }}EOFCargo / rustup
Section titled “Cargo / rustup”cat > ~/.cargo/config.toml <<'EOF'[source.crates-io]replace-with = 'tuna'
[source.tuna]registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"EOFrustup has its own switch:
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustupexport RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustupContainer images
Section titled “Container images”Podman pulls from Docker Hub by default, which frequently times out here. Drop a file into /etc/containers/registries.conf.d/:
sudo tee /etc/containers/registries.conf.d/99-cn.conf >/dev/null <<'EOF'unqualified-search-registries = ["docker.io"]
[[registry]]prefix = "docker.io"location = "docker.m.daocloud.io"EOFAfter that, podman pull nginx goes through the mirror automatically.
Go module proxy
Section titled “Go module proxy”go env -w GOPROXY=https://goproxy.cn,directgo env GOPROXYFlatpak
Section titled “Flatpak”flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepoflatpak remote-ls --app flathub | head -5Some university mirrors (USTC, SJTU) carry a /flathub tree, but the internal layout differs from the official one. Verify with flatpak remote-ls before switching, or you end up with a remote that lists nothing.
Measurements: what switching actually buys
Section titled “Measurements: what switching actually buys”Same machine (F45, gigabit LAN), measured 2026-10-28:
| Operation | Official | Domestic | Outcome |
|---|---|---|---|
dnf install firewalld (11 packages) | could not complete (DNS/metalink failure) | Aliyun at 4.0 MiB/s, succeeded | the mirror fixed availability, not just speed |
npm view express version | 1817 ms | npmmirror 439 ms | 4x faster |
pip download numpy (16 MB) | PyPI 2300 ms | Tsinghua 3652 ms | official was faster |
One-shot script
Section titled “One-shot script”#!/bin/bash# Fedora domestic mirrors; comment out what you do not needset -e
# 1) dnf: official -> Aliyun (swap 45_Beta for 45 after GA)sudo tee /etc/yum.repos.d/99-cn.repo >/dev/null <<'EOF'[cn-base]name=Aliyun Fedorabaseurl=https://mirrors.aliyun.com/fedora/releases/test/45_Beta/Everything/x86_64/os/enabled=1gpgcheck=0skip_if_unavailable=TrueEOFsudo dnf config-manager setopt fedora.enabled=0 updates.enabled=0
# 2) npmnpm config set registry https://registry.npmmirror.com
# 3) pipmkdir -p ~/.config/pipprintf '[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n' > ~/.config/pip/pip.conf
# 4) gocommand -v go >/dev/null && go env -w GOPROXY=https://goproxy.cn,direct
# 5) containerssudo mkdir -p /etc/containers/registries.conf.dprintf 'unqualified-search-registries = ["docker.io"]\n\n[[registry]]\nprefix = "docker.io"\nlocation = "docker.m.daocloud.io"\n' \ | sudo tee /etc/containers/registries.conf.d/99-cn.conf >/dev/null
echo "done"Common traps
Section titled “Common traps”| Symptom | Cause |
|---|---|
edits to /etc/yum.repos.d/ seem ignored | F45 keeps official repos in /usr/share/dnf5/repos.d/; /etc wins on identical repo id, but editing only the /usr copy gets overwritten on upgrade |
Failed to download metadata for repo 'updates' | metalink cannot find fedora-45; disable the original repository first |
| signature warnings after install | the cost of gpgcheck=0; restore it after GA |
| pip got slower after switching | your link is already good and the mirror adds a hop; measure with the curl above |
podman pull still times out | only unqualified-search-registries was set without the [[registry]] rewrite, or podman system reset is needed |
Related pages
Section titled “Related pages”- Repository configuration moves to /usr — the F45 path change
- Fedora repositories and dnf5 — package management basics
- Signature enforcement — why
gpgcheck=0is a temporary measure - COPR third-party repositories — community repositories