{"id":1314,"date":"2020-07-12T16:32:56","date_gmt":"2020-07-12T21:32:56","guid":{"rendered":"http:\/\/littlesvr.ca\/grumble\/?p=1314"},"modified":"2026-03-12T13:16:13","modified_gmt":"2026-03-12T18:16:13","slug":"set-up-your-own-linux-mint-mirror-for-lightning-fast-downloads","status":"publish","type":"post","link":"http:\/\/littlesvr.ca\/grumble\/2020\/07\/12\/set-up-your-own-linux-mint-mirror-for-lightning-fast-downloads\/","title":{"rendered":"Set up your own Linux Mint mirror for lightning-fast downloads"},"content":{"rendered":"\n<p>For a very long time I&#8217;ve been a Slackware user. I still happily run Slackware on my servers, but I moved to Linux Mint for all my workstations.<\/p>\n\n\n\n<p>One of the things that always pissed me off about non-Slackware distributions is the amount of time it takes to install new software. Sure in Slackware I had to download the source code and build it myself, but I did that once, and then literally never had to download it again for years.<\/p>\n\n\n\n<p>On any apt-based or yum-based or similar system it seems that any time you do anything with the package manager you have to wait minutes, and sometimes hours for something to be downloaded from a mirror. And if you have more than one machine &#8211; you have to double, triple, quadruple, etc. that time.<\/p>\n\n\n\n<p>Finally I had enough and I set up my own mirror. This post is a walkthrough of what I did.<\/p>\n\n\n\n<p>I considered the following options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/github.com\/apt-mirror\/apt-mirror\">apt-mirror<\/a><\/strong> is the most commonly recommended tool. It didn&#8217;t work for me for two reasons: it&#8217;s officially no longer maintained, and even though it&#8217;s just a Perl script &#8211; it needs to run on a Debian (or derivative) server. My server is Slackware.<\/li>\n\n\n\n<li><a href=\"https:\/\/www.debian.org\/mirror\/ftpmirror\"><strong>ftpsync<\/strong><\/a> seemed overkill for my needs. And I don&#8217;t think it&#8217;s intended for partial mirrors.<\/li>\n\n\n\n<li><strong>apt-cache<\/strong> and <a href=\"https:\/\/help.ubuntu.com\/community\/HttpReplicator\"><strong>HttpReplicator<\/strong><\/a> seemed too limited for my needs.<\/li>\n\n\n\n<li><a href=\"https:\/\/help.ubuntu.com\/community\/Rsyncmirror\"><strong>Rsyncmirror<\/strong><\/a> might be a good option but I didn&#8217;t try it.<\/li>\n<\/ul>\n\n\n\n<p>I settled on <strong><a href=\"https:\/\/help.ubuntu.com\/community\/Debmirror\">DebMirror<\/a><\/strong>. It does not have any dependencies (except one Perl module), it&#8217;s very configurable, and at the same time it&#8217;s simple.<\/p>\n\n\n\n<p>Mostly I followed that tutorial on the Ubuntu help page (which is very good) but I had to customise it to work in my environment and make it work for Linux Mint.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-1-disk-space\">Step 1 &#8211; Disk space<\/h2>\n\n\n\n<p>I knew it would take a lot of disk space, but still I underestimated it. I ended up adding a cheap rotating drive to my server just to hold the mirrored files. I figured in the long term I&#8217;ll have mirrors for different distributions so the extra space won&#8217;t hurt.<\/p>\n\n\n\n<p>Just to give yourself a clear idea: have a look at the <a href=\"https:\/\/www.debian.org\/mirror\/size\">Debian mirror size page<\/a>. Even if you choose one or two architectures &#8211; you probably don&#8217;t have that much disk space sitting there unused. So figure that out before you start.<\/p>\n\n\n\n<p>The minimum today for the Linux Mint mirror is just over 100GB. But Who knows what it will be by the time you read this.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-2-install-debmirror\">Step 2 &#8211; Install debmirror<\/h2>\n\n\n\n<p>If you&#8217;re running an apt-based distro on your server &#8211; you use apt to install debmirror. For everyone else &#8211; you&#8217;ll have to download the source package, get the script out of there, and put it into \/usr\/local\/bin. For me the steps looked like this (I did everything as root):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cd \/root\nwget http:\/\/deb.debian.org\/debian\/pool\/main\/d\/debmirror\/debmirror_2.32.tar.xz\ntar xvf debmirror_2.32.tar.xz\ncd debmirror\ncp debmirror \/usr\/local\/bin<\/pre>\n\n\n\n<p>Finding the URL to download the latest debmirror package was a pain, but I don&#8217;t think the version matters that much.<\/p>\n\n\n\n<p>At this point on my server when I ran it, I got an error like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># debmirror\nCan't locate LockFile\/Simple.pm in @INC (you may need to install the LockFile::Simple module) (@INC contains: \/usr\/local\/lib64\/perl5 \/usr\/local\/share\/perl5 \/usr\/lib64\/perl5\/vendor_perl \/usr\/share\/perl5\/vendor_perl \/usr\/lib64\/perl5 \/usr\/share\/perl5 .) at .\/debmirror line 592.\nBEGIN failed--compilation aborted at .\/debmirror line 592.<\/pre>\n\n\n\n<p>I already used CPAN before, so the fix was easy:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cpan install LockFile::Simple<\/pre>\n\n\n\n<p>Then it runs, but doesn&#8217;t do anything yet:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># debmirror\nmirrordir not specified\nUsage: .\/debmirror [options]<\/pre>\n\n\n\n<p>Later I found that the version of gpgv On Slackware 14  doesn&#8217;t understand the &#8211;output argument which the debmirror script uses, so I had to edit debmirror and remove the &#8220;<strong>&#8211;output &#8211;<\/strong>&#8221; from this line:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\"my @gpgv = qw(gpgv --output - --status-fd);\"<\/pre>\n\n\n\n<p>I don&#8217;t know what that was intended to do, but it worked fine for me.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-3-signatures\">Step 3: Signatures<\/h2>\n\n\n\n<p>The Ubuntu guide didn&#8217;t explain what this does, and I didn&#8217;t bother figuring it out. Probably debmirror will verify the integrity of the mirrored packages.<\/p>\n\n\n\n<p>I needed both the Ubuntu and Mint keys, and since the server wasn&#8217;t running either &#8211; I had to scp them from one of my workstations (10.0.0.150):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir \/root\/mirrorkeyring<br>cd \/root\/mirrorkeyring<br>scp <strong>andrew@10.0.0.150<\/strong>:\/usr\/share\/keyrings\/ubuntu-archive-keyring.gpg .<br>gpg --no-default-keyring --keyring \/root\/mirrorkeyring\/trustedkeys.gpg --import ubuntu-archive-keyring.gpg<br>scp <strong>andrew@10.0.0.150<\/strong>:\/usr\/share\/keyrings\/linuxmint-keyring.gpg .<br>gpg --no-default-keyring --keyring \/root\/mirrorkeyring\/trustedkeys.gpg --import linuxmint-keyring.gpg<\/pre>\n\n\n\n<p>You&#8217;ll use this \/root\/mirrorkeyring directory in your scripts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-4-create-mirror-scripts\">Step 4: Create mirror scripts<\/h2>\n\n\n\n<p>Linux Mint is mostly Ubuntu. But it has a couple of gigabytes of its own packages. So you&#8217;ll need to make a script to mirror the Ubuntu repositories and another (almost identical) script to mirror the Mint repository.<\/p>\n\n\n\n<p>The comments in the script in the Ubuntu help page are quite useful, but I removed them here for brevity.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong># cat \/root\/mirror-ubuntu.sh<\/strong><br>#!\/bin\/bash<br>export GNUPGHOME=\/root\/mirrorkeyring<br>arch=i386,amd64<br>section=main,restricted,universe,multiverse<br>release=noble,noble-updates,noble-backports,noble-security<br>server=mirror.csclub.uwaterloo.ca<br>inPath=\/ubuntu<br>proto=http<br>outPath=\/srv\/httpd2\/htdocs\/mirror\/ubuntu<br><br>debmirror       -a $arch \\<br>                --no-source \\<br>                -s $section \\<br>                -h $server \\<br>                -d $release \\<br>                -r $inPath \\<br>                --progress \\<br>                --method=$proto \\<br>                $outPath<\/pre>\n\n\n\n<p>Here are my notes for these variables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>arch<\/strong> needs both i386 and amd64. I don&#8217;t know why. My workstations are amd64 but apt complained that the server was missing the i386 Packages files.<\/li>\n\n\n\n<li><strong>section<\/strong> and <strong>release<\/strong> I figured out by looking at the \/etc\/apt\/sources.list.d\/official-package-repositories.list file on a Linux Mint box of the correct version (Linux Mint 20 in this case). I expect that in the future only the &#8220;focal&#8221; part will ever need to be changed.<\/li>\n\n\n\n<li><strong>server<\/strong> and <strong>inPath<\/strong> were also from that original sources list file, I always used the mirror.csclub.uwaterloo.ca in the past (thnks guys!).<\/li>\n\n\n\n<li><strong>outPath<\/strong> is where the mirrored files will be stored on your server. In my case that&#8217;s just a symlink to where I mounted my extra hard drive.<\/li>\n<\/ul>\n\n\n\n<p>Then I made a copy of that script to handle mirroring Mint instead. I didn&#8217;t see any immediately obvious way to do both from one script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong># cat ~\/mirror-mint.sh<\/strong><br>#!\/bin\/bash<br>export GNUPGHOME=\/root\/mirrorkeyring<br>arch=amd64,i386<br>section=main,upstream,import,backport<br># Mint versions:<br># 20\tulyana<br># 20.1\tulyssa<br># 20.2\tuma<br># 20.3\tuna<br># 21\tvanessa<br># 21.1\tvera<br># 21.2\tvictoria<br># 21.3\tvirginia<br># 22    wilma<br># 22.1  xia<br># 22.2  zara<br># 22.3 zena<br>release=xia,zara,zena<br><br>server=mirror.csclub.uwaterloo.ca<br>inPath=\/linuxmint-packages<br>proto=http<br>outPath=\/srv\/httpd2\/htdocs\/mirror\/linuxmint-packages\/<br><br>debmirror       -a $arch \\<br>                --no-source \\<br>                -s $section \\<br>                -h $server \\<br>                -d $release \\<br>                -r $inPath \\<br>                --progress \\<br>                --method=$proto \\<br>                $outPath<br><\/pre>\n\n\n\n<p>It&#8217;s almost identical. The only that differ are the section, release, and the two paths.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-5-first-sync\">Step 5: First sync<\/h2>\n\n\n\n<p>The first time you run the mirror-ubuntu.sh script it&#8217;s going to take a very long time. For me on a 25Mbps connection it took about 24-36 hours.<\/p>\n\n\n\n<p>Thankfully because you&#8217;re doing it properly &#8211; this can be interrupted at any time and it will resume from where you left off with very little overhead.<\/p>\n\n\n\n<p>When it&#8217;s almost done you should be able to see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong># cd \/srv\/httpd2\/htdocs\/mirror<\/strong>\n<strong># ls<\/strong>\nlinuxmint-packages\/  lost+found\/  ubuntu\/\n<strong># ls linuxmint-packages\/<\/strong>\ndists\/  pool\/  project\/\n<strong># ls ubuntu\/<\/strong>\nArchive-Update-in-Progress-littlesvr.ca  dists\/  pool\/  project\/\n<strong># ls ubuntu\/pool\/<\/strong>\nmain\/  multiverse\/  restricted\/  universe\/\n<strong># ls ubuntu\/pool\/main\/<\/strong>\na\/  d\/  g\/  j\/  liba\/  libd\/  libg\/  libj\/  libm\/  libp\/  libs\/  libv\/  liby\/  n\/  q\/  t\/  w\/  z\/\nb\/  e\/  h\/  k\/  libb\/  libe\/  libh\/  libk\/  libn\/  libq\/  libt\/  libw\/  libz\/  o\/  r\/  u\/  x\/\nc\/  f\/  i\/  l\/  libc\/  libf\/  libi\/  libl\/  libo\/  libr\/  libu\/  libx\/  m\/     p\/  s\/  v\/  y\/\n<strong># ls ubuntu\/pool\/main\/a\/aalib\/<\/strong>\nlibaa1-dbg_1.4p5-46_amd64.deb  libaa1-dev_1.4p5-46_amd64.deb  libaa1_1.4p5-46_amd64.deb\nlibaa1-dbg_1.4p5-46_i386.deb   libaa1-dev_1.4p5-46_i386.deb   libaa1_1.4p5-46_i386.deb\n<strong># du -hs ubuntu\/<\/strong>\n100G     ubuntu\/\n<strong># du -hs linuxmint-packages\/<\/strong>\n1.7G    linuxmint-packages\/<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-6-web-server-setup\">Step 6: Web server setup<\/h2>\n\n\n\n<p>I didn&#8217;t need to do anything here, \/srv\/httpd2\/htdocs\/mirror was already served automatically by my Apache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-7-client-setup\">Step 7: Client setup<\/h2>\n\n\n\n<p>For some reason there doesn&#8217;t seem to be a user-friendly way to add a custom mirror to a Debian-based distribution. You have to edit text files. Oh well, on my workstations I edited \/etc\/apt\/sources.list.d\/official-package-repositories.list like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">deb http:\/\/10.0.0.2\/mirror\/linuxmint-packages zena main upstream import backport #id:linuxmint_main<br>deb http:\/\/10.0.0.2\/mirror\/ubuntu noble main restricted universe multiverse<br>deb http:\/\/10.0.0.2\/mirror\/ubuntu noble-updates main restricted universe multiverse<br>deb http:\/\/10.0.0.2\/mirror\/ubuntu noble-backports main restricted universe multiverse<br>deb http:\/\/10.0.0.2\/mirror\/ubuntu\/ noble-security main restricted universe multiverse<br><br># deb http:\/\/packages.linuxmint.com zena main upstream import backport #id:linuxmint_main<br><br># deb http:\/\/archive.ubuntu.com\/ubuntu noble main restricted universe multiverse<br># deb http:\/\/archive.ubuntu.com\/ubuntu noble-updates main restricted universe multiverse<br># deb http:\/\/archive.ubuntu.com\/ubuntu noble-backports main restricted universe multiverse<br><br># deb http:\/\/security.ubuntu.com\/ubuntu\/ noble-security main restricted universe multiverse<\/pre>\n\n\n\n<p>My entries are at the top, the original ones commented out at the bottom. Basically I just changed the server URL, leaving everything else as it was.<\/p>\n\n\n\n<p>Note that I only have one server, that hosts everything I need from packages.linuxmint.com, archive.ubuntu.com, and security.ubuntu.com<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-8-try-it\">Step 8: Try it<\/h2>\n\n\n\n<p>Run and apt-get update and apt-get upgrade on the client, and be amazed at how all the donwloading from the servers takes no time whatsoever!<\/p>\n\n\n\n<p>If only I knew I was going to use Linux Mint for so long &#8211; I would have set this up years ago.<\/p>\n\n\n\n<p>I&#8217;ll probably do the same eventually for CentOS which I use for work, and the waiting for downloads is equally frustrating.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For a very long time I&#8217;ve been a Slackware user. I still happily run Slackware on my servers, but I moved to Linux Mint for all my workstations. One of the things that always pissed me off about non-Slackware distributions is the amount of time it takes to install new software. Sure in Slackware I &hellip; <\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-andrew","4":"post-1314","6":"format-standard","7":"category-opensource"},"_links":{"self":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/1314","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/comments?post=1314"}],"version-history":[{"count":30,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/1314\/revisions"}],"predecessor-version":[{"id":1459,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/1314\/revisions\/1459"}],"wp:attachment":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/media?parent=1314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/categories?post=1314"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/tags?post=1314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}