# Docker Hub Scraper · Images, Tags, Pulls & Publishers (`reapx/docker-hub-scraper`) Actor

Scrape Docker Hub container images, tags, pull counts, star counts, publishers, official vs community status, and categories.

- **URL**: https://apify.com/reapx/docker-hub-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Developer tools, Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 docker hub container record scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## Docker Hub Scraper · Images, Tags, Pulls & Publishers

Extract structured container image data, star counts, total download pulls, publisher verification status, official vs community categorization, and image tags from Docker Hub. Fast, lightweight, HTTP-only API client with pay-per-event pricing.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/docker-hub-scraper/](https://reapx.dev/data/docker-hub-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/docker-hub-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/docker-hub-scraper). Questions: reapxdev@proton.me

***

### 💡 Overview & Detailed Features

**Docker Hub Scraper** provides comprehensive, real-time access to the public Docker Hub container repository registry ecosystem (`hub.docker.com`). Whether you are conducting software supply chain security audits, tracking open-source container adoption trends, analyzing cloud-native technology market shares, or building automated developer tooling, this scraper retrieves clean, addressable JSON records directly from Docker Hub without requiring browser automation or API keys.

#### Key Capabilities

- **Complete Repository Metadata:** Extract canonical repository slugs (`namespace/name`), namespace handles, image names, maintainer-provided short descriptions, total download pull counts, star counts, automated build flags, and official status.
- **Official vs Community Categorization:** Filter specifically for Docker Official Images (`library/*` curated by Docker) or third-party community and organization repositories (`bitnami/*`, `hashicorp/*`, `grafana/*`, etc.).
- **Pull Band Standardized Analytics:** Automated categorization of image download volumes into standardized, comparable pull bands (`10B+`, `1B-10B`, `100M-1B`, `10M-100M`, `1M-10M`, `100K-1M`, `10K-100K`, `<10K`).
- **Publisher & Maintainer Insights:** Differentiate between Docker Official curation, verified organization publishers, and individual community contributors.
- **Optional Tag & Architecture Extraction:** Enable tag details fetching to extract recent OCI image tags, version tags, and build architectures directly from repository registries.
- **Pure HTTP Execution:** Zero headless browser overhead. Uses lightweight HTTP client calls for maximum throughput, low resource usage (256–512 MB RAM), and fast execution speed.
- **Transparent Event Pricing:** Pay strictly per scraped image record. No hidden platform markup or continuous server rental costs.

***

### ⬇️ Input

The actor accepts structured JSON input specifying search queries, publisher filter constraints, total dataset capacity limits, and tag retrieval preferences.

#### Input Parameters Specification

| Parameter | Type | Required | Default / Prefill | Description |
| :--- | :--- | :--- | :--- | :--- |
| `searchQuery` | `string` | No | `"nginx"` | Technology keyword, application name, or repository search pattern (e.g., `nginx`, `postgres`, `python`, `redis`, `kubernetes`, `monitoring`). Leaving this field empty returns general top-ranked repositories on Docker Hub. |
| `filterType` | `string` | No | `"all"` | Publisher filter category. Options: `all` (both official and community images), `official` (Docker Official Images only), or `community` (user and organization repositories only). |
| `maxItems` | `integer` | No | `100` | Maximum total number of repository records to scrape and push to the default dataset. Range: `1` to `5000`. |
| `includeTags` | `boolean` | No | `false` | When set to `true`, queries the Docker Hub tags endpoint for each repository to include recent image tag names. |

#### Worked Input Examples

##### Example 1: Scraping Official Base Operating Systems

```json
{
  "searchQuery": "ubuntu",
  "filterType": "official",
  "maxItems": 50,
  "includeTags": true
}
```

##### Example 2: Tracking Community Database Repositories

```json
{
  "searchQuery": "postgres",
  "filterType": "community",
  "maxItems": 100,
  "includeTags": false
}
```

##### Example 3: Auditing Cloud-Native Observability Tools

```json
{
  "searchQuery": "monitoring",
  "filterType": "all",
  "maxItems": 200,
  "includeTags": false
}
```

***

### ⬆️ Output

Scraped container repositories are pushed incrementally to the default dataset. Each row contains structured key-value pairs representing a single Docker image entity.

#### Output Dataset Schema

| Field | Type | Description | Sample Value |
| :--- | :--- | :--- | :--- |
| `slug` | `string` | Primary canonical entity identifier formatted as `namespace/name`. | `"library/nginx"` |
| `namespace` | `string` | Repository namespace or publisher handle (`"library"` for official images). | `"library"` |
| `name` | `string` | Repository name without namespace prefix. | `"nginx"` |
| `shortDescription` | `string` | Maintainer-provided repository description snippet. | `"Official build of Nginx."` |
| `starCount` | `integer` | Total number of community stars received on Docker Hub. | `21352` |
| `pullCount` | `integer` | Total cumulative download pulls recorded by Docker Hub. | `13220858430` |
| `pullBand` | `string` | Categorized pull volume tier (`10B+`, `1B-10B`, `100M-1B`, etc.). | `"10B+"` |
| `isOfficial` | `boolean` | `true` if the image is a Docker Official Image curated by Docker. | `true` |
| `isAutomated` | `boolean` | `true` if automated builds are configured from source control. | `false` |
| `publisher` | `string` | Display name of the publisher or `"Docker Official Image"`. | `"Docker Official Image"` |
| `hubUrl` | `string` | Web URL to the container repository on Docker Hub. | `"https://hub.docker.com/_/nginx"` |
| `recentTags` | `array[string]` | Array of recent image tag names (populated if `includeTags` is true). | `["latest", "alpine", "1.25.3"]` |
| `scrapedAt` | `string` | ISO 8601 UTC timestamp recording when the item was scraped. | `"2026-08-03T20:11:24Z"` |

#### Worked Sample Output Records

```json
[
  {
    "slug": "library/nginx",
    "namespace": "library",
    "name": "nginx",
    "shortDescription": "Official build of Nginx.",
    "starCount": 21352,
    "pullCount": 13220858430,
    "pullBand": "10B+",
    "isOfficial": true,
    "isAutomated": false,
    "publisher": "Docker Official Image",
    "hubUrl": "https://hub.docker.com/_/nginx",
    "recentTags": [
      "latest",
      "alpine",
      "1.25.3"
    ],
    "scrapedAt": "2026-08-03T20:11:24Z"
  },
  {
    "slug": "nginx/nginx-ingress",
    "namespace": "nginx",
    "name": "nginx-ingress",
    "shortDescription": "NGINX and NGINX Plus Ingress Controllers for Kubernetes",
    "starCount": 122,
    "pullCount": 1086428245,
    "pullBand": "1B-10B",
    "isOfficial": false,
    "isAutomated": false,
    "publisher": "nginx",
    "hubUrl": "https://hub.docker.com/r/nginx/nginx-ingress",
    "recentTags": [
      "3.6.0",
      "latest-alpine"
    ],
    "scrapedAt": "2026-08-03T20:11:24Z"
  }
]
```

***

### How it works

```
┌─────────────────────────────────────────────────────────┐
│                      Input Parameters                   │
│   (searchQuery, filterType, maxItems, includeTags)       │
└───────────────────────────┬─────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────┐
│           Docker Hub Search API Endpoint                │
│    GET https://hub.docker.com/v2/search/repositories    │
└───────────────────────────┬─────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────┐
│         Record Normalization & Categorization           │
│   • Compute Canonical Slug (namespace/name)             │
│   • Calculate Pull Band (10B+, 1B-10B, etc.)            │
│   • Apply Publisher Filter (Official vs Community)       │
│   • (Optional) Query /v2/repositories/.../tags          │
└───────────────────────────┬─────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────┐
│         Apify Event Charging & Data Pushing             │
│   • Charge Event: image-scraped                         │
│   • Incremental Push to Default Dataset                 │
└─────────────────────────────────────────────────────────┘
```

1. **API Interception & Querying:** The scraper queries Docker Hub's public search v2 REST API (`https://hub.docker.com/v2/search/repositories/`) using direct HTTP GET requests.
2. **Namespace Normalization:** Single-word official repositories (e.g., `nginx`, `ubuntu`, `python`) are automatically prefixed with `library/` to produce canonical, addressable `slug` identifiers (`library/nginx`, `library/ubuntu`).
3. **Publisher Filtering:** In-memory filtering logic evaluates `is_official` metadata against user preferences (`official`, `community`, or `all`).
4. **Pull Band Computation:** Cumulative download pull counts are converted into standardized pull tiers (`10B+`, `1B-10B`, `100M-1B`, `10M-100M`, `1M-10M`, `100K-1M`, `10K-100K`, `<10K`) for aggregate analytics.
5. **Streaming Pushes & Charging:** Every record is charged once via `image-scraped` and pushed to the default dataset immediately.
6. **Automatic Backoff & Resiliency:** Integrated HTTP retry mechanisms handle intermittent network timeouts or rate limits (HTTP 429 / 5xx) with exponential backoff delays.

***

### 🎯 Use Cases & Data Applications

#### 1. Software Supply Chain Security & Audit

Monitor public container registries to maintain verified inventories of base images. Distinguish curated Docker Official Images from third-party community builds, identifying unverified or abandoned container repositories across enterprise pipelines.

#### 2. Technology Adoption & Market Share Analytics

Analyze container pull count velocity and star growth across competing open-source technologies:

- **Relational Databases:** PostgreSQL (`library/postgres`) vs MySQL (`library/mysql`) vs MariaDB (`library/mariadb`)
- **In-Memory Caches:** Redis (`library/redis`) vs Memcached (`library/memcached`) vs KeyDB
- **Web Servers & Ingress Proxies:** Nginx (`library/nginx`) vs HAProxy (`library/haproxy`) vs Traefik (`library/traefik`) vs Caddy (`library/caddy`)

#### 3. Open Source Maintainer & Publisher Intelligence

Track total download volume, community engagement (stars), and build automation status for vendor-published container images (e.g., Bitnami, HashiCorp, Grafana Labs, Elastic, Datadog, MinIO).

#### 4. Vulnerability Audit & CVE Compliance Tooling

Feed extracted Docker Hub container metadata into vulnerability scanners and compliance tools to monitor software component inventories.

***

### 💻 API & Integration Examples

#### Python Integration (via `apify-client`)

```python
from apify_client import ApifyClient

## Initialize client with your Apify API token
client = ApifyClient("YOUR_APIFY_TOKEN")

## Define execution parameters
run_input = {
    "searchQuery": "postgres",
    "filterType": "official",
    "maxItems": 50,
    "includeTags": True
}

## Launch the actor
run = client.actor("reapx/docker-hub-scraper").call(run_input=run_input)

## Fetch scraped items from default dataset
dataset_items = client.dataset(run["defaultDatasetId"]).list_items().items
for item in dataset_items:
    print(f"Slug: {item['slug']} | Pulls: {item['pullCount']:,} | Stars: {item['starCount']} | Publisher: {item['publisher']}")
```

#### Node.js / JavaScript Integration

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const input = {
  searchQuery: 'monitoring',
  filterType: 'community',
  maxItems: 100
};

const run = await client.actor('reapx/docker-hub-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

console.log(`Scraped ${items.length} repositories:`);
items.forEach(item => {
  console.log(`- [${item.pullBand}] ${item.slug} (${item.starCount} stars)`);
});
```

#### cURL & REST API Direct Invocation

```bash
curl -X POST "https://api.apify.com/v2/acts/reapx~docker-hub-scraper/runs?token=YOUR_APIFY_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
           "searchQuery": "redis",
           "filterType": "official",
           "maxItems": 20
         }'
```

***

### ❓ FAQ

##### How are official Docker images identified?

Docker Official Images are curated base images maintained by Docker in partnership with upstream project maintainers. In Docker Hub API, these images carry `is_official: true` and belong to the `library` namespace (e.g., `library/ubuntu`, `library/nginx`).

##### Why is the `slug` formatted as `namespace/name`?

To provide a unique, non-constant addressable key across every container image on Docker Hub, single-word official images are prefixed with `library/`. This ensures 100% addressability across entity pages, databases, and analytics pipelines.

##### Does this scraper require Docker Hub authentication or credentials?

No. The scraper accesses Docker Hub's public v2 search endpoints over plain HTTP. No login, OAuth token, or registry credentials are required.

##### What happens if a search query yields no results?

If a query matches zero repositories, the actor completes successfully with 0 rows returned and charges $0.00 in event fees.

##### Can I scrape thousands of repositories in a single run?

Yes. Adjust the `maxItems` parameter up to `5000`. The scraper automatically handles page pagination and backoff throttling.

##### Is platform usage billed separately?

No. Platform compute usage is fully absorbed within the simple per-event pricing structure (`image-scraped`).

***

### 💬 Your feedback

We actively maintain and update all scrapers in response to upstream platform changes and user feedback.

- **Support Email:** `reapxdev@proton.me`
- **Deep Data Archive:** [reapx.dev/data/docker-hub-scraper/](https://reapx.dev/data/docker-hub-scraper/)
- **Open Datasets:** [Hugging Face Datasets](https://huggingface.co/datasets/reapxdev/docker-hub-scraper) | [Kaggle Datasets](https://www.kaggle.com/datasets/reapxdev/docker-hub-scraper)

***

*Disclaimer: Unofficial - not affiliated with Docker, Inc. Collects public data only. reapx. Contact reapxdev@proton.me.*

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "searchQuery": "nginx",
  "filterType": "official",
  "maxItems": 100,
  "includeTags": false
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "slug": "library/nginx",
  "namespace": "library",
  "name": "nginx",
  "shortDescription": "Official build of Nginx.",
  "starCount": 21352,
  "pullCount": 13220858430,
  "pullBand": "10B+",
  "isOfficial": true,
  "isAutomated": false,
  "publisher": "Docker Official Image",
  "hubUrl": "https://hub.docker.com/_/nginx",
  "recentTags": [],
  "scrapedAt": "2026-08-03T18:12:43.078432+00:00"
}
```

### ⚠️ Run outcomes and error handling

This Actor reports what happened in the run's **status message**, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.

| Outcome | What it means |
|---|---|
| **Success** | Rows were returned and you were charged `image-scraped` at $0.001 per row. |
| **No matches** | The source returned nothing for your filters. **Nothing is charged.** Widen the date window or drop a filter. |

#### What is guaranteed either way

- **Every row is pushed as it is built**, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- **A field absent from the source is absent from the row.** Nothing is inferred, modelled or filled in to make a row look complete.

# Actor input Schema

## `searchQuery` (type: `string`):

<b>Search Query / Technology Keyword</b><br><br>Enter a technology keyword, application name, or repository pattern to query on Docker Hub (e.g., <code>nginx</code>, <code>python</code>, <code>postgres</code>, <code>redis</code>, <code>kubernetes</code>).<br><br><b>Consequence:</b> Specific query terms narrow results to matching image repositories, while broader keywords return a wider variety of container images. Leaving this field empty will return general top-ranked container repositories on Docker Hub.<br><br>Leave this field empty to skip this filter.

## `filterType` (type: `string`):

<b>Publisher Filter (Official vs Community)</b><br><br>Select which publisher category of Docker Hub container repositories to include: <code>all</code> returns both official and community repositories, <code>official</code> restricts output strictly to Docker Official Images curated by Docker, and <code>community</code> returns user- or organization-contributed repositories.<br><br><b>Consequence:</b> Selecting official images narrows output to verified base container images. Leaving this as default retrieves all repository types.

## `maxItems` (type: `integer`):

<b>Maximum Repositories Limit</b><br><br>Set the maximum total number of container repository records to scrape and push to the default dataset.<br><br><b>Consequence:</b> The higher the number, the longer the run takes and the more dataset events are consumed. Lower numbers finish faster and cost less. Range: 1 to 5000.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `includeTags` (type: `boolean`):

<b>Fetch Tag Details & Metadata</b><br><br>Enable this option to query the Docker Hub tags endpoint for each repository, adding recent tag names and architecture details.<br><br><b>Consequence:</b> Enabling tag fetching makes additional API requests for each repository, which slightly increases total execution time.

## Actor input object example

```json
{
  "searchQuery": "nginx",
  "filterType": "all",
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Every Docker Hub container repository record found by this run, one row per image, in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "nginx",
    "filterType": "all",
    "maxItems": 100,
    "includeTags": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/docker-hub-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "nginx",
    "filterType": "all",
    "maxItems": 100,
    "includeTags": False,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/docker-hub-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "nginx",
  "filterType": "all",
  "maxItems": 100,
  "includeTags": false
}' |
apify call reapx/docker-hub-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=reapx/docker-hub-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7Mc7F2bAlKWNs1Tx5/builds/i6hCX5kywjSOU8Ncq/openapi.json
