Python Private Package Index Management System.
pigo is an in-house PyPI package management platform that provides:
- PEP 503-compatible pip proxy — unified index for
pip installwith local cache and upstream fallback - Private package hosting — upload, manage, and distribute internal Python packages
- Web admin console — browse packages, manage users, view download logs, configure system settings
Browser / pip ─── Gin Router ─── Service Layer ─── MySQL + File Storage
│
Upstream PyPI
| Tier | Technology |
|---|---|
| Frontend | Vue 3 + Element Plus |
| Backend | Go + Gin |
| ORM | GORM |
| Database | MySQL 8.0+ |
| Config | Viper |
| Logging | Logrus + file-rotatelogs |
| Embedding | github.com/rakyll/statik |
| Build | Makefile |
- Go 1.21+
- Node.js 18+
- MySQL 8.0+
# Full build (frontend + embed + backend)
make build-all
# Backend only (requires fe/dist on disk)
make buildThe binary bin/pigo contains the embedded frontend and can be deployed as a single file.
Copy and edit config/config.yaml:
server:
host: 0.0.0.0
port: 8080
database:
user: devops
password: your-password
host: 127.0.0.1
port: 3306
dbname: pigo
charset: utf8mb4
proxy:
upstream_url: https://pypi.org/simple
auth:
jwt_secret: use-a-strong-random-secretOverride config path with PIGO_CONFIG env var:
PIGO_CONFIG=/etc/pigo/config.yaml ./bin/pigo./bin/pigo
# or
make runThe service starts on http://0.0.0.0:8080. Database tables are auto-migrated on startup.
A default admin account is created on first run:
- Username:
admin - Password:
admin123
Change the password immediately after login.
pip install django -i http://your-host:8080/simple/ --trusted-host=your-hostOr configure ~/.config/pip/pip.conf (Linux/macOS) / %APPDATA%\pip\pip.ini (Windows) permanently:
[global]
index-url = http://your-host:8080/simple/
trusted-host = your-hostpigo will:
- Serve the package from local cache if available
- Fall back to upstream PyPI, download, cache, and serve
Open http://your-host:8080 in a browser.
| Page | Description |
|---|---|
| Dashboard | Overview, statistics, and pip usage guide |
| Packages | Browse, search, and filter packages |
| Package Detail | View versions, files, and download links |
| Upload | Upload private .whl or source distributions |
| Download Logs | View download history and cache hit rates |
| Users | Manage system users (admin only) |
| Settings | Configure system parameters (admin only) |
See API Reference below or docs/swagger.json for the full OpenAPI spec.
pigo/
├── cmd/server/main.go # Entry point
├── internal/
│ ├── bootstrap/ # DB init, default admin
│ ├── config/ # Viper config loading
│ ├── handler/ # HTTP handlers
│ ├── middleware/ # JWT auth, RBAC, request ID
│ ├── model/ # GORM models
│ ├── proxy/ # Upstream PyPI proxy + cache
│ ├── repository/ # Data access layer
│ ├── router/ # Route registration
│ ├── service/ # Business logic
│ └── storage/ # Local file storage
├── pkg/
│ ├── errs/ # Error codes
│ ├── hash/ # bcrypt + SHA256
│ ├── logx/ # Structured logging
│ ├── response/ # Unified API response
│ └── utils/ # Normalize, sanitize helpers
├── fe/ # Vue 3 frontend
├── config/ # Configuration (not committed)
├── logs/ # Runtime logs (gitignored)
├── storage/ # File storage (gitignored)
├── statik/ # Embedded frontend
├── docs/ # Swagger docs
└── Makefile
| Method | Path | Description |
|---|---|---|
| GET | /simple/ |
Simple index root |
| GET | /simple/:package/ |
Package index page |
| GET | /packages/:filename |
Download package file |
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/auth/login |
Login |
| GET | /api/v1/auth/me |
Current user info |
| POST | /api/v1/auth/logout |
Logout |
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/packages |
List packages |
| GET | /api/v1/packages/:name |
Package detail |
| GET | /api/v1/packages/:name/versions |
Version list |
| POST | /api/v1/packages/upload |
Upload package |
| DELETE | /api/v1/package-files/:id |
Delete file |
| GET | /api/v1/download-logs |
Download logs |
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/users |
List users |
| POST | /api/v1/users |
Create user |
| PUT | /api/v1/users/:id/status |
Update status |
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/settings |
List settings |
| PUT | /api/v1/settings/:key |
Update setting |
| Role | Permissions |
|---|---|
admin |
Full access: manage users, settings, all packages |
developer |
View packages, upload private packages |
readonly |
View and download only |
See config/config.yaml for all options:
| Section | Key | Description |
|---|---|---|
server |
host, port |
HTTP listen address |
server |
read_timeout, write_timeout |
Request timeouts |
database |
user, password, host, port, dbname |
MySQL connection |
database |
max_idle_conns, max_open_conns |
Connection pool |
storage |
private_dir |
Private package storage path |
storage |
cache_dir |
Proxy cache storage path |
proxy |
upstream_url |
Upstream PyPI URL |
proxy |
timeout, max_retries |
Upstream request settings |
proxy |
index_ttl |
Simple index cache TTL (seconds) |
auth |
jwt_secret |
JWT signing secret |
auth |
expire_hours |
Token expiration |
log |
level |
Log level (debug/info/warn/error) |
log |
dir |
Log directory |
log |
max_size, max_backups, max_age |
Log rotation |
Logs are written to both stdout and rotated log files under ./logs/:
| File | Contents |
|---|---|
pigo-YYYYMMDD.log |
Application-level logs |
access-YYYYMMDD.log |
HTTP access logs (every request) |
error-YYYYMMDD.log |
Error-level and above |
proxy-YYYYMMDD.log |
Upstream proxy requests |
Each log entry is JSON-formatted and includes a request_id for request tracing.
| Target | Description |
|---|---|
make fe |
Build Vue frontend |
make build |
Build Go backend |
make build-all |
Build frontend → embed → backend |
make run |
Run with go run |
make test |
Run tests with race detection |
make fmt |
Format Go code |
make lint |
Run go vet |
make clean |
Remove build artifacts |