Container images

Two images. One filter. Wherever you ship.

Every release publishes two distroless Linux imagesto GitHub Container Registry— one packaged as a GitHub Action, one as a standalone HTTP API. Both are built from the same Native AOT engine and tagged in lockstep.

Native AOTDistroless baselinux/amd64 · linux/arm64v13.4.6.2263K+ pulls
Trusted at scale

Real pulls, straight fromGitHub Container Registry— the total downloads GitHub reports across both images.

263K+
Total pulls
across both images
262K+
Action image
GitHub Action runner
1,185
API image
standalone HTTP API

Total downloads as reported by GitHub Container Registry.

🐙

Action container

ghcr.io/ievangelist/profanity-filter — the runner image used by the GitHub Action step. You usually don’t pull this directly; GitHub does it for you when a workflow says uses: IEvangelist/profanity-filter@main.

🛰️

API container

ghcr.io/ievangelist/profanity-filter-api — the standalone HTTP API. Powers the Aspire integration, theProfanityFilter.Client NuGet, and any standalone deployment.

Action container

View on GHCR

The Action container packages the runner the workflow step uses. Powered by.NET 10 Native AOT, it cold-starts in milliseconds, has no .NET runtime to install, and is what makes a singleuses:line work end-to-end.

Pull

terminalbash
docker pull ghcr.io/ievangelist/profanity-filter:13.4.6.2

API container

View on GHCR

A standalone ASP.NET Core minimal-API surface over the same filter engine, plus a SignalR hub for live streaming. Same image theAspire integrationpulls.

Pull

terminalbash
docker pull ghcr.io/ievangelist/profanity-filter-api:13.4.6.2

Run it standalone

The API listens on :8080inside the container. Map the port and you’re live.

terminalbash
# Run the API on http://localhost:8080
docker run --rm \
  --name profanity-filter-api \
  -p 8080:8080 \
  ghcr.io/ievangelist/profanity-filter-api:13.4.6.2

# Optional — mount your own *.txt word lists, merged with the
# built-in 6,500+ word dictionary at startup:
docker run --rm \
  --name profanity-filter-api \
  -p 8080:8080 \
  -v "$(pwd)/CustomData":/app/CustomData:ro \
  ghcr.io/ievangelist/profanity-filter-api:13.4.6.2

Or with Compose

compose.yamlyaml
# compose.yaml
services:
  profanity-filter:
    image: ghcr.io/ievangelist/profanity-filter-api:13.4.6.2
    container_name: profanity-filter-api
    ports:
      - "8080:8080"
    volumes:
      - ./CustomData:/app/CustomData:ro
    restart: unless-stopped

HTTP surface

All routes return JSON. The container also serves an interactiveScalarreference at /scalarand an OpenAPI document at /openapi/v1.json.

MethodPathDescription
POST/profanity/filterApply the filter to a body of text. Returns the filtered output, the matched words, and the per-step trace.
GET/profanity/strategiesList the 14 replacement strategies (Emoji, RedactedRectangle, AngerEmoji, …).
GET/profanity/targetsList the supported filter targets.
GET/profanity/dataList the available word-list data set names (one per language plus any custom mounts).
GET/profanity/data/{name}Return the words in a single data set.
WS/profanity/hubSignalR hub — bi-directional streaming for live UIs (WebSockets / SSE / long-polling).

Try it

terminalbash
curl -X POST http://localhost:8080/profanity/filter \
  -H "content-type: application/json" \
  -d '{
    "text": "What the heck, dude?",
    "strategy": "Emoji"
  }'