Skip to content

Haelle/pulp-hub

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

132 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PulpHub

A Pulp repository viewer UI, inspired by Docker Hub.

Supports container (OCI) repositories, file repositories, and pull-through cache display (DockerHub, Quay.io, PyPI, npm) with client configuration commands.

Image on DockerHub

Installation

Prerequisites

  • Docker with Docker Compose
  • pip/pipx (for pulp-cli)

Quick start

# 1. Start Pulp + PulpHub
docker compose -f docker-compose.demo.yml up -d
# Wait ~30s for Pulp to fully start

# 2. Populate Pulp with test data
pip install pulp-cli[container]
# configured by default to work with the docker-compose Pulp instance
./bin/setup.sh
# populates the Pulp instance configured via ./bin/setup.sh
./bin/seed.sh

# 3. Open PulpHub
# http://localhost:8080
# Pulp URL: http://localhost:8081
# Credentials: admin / admin

Use with an existing Pulp instance

docker run -d -p 8080:80 \
  -e PULP_URL=https://your.pulp.example.com \
  docker.io/estb/pulp-hub:latest

Open http://localhost:8080 and log in.

CORS: the Pulp instance must allow cross-origin requests from PulpHub's origin. See nginx/pulp-cors-proxy.conf for an example reverse proxy configuration.

Configuration

PulpHub is configured at runtime via environment variables — no rebuild needed when changing the target Pulp instance. See docs/configuration.md for the full reference.

Variable Required Description
PULP_URL Public URL of the Pulp API as seen by the user's browser (see docs/configuration.md)

Example with docker-compose.yml:

services:
  pulphub:
    image: docker.io/estb/pulp-hub:latest
    ports:
      - '8080:80'
    environment:
      PULP_URL: http://localhost:8081

The container fails to start with a clear error message if PULP_URL is missing.

Authentication

PulpHub supports two authentication modes:

  • Session auth (preferred): logs in via Django's /auth/login/ endpoint, then uses a sessionid cookie. The password is sent once and not stored client-side. Detected automatically — if the Pulp instance exposes /auth/login/, session auth is used.
  • Basic auth (fallback): sends Authorization: Basic header on every request. Used when session auth is not available.

Session auth with cross-origin deployment

If PulpHub and Pulp are on different origins (e.g. hub.example.com and registry.example.com), the Pulp reverse proxy needs extra configuration:

# Specific origin (not wildcard) + credentials
add_header Access-Control-Allow-Origin "https://hub.example.com" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-CSRFToken" always;

# Rewrite Django cookies for cross-origin use (requires nginx >= 1.19.3)
proxy_cookie_flags sessionid SameSite=None Secure;
proxy_cookie_flags csrftoken SameSite=None Secure;

HTTPS is required for cross-origin session auth (SameSite=None cookies require Secure).

See nginx/pulp-cors-proxy.conf for the full example with commented-out session auth lines.

Pull-through cache (OCI)

To test an image pull through the pull-through cache over HTTP (local dev):

# Login (required once)
podman login --tls-verify=false localhost:8081 -u admin -p admin

# Pull through the cache
podman pull --tls-verify=false localhost:8081/dockerhub-cache/library/nginx:latest

Note: --tls-verify=false is required because Pulp is exposed over HTTP. In production with TLS, this flag is not needed.

Docker Hub authentication (optional)

To bypass Docker Hub rate limiting during seeding, seed.sh supports authentication via environment variables:

# Edit .env with your credentials
cp .env.example .env
./bin/seed.sh

The password is a Personal Access Token, not the account password. Without these variables, seed.sh works normally in anonymous mode.

Development

Il faut lancer un Pulp de dev et s'y connecter, par défaut le Pulp de dev tourne sur localhost:8081.

Dev prerequisites

Start Pulp for development

make create-pulp   # First time: creates Pulp + CORS proxy on http://localhost:8081
# Wait ~30s for Pulp to start

make start-pulp    # Restart after a stop

Devcontainer

make up            # Start the devcontainer
make setup         # Configure pulp-cli (default URL: http://host.docker.internal:8081)
make seed          # Populate Pulp with test data
make dev           # Start the dev server (http://localhost:5173)

Stop Pulp

make stop-pulp

Commands

make help

Tests

make test          # E2E Playwright
make test-record   # Re-record tapes

See docs/e2e-tests.md for the Talkback setup, the mocked /auth/* endpoints, and the recommended workflow for adding new tests without re-recording the whole suite.

Pulp reference

On-demand mode

Pulp operates in on_demand mode: during a sync, only metadata (manifests, tags) are downloaded. Layers (blobs) are fetched on demand during a pull.

Consequence: only synced tags are available. To add a new tag:

# Add a tag to the remote filter
pulp container remote update \
  --name "dockerhub/library/alpine" \
  --include-tags '["3.17","3.18","3.19","latest"]'

# Re-sync the repo
pulp container repository sync \
  --name "dockerhub/library/alpine" \
  --remote "dockerhub/library/alpine"

Tag management

Only tags filtered via --include-tags on the remote are synced. A pull on a non-synced tag will return manifest unknown.

Docker Hub rate limiting

Without authentication, Docker Hub limits to ~100 pulls/6h. Each synced tag consumes pulls (manifests + layers). This is why --include-tags filters on a small number of tags in seed.sh. Without this filter, syncing alpine would pull hundreds of tags and exhaust the quota.

About

Modern Pulp UI to Read infos about OCI, NPM, Python, Files on your Pulp instance

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors