Skip to content

feat: add dev container with all Pulp services for AI agents#1062

Merged
dkliban merged 1 commit into
pulp:mainfrom
dkliban:dev-env-testing
Apr 19, 2026
Merged

feat: add dev container with all Pulp services for AI agents#1062
dkliban merged 1 commit into
pulp:mainfrom
dkliban:dev-env-testing

Conversation

@dkliban
Copy link
Copy Markdown
Member

@dkliban dkliban commented Apr 19, 2026

Summary

  • Adds a self-contained development container (dev-container/) with PostgreSQL 16, Redis, and all three Pulp services (api, content, worker) managed by supervisord
  • Includes helper scripts: pulp-add-patch, pulp-remove-patch, pulp-restart, pulp-test
  • GitHub Action builds and pushes ghcr.io/<owner>/hosted-pulp-dev-env:<branch> on every push to any branch
  • .CLAUDE.md documents all commands, services, and alcove /workspace volume integration
  • Verified: all 5 services running, API responding, DB + Redis connected, 11 plugins loaded

Test plan

  • GitHub Action builds image successfully
  • Container starts with all services (PostgreSQL, Redis, pulp-api, pulp-content, pulp-worker)
  • /pulp/api/v3/status/ returns healthy status with all plugins
  • Test pulp-add-patch / pulp-remove-patch scripts
  • Test pulp-test with mounted workspace
  • Test alcove integration with /workspace volume

🤖 Generated with Claude Code

Summary by Sourcery

Add a self-contained development container image that runs all Pulp services with PostgreSQL and Redis for local development and AI agent integration.

New Features:

  • Provide a dev container image that bundles Pulp API, content, worker services with PostgreSQL and Redis under supervisord.
  • Add helper CLI scripts for patch management, service restarts, and running tests inside the dev container.

Enhancements:

  • Introduce Pulp dev settings tailored for local development with domain support and token auth disabled to mirror hosted configuration.

Build:

  • Add a Dockerfile for building the Pulp dev environment image with all dependencies and pre-applied production patches.

CI:

  • Add a GitHub Actions workflow to build and push the dev container image to GHCR on every branch push.

Documentation:

  • Document dev container usage, configuration, commands, and Alcove /workspace integration in .CLAUDE.md.

Adds a self-contained development container (dev-container/) that runs
PostgreSQL 16, Redis, and all three Pulp services (api, content, worker)
managed by supervisord. Includes helper scripts for patch management,
service restarts, and testing. A GitHub Action builds and pushes the
image to GHCR on every branch push.

The /workspace volume follows alcove conventions for shared access
between the Skiff container and the dev environment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 19, 2026

Reviewer's Guide

Adds a new UBI9-based dev container image that runs PostgreSQL, Redis, and all three Pulp services under supervisord, plus CI automation to build/push the image and helper scripts and docs for patching, restarting, and testing within the container.

Sequence diagram for dev container startup and service initialization

sequenceDiagram
    actor Developer
    participant DockerEngine
    participant DevContainer
    participant Entrypoint as entrypoint_sh
    participant Postgres as PostgreSQL16
    participant Redis
    participant Pulpcore as pulpcore_manager
    participant Supervisor as supervisord

    Developer->>DockerEngine: docker run hosted-pulp-dev-env
    DockerEngine->>DevContainer: Start container with entrypoint
    DevContainer->>Entrypoint: Execute /entrypoint.sh

    Entrypoint->>Postgres: pg_ctl start
    loop Wait for PostgreSQL
        Entrypoint->>Postgres: pg_isready
        Postgres-->>Entrypoint: ready when accepting connections
    end

    Entrypoint->>Postgres: Create user pulp (if missing)
    Entrypoint->>Postgres: Create database pulp (if missing)

    Entrypoint->>Redis: Start redis-server (daemon)

    Entrypoint->>DevContainer: Check /workspace/pulp-service
    alt Dev source present
        Entrypoint->>DevContainer: pip install -e /workspace/pulp-service/pulp_service
    end

    Entrypoint->>Pulpcore: pulpcore-manager migrate --noinput
    Entrypoint->>Pulpcore: reset-admin-password (PULP_DEFAULT_ADMIN_PASSWORD)

    Entrypoint->>Postgres: pg_ctl stop
    Entrypoint->>Redis: redis-cli shutdown

    Entrypoint->>Supervisor: Start supervisord -n -c /etc/supervisord.conf
    Supervisor->>Postgres: Manage PostgreSQL program
    Supervisor->>Redis: Manage Redis program
    Supervisor->>DevContainer: Start pulp-api, pulp-content, pulp-worker
Loading

File-Level Changes

Change Details Files
Introduce a dev container Docker image that bundles Pulp services with PostgreSQL and Redis and pre-applies production patches.
  • Add UBI9-based Dockerfile that installs Python 3.11, system dependencies, PostgreSQL 16, Redis, and pulpcore into a dedicated virtualenv
  • Create pulp system user, filesystem layout, static asset collection, and permissions for logs, media, and tmp directories
  • Copy in existing Pulp entrypoint utilities and apply production patch files into the pulpcore site-packages at build time
  • Generate symmetric key material for encrypted DB fields and initialize PostgreSQL cluster with trust-based local auth
