Reorg sections, tighten criteria, add new projects (#1437)

* Structural reorg - part 1

Removals (~16 entries that failed the "for Docker" test):
- Container Composition: LLM Harbor
- Deployment: awesome-stacks
- Orchestration: Ansible Linux Docker, ManageIQ, RedHerd Framework
- Reverse Proxy: idle-less
- Service Discovery: etcd, istio (then section deleted)
- Volume: duplicacy-cli-cron
- Security: crowdsec-blocklist-import, dvwassl
- Dev Env: DockerDL, ESP32 Linux builder, Rust Universal Compiler
- Testing: InSpec
- Wrappers: Ansible
- Monitoring SaaS: Prometheus, Broadcom, Splunk-blog (when merging)

Structural moves:
- Service Discovery → folded into Networking (docker-consul, docker-dns, registrator kept; etcd/istio dropped)
- Metadata (1 entry, OCI spec) → deleted
- User Interface > Terminal > {Terminal UI, CLI tools, Other} → flattened to one Terminal subsection
- CI Services (under "Services based on Docker") → merged into CI/CD
- Monitoring Services → merged into Monitoring
- CaaS → merged into PaaS / CaaS
- Top-level Services based on Docker (mostly 💴) → deleted; pricing is signaled by 💴, not topology
- TOC updated to match

CONTRIBUTING.md tightening:
- Added a "for Docker" test framed as one yes/no question
- 12-row example table covering monitoring, reverse proxies, scanners, schedulers, tutorials, awesome-stacks-style submissions
- One-sentence sanity check ("This project exists to ____")
- New entry-description rule: descriptions must make the Docker connection obvious

* Tighten project submission criteria

* Manual review and clean up

* Add relevant project in 2026

* fix lint

* add relevant projects

* Add Cloud Run Compose, fix redirected URLs

- Add Cloud Run Compose under Deployment & Platforms (docker-compose deploys).
- Update GCP Artifact Registry URL to follow docs.cloud.google.com redirect.
- Update CodeFresh URL to its post-acquisition home at octopus.com/codefresh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* remove dead projects

* exclude bot protected website

* clean up

* clean up more

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Julien Bisconti
2026-05-17 23:40:31 +02:00
committed by GitHub
parent da8890dda6
commit aa0df11fba
4 changed files with 644 additions and 688 deletions
+40 -3
View File
@@ -8,17 +8,54 @@ Please read and follow the [Code of Conduct](./CODE_OF_CONDUCT.md).
## What We Accept ## What We Accept
- New high-quality Docker/container-related projects - New high-quality projects that are **for Docker** (see the test below)
- Fixes to descriptions, ordering, or categorization - Fixes to descriptions, ordering, or categorization
- Removal of broken, archived, deprecated, or duplicate entries - Removal of broken, archived, deprecated, or duplicate entries
- Improvements to the Go CLI and GitHub workflows - Improvements to the Go CLI and GitHub workflows
## The "for Docker" Test (read this before submitting)
This list is for projects whose purpose is to make working with Docker better.
It is **not** a directory of "software you can run in a container" — that's most
software ever written. Before opening a PR, apply this test:
> **If you removed the Docker integration, would the project still have a reason to exist?**
>
> - **Yes, it would** → it's a general tool that happens to use Docker. **Reject.**
> - **No, the project is *about* Docker** → it belongs here.
### Examples
| Project shape | Verdict | Why |
| ----------------------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------- |
| Tool that monitors **containers**, container resources, or container logs | ✅ Accept | Its value disappears if you take Docker away. |
| Tool that monitors **a host / server / service** and happens to ship as Docker | ❌ Reject | Its job is monitoring; Docker is just the delivery vehicle. |
| Reverse proxy that **auto-configures from Docker labels/events** | ✅ Accept | Tightly coupled to the Docker API. |
| Reverse proxy that just *runs in* Docker and configures from a static YAML file | ❌ Reject | Same proxy works fine without Docker. |
| Dockerfile linter, image scanner, registry, BuildKit frontend, runtime, SDK | ✅ Accept | Object of work is the Docker image, daemon, or socket. |
| General IaC scanner that **happens to read Dockerfiles** among many formats | ⚠️ Borderline | Allowed if Docker support is a first-class feature, not an afterthought. |
| "Awesome 150 web apps deployable with `docker run`" | ❌ Reject | Belongs in `awesome-selfhosted`; Docker is incidental. |
| Cron / privilege-drop / health-check utility designed for **container init** | ✅ Accept | Solves a problem that only exists *because* of how containers are built. |
| Generic KV store / service mesh / cluster scheduler that supports Docker | ❌ Reject | Existed before Docker, works without it. |
| Tutorial, video, or book whose **subject** is Docker | ✅ Accept | Under Useful Resources / Videos / Where to start. |
| Tutorial that uses Docker as a setup step for an unrelated topic | ❌ Reject | Belongs with the unrelated topic. |
### One-sentence sanity check
Write the sentence: *"This project exists to ____."* If the blank doesn't
contain **Docker, container, image, registry, Dockerfile, Compose, Swarm,
BuildKit, or OCI** — it probably doesn't belong here.
## README Entry Rules ## README Entry Rules
- Use one link per entry. - Use one link per entry.
- Prefer GitHub project/repository URLs over marketing pages. - Prefer GitHub project/repository URLs over marketing pages.
- Keep entries alphabetically sorted within their section. - Keep entries alphabetically sorted within their section (case-insensitive).
- Keep descriptions concise and concrete. - Keep descriptions concise and concrete: one sentence, lead with the verb.
- **The description should make the Docker connection obvious.** "Monitor
unhealthy containers" is good; "Monitor your services" is not — the latter
could be any monitoring tool, and a reviewer can't tell whether the project
passes the test above.
- Use `:yen:` for paid/commercial services. - Use `:yen:` for paid/commercial services.
- Use `:ice_cube:` for stale projects (2+ years inactive). - Use `:ice_cube:` for stale projects (2+ years inactive).
- Do not use `:skull:`; archived/deprecated projects should be removed. - Do not use `:skull:`; archived/deprecated projects should be removed.
+529 -685
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -16,3 +16,4 @@ domains:
- https://www.youtube.com/playlist - https://www.youtube.com/playlist
- https://www.aquasec.com - https://www.aquasec.com
- https://cloudsmith.com - https://cloudsmith.com
- https://pythonspeed.com/
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Normalize :yen: placement in README.md entries.
Transformations (only on list entries — leaves legend lines and section prose alone):
- [Title :yen:](url) - desc -> - [Title](url) - :yen: desc
- [Title](url) :yen:- desc -> - [Title](url) - :yen: desc
- [Title](url) :yen: desc -> - [Title](url) - :yen: desc
- [Title](url) :yen: -> - [Title](url) - :yen:
Idempotent: already-correct lines pass through untouched.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
# Entry where :yen: is inside the link title.
RE_IN_TITLE = re.compile(r'^(\s*[-*]\s+\[)([^\]]*?)\s+:yen:(\s*\]\([^)]+\))(\s*-?\s*)(.*)$')
# Entry where :yen: sits right after the URL, followed by "- desc", " desc", or nothing.
RE_AFTER_URL = re.compile(r'^(\s*[-*]\s+\[[^\]]+\]\([^)]+\))\s+:yen:\s*(-\s*)?(.*)$')
# Already-correct entries: "(url) - :yen: ..."
RE_ALREADY_OK = re.compile(r'\]\([^)]+\)\s+-\s+:yen:(\s|$)')
def transform(line: str) -> str:
if ':yen:' not in line:
return line
if RE_ALREADY_OK.search(line):
return line
m = RE_IN_TITLE.match(line)
if m:
prefix, title, link_close, _sep, desc = m.groups()
desc = desc.lstrip()
if desc:
return f"{prefix}{title.rstrip()}{link_close} - :yen: {desc}"
return f"{prefix}{title.rstrip()}{link_close} - :yen:"
m = RE_AFTER_URL.match(line)
if m:
head, _dash, desc = m.groups()
desc = desc.lstrip()
if desc:
return f"{head} - :yen: {desc}"
return f"{head} - :yen:"
return line
def main(path: str) -> int:
p = Path(path)
original = p.read_text()
out_lines = []
changed = 0
for line in original.splitlines():
new = transform(line)
if new != line:
changed += 1
out_lines.append(new)
# Preserve trailing newline.
new_text = "\n".join(out_lines)
if original.endswith("\n"):
new_text += "\n"
if new_text != original:
p.write_text(new_text)
print(f"{changed} line(s) changed in {path}")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else "README.md"))