Setting up a Repo Mirror

I have an Ubuntu File Server, and I want to set up a Local Repo Server for the multiple Manjaro OSs I have on my LAN.

The info I have read on the Forum appears to be related to creating a Local Mirror on a Manjaro OS, using for example Pacserve, and similar Manjaro/Arch oriented tool.

What I want to know, is setting up a repo Mirror for Manjaro any more complicated than setting up a Web server and serving HTTP and or FTP, and syncing back to a public Mirror. Or are there specifics I need to know?

Depends on what you want to serve: a full mirror of all repos or pacserve which seems like a cache in your LAN.

I want to set up the local repo on an Ubuntu Server.

You can use any OS as a server. You can take inspiration from this post: [root tip] [How To] Create Manjaro mirror server

That is all there is to it.

Ensure the custom mirror is used

When you setup a mirror you want to ensure your local computers use that mirror.

You need to make a special configuration for pacman-mirrors to avoid the pamac mirrorlist timer rewriting your mirror list.

Configure pacman-mirrors to use a mirror pool with only one mirror.

sudo pacman-mirrors --country dk

Then edit the resulting pool file /var/lib/pacman-mirrors/custom-mirrors.json and remove unnecessary data.

Initially the file may look like this

    "branches": [
    "country": "Denmark",
    "last_sync": "00:59",
    "protocols": [
    "resp_time": "00.00",
    "url": ""

Remove status configs branches, last_sync and resp_time.

Modify url to point to your server.

JSON data is picky on format so ensure all brackets and braces are in place.

    "country": "CUSTOM",
    "protocols": [ "https" ],
    "url": "https://your-mirror.tld/manjaro"

Save the file and copy to a convenient location e.g. your home.

cp /var/lib/pacman-mirrors/custom-mirrors.json ~

From there you can distribute the configuration all your systems - copy the file to the same location - replacing the existing file if necessary.

cp custom-mirrors.json /var/lib/pacman-mirrors

Ensure your custom pool is never replaced

Ideally this should be done with a custom pacman-mirrors package.

The package must rebuild on python version change - but the following will work as well.

If you want to ensure the custom pool is never reset by a user running pacman-mirrors -c all you can apply some system wide changes.

REMEMBER: Modifying system files will be reverted when the package owning the files is rebuilt.

Copy the file custom-mirrors.json as mirrors.json to /usr/share/pacman.mirrors - replacing the upstream mirror pool.

sudo cp ~/custom-mirrors.json /usr/share/pacman-mirrors/mirrors.json

Locate the file /usr/lib/python3.10/site-packages/pacman_mirrors/config/

Edit the configuration and change the URL_MIRROR_JSON and URL_STATUS_JSON to be an empty string


Save the file.

no shiny-mirrors

Of course none of the above will work as expected if your systems use shiny-mirrors - only pacman-mirrors can do this.

1 Like


Please focus on one thing.

shiny-mirrors is an alternative to pacman-mirrors


I had started to read that article, but it seemed to be about Manjaro Apps, so I discarded it… Thanks I’ll read it properly.

@ linux-aarhus thanks

I’ll let you guys know as soon as I get this set up, could take a while though.

… not really a repo mirror here
but may be easier and more effective

With my Manjaro virtual machines I do that kind of thing
which essentially is:
download only once and use for all

by having a separate disk, which I mount to /var/cache/pacman/pkg
on each machine

All the machines are then using the same package cache.

This same thing could be achieved using a server and (NFS or sshfs) mounting a directory on it to
/var/cache/pacman/pkg on each machine.

This way, not the whole repo needs to be cloned - but just the packages that are actually needed.

Just another idea …


as @ mithrial says, that’s probably pacserve. I’ll go with setting up a Mirror on my File server. I have plenty of space, and I already have Apache running on it.

It will take a while 'cos of finding the time to concentrate on actually doing the job. It’s coming into Fire Season over here, so were pretty busy making sure only our Bush burns, and not the house.

My scenario was
VM’s, I run them one at a time, not simultaneously.
My only requirement is not to download all the updates multiple times for each of them but re-use them once they are present.
No need for the full repo and sharing the cache via pacserve would require more than one to be running at a time which is never the case.

Just a primitive re-use of the pacman cache.

You describe a scenario that is unique to you, and probably be too complicated for OP.

If your server is already running apache, then all you have to do is mirror one of the mirrors to any subdirectory of apache, and point your clients to this server.

… maybe
It’s a network mount - plenty of documentation on that.

It was just another way to do it.

And it avoids mirroring the whole mirror when only a few packages are actually needed.
That is how I understood how pacserve works.
But I’m not sure about that.
changed because only the pacman cache is shared

… would not have worked for me anyway

If you don’t have it already - setup a web server on your ubuntu box and create a manjaro subfolder.

Then setup a script and a systemd timer to sync from the repo.

Create a script folder

sudo mkdir /etc/systemd/scripts

Create a file /etc/systemd/scripts/ and make it executable

sudo touch /etc/systemd/scripts/
sudo chmod +x /etc/systemd/scripts/

Edit the file as root and paste below content


# This is a simple mirroring script. To save bandwidth it first checks a
# timestamp via HTTP and only runs rsync when the timestamp differs from the
# local copy. As of 2016, a single rsync run without changes transfers roughly
# 6MiB of data which adds up to roughly 250GiB of traffic per month when rsync
# is run every minute. Performing a simple check via HTTP first can thus save a
# lot of traffic.

# EDIT to match your system

# possible rsync mirrors


# NOTE: You'll probably want to change this or remove the --bwlimit setting in
# the rsync call below

[ ! -d "${TARGET}" ] && mkdir -p "${TARGET}"
[ ! -d "${TMP}" ] && mkdir -p "${TMP}"

exec 9>"${LOCK}"
flock -n 9 || exit

## if we are called without a tty (cronjob) only run when there are changes
#if ! tty -s && diff -b <(curl -s "${STATE}") "${TARGET}/state" >/dev/null; then
#    exit 0

if ! stty &>/dev/null; then

# excluded fh 2016-11-01
rsync -rtlvH --safe-links \
    --bwlimit=${BWLIMIT} \
    --delete-after --progress \
    -h ${QUIET} --timeout=300 --contimeout=120 -p \
    --delay-updates --no-motd \
    --temp-dir="${TMP}" \
    --exclude='/arm-stable' \
    --exclude='/arm-testing' \
    --exclude='/arm-unstable' \
    --exclude='/pool/overlay-arm' \
    --exclude='/pool/sync-arm' \
    ${SOURCE} \

rm -f ${LOCK}

Run the script as root to do the initial sync - I don’t know how much the arm-repos are worth but I think a lot - and there’s no benefit from excluding branches as branch files - except database files - are symlinks to actual files in the pool.

If you have no need for the arm branches you can get down to around 90G only for x86_64 - I have modified the sync script to exclude arm.

When you have synced the repos - create a service and a timer

sudo touch /etc/systemd/system/rsync-manjaro.service
sudo touch /etc/systemd/system/rsync-manjaro.timer

Edit the service file and paste below

Description=Sync manjaro repo



Edit the timer file and paste below

Description=Sync Manjaro mirror on a daily base



Then enable the timer

sudo systemctl enable --now rsync-manjaro.timer

Thanks I’ve complimented this. I’ll guess I’ll know shortly how well it works.

I do have one minor problem.

I am now unable to sync the AUR database.

I have a couple of AUR packages installed on two of the computers. Most importantly is Mullvad-VPN.

AUR has nothing to do with the package repositories.

@mithrial That’s correct.

and yet… on multiple computers it no longer synchronises.

To be specific, when one synchronises databases using the GUI the message returned is ‘Failed to synchronise AUR database’

I am sorry to butt in like this when it was already solved but to me this is just too unnecessary and complicated with no good pros only cons,
I think it doesn’t make sense to make custom pool for just one local mirror,
I would just disable the timer and set in /etc/pacman.d/mirrorlist the local IP of the mirror
like so: Server = <protocol>://<local_IP>/<branch>/$repo/$arch
And it’s done
There is no need to keep using any kind of mirror helper(pacman-mirrors or shiny-mirrors), in such case it’s useless when you are going to use only one mirror.