dev-container/Dockerfile
Configure supervisord to manage PostgreSQL, Redis, and all Pulp runtime services inside the dev container.
  • Define supervisord as the main process with logging and control socket configuration
  • Add managed programs for PostgreSQL and Redis with appropriate users, restart policies, and log files
  • Add managed programs for pulp-api, pulp-content, and pulp-worker with environment wiring to the Pulp virtualenv and settings file
dev-container/supervisord.conf
Implement an entrypoint that bootstraps the database and runtime environment before handing control to supervisord.
  • Start PostgreSQL directly, wait for readiness, and idempotently create the pulp user and database
  • Start Redis in the background, then optionally install a workspace checkout of pulp-service in editable mode if present
  • Run Django migrations and reset the admin password using pulpcore-manager under the pulp user
  • Shut down the bootstrap PostgreSQL/Redis processes and then exec supervisord to manage long-running services
dev-container/entrypoint.sh
Add Pulp dev settings tuned for a single-node container environment with domain support and disabled token auth.
  • Define local Postgres connection parameters, Redis URL, and basic caching toggle
  • Configure media, storage backend, working directory, and allowed content checksums
  • Enable domain support and explicitly disable token authentication, mirroring hosted Pulp behavior
dev-container/settings.py
Provide helper CLI scripts inside the container for patch management, service restart, and running tests from a mounted workspace.
  • Introduce pulp-add-patch and pulp-remove-patch scripts that operate on pulpcore site-packages to apply or revert patch files
  • Add pulp-restart wrapper that restarts all or specific Pulp services via supervisorctl
  • Add pulp-test helper that runs the functional test suite from /workspace/pulp-service by default, with override via PULP_SERVICE_DIR
dev-container/scripts/pulp-add-patch
dev-container/scripts/pulp-remove-patch
dev-container/scripts/pulp-restart
dev-container/scripts/pulp-test
Document the dev container usage, configuration, and Alcove integration for AI agents and developers.
  • Describe image naming, branch-to-tag mapping, and docker run invocation including /workspace volume and ports
  • List managed services, environment variables, helper commands, log locations, and admin credentials
  • Explain Alcove /workspace sharing semantics and high-level architecture of the three-service Pulp model in the container
.CLAUDE.md
Automate building and publishing the dev container to GitHub Container Registry on every branch push.
  • Create GitHub Actions workflow that checks out the repo, configures Buildx, and logs into ghcr.io with GITHUB_TOKEN
  • Derive a Docker tag from the branch name by replacing slashes with dashes for tag safety
  • Build the dev-container/Dockerfile and push the resulting image to ghcr.io//hosted-pulp-dev-env:
  • Enable build cache reuse via GitHub Actions cache-from/cache-to configuration
.github/workflows/build-dev-container.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The entrypoint script manually starts/stops PostgreSQL and Redis before handing over to supervisord, while supervisord is also configured to manage those same processes; consider running migrations against the supervisord-managed services (e.g., by starting supervisord first, then using supervisorctl or a one-shot command) to avoid duplicated process management and potential race conditions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The entrypoint script manually starts/stops PostgreSQL and Redis before handing over to supervisord, while supervisord is also configured to manage those same processes; consider running migrations against the supervisord-managed services (e.g., by starting supervisord first, then using `supervisorctl` or a one-shot command) to avoid duplicated process management and potential race conditions.

## Individual Comments

### Comment 1
<location path="dev-container/settings.py" line_range="6-13" />
<code_context>
+DOMAIN_ENABLED = True
+SECRET_KEY = "dev-secret-key-not-for-production"
+
+DATABASES = {
+    "default": {
+        "ENGINE": "django.db.backends.postgresql",
+        "NAME": "pulp",
+        "USER": "pulp",
+        "PASSWORD": "",
+        "HOST": "localhost",
+        "PORT": "5432",
+    }
+}
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Align the database password configuration with how the PostgreSQL role is created, or make it explicit that trust auth is used.

The entrypoint creates the `pulp` DB role with a password (`CREATE USER pulp WITH SUPERUSER PASSWORD 'pulp'`), but this config sets `

Suggested implementation:

```python
DOMAIN_ENABLED = True
SECRET_KEY = "dev-secret-key-not-for-production"

# NOTE: The dev container entrypoint creates the 'pulp' PostgreSQL role with password 'pulp':
#   CREATE USER pulp WITH SUPERUSER PASSWORD 'pulp';
# This database configuration is for development only and assumes that setup.
DATABASES = {

```

```python
        "USER": "pulp",
        "PASSWORD": "pulp",

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread dev-container/settings.py
Comment on lines +6 to +13
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "pulp",
"USER": "pulp",
"PASSWORD": "",
"HOST": "localhost",
"PORT": "5432",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Align the database password configuration with how the PostgreSQL role is created, or make it explicit that trust auth is used.

The entrypoint creates the pulp DB role with a password (CREATE USER pulp WITH SUPERUSER PASSWORD 'pulp'), but this config sets `

Suggested implementation:

DOMAIN_ENABLED = True
SECRET_KEY = "dev-secret-key-not-for-production"

# NOTE: The dev container entrypoint creates the 'pulp' PostgreSQL role with password 'pulp':
#   CREATE USER pulp WITH SUPERUSER PASSWORD 'pulp';
# This database configuration is for development only and assumes that setup.
DATABASES = {
        "USER": "pulp",
        "PASSWORD": "pulp",

@dkliban dkliban merged commit 5927b48 into pulp:main Apr 19, 2026
1 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant