PulpUI is a community driven single-page application that talks to a running pulpcore instance over its REST API, giving that content - across whichever plugins your Pulp deployment has installed - a shared, consistent web UI instead of requiring the CLI or raw API calls.
- Task Management
- User / Group / Role management
- Content Signing Keys
- Cross-plugin search
- Ansible (repositories, remotes, collections, namespaces, approvals, imports)
- File (repositories, remotes)
- RPM (content)
- Container (execution environments, tags, manifests)
- Node.js >= 22.32.2
- npm >= 10 (macOS or Linux)
- Python 3 + pip (only for the optional
pulp-cli)
Follow the pulp-oci-images quickstart
mkdir -p ~/pulp-backend-oci/{settings/certs,pulp_storage,pgsql,containers}
cd ~/pulp-backend-oci/
echo "
CONTENT_ORIGIN='http://$(hostname):8080'
ANSIBLE_API_HOSTNAME='http://$(hostname):8080'
ANSIBLE_CONTENT_HOSTNAME='http://$(hostname):8080/pulp/content'
" >> settings/settings.pycd ~/pulp-backend-oci/
podman run --publish 8080:80 \
--replace --name pulp \
--volume "$(pwd)/settings":/etc/pulp \
--volume "$(pwd)/pulp_storage":/var/lib/pulp \
--volume "$(pwd)/pgsql":/var/lib/pgsql \
--volume "$(pwd)/containers":/var/lib/containers \
docker.io/pulp/pulpcurl localhost:8080/pulp/api/v3/status/ | jqpodman exec -it pulp pulpcore-manager reset-admin-password --password adminpip install pulp-cli[pygments]
pulp config create --username admin --base-url http://localhost:8080 --password admin
pulp --help
pulp user listEverything below works the same on macOS and Linux.
git clone https://github.com/pulp/pulp-ui
cd pulp-ui
npm cinpm ci installs the exact versions of package-lock.json and also installs the git hooks
described under Git hooks. Use plain npm ci; no extra flags are needed.
npm run startOpen http://localhost:8002/.
The dev server proxies the API paths (/pulp/, /api/, /auth/, /assets/, /extensions/,
/v2/, /static/rest_framework/) to a Pulp at http://localhost:8080 unless API_PROXY says
otherwise. Do NOT use the webpack proxy in production.
Point the dev server at a Pulp that listens elsewhere, including one behind HTTPS:
API_PROXY=https://pulp.example.org npm start- The proxy sends the target's own
Hostand presents the target's origin in theOriginandRefererheaders. Pulp checks these for requests that change data after a browser sign-in (it refuses them with a CSRF error otherwise), so sign-in, reads, logout and writes all work throughhttp://localhost:8002/ui/. The proxy adds no credential of its own. - The dev server listens on all interfaces when the target is on your machine (the default
http://localhost:8080), and on127.0.0.1only whenAPI_PROXYnames any other target. The proxy presents the target's own origin, so a dev server that anyone on your network could reach would be a relay to the target. SetDEV_HOSTto choose the address yourself, for exampleDEV_HOST=0.0.0.0to expose it on purpose orDEV_HOST=127.0.0.1to keep a local target private. - To use another port, for example when 8002 is taken:
npm start -- --port 8012. - Use Chrome or Firefox. A deployment that sets
Securecookies is reached over plainhttp://localhost, which these browsers accept for localhost; Safari does not. - TLS certificates of the target are verified. For a lab with a self-signed certificate, trust
it for Node instead of turning verification off:
NODE_EXTRA_CA_CERTS=/path/to/ca.pem API_PROXY=https://pulp.example.org npm start. - The dev server serves its own
pulp-ui-config.json(the repository's default), not the one of the target deployment.
npm run buildThe production build is written to dist/. It needs no environment variables inside a git
checkout.
npm test
npm test -w @pulp-ui/sdkThe first runs the application's unit and component tests, the second the SDK's tests.
The Playwright projects take their target and accounts from the environment only; no host or
credential is stored in the repository. PULP_UI_E2E_BASE_URL is the UI root and must end in
/ui/. Install the browser once with npx playwright install chromium.
The smoke project signs in with one account against a built UI served next to a throwaway Pulp (this is what CI runs):
PULP_UI_E2E_BASE_URL=http://127.0.0.1:8002/ui/ \
PULP_UI_E2E_USERNAME=admin PULP_UI_E2E_PASSWORD=admin \
npx playwright test --project=smokeThe remote projects (remote-admin and remote-viewer) run against a deployment you own, with
an administrator and a limited account. The accounts come from a JSON file named by
PULP_UI_E2E_ACCOUNTS, shaped like
{
"admin": { "username": "...", "password": "..." },
"viewer": { "username": "...", "password": "..." }
}Keep the file outside the repository with mode 0600. The tests create and delete only
objects named zz-e2e-.... The target is either a deployed UI or the dev server of the
previous section:
PULP_UI_E2E_ACCOUNTS=/path/to/accounts.json \
PULP_UI_E2E_BASE_URL=http://127.0.0.1:8002/ui/ \
npx playwright test --project=remote-admin --project=remote-viewerOutput of the remote projects (screenshots, the HTML report) can show data of that deployment; keep it local. These projects record no Playwright trace, because a trace keeps the headers of every request, including the sign-in request with the account's credential. The smoke project, which runs against a throwaway local instance, keeps traces on failure.
npm ci points git at the hooks in .githooks. They run scripts/check-public.mjs, which
refuses internal hostnames, private addresses and other details that must not be published,
before a commit and before a push; CI runs it again over the whole tree. You can add a private
denylist of your own terms in a file outside the repository, named by the
PUBLIC_CHECK_DENYLIST environment variable or by git config publiccheck.denylist. When it
is configured but unreadable, or holds no entry, the check fails instead of passing silently.
When none is configured, the hooks say so on every run: only the public rules ran, and internal
names that those rules cannot recognise are not checked.
A production build (npm run build) can be further configured by serving a /pulp-ui-config.json alongside the built UI, mapped at /.
| Key | Default | Purpose |
|---|---|---|
API_BASE_PATH |
/pulp/api/v3/ |
Change when using domains or a different path |
UI_BASE_PATH |
/ui/ |
Change when only serving index in a subdirectory, or want different browser path prefix |
UI_EXTERNAL_LOGIN_URI |
null |
Set to something like /login/ when using SSO |
EXTRA_VERSION |
"" |
An extra version string to display in about modal |
See the Pulp developer guide to contribute, or reach the community on Discourse / Matrix (#pulp, #pulp-dev)
