中文 | English
APK Cache is a high-performance proxy server for caching Alpine Linux APK packages and Debian/Ubuntu APT packages. It features a three-tier caching architecture (Memory → File → Upstream), health monitoring with self-healing capabilities, and comprehensive security features.
apk-cache/
├── cmd/
│ ├── apk-cache/ # Main application
│ │ ├── main.go # Entry point
│ │ ├── app.go # App assembly (config, HTTP server, shutdown)
│ │ ├── pipeline.go # Unified request pipeline (cache tiering)
│ │ ├── protocol.go # ProtocolAdapter interface + APK/APT/Proxy adapters
│ │ ├── proxy_tunnel.go # TCP tunnel helpers for CONNECT
│ │ ├── memory_cache.go # In-memory LRU cache with TTL
│ │ ├── apk_index_service.go # APKINDEX index/validation
│ │ ├── apk_archive.go # APK .apk archive reading
│ │ ├── apk_signature.go # APK RSA signature verification
│ │ ├── apt_index_service.go # APT Release/Packages index/validation
│ │ ├── admin.html # Admin dashboard HTML
│ │ ├── *_test.go # Tests
│ │ └── apk_test_helpers_test.go # Test helper utilities
│ ├── apt-hash/ # APT hash tool
│ └── i18n-analyzer/ # i18n coverage analyzer
├── internal/
│ ├── config/
│ │ └── config.go # TOML config loading + validation
│ ├── upstream/
│ │ ├── upstream.go # Upstream server manager + failover fetcher
│ │ └── transport.go # HTTP transport with proxy (SOCKS5/HTTP)
│ └── policy/
│ └── policy.go # Fine-grained cache policies
├── utils/
│ ├── monitoring.go # Prometheus metrics
│ ├── lockman.go # In-process file-level lock manager
│ ├── rate_limiter.go # Token-bucket rate limiter
│ ├── ip_utils.go # IP validation utilities
│ ├── matcher.go # Path matching utilities (path type detection)
│ ├── parse_utils.go # Path normalization
│ ├── set.go # Set data structure
│ ├── decompress.go # Decompression helpers
│ ├── apt/ # APT package parsing
│ │ ├── package.go
│ │ ├── release.go
│ │ ├── diff.go
│ │ └── utils.go
│ └── i18n/ # Internationalization
│ ├── i18n.go
│ └── locales/
├── build.sh # Build script (required for admin.html compression)
├── run_test.sh # Integration test script
├── Dockerfile # Docker build
├── entrypoint.sh # Docker entrypoint
├── config.example.toml # Configuration reference
├── go.mod # Go module
└── go.sum # Go dependencies
- Go 1.25 or later
- Git
- For HTML compression (optional): html-minifier, python-htmlmin, or esbuild
Important: Always use the build script, not go build directly:
./build.shThe build script automatically:
- Detects available HTML compression tools
- Compresses the admin dashboard HTML
- Creates gzip-compressed versions
- Builds the Go application with optimizations
# Default configuration
./apk-cache
# With custom config
./apk-cache -config config.toml
# With command-line arguments
./apk-cache -addr :3142 -cache ./cache -proxy socks5://127.0.0.1:1080- Docker installed and running
The project includes an integration test script that tests both APK and APT caching functionality:
./run_test.shThe test script performs the following steps:
- Build the application using
build.sh(called automatically during Docker build) - Build Docker image
- Start the apk-cache service
- Test with Alpine Linux client (apk update)
- Test with Debian client (apt-get update)
The script automatically cleans up the test environment (containers, images) after tests complete, but preserves the cache directory (/tmp/apk-cache-test-cache) for inspection.
| Parameter | Description |
|---|---|
--goproxy <value> |
Set GOPROXY for go build dependencies |
--alpine-apk-mirror <url> |
Alpine mirror for Docker build (e.g., http://mirror/alpine) |
--apk-mirror <url> |
Alias for --alpine-apk-mirror |
--lang <zh|en> |
Set language (default: auto-detect) |
-h, --help |
Show help message |
# Run tests with Chinese output
./run_test.sh --lang zh
# Run tests with a custom Go proxy
./run_test.sh --goproxy https://goproxy.cn
# Run tests with a custom Alpine mirror
./run_test.sh --alpine-apk-mirror http://mirror.example.com/alpine- Use camelCase for variable and function names
- Use PascalCase for exported types, functions, and constants
- Use mixedCaps for unexported global variables
- Always handle errors explicitly
- Return errors instead of logging silently when appropriate
- Use
fmt.Errorf("context: %v", err)for error messages - Use
errors.New()for static error messages
- Use
log/slogfor all logging (structured key-value pairs:slog.Info("msg", "key", value)) - Never use
log.Println/log.Printf/fmt.Printfor logging - Use appropriate levels:
Debug(diagnostics),Warn(recoverable issues),Error(failures) - Do not expose internal paths or config values in error messages sent to clients
- Only user-facing strings (HTTP error bodies, CLI output) use
i18n.T() - Internal logging and diagnostic messages use
slog, not i18n - Provide translation keys in
utils/i18n/locales/ - Remove stale translation keys when the corresponding code path is migrated away from i18n
- All configuration options must have CLI flags
- Configuration can also be loaded from TOML files
- Use sensible defaults with clear documentation
All incoming requests flow through a unified pipeline that delegates to protocol-specific adapters:
- APKAdapter: Matches APK package/index requests by path pattern. Normalizes to upstream path, handles APKINDEX hash verification and RSA signature validation.
- APTAdapter: Matches APT proxy requests (absolute-form URLs). Handles by-hash verification and Release/Packages index parsing.
- ProxyAdapter: Matches CONNECT tunnels and generic absolute-form HTTP requests. Supports upstream proxy chaining.
- Memory Cache: LRU cache with TTL, fastest access. Only for package files and APT indexes, not APKINDEX.
- File Cache: Persistent disk storage with per-file locking via
FileLockManager. - Upstream: Original package sources via
upstream.Managerwith health-based failover.
- Match adapter by request pattern
- Normalize request to adapter-specific format
- Check cache policy → try memory cache → try disk cache (with TTL + validation)
- On miss: acquire file lock → double-check caches → fetch from upstream
- Stream response to client while writing to temp file
- Validate temp file → promote to cache → notify index services
- Automatic failover between healthy upstream servers
- Panic recovery in HTTP handler (returns 500, logs stack trace)
- Request timeout protection (120s default, CONNECT exempt)
- Graceful shutdown with background goroutine draining
- Create a new branch:
git checkout -b feature/your-feature - Make changes following code conventions
- Add tests for new functionality
- Update documentation
- Submit pull request
Core dependencies (see go.mod):
github.com/prometheus/client_golang- Prometheus metricsgo.etcd.io/bbolt- Embedded databasegolang.org/x/net- HTTP utilitiesgithub.com/nicksnyder/go-i18n/v2- Internationalization