Pip Package Index Configuration Guide

This guide explains how pip searches for packages across different repositories and how to configure multiple package indexes effectively.

Table of Contents

🔍 Package Search Order

Option 1: Using -i (Index URL)

Use Case: Replace default PyPI completely

pip install -i http://localhost:8080/simple/ some-package

Search Order:

  1. ✅ Your custom index first (http://localhost:8080/simple/)
  2. ✅ Official PyPI as fallback (https://pypi.org/simple/)

⚠️ Limitation: If your private server is down, installation may fail even for public packages.

Use Case: Add private repository while keeping PyPI as primary source

pip install --extra-index-url http://localhost:8080/simple/ some-package

Search Order:

  1. ✅ Official PyPI first (https://pypi.org/simple/)
  2. ✅ Your custom index second (http://localhost:8080/simple/)

✅ Advantage: Robust fallback behavior - public packages always available.

Option 3: Multiple Extra Indexes

Use Case: Multiple private repositories

pip install \
  --extra-index-url http://localhost:8080/simple/ \
  --extra-index-url http://another-repo:8080/simple/ \
  some-package

Search Order:

  1. Official PyPI
  2. First extra index
  3. Second extra index
  4. And so on…

📝 Example Requirements File

# requirements.txt
--extra-index-url http://localhost:8080/simple/
--trusted-host localhost

# Standard packages (from PyPI)
requests>=2.28.0
numpy>=1.21.0
pandas>=1.3.0

# Private packages (from your private repo)
my-private-package>=1.0.0
internal-tools>=2.1.0

⚙️ Configuration Methods

Best for: Project-specific package sources

# requirements.txt
--extra-index-url http://localhost:8080/simple/
--trusted-host localhost

# Your dependencies here
private-package>=1.0.0
public-package>=2.0.0

Install with:

pip install -r requirements.txt

2. Command Line Arguments

Best for: One-time installations or testing

pip install -r requirements.txt --extra-index-url http://localhost:8080/simple/ --trusted-host localhost

3. Global pip Configuration

Best for: System-wide or user-wide defaults

Linux/macOS: ~/.pip/pip.conf

[global]
extra-index-url = http://localhost:8080/simple/
trusted-host = localhost

[install]
trusted-host = localhost

Windows: %APPDATA%\pip\pip.ini

[global]
extra-index-url = http://localhost:8080/simple/
trusted-host = localhost

[install]
trusted-host = localhost

4. Environment Variables

Best for: CI/CD pipelines and containerized environments

# Linux/macOS
export PIP_EXTRA_INDEX_URL=http://localhost:8080/simple/
export PIP_TRUSTED_HOST=localhost
pip install -r requirements.txt

# Windows PowerShell
$env:PIP_EXTRA_INDEX_URL="http://localhost:8080/simple/"
$env:PIP_TRUSTED_HOST="localhost"
pip install -r requirements.txt

🔄 Package Installation Flow

How pip Searches for Packages

When you run pip install package-name, here’s what happens:

Example 1: Private Package Installation

pip install --extra-index-url http://localhost:8080/simple/ my-private-package

Flow:

1. pip install my-private-package
   ↓
2. Check official PyPI (https://pypi.org/simple/)
   → my-private-package not found
   ↓  
3. Check extra index (http://localhost:8080/simple/)
   → my-private-package found! ✅
   ↓
4. Install from your private repository

Example 2: Public Package Installation

pip install --extra-index-url http://localhost:8080/simple/ requests

Flow:

1. pip install requests
   ↓
2. Check official PyPI (https://pypi.org/simple/)
   → requests found! ✅
   ↓
3. Install from official PyPI
   (Extra indexes not checked when package found in primary index)

🚨 Important Considerations

1. Version Priority Resolution

When the same package exists in multiple repositories, pip chooses based on:

Priority Order:

  1. Highest version number (regardless of source)
  2. Source preference (only if versions are equal)

Example:

Official PyPI: my-package==1.0.0
Private Repo:  my-package==1.1.0

Result: pip installs 1.1.0 from private repo ✅

2. Network Reliability

❌ Risky Approach (using -i):

# If your private server is down, this will fail even for public packages
pip install -i http://localhost:8080/simple/ requests

✅ Safe Approach (using –extra-index-url):

# Falls back to PyPI if private server is down
pip install --extra-index-url http://localhost:8080/simple/ requests

3. Security Considerations

  • Always use HTTPS in production environments
  • Verify package authenticity from private repositories
  • Use authentication for private repositories containing sensitive code

🐳 Docker Integration

Dockerfile Example

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# Copy requirements first for better caching
COPY requirements.txt .

# Install packages with private repo access
RUN pip install -r requirements.txt \
    --extra-index-url http://your-private-repo:8080/simple/ \
    --trusted-host your-private-repo

COPY . .

CMD ["python", "app.py"]

Docker Compose with Private PyPI

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    environment:
      - PIP_EXTRA_INDEX_URL=http://pypi-server:8080/simple/
      - PIP_TRUSTED_HOST=pypi-server
    depends_on:
      - pypi-server
  
  pypi-server:
    image: pypiserver/pypiserver:latest
    ports:
      - "8080:8080"
    volumes:
      - ./packages:/data/packages
    command: -p 8080 -a . /data/packages

🛠️ Troubleshooting

Common Issues

Issue: Could not find a version that satisfies the requirement

  • Solution: Check if package exists in your private repository
  • Debug: Use pip install --verbose to see search process

Issue: Connection error or timeout

  • Solution: Verify private repository URL and network connectivity
  • Workaround: Use --extra-index-url instead of -i for fallback

Issue: SSL certificate verify failed

  • Solution: Add --trusted-host your-domain.com or configure proper SSL certificates

Issue: Wrong package version installed

  • Solution: Check version numbers across repositories; pip chooses highest version

Debug Commands

# Show pip configuration
pip config list

# Verbose installation to see search process
pip install --verbose package-name

# Show available versions from all sources
pip index versions package-name

# Check which repository a package came from
pip show package-name