= Mirroring Thank you for your interest in providing a public MacPorts mirror server to join our existing [wiki:Mirrors list of mirrors]. Making MacPorts content available in more locations makes MacPorts faster. If you find inaccuracies in these instructions or have other comments or questions, please let us know by contacting [mailto:portmgr@macports.org portmgr]. [[PageOutline(2-3,Table of Contents,inline)]] == Contact us First, please contact [https://lists.macports.org/mailman/listinfo/macports-mgr portmgr] to let us know you would like to create a mirror. Please tell us the following information: * The name and web page URL of the organization providing the mirror, so that we can credit you properly. * The city, state/province and [wikipedia:ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code] where your mirror is located and the [wikipedia:International_Air_Transport_Association_airport_code IATA airport code] of the closest airport. The airport code and country code will become your MacPorts mirror name. * GPS coordinates of your mirror's approximate location that we may display on a map. You may provide the coordinates of the above airport if you don't want to be more specific. * Your mirror's existing hostname. We will create new hostnames abc.xy.distfiles.macports.org, abc.xy.packages.macports.org and abc.xy.rsync.macports.org (where "abc" is your airport code and "xy" is your country code) `CNAME`d to your existing hostname. * Whether your server can be accessed over only http or only [#SSL https] or both. * The email address of the server's administrator. We will list this on our mirrors page and MacPorts users might report problems to this address. * Your mirror's upstream Internet connection speed and whether or not your mirror supports IPv6. We will list this information on our mirrors page. We will review your request to become a mirror and will let you know if there are any problems. Meanwhile you can follow the rest of these instructions to get your mirror ready. We reserve the right to refuse a request to become a mirror for any reason, or to remove existing mirrors from use at any time and without notice. If in the future you wish to temporarily or permanently discontinue providing your mirror, please let us know so that we can make the appropriate changes. == Requirements Running a MacPorts mirror will use a possibly significant amount of bandwidth. One of our servers in California, for example, served around 250GB of data via http and another 70GB of data via rsync per day. For http traffic, MacPorts chooses the closest mirror automatically, so how much traffic your mirror sees depends on the number of MacPorts users for whom your mirror is the closest. Ensure you have the permission of your network provider to run such a mirror, and that this amount of traffic will not be a problem for you. You'll need a server with at least 2 TB of available disk space on a case-sensitive filesystem. You'll need a web server on port 80 such as Apache httpd or nginx on which you can configure new virtual hosts, and the rsync daemon running on port 873. The server should have a hostname and a static IPv4 address. IPv6 access is welcomed but is not required. The server must respond to pings. The server does not need to be running macOS and does not need to have MacPorts installed. == Rsync modules We recommend you copy all of our content by mirroring our ''macports'' rsync module, and we recommend you republish this on your server in a ''macports'' rsync module. If you prefer to copy only a subset of our content, you can mirror the packages, distfiles, release and/or trunk subdirectories of the ''macports'' module (into a ''macports'' rsync module on your server). **Note:** We also offer those four directories as separate rsync modules, however they are deprecated. Please use only the ''macports'' module. The four directories contain the following data: * **packages** contains precompiled archives of each MacPorts port for several macOS versions. This is the largest directory, currently around 1.2 TB. Mirroring this data will provide the greatest benefit to MacPorts users near you since it lets them automatically receive these large files more quickly. * **distfiles** contains the source code tarballs from which the precompiled archives were created. There are some ports that cannot legally be distributed as binaries, so those must build on the user's computer using these source files. This is the second-largest directory, currently around 700 GB. **Note:** this used to be called ''mpdistfiles''. If you are mirroring ''mpdistfiles'', please switch to mirroring ''distfiles''. If your local module is called ''mpdistfiles'', please rename it to ''distfiles'' and let us know so that we can update mirror_sites.tcl. * **release** contains the latest released version of the MacPorts base source code which users update by running `sudo port selfupdate`, as well as the collection of Portfiles—the text files MacPorts reads that tell it how to install each port—which users update by running `sudo port sync`. Users near you can manually configure MacPorts to user your mirror for faster speed. This small directory has a size of less than 2 GB. * **trunk** contains the latest development version of the MacPorts base source code. This small directory is around 120 MB. == Get the files You'll get the files from our server via [https://rsync.samba.org/ rsync]. You should use the latest version of rsync. For your initial sync, you might speed up your transfer by using the nearest of the existing [wiki:Mirrors MacPorts mirror servers]. For subsequent scheduled syncing, use the master rsync server, rsync-origin.macports.org. **Note:** If you are syncing from a different hostname such as rsync.macports.org, or from a specific IP address, please switch to rsync-origin.macports.org. There is a sample script below for mirroring these modules via rsync. You don't have to use that script if you already have other arrangements for syncing, but please use the following `rsync` flags, for the following reasons: ||=`rsync` flag =|| \ ||=Purpose || [[span(`--compress`, style=white-space: pre)]], [[span(`-z`, style=white-space: pre)]] || \ || File data is compressed during transfer. The server won't re-compress files that are already compressed. || [[span(`--delete-delay`, style=white-space: pre)]] || \ || Files which were removed on the server are removed from the mirror after the transfer is finished. This option is similar to but more efficient than `--delete-after`. || [[span(`--hard-links`, style=white-space: pre)]], [[span(`-H`, style=white-space: pre)]] || \ || Hard links are preserved. || [[span(`--links`, style=white-space: pre)]], [[span(`-l`, style=white-space: pre)]] || \ || Symbolic links (symlinks) are preserved. || [[span(`--perms`, style=white-space: pre)]], [[span(`-p`, style=white-space: pre)]] || \ || File and directory permissions are preserved. || [[span(`--recursive`, style=white-space: pre)]], [[span(`-r`, style=white-space: pre)]] || \ || Directories are copied recursively. || [[span(`--timeout=600`, style=white-space: pre)]] || \ || If no data is transferred for 10 minutes, the connection is dropped. || [[span(`--times`, style=white-space: pre)]], [[span(`-t`, style=white-space: pre)]] || \ || Modification times are preserved. == Stay up to date After the initial sync is complete, keep your mirror up to date by periodically re-running the sync script. You can do this using cron, launchd, systemd, or another scheduler. A sample cron configuration is provided below. The sample configuration syncs every hour. It is not necessary to sync that often, but MacPorts developers commit dozens of port updates each day, so the more frequently you sync, the more likely your mirror is to have the content users are requesting. Ensure your mirror syncs at least once daily. == Rsync server MacPorts retrieves files from ''release'' and ''trunk'' via rsync. MacPorts comes preconfigured to use the server rsync.macports.org but users can edit their configuration to use your mirror instead. In addition, other mirror administrators may wish to copy your ''packages'' and ''distfiles''. So you should run an rsync daemon to republish the files you synced. The MacPorts rsync modules have generic names, so we suggest you put our files in subdirectories of a single "macports" module. We would prefer you not rename those subdirectories. If your site convention is to use the original server's hostname as the rsync module name, please use the name ''rsync.macports.org'' (even though you are actually syncing from rsync-origin.macports.org). **Note:** If you are providing the modules under nonstandard names, please edit your rsyncd configuration to provide the files under a single module with subdirectories, but continue to serve the files from your old module names so that existing users can still find the files. If you are already providing a single module but with nonstandard subdirectory names, rename the subdirectories to their standard names but add symlinks at their previous names. Edit the [wiki:Mirrors Mirrors] page to reflect your changes, and if you changed your configuration for ''packages'' or ''distfiles'' let us know so that we can update mirror_sites.tcl and/or archive_sites.tcl. There is a sample rsyncd configuration below. == Web server MacPorts retrieves files from ''packages'' and ''distfiles'' via http or https. MacPorts automatically downloads these files from whichever mirror is closest. So you should run a web server to make these modules available. The contents of the ''packages'' module should be made available directly under !http(s)://abc.xy.packages.macports.org/ and the contents of the ''distfiles'' module should be made available directly under !http(s)://abc.xy.distfiles.macports.org/. It is not necessary to provide the contents of the ''release'' or ''trunk'' modules via http. **Note:** If you are currently providing the contents of the ''packages'' or ''distfiles'' modules in a subdirectory of your MacPorts mirror hostname, you should reconfigure your web server to provide the contents directly under the MacPorts mirror hostname, and let us know so we can update archive_sites.tcl and/or mirror_sites.tcl. You should configure HTTP 301 redirects from the previously-used URLs to the new ones. Directory listings should be turned on. URL spelling correction and multiviews must be turned off. There are sample web server configurations below. == SSL MacPorts verifies the integrity of downloaded files via checksums or signatures so your mirror is not required to provide access via https, but you can if you wish. [https://letsencrypt.org Let's Encrypt] offers free SSL certificates which can be used. Please add your `abc.xy.(distfiles|packages|rsync).macports.org` hostnames as Subject Alternative Names in your SSL certificate. We suggest you continue to provide access via http, even if you also provide access via https. MacPorts still supports very old OS versions such as Mac OS X 10.4 Tiger, and the version of OpenSSL in old OS versions is not able to communicate with modern SSL web servers. (The cutoff version depends on which encryption algorithms you've configured your web server to allow.) You can disallow http access if you wish, but if you do so it will limit the OS versions that are able to connect to your server. == Add mirror to MacPorts Once your server is synced and ready to accept MacPorts traffic, let us know and we will edit archive_sites.tcl and mirror_sites.tcl to add the URLs of your MacPorts mirror hostnames. Also edit the [wiki:Mirrors Mirrors] page to add information about your server, or we can add it for you. == Sample scripts and configuration files === Sample rsync update script This sample script can be used to mirror all MacPorts content to your server using rsync. For your initial sync, you can possibly make your transfer faster by uncommenting the `RSYNC_URL` line for a mirror server closer to you. For subsequent scheduled syncs, use the origin server to ensure you get the latest content. {{{ #!/bin/bash # This script mirrors all MacPorts content from RSYNC_URL to RSYNC_DIR. set -euo pipefail RSYNC_DIR="/var/www/html/macports" RSYNC_URL="rsync://rsync-origin.macports.org/macports/" #RSYNC_URL="rsync://jnb.za.rsync.macports.org/macports/" #RSYNC_URL="rsync://jog.id.rsync.macports.org/macports/" #RSYNC_URL="rsync://lil.fr.rsync.macports.org/macports/" #RSYNC_URL="rsync://nue.de.rsync.macports.org/macports/" #RSYNC_URL="rsync://osl.no.rsync.macports.org/macports/" RSYNC="rsync" RSYNC_ARGS="--compress --delete-delay --hard-links --links --no-motd --perms --recursive --stats --timeout=600 --times" if [ -t 1 ]; then RSYNC_ARGS="$RSYNC_ARGS --info=progress2" fi echo "Syncing from $RSYNC_URL to $RSYNC_DIR" $RSYNC $RSYNC_ARGS "$RSYNC_URL" "$RSYNC_DIR" echo }}} If you wish to mirror only some of our content, you can instead use the following script and remove unwanted modules from the RSYNC_MODULES line. {{{ #!/bin/bash # This script mirrors the selected RSYNC_MODULES from RSYNC_URL to RSYNC_DIR. set -euo pipefail RSYNC_DIR="/var/www/html/macports" RSYNC_MODULES="packages distfiles release trunk" RSYNC_URL_FORMAT="rsync://rsync-origin.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://cjj.kr.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://fco.it.rsync.macports.org/macports-%s/" #RSYNC_URL_FORMAT="rsync://jnb.za.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://jog.id.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://lil.fr.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://mse.uk.rsync.macports.org/%s.macports.org/" #RSYNC_URL_FORMAT="rsync://nou.nc.rsync.macports.org/macports/%s.macports.org/" #RSYNC_URL_FORMAT="rsync://nue.de.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://osl.no.rsync.macports.org/macports/%s/" #RSYNC_URL_FORMAT="rsync://sea.us.rsync.macports.org/%s/" RSYNC="rsync" RSYNC_ARGS="--compress --delete-delay --hard-links --links --no-motd --perms --recursive --stats --timeout=600 --times" if [ -t 1 ]; then RSYNC_ARGS="$RSYNC_ARGS --info=progress2" fi for RSYNC_MODULE in $RSYNC_MODULES; do RSYNC_URL="$(printf "$RSYNC_URL_FORMAT" "$RSYNC_MODULE")" echo "Syncing from $RSYNC_URL to $RSYNC_DIR/$RSYNC_MODULE" $RSYNC $RSYNC_ARGS "$RSYNC_URL" "$RSYNC_DIR/$RSYNC_MODULE" echo done }}} === Sample cron configuration This sample cron configuration runs the above sync script every hour at 30 minutes past the hour: {{{ 30 * * * * /usr/local/bin/macports-rsync.sh 2>&1 >> /var/log/macports-rsync.log }}} So that not all mirrors are trying to connect to the origin server at the same time, please change "30" to a random number between 0 and 59. === Sample Apache httpd configuration This sample configuration can be used to serve MacPorts files with Apache httpd. {{{ Order allow,deny Allow from all AllowOverride None Options +Indexes -FollowSymLinks -MultiViews IndexOptions Charset=UTF-8 FancyIndexing IconsAreLinks HTMLTable NameWidth=* SuppressDescription AddType application/mac-binhex40 .hqx AddType application/octet-stream .bin .exe .rmd160 AddType application/vnd.apple.installer+xml .dist .distz .mpkg .pkg AddType application/x-7z-compressed .7z AddType application/x-apple-diskimage .dmg .image .img .smi AddType application/x-bzip2 .bz2 .tbz .tbz2 AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType application/x-iso9660-image .iso AddType application/x-lzip .lz AddType application/x-lzma .lzma .tlz AddType application/x-rar-compressed .rar AddType application/x-stuffit .sit AddType application/x-stuffitx .sitx AddType application/x-tar .tar AddType application/x-tcl .tcl AddType application/x-xz .txz .xz AddType application/zip .zip AddType image/icns .icns ServerName abc.xy.distfiles.macports.org ServerAlias distfiles.macports.org DocumentRoot /var/www/html/macports/distfiles UseCanonicalName On CheckSpelling Off Header set "Cache-Control" "max-age=2592000, public" Header set "Cache-Control" "max-age=300, public" Header set "Cache-Control" "max-age=1800, public" ServerName abc.xy.packages.macports.org ServerAlias packages.macports.org DocumentRoot /var/www/html/macports/packages UseCanonicalName On CheckSpelling Off Header set "Cache-Control" "max-age=2592000, public" Header set "Cache-Control" "max-age=300, public" }}} If you are serving MacPorts files from subdirectories of your MacPorts mirror hostnames, use `Redirect` directives to redirect those requests to their new locations. For example, these directives show how to redirect requests for !http://hostname/pub/macports/packages/... to !http://abc.xy.packages.macports.org/... and requests for !http://hostname/pub/macports/distfiles/... to !http://abc.xy.distfiles.macports.org/...: {{{ Redirect 301 /pub/macports/packages http://abc.xy.packages.macports.org Redirect 301 /pub/macports/distfiles http://abc.xy.distfiles.macports.org }}} Place these directives inside the `VirtualHost` directives for your MacPorts mirror hostnames. === Sample nginx configuration This sample configuration can be used to serve MacPorts files with nginx. {{{ types { application/mac-binhex40 hqx; application/octet-stream bin exe rmd160; application/vnd.apple.installer+xml dist distz mpkg pkg; application/x-7z-compressed 7z; application/x-apple-diskimage dmg image img smi; application/x-bzip2 bz2 tbz tbz2; application/x-compress Z; application/x-gzip gz tgz; application/x-iso9660-image iso; application/x-lzip lz; application/x-lzma lzma tlz; application/x-rar-compressed rar; application/x-stuffit sit; application/x-stuffitx sitx; application/x-tar tar; application/x-tcl tcl; application/x-xz txz xz; application/zip zip; image/icns icns; } server { listen 80; listen [::]:80; server_name abc.xy.distfiles.macports.org distfiles.macports.org; root /var/www/html/macports/distfiles; server_name_in_redirect on; autoindex on; add_header Cache-Control "max-age=2592000, public"; location ~ /$ { add_header Cache-Control "max-age=300, public"; } location = /ports.tar.gz { add_header Cache-Control "max-age=1800, public"; } } server { listen 80; listen [::]:80; server_name abc.xy.packages.macports.org packages.macports.org; root /var/www/html/macports/packages; server_name_in_redirect on; autoindex on; add_header Cache-Control "max-age=2592000, public"; location ~ /$ { add_header Cache-Control "max-age=300, public"; } } }}} If you are serving MacPorts files from subdirectories of your MacPorts mirror hostnames, use `return` directives inside a `location` directive to redirect those requests to their new locations. For example, these directives show how to redirect requests for !http://hostname/pub/macports/packages/... to !http://abc.xy.packages.macports.org/... and requests for !http://hostname/pub/macports/distfiles/... to !http://abc.xy.distfiles.macports.org/...: {{{ location ^~ /pub/macports/packages(/.*)?$ { return 301 http://abc.xy.packages.macports.org$1; } location ^~ /pub/macports/distfiles(/.*)?$ { return 301 http://abc.xy.distfiles.macports.org$1; } }}} Place these directives inside the `server` directives for your MacPorts mirror hostnames. === Sample rsyncd configuration This sample rsyncd.conf file can be used to serve MacPorts files with the rsync daemon. {{{ dont compress = 7z ace avi bin bz2 deb distz dmg gem gif gpg gz \ icns image img iso jar jpeg jpg lz lzma lzo mov mp3 mp4 mpkg msi \ ogg pdf pkg png rar rmd160 rpm rzip sig sit sitx smi tbz tbz2 \ tgz tlz ttf txz xz Z zip forward lookup = false gid = nobody list = true log file = /var/log/rsyncd/rsyncd.log max connections = 0 pid file = /var/run/rsyncd.pid read only = true reverse lookup = false timeout = 600 transfer logging = true uid = nobody use chroot = no [macports] comment = MacPorts release, trunk, distfiles and packages log file = /var/log/rsyncd/macports.log path = /var/www/html/macports }}} Start rsync with: {{{ rsync --daemon --config=/etc/rsyncd.conf }}} If you are serving individual rsync modules, move those directories into a single new ''macports'' module but continue to serve the old modules under your existing names so that users using the old names can still get the files. For example: {{{ cd /var/www/html mkdir macports mv packages distfiles release trunk macports/ }}} Adjust your rsyncd.conf to the new directory locations: {{{ [release] comment = MacPorts release (deprecated; use "macports/release" instead) log file = /var/log/rsyncd/macports.log path = /var/www/html/macports/release [trunk] comment = MacPorts trunk (deprecated; use "macports/trunk" instead) log file = /var/log/rsyncd/macports.log path = /var/www/html/macports/trunk [distfiles] comment = MacPorts distfiles (deprecated; use "macports/distfiles" instead) log file = /var/log/rsyncd/macports.log path = /var/www/html/macports/distfiles [mpdistfiles] comment = MacPorts distfiles (deprecated; use "macports/distfiles" instead) log file = /var/log/rsyncd/macports.log path = /var/www/html/macports/distfiles [packages] comment = MacPorts packages (deprecated; use "macports/packages" instead) log file = /var/log/rsyncd/macports.log path = /var/www/html/macports/packages }}} If you are already serving a single module but with subdirectories with nonstandard names, move the subdirectories to their standard names and add a symlink so that users using the old nonstandard names can still get the files. For example, if you are currently serving ''mpdistfiles'', rename it to ''distfiles'' and add an ''mpdistfiles'' symlink: {{{ cd /var/www/html/macports mv mpdistfiles distfiles ln -s distfiles mpdistfiles }}}