mirava
Universal proxy for Docker registry and PyPI mirrors with automatic failover.
Features
- Docker Registry Proxy: Transparent mirror for Docker Hub with fallback
- PyPI Proxy: Python package index mirror with automatic retry
- Health Monitoring: Automatic mirror health checks and degradation
- Dynamic Configuration: Add/remove mirrors via API
- Swagger UI: Built-in API documentation
Installation
git clone https://github.com/yourusername/mirava.git
cd mirava
uv sync
Quick Start
# Run with default configuration
uv run mirava
# Or run directly
uv run python -m hyper_mirror.main
Server starts on http://localhost:8080
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Server bind address |
PORT |
8080 |
Server port |
PYPI_OFFICIAL_URL |
https://pypi.org/simple |
Official PyPI index |
PYPI_MIRRORS |
(built-in) | Comma-separated PyPI mirrors |
DOCKER_OFFICIAL_URL |
https://registry-1.docker.io |
Official Docker registry |
DOCKER_MIRRORS |
(built-in) | Comma-separated Docker mirrors |
Examples
# Use custom PyPI index
PYPI_OFFICIAL_URL=https://pypi.company.internal/simple uv run mirava
# Custom mirrors only
PYPI_MIRRORS="https://mirror1.com/simple,https://mirror2.com/simple" \
DOCKER_MIRRORS="https://docker-mirror1.com,https://docker-mirror2.com" \
uv run mirava
Docker Setup
Configure Docker to use the proxy:
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["http://127.0.0.1:8080"],
"insecure-registries": ["127.0.0.1:8080"]
}
EOF
sudo systemctl restart docker
Now use Docker normally:
docker pull hello-world
docker pull nginx
PyPI Setup
Configure pip to use the proxy:
# Global config
pip config set global.index-url http://127.0.0.1:8080/simple
pip config set global.trusted-host 127.0.0.1
# Or per-command
pip install --index-url http://127.0.0.1:8080/simple --trusted-host 127.0.0.1 requests
Or use environment variables:
export PIP_INDEX_URL=http://127.0.0.1:8080/simple
export PIP_TRUSTED_HOST=127.0.0.1
pip install requests
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Service info |
/docs |
GET | Swagger UI |
/redoc |
GET | ReDoc documentation |
/health |
GET | Mirror health status |
/v2/ |
GET/HEAD | Docker registry root |
/v2/{path} |
GET/HEAD/POST | Docker registry proxy |
/simple/{package}/ |
GET | PyPI package proxy |
/mirrors/{type} |
POST | Add mirror dynamically |
/config/{type}/official |
PUT | Update official URL |
API Usage Examples
# Check health
curl http://localhost:8080/health
# Add mirror dynamically
curl -X POST "http://localhost:8080/mirrors/pypi?url=https://new.mirror.com/simple&name=newmirror&priority=5"
# Update official PyPI URL
curl -X PUT "http://localhost:8080/config/pypi/official?url=https://test.pypi.org/simple"
Project Structure
src/hyper_mirror/
├── __init__.py # Package init
├── main.py # FastAPI application
├── cli.py # CLI entry point
├── config.py # Configuration management
├── base.py # Base classes and utilities
├── mirrors.py # Mirror registry and initialization
├── docker.py # Docker registry routes
└── pypi.py # PyPI proxy routes
Adding New Mirror Types
- Create new file
src/hyper_mirror/npm.py:
from fastapi import APIRouter
from .mirrors import registry
router = APIRouter(tags=["NPM"])
@router.get("/npm/{package}")
async def npm_proxy(package: str):
# Implementation
pass
- Add mirrors to
mirrors.py:
NPM_MIRRORS = [
("https://registry.npmmirror.com", "npmmirror", 0),
]
- Register in
init_mirrors():
npm_mgr = BaseMirrorManager("npm")
npm_mgr.official_url = "https://registry.npmjs.org"
for url, name, priority in NPM_MIRRORS:
npm_mgr.add_mirror(url, name, priority)
registry.register("npm", npm_mgr)
- Include router in
main.py:
from . import npm
app.include_router(npm.router)
Development
# Run in development mode with auto-reload
uv run --reload mirava
# Or with Python directly
cd src
PYTHONPATH=. uvicorn hyper_mirror.main:create_app --factory --reload
Docker Compose
version: '3.8'
services:
mirava:
build: .
ports:
- "8080:8080"
environment:
- PYPI_OFFICIAL_URL=https://pypi.org/simple
- PYPI_MIRRORS=https://mirror1.com/simple,https://mirror2.com/simple
restart: unless-stopped
License
MIT License
Metadata
Release files for mirava 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mirava-0.2.0.tar.gz | 6.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mirava-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.3 kB
Release files / mirava-0.2.0.tar.gz
| Download URL | mirava-0.2.0.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12f42593da7209e72620c69c6d3976f6850f8ecab394e8014ab3a47ae9174836
|
|
BLAKE2b-256 checksum How to use checksums |
1e28343d4347987c5958fa01e395c66a9e77b75f30a4c1ca5d95a51468d58797
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mirava-0.2.0-py3-none-any.whl
| Download URL | mirava-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b799ff664342339478a5430eb1ca437a136ff4ba2525379c508b97b58be42b66
|
|
BLAKE2b-256 checksum How to use checksums |
01eb19631b412902e180d4a42456ef4a4ef0f3e835b84cf4b6f741e073406bdd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mirava 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.