Fully featured Arch Linux package mirror operated by @pmh-only
- High Availability and Scalability
ftp.io.kr focuses on enterprise-grade reliability and elasticity by implementing modern Kubernetes best practices, proper health checks, and load balancing.
Core components in all nodes work independently without inter-node communication. - User Satisfaction
ftp.io.kr provides pure HTML directory listings to ensure compatibility with environments that lack GUI browsers, such as fresh Arch Linux installations. Since listing pages are rendered early and served via HTTP streaming, users can view directory items immediately without waiting for HTML rendering or download completion.
For modern browsers, ftp.io.kr also offers a React-based frontend with virtualized tables, preventing browser crashes when loading large directory listings. - Transparency and User Privacy
ftp.io.kr's source code is publicly available without any hidden components. Its ArgoCD instance implements a single-source-of-truth approach, ensuring that all public configurations are applied exactly as displayed without any modifications.
Additionally, ftp.io.kr does not collect any tracking data or cookies, preserving complete user anonymity. - Cost Optimization and Abuse Prevention
ftp.io.kr's components are highly optimized for cloud infrastructure platforms to reduce operational costs while ensuring that less critical features do not impact the performance of core functionality.
ftp.io.kr also implements automated abuse prevention mechanisms using netflow/ipfix and iptables to block abusive users.
webserveris the cattle component consisting of nginx instances that serve stored package binaries and pre-rendered directory listing files to user browsers. It supports byte-range and ETag headers to ensure HTTP streaming and caching. It includes logic that reads theAcceptheader to decide whether to serve .html files (needed for terminal browsers) or .json files (needed for the React frontend). It also serves a public health check endpoint, frontend asset files, and a TLS-powered endpoint forrsyncserver. This component does not accept traffic untilsyncrepo'sinitsyncmode is completed.syncrepois the pet component consisting of shell scripts that periodically sync package binaries with upper-tier mirrors. It also triggersindexerafter each sync to pre-render directory listing files. It has two modes:initsyncmode downloads all binaries from the upper-tier server to provision package storage initially, andnormalmode checks for updates and applies changes incrementally.indexeris the cattle component consisting of a series of Go processes. It is triggered bysyncrepoor manually to traverse the entire directory structure of package storage and render directory listing files in .html and .json formats. It also calculates the total size of directories and last modification dates recursively.frontendis the React application that reads pre-rendered .json directory listing files and displays them in a virtualized table to prevent browser crashes when loading large lists. It has the ability to handle incomplete .json data streams so users don't need to wait until .json data is fully loaded. It also rendersstatcat's SSE events, which display bandwidth statistics. This component's assets are served bywebserver.statcatis the pet component, a Go application that collects network bandwidth metric data from multiple nodes and aggregates it to a single endpoint. It has two modes:hubmode opens a Server-Sent Events (SSE) endpoint to send stats to the frontend and a WebSocket endpoint to receive metrics from eachspokenode.spokemode collects metrics from sysfs and sends them to thehubnode.healthzis the Cloudflare Worker application that checks the /lastsync file for all nodes and updatesAandHTTPSDNS records to point to healthy nodes, ensuring users can reach healthy nodes that have completedinitsync.bwlimitis the cattle component consisting of NetFlow/IPFIX,pmacct, and shell scripts that meter traffic from UDP, TCP, and other protocols. It aggregates traffic by destination IP and blocks abusive IP addresses.ftpserveris the pet component, a read-only vsftpd instance. It supportscurl ftp.io.krcommands since curl treats the domain as FTP protocol. It supports both active and passive modes. This component does not accept traffic untilsyncrepo'sinitsyncmode is completed.rsyncserveris the cattle component, a read-only rsyncd instance. It supports syncing by lower-tier mirrors and provides an origin endpoint for nginx to supportrsync-ssl. This component does not accept traffic untilsyncrepo'sinitsyncmode is completed.infrais the directory containing Kubernetes manifests and Helm charts to implement SSOT (Single Source of Truth) and GitOps. It also implements automated updates for container images built by GitHub Actions.
graph LR
UpperTier[Upper-tier Mirrors]
LowerTier[Lower-tier Mirrors]
Users[Users / Browsers]
Storage[(File Storage)]
DNS[DNS Records]
subgraph "Core Components"
syncrepo[syncrepo]
indexer[indexer]
webserver[webserver]
end
subgraph "Access Protocols"
ftpserver[ftpserver]
rsyncserver[rsyncserver]
end
subgraph "Frontend & Monitoring"
frontend[frontend]
statcat_hub[statcat hub]
statcat_spoke[statcat spoke]
end
subgraph "Infrastructure & Security"
healthz[healthz]
bwlimit[bwlimit]
infra[infra<br/>GitOps]
end
UpperTier -->|sync binaries| syncrepo
syncrepo -->|write packages| Storage
syncrepo -->|trigger| indexer
indexer -->|read & write listings| Storage
Storage -->|serve files| webserver
Storage -->|serve files| ftpserver
Storage -->|serve files| rsyncserver
webserver -->|HTTP/HTTPS| Users
webserver -->|serve assets| frontend
webserver -.->|TLS endpoint| rsyncserver
ftpserver -->|FTP| Users
rsyncserver -->|rsync/rsync-ssl| LowerTier
frontend -->|read .json| webserver
frontend -->|receive SSE| statcat_hub
statcat_spoke -->|collect metrics| statcat_spoke
statcat_spoke -->|WebSocket| statcat_hub
statcat_hub -->|SSE stats| frontend
healthz -->|check /lastsync| webserver
healthz -->|update A/HTTPS| DNS
bwlimit -->|monitor traffic| webserver
bwlimit -->|block IPs| webserver
infra -.->|deploy & manage| syncrepo
infra -.->|deploy & manage| indexer
infra -.->|deploy & manage| webserver
infra -.->|deploy & manage| ftpserver
infra -.->|deploy & manage| rsyncserver
infra -.->|deploy & manage| statcat_hub
infra -.->|deploy & manage| statcat_spoke
infra -.->|deploy & manage| bwlimit
DNS -->|route to healthy nodes| Users
See DEPLOYMENT.md file for more information.
© 2025-2026. Minhyeok Park pmh_only@pmh.codes.
See LICENSE file for more information.
