From bae26ccdb120b4b694d61dabb9cbb6ecb5d02fa7 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 18:56:36 +0100 Subject: [PATCH 01/29] chore: add .worktrees to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 13ca927..46006cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ website/table.html .idea **/.DS_Store +.worktrees From 08da394e71963585a2da47e4d690b0a72226b01d Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 19:03:06 +0100 Subject: [PATCH 02/29] feat: scaffold Go project with cobra CLI, Makefile, and config Set up the Go module, directory structure, and minimal CLI entrypoint for the awesome-docker Go rewrite. Includes: - cobra-based CLI with version command - Makefile with build/test/lint/check/health/report/clean targets - config/exclude.yaml migrated from tests/exclude_in_test.json - config/website.tmpl.html copied from website/index.tmpl.html - .gitignore updated for Go binary Co-Authored-By: Claude Opus 4.6 --- .gitignore | 3 + Makefile | 23 ++++ cmd/awesome-docker/main.go | 23 ++++ config/exclude.yaml | 18 +++ config/website.tmpl.html | 229 +++++++++++++++++++++++++++++++++++++ go.mod | 10 ++ go.sum | 10 ++ 7 files changed, 316 insertions(+) create mode 100644 Makefile create mode 100644 cmd/awesome-docker/main.go create mode 100644 config/exclude.yaml create mode 100644 config/website.tmpl.html create mode 100644 go.mod create mode 100644 go.sum diff --git a/.gitignore b/.gitignore index 46006cb..b3f098d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ website/table.html .idea **/.DS_Store .worktrees + +# Go +/awesome-docker diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9101c7e --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +BINARY := awesome-docker +.PHONY: build test lint check health report clean + +build: + go build -o $(BINARY) ./cmd/awesome-docker + +test: + go test ./internal/... -v + +lint: build + ./$(BINARY) lint + +check: build + ./$(BINARY) check + +health: build + ./$(BINARY) health + +report: build + ./$(BINARY) report + +clean: + rm -f $(BINARY) diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go new file mode 100644 index 0000000..1ac12ff --- /dev/null +++ b/cmd/awesome-docker/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +func main() { + root := &cobra.Command{ + Use: "awesome-docker", + Short: "Quality tooling for the awesome-docker curated list", + } + root.AddCommand( + &cobra.Command{Use: "version", Short: "Print version", Run: func(cmd *cobra.Command, args []string) { + fmt.Println("awesome-docker v0.1.0") + }}, + ) + if err := root.Execute(); err != nil { + os.Exit(1) + } +} diff --git a/config/exclude.yaml b/config/exclude.yaml new file mode 100644 index 0000000..baf252d --- /dev/null +++ b/config/exclude.yaml @@ -0,0 +1,18 @@ +# URLs or URL prefixes to skip during link checking. +# These are known false positives or rate-limited domains. +domains: + - https://vimeo.com + - https://travis-ci.org/veggiemonk/awesome-docker.svg + - https://github.com/apps/ + - https://twitter.com + - https://www.meetup.com/ + - https://cycle.io/ + - https://www.manning.com/ + - https://deepfence.io + - https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg + - https://www.se-radio.net/2017/05/se-radio-episode-290-diogo-monica-on-docker-security + - https://www.reddit.com/r/docker/ + - https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615 + - https://www.youtube.com/playlist + - https://www.aquasec.com + - https://cloudsmith.com diff --git a/config/website.tmpl.html b/config/website.tmpl.html new file mode 100644 index 0000000..94e88e0 --- /dev/null +++ b/config/website.tmpl.html @@ -0,0 +1,229 @@ + + + + + + + Awesome-docker + + + + + + + + + + + +
+ + + + + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7bed71c --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module github.com/veggiemonk/awesome-docker + +go 1.25.0 + +require github.com/spf13/cobra v1.10.2 + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a6ee3e0 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From f2680c62214d3eeba8dfb201e883fb2f121a70ab Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:17:50 +0100 Subject: [PATCH 03/29] feat: add README parser with entry extraction and section tree building Co-Authored-By: Claude Opus 4.6 --- internal/parser/parser.go | 128 ++++++++++++++++++++++++++++ internal/parser/parser_test.go | 147 +++++++++++++++++++++++++++++++++ internal/parser/types.go | 35 ++++++++ 3 files changed, 310 insertions(+) create mode 100644 internal/parser/parser.go create mode 100644 internal/parser/parser_test.go create mode 100644 internal/parser/types.go diff --git a/internal/parser/parser.go b/internal/parser/parser.go new file mode 100644 index 0000000..fdc0854 --- /dev/null +++ b/internal/parser/parser.go @@ -0,0 +1,128 @@ +package parser + +import ( + "bufio" + "fmt" + "io" + "regexp" + "strings" +) + +// entryRe matches: - [Name](URL) - Description +var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s+-\s+(.+)$`) + +// headingRe matches markdown headings: # Title, ## Title, etc. +var headingRe = regexp.MustCompile(`^(#{1,6})\s+(.+?)(?:\s*)?$`) + +var markerMap = map[string]Marker{ + ":skull:": MarkerAbandoned, + ":heavy_dollar_sign:": MarkerPaid, + ":construction:": MarkerWIP, +} + +// ParseEntry parses a single markdown list line into an Entry. +func ParseEntry(line string, lineNum int) (Entry, error) { + m := entryRe.FindStringSubmatch(strings.TrimSpace(line)) + if m == nil { + return Entry{}, fmt.Errorf("line %d: not a valid entry: %q", lineNum, line) + } + + desc := m[3] + var markers []Marker + + for text, marker := range markerMap { + if strings.Contains(desc, text) { + markers = append(markers, marker) + desc = strings.ReplaceAll(desc, text, "") + } + } + desc = strings.TrimSpace(desc) + + return Entry{ + Name: m[1], + URL: m[2], + Description: desc, + Markers: markers, + Line: lineNum, + Raw: line, + }, nil +} + +// Parse reads a full README and returns a Document. +func Parse(r io.Reader) (Document, error) { + scanner := bufio.NewScanner(r) + var doc Document + var allSections []struct { + section Section + level int + } + + lineNum := 0 + for scanner.Scan() { + lineNum++ + line := scanner.Text() + + // Check for heading + if hm := headingRe.FindStringSubmatch(line); hm != nil { + level := len(hm[1]) + title := strings.TrimSpace(hm[2]) + allSections = append(allSections, struct { + section Section + level int + }{ + section: Section{Title: title, Level: level, Line: lineNum}, + level: level, + }) + continue + } + + // Check for entry (list item with link) + if entry, err := ParseEntry(line, lineNum); err == nil { + if len(allSections) > 0 { + allSections[len(allSections)-1].section.Entries = append( + allSections[len(allSections)-1].section.Entries, entry) + } + continue + } + + // Everything else: preamble if no sections yet + if len(allSections) == 0 { + doc.Preamble = append(doc.Preamble, line) + } + } + + if err := scanner.Err(); err != nil { + return doc, err + } + + // Build section tree by nesting based on heading level + doc.Sections = buildTree(allSections) + return doc, nil +} + +func buildTree(flat []struct { + section Section + level int +}) []Section { + if len(flat) == 0 { + return nil + } + + var result []Section + for i := 0; i < len(flat); i++ { + current := flat[i].section + currentLevel := flat[i].level + + // Collect children: everything after this heading at a deeper level + j := i + 1 + for j < len(flat) && flat[j].level > currentLevel { + j++ + } + if j > i+1 { + current.Children = buildTree(flat[i+1 : j]) + } + result = append(result, current) + i = j - 1 + } + return result +} diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go new file mode 100644 index 0000000..d414747 --- /dev/null +++ b/internal/parser/parser_test.go @@ -0,0 +1,147 @@ +package parser + +import ( + "os" + "strings" + "testing" +) + +func TestParseEntry(t *testing.T) { + line := `- [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Official native app. Only for Windows and MacOS.` + entry, err := ParseEntry(line, 1) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if entry.Name != "Docker Desktop" { + t.Errorf("name = %q, want %q", entry.Name, "Docker Desktop") + } + if entry.URL != "https://www.docker.com/products/docker-desktop/" { + t.Errorf("url = %q, want %q", entry.URL, "https://www.docker.com/products/docker-desktop/") + } + if entry.Description != "Official native app. Only for Windows and MacOS." { + t.Errorf("description = %q, want %q", entry.Description, "Official native app. Only for Windows and MacOS.") + } + if len(entry.Markers) != 0 { + t.Errorf("markers = %v, want empty", entry.Markers) + } +} + +func TestParseEntryWithMarkers(t *testing.T) { + line := `- [Docker Swarm](https://github.com/docker/swarm) - Swarm clustering system. :skull:` + entry, err := ParseEntry(line, 1) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if entry.Name != "Docker Swarm" { + t.Errorf("name = %q, want %q", entry.Name, "Docker Swarm") + } + if len(entry.Markers) != 1 || entry.Markers[0] != MarkerAbandoned { + t.Errorf("markers = %v, want [MarkerAbandoned]", entry.Markers) + } + if strings.Contains(entry.Description, ":skull:") { + t.Errorf("description should not contain marker text, got %q", entry.Description) + } +} + +func TestParseEntryMultipleMarkers(t *testing.T) { + line := `- [SomeProject](https://example.com) - A project. :heavy_dollar_sign: :construction:` + entry, err := ParseEntry(line, 1) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(entry.Markers) != 2 { + t.Fatalf("markers count = %d, want 2", len(entry.Markers)) + } +} + +func TestParseDocument(t *testing.T) { + input := `# Awesome Docker + +> A curated list + +# Contents + +- [Projects](#projects) + +# Legend + +- Abandoned :skull: + +# Projects + +## Tools + +- [ToolA](https://github.com/a/a) - Does A. +- [ToolB](https://github.com/b/b) - Does B. :skull: + +## Services + +- [ServiceC](https://example.com/c) - Does C. :heavy_dollar_sign: +` + doc, err := Parse(strings.NewReader(input)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(doc.Sections) == 0 { + t.Fatal("expected at least one section") + } + // Find the "Projects" section + var projects *Section + for i := range doc.Sections { + if doc.Sections[i].Title == "Projects" { + projects = &doc.Sections[i] + break + } + } + if projects == nil { + t.Fatal("expected a Projects section") + } + if len(projects.Children) != 2 { + t.Errorf("projects children = %d, want 2", len(projects.Children)) + } + if projects.Children[0].Title != "Tools" { + t.Errorf("first child = %q, want %q", projects.Children[0].Title, "Tools") + } + if len(projects.Children[0].Entries) != 2 { + t.Errorf("Tools entries = %d, want 2", len(projects.Children[0].Entries)) + } +} + +func TestParseNotAnEntry(t *testing.T) { + _, err := ParseEntry("- Abandoned :skull:", 1) + if err == nil { + t.Error("expected error for non-entry list item") + } +} + +func TestParseRealREADME(t *testing.T) { + f, err := os.Open("../../README.md") + if err != nil { + t.Skip("README.md not found, skipping integration test") + } + defer f.Close() + + doc, err := Parse(f) + if err != nil { + t.Fatalf("failed to parse README: %v", err) + } + + if len(doc.Sections) == 0 { + t.Error("expected sections") + } + + total := countEntries(doc.Sections) + if total < 100 { + t.Errorf("expected at least 100 entries, got %d", total) + } + t.Logf("Parsed %d sections, %d total entries", len(doc.Sections), total) +} + +func countEntries(sections []Section) int { + n := 0 + for _, s := range sections { + n += len(s.Entries) + n += countEntries(s.Children) + } + return n +} diff --git a/internal/parser/types.go b/internal/parser/types.go new file mode 100644 index 0000000..43a1ccf --- /dev/null +++ b/internal/parser/types.go @@ -0,0 +1,35 @@ +package parser + +// Marker represents a status emoji on an entry. +type Marker int + +const ( + MarkerAbandoned Marker = iota // :skull: + MarkerPaid // :heavy_dollar_sign: + MarkerWIP // :construction: +) + +// Entry is a single link entry in the README. +type Entry struct { + Name string + URL string + Description string + Markers []Marker + Line int // 1-based line number in source + Raw string // original line text +} + +// Section is a heading with optional entries and child sections. +type Section struct { + Title string + Level int // heading level: 1 = #, 2 = ##, etc. + Entries []Entry + Children []Section + Line int +} + +// Document is the parsed representation of the full README. +type Document struct { + Preamble []string // lines before the first section + Sections []Section +} From a49077803c6880b35d8c8692d422bc873b945569 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:18:49 +0100 Subject: [PATCH 04/29] feat: add linter with formatting rules, duplicate detection, sorting, and auto-fix Co-Authored-By: Claude Opus 4.6 --- internal/linter/linter.go | 60 +++++++++++++++ internal/linter/linter_test.go | 111 +++++++++++++++++++++++++++ internal/linter/rules.go | 134 +++++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 internal/linter/linter.go create mode 100644 internal/linter/linter_test.go create mode 100644 internal/linter/rules.go diff --git a/internal/linter/linter.go b/internal/linter/linter.go new file mode 100644 index 0000000..4183b11 --- /dev/null +++ b/internal/linter/linter.go @@ -0,0 +1,60 @@ +package linter + +import ( + "github.com/veggiemonk/awesome-docker/internal/parser" +) + +// Result holds all lint issues found. +type Result struct { + Issues []Issue + Errors int + Warnings int +} + +// Lint checks an entire parsed document for issues. +func Lint(doc parser.Document) Result { + var result Result + + // Collect all entries for duplicate checking + allEntries := collectEntries(doc.Sections) + for _, issue := range CheckDuplicates(allEntries) { + addIssue(&result, issue) + } + + // Check each section + lintSections(doc.Sections, &result) + + return result +} + +func lintSections(sections []parser.Section, result *Result) { + for _, s := range sections { + for _, e := range s.Entries { + for _, issue := range CheckEntry(e) { + addIssue(result, issue) + } + } + for _, issue := range CheckSorted(s.Entries) { + addIssue(result, issue) + } + lintSections(s.Children, result) + } +} + +func collectEntries(sections []parser.Section) []parser.Entry { + var all []parser.Entry + for _, s := range sections { + all = append(all, s.Entries...) + all = append(all, collectEntries(s.Children)...) + } + return all +} + +func addIssue(result *Result, issue Issue) { + result.Issues = append(result.Issues, issue) + if issue.Severity == SeverityError { + result.Errors++ + } else { + result.Warnings++ + } +} diff --git a/internal/linter/linter_test.go b/internal/linter/linter_test.go new file mode 100644 index 0000000..bd4fd5e --- /dev/null +++ b/internal/linter/linter_test.go @@ -0,0 +1,111 @@ +package linter + +import ( + "testing" + + "github.com/veggiemonk/awesome-docker/internal/parser" +) + +func TestRuleDescriptionCapital(t *testing.T) { + entry := parser.Entry{Name: "Test", URL: "https://example.com", Description: "lowercase start.", Line: 10} + issues := CheckEntry(entry) + found := false + for _, issue := range issues { + if issue.Rule == RuleDescriptionCapital { + found = true + } + } + if !found { + t.Error("expected RuleDescriptionCapital issue for lowercase description") + } +} + +func TestRuleDescriptionPeriod(t *testing.T) { + entry := parser.Entry{Name: "Test", URL: "https://example.com", Description: "No period at end", Line: 10} + issues := CheckEntry(entry) + found := false + for _, issue := range issues { + if issue.Rule == RuleDescriptionPeriod { + found = true + } + } + if !found { + t.Error("expected RuleDescriptionPeriod issue") + } +} + +func TestRuleSorted(t *testing.T) { + entries := []parser.Entry{ + {Name: "Zebra", URL: "https://z.com", Description: "Z.", Line: 1}, + {Name: "Alpha", URL: "https://a.com", Description: "A.", Line: 2}, + } + issues := CheckSorted(entries) + if len(issues) == 0 { + t.Error("expected sorting issue") + } +} + +func TestRuleSortedOK(t *testing.T) { + entries := []parser.Entry{ + {Name: "Alpha", URL: "https://a.com", Description: "A.", Line: 1}, + {Name: "Zebra", URL: "https://z.com", Description: "Z.", Line: 2}, + } + issues := CheckSorted(entries) + if len(issues) != 0 { + t.Errorf("expected no sorting issues, got %d", len(issues)) + } +} + +func TestRuleDuplicateURL(t *testing.T) { + entries := []parser.Entry{ + {Name: "A", URL: "https://example.com/a", Description: "A.", Line: 1}, + {Name: "B", URL: "https://example.com/a", Description: "B.", Line: 5}, + } + issues := CheckDuplicates(entries) + if len(issues) == 0 { + t.Error("expected duplicate URL issue") + } +} + +func TestValidEntry(t *testing.T) { + entry := parser.Entry{Name: "Good", URL: "https://example.com", Description: "A good project.", Line: 10} + issues := CheckEntry(entry) + if len(issues) != 0 { + t.Errorf("expected no issues, got %v", issues) + } +} + +func TestFixDescriptionCapital(t *testing.T) { + entry := parser.Entry{Name: "Test", URL: "https://example.com", Description: "lowercase.", Line: 10} + fixed := FixEntry(entry) + if fixed.Description != "Lowercase." { + t.Errorf("description = %q, want %q", fixed.Description, "Lowercase.") + } +} + +func TestFixDescriptionPeriod(t *testing.T) { + entry := parser.Entry{Name: "Test", URL: "https://example.com", Description: "No period", Line: 10} + fixed := FixEntry(entry) + if fixed.Description != "No period." { + t.Errorf("description = %q, want %q", fixed.Description, "No period.") + } +} + +func TestLintDocument(t *testing.T) { + doc := parser.Document{ + Sections: []parser.Section{ + { + Title: "Tools", + Level: 2, + Entries: []parser.Entry{ + {Name: "Zebra", URL: "https://z.com", Description: "Z tool.", Line: 1}, + {Name: "Alpha", URL: "https://a.com", Description: "a tool", Line: 2}, + }, + }, + }, + } + result := Lint(doc) + if result.Errors == 0 { + t.Error("expected errors (unsorted, lowercase, no period)") + } +} diff --git a/internal/linter/rules.go b/internal/linter/rules.go new file mode 100644 index 0000000..03bc1b2 --- /dev/null +++ b/internal/linter/rules.go @@ -0,0 +1,134 @@ +package linter + +import ( + "fmt" + "sort" + "strings" + "unicode" + + "github.com/veggiemonk/awesome-docker/internal/parser" +) + +// Rule identifies a linting rule. +type Rule string + +const ( + RuleDescriptionCapital Rule = "description-capital" + RuleDescriptionPeriod Rule = "description-period" + RuleSorted Rule = "sorted" + RuleDuplicateURL Rule = "duplicate-url" +) + +// Severity of a lint issue. +type Severity int + +const ( + SeverityError Severity = iota + SeverityWarning +) + +// Issue is a single lint problem found. +type Issue struct { + Rule Rule + Severity Severity + Line int + Message string +} + +func (i Issue) String() string { + sev := "ERROR" + if i.Severity == SeverityWarning { + sev = "WARN" + } + return fmt.Sprintf("[%s] line %d: %s (%s)", sev, i.Line, i.Message, i.Rule) +} + +// CheckEntry validates a single entry against formatting rules. +func CheckEntry(e parser.Entry) []Issue { + var issues []Issue + + if len(e.Description) > 0 && !unicode.IsUpper(rune(e.Description[0])) { + issues = append(issues, Issue{ + Rule: RuleDescriptionCapital, + Severity: SeverityError, + Line: e.Line, + Message: fmt.Sprintf("%q: description should start with a capital letter", e.Name), + }) + } + + if len(e.Description) > 0 && !strings.HasSuffix(e.Description, ".") { + issues = append(issues, Issue{ + Rule: RuleDescriptionPeriod, + Severity: SeverityError, + Line: e.Line, + Message: fmt.Sprintf("%q: description should end with a period", e.Name), + }) + } + + return issues +} + +// CheckSorted verifies entries are in alphabetical order (case-insensitive). +func CheckSorted(entries []parser.Entry) []Issue { + var issues []Issue + for i := 1; i < len(entries); i++ { + prev := strings.ToLower(entries[i-1].Name) + curr := strings.ToLower(entries[i].Name) + if prev > curr { + issues = append(issues, Issue{ + Rule: RuleSorted, + Severity: SeverityError, + Line: entries[i].Line, + Message: fmt.Sprintf("%q should come before %q (alphabetical order)", entries[i].Name, entries[i-1].Name), + }) + } + } + return issues +} + +// CheckDuplicates finds entries with the same URL across the entire document. +func CheckDuplicates(entries []parser.Entry) []Issue { + var issues []Issue + seen := make(map[string]int) // URL -> first line number + for _, e := range entries { + url := strings.TrimRight(e.URL, "/") + if firstLine, exists := seen[url]; exists { + issues = append(issues, Issue{ + Rule: RuleDuplicateURL, + Severity: SeverityError, + Line: e.Line, + Message: fmt.Sprintf("duplicate URL %q (first seen at line %d)", e.URL, firstLine), + }) + } else { + seen[url] = e.Line + } + } + return issues +} + +// FixEntry returns a copy of the entry with auto-fixable issues corrected. +func FixEntry(e parser.Entry) parser.Entry { + fixed := e + if len(fixed.Description) > 0 { + // Capitalize first letter + runes := []rune(fixed.Description) + runes[0] = unicode.ToUpper(runes[0]) + fixed.Description = string(runes) + + // Ensure period at end + if !strings.HasSuffix(fixed.Description, ".") { + fixed.Description += "." + } + } + return fixed +} + +// SortEntries returns a sorted copy of entries (case-insensitive by Name). +func SortEntries(entries []parser.Entry) []parser.Entry { + sorted := make([]parser.Entry, len(entries)) + copy(sorted, entries) + sort.Slice(sorted, func(i, j int) bool { + return strings.ToLower(sorted[i].Name) < strings.ToLower(sorted[j].Name) + }) + return sorted +} From ddc32f45d0300c461423b489bc1bf2d8321df302 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:19:31 +0100 Subject: [PATCH 05/29] feat: add cache package for exclude list and health cache YAML read/write Co-Authored-By: Claude Opus 4.6 --- go.mod | 1 + go.sum | 2 + internal/cache/cache.go | 95 +++++++++++++++++++++++++++++++ internal/cache/cache_test.go | 105 +++++++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 internal/cache/cache.go create mode 100644 internal/cache/cache_test.go diff --git a/go.mod b/go.mod index 7bed71c..5e4eb4f 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,5 @@ require github.com/spf13/cobra v1.10.2 require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/pflag v1.0.9 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a6ee3e0..ff4d6ec 100644 --- a/go.sum +++ b/go.sum @@ -8,3 +8,5 @@ github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/cache/cache.go b/internal/cache/cache.go new file mode 100644 index 0000000..a19089d --- /dev/null +++ b/internal/cache/cache.go @@ -0,0 +1,95 @@ +package cache + +import ( + "os" + "strings" + "time" + + "gopkg.in/yaml.v3" +) + +// ExcludeList holds URL prefixes to skip during checking. +type ExcludeList struct { + Domains []string `yaml:"domains"` +} + +// IsExcluded returns true if the URL starts with any excluded prefix. +func (e *ExcludeList) IsExcluded(url string) bool { + for _, d := range e.Domains { + if strings.HasPrefix(url, d) { + return true + } + } + return false +} + +// LoadExcludeList reads an exclude.yaml file. +func LoadExcludeList(path string) (*ExcludeList, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var excl ExcludeList + if err := yaml.Unmarshal(data, &excl); err != nil { + return nil, err + } + return &excl, nil +} + +// HealthEntry stores metadata about a single entry. +type HealthEntry struct { + URL string `yaml:"url"` + Name string `yaml:"name"` + Status string `yaml:"status"` // healthy, inactive, stale, archived, dead + Stars int `yaml:"stars,omitempty"` + Forks int `yaml:"forks,omitempty"` + LastPush time.Time `yaml:"last_push,omitempty"` + HasLicense bool `yaml:"has_license,omitempty"` + HasReadme bool `yaml:"has_readme,omitempty"` + CheckedAt time.Time `yaml:"checked_at"` +} + +// HealthCache is the full YAML cache file. +type HealthCache struct { + Entries []HealthEntry `yaml:"entries"` +} + +// LoadHealthCache reads a health_cache.yaml file. Returns empty cache if file doesn't exist. +func LoadHealthCache(path string) (*HealthCache, error) { + data, err := os.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return &HealthCache{}, nil + } + return nil, err + } + var hc HealthCache + if err := yaml.Unmarshal(data, &hc); err != nil { + return nil, err + } + return &hc, nil +} + +// SaveHealthCache writes the cache to a YAML file. +func SaveHealthCache(path string, hc *HealthCache) error { + data, err := yaml.Marshal(hc) + if err != nil { + return err + } + return os.WriteFile(path, data, 0644) +} + +// Merge updates the cache with new entries, replacing existing ones by URL. +func (hc *HealthCache) Merge(entries []HealthEntry) { + index := make(map[string]int) + for i, e := range hc.Entries { + index[e.URL] = i + } + for _, e := range entries { + if i, exists := index[e.URL]; exists { + hc.Entries[i] = e + } else { + hc.Entries = append(hc.Entries, e) + } + } +} diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go new file mode 100644 index 0000000..03ec514 --- /dev/null +++ b/internal/cache/cache_test.go @@ -0,0 +1,105 @@ +package cache + +import ( + "os" + "path/filepath" + "testing" + "time" +) + +func TestLoadExcludeList(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "exclude.yaml") + content := `domains: + - https://example.com + - https://test.org +` + if err := os.WriteFile(path, []byte(content), 0644); err != nil { + t.Fatal(err) + } + + excl, err := LoadExcludeList(path) + if err != nil { + t.Fatal(err) + } + if len(excl.Domains) != 2 { + t.Errorf("domains count = %d, want 2", len(excl.Domains)) + } + if !excl.IsExcluded("https://example.com/foo") { + t.Error("expected https://example.com/foo to be excluded") + } + if excl.IsExcluded("https://other.com") { + t.Error("expected https://other.com to NOT be excluded") + } +} + +func TestHealthCacheRoundTrip(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "health.yaml") + + original := &HealthCache{ + Entries: []HealthEntry{ + { + URL: "https://github.com/example/repo", + Name: "Example", + Status: "healthy", + Stars: 42, + LastPush: time.Date(2026, 1, 15, 0, 0, 0, 0, time.UTC), + HasLicense: true, + HasReadme: true, + CheckedAt: time.Date(2026, 2, 27, 9, 0, 0, 0, time.UTC), + }, + }, + } + + if err := SaveHealthCache(path, original); err != nil { + t.Fatal(err) + } + + loaded, err := LoadHealthCache(path) + if err != nil { + t.Fatal(err) + } + if len(loaded.Entries) != 1 { + t.Fatalf("entries = %d, want 1", len(loaded.Entries)) + } + if loaded.Entries[0].Stars != 42 { + t.Errorf("stars = %d, want 42", loaded.Entries[0].Stars) + } +} + +func TestLoadHealthCacheMissing(t *testing.T) { + hc, err := LoadHealthCache("/nonexistent/path.yaml") + if err != nil { + t.Fatal(err) + } + if len(hc.Entries) != 0 { + t.Errorf("entries = %d, want 0 for missing file", len(hc.Entries)) + } +} + +func TestMerge(t *testing.T) { + hc := &HealthCache{ + Entries: []HealthEntry{ + {URL: "https://github.com/a/a", Name: "A", Stars: 10}, + {URL: "https://github.com/b/b", Name: "B", Stars: 20}, + }, + } + + hc.Merge([]HealthEntry{ + {URL: "https://github.com/b/b", Name: "B", Stars: 25}, // update + {URL: "https://github.com/c/c", Name: "C", Stars: 30}, // new + }) + + if len(hc.Entries) != 3 { + t.Fatalf("entries = %d, want 3", len(hc.Entries)) + } + // B should be updated + if hc.Entries[1].Stars != 25 { + t.Errorf("B stars = %d, want 25", hc.Entries[1].Stars) + } + // C should be appended + if hc.Entries[2].Name != "C" { + t.Errorf("last entry = %q, want C", hc.Entries[2].Name) + } +} From bc46effe08c1a6f76230a70a524ea0e735126dd8 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:20:50 +0100 Subject: [PATCH 06/29] feat: add HTTP link checker and GitHub GraphQL repo checker Co-Authored-By: Claude Opus 4.6 --- go.mod | 3 + go.sum | 6 ++ internal/checker/github.go | 138 ++++++++++++++++++++++++++++++++ internal/checker/github_test.go | 52 ++++++++++++ internal/checker/http.go | 111 +++++++++++++++++++++++++ internal/checker/http_test.go | 80 ++++++++++++++++++ 6 files changed, 390 insertions(+) create mode 100644 internal/checker/github.go create mode 100644 internal/checker/github_test.go create mode 100644 internal/checker/http.go create mode 100644 internal/checker/http_test.go diff --git a/go.mod b/go.mod index 5e4eb4f..f608100 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,9 @@ require github.com/spf13/cobra v1.10.2 require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed // indirect + github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf // indirect github.com/spf13/pflag v1.0.9 // indirect + golang.org/x/oauth2 v0.35.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index ff4d6ec..8c787c0 100644 --- a/go.sum +++ b/go.sum @@ -2,11 +2,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed h1:KT7hI8vYXgU0s2qaMkrfq9tCA1w/iEPgfredVP+4Tzw= +github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed/go.mod h1:zqMwyHmnN/eDOZOdiTohqIUKUrTFX62PNlu7IJdu0q8= +github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf h1:o1uxfymjZ7jZ4MsgCErcwWGtVKSiNAXtS59Lhs6uI/g= +github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/checker/github.go b/internal/checker/github.go new file mode 100644 index 0000000..e1f1dac --- /dev/null +++ b/internal/checker/github.go @@ -0,0 +1,138 @@ +package checker + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/shurcooL/githubv4" + "golang.org/x/oauth2" +) + +// RepoInfo holds metadata about a GitHub repository. +type RepoInfo struct { + Owner string + Name string + URL string + IsArchived bool + IsDisabled bool + IsPrivate bool + PushedAt time.Time + Stars int + Forks int + HasLicense bool +} + +// ExtractGitHubRepo extracts owner/name from a GitHub URL. +// Returns false for non-repo URLs (issues, wiki, apps, etc.). +func ExtractGitHubRepo(url string) (owner, name string, ok bool) { + if !strings.HasPrefix(url, "https://github.com/") { + return "", "", false + } + path := strings.TrimPrefix(url, "https://github.com/") + path = strings.TrimRight(path, "/") + parts := strings.Split(path, "/") + if len(parts) != 2 || parts[0] == "" || parts[1] == "" { + return "", "", false + } + // Skip non-repo paths + if parts[0] == "apps" || parts[0] == "features" || parts[0] == "topics" { + return "", "", false + } + return parts[0], parts[1], true +} + +// PartitionLinks separates URLs into GitHub repos and external links. +func PartitionLinks(urls []string) (github, external []string) { + for _, url := range urls { + if _, _, ok := ExtractGitHubRepo(url); ok { + github = append(github, url) + } else { + external = append(external, url) + } + } + return +} + +// GitHubChecker uses the GitHub GraphQL API. +type GitHubChecker struct { + client *githubv4.Client +} + +// NewGitHubChecker creates a checker with the given OAuth token. +func NewGitHubChecker(token string) *GitHubChecker { + src := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) + httpClient := oauth2.NewClient(context.Background(), src) + return &GitHubChecker{client: githubv4.NewClient(httpClient)} +} + +// CheckRepo queries a single GitHub repository. +func (gc *GitHubChecker) CheckRepo(ctx context.Context, owner, name string) (RepoInfo, error) { + var query struct { + Repository struct { + IsArchived bool + IsDisabled bool + IsPrivate bool + PushedAt time.Time + StargazerCount int + ForkCount int + LicenseInfo *struct { + Name string + } + } `graphql:"repository(owner: $owner, name: $name)"` + } + + vars := map[string]interface{}{ + "owner": githubv4.String(owner), + "name": githubv4.String(name), + } + + if err := gc.client.Query(ctx, &query, vars); err != nil { + return RepoInfo{}, fmt.Errorf("github query %s/%s: %w", owner, name, err) + } + + r := query.Repository + return RepoInfo{ + Owner: owner, + Name: name, + URL: fmt.Sprintf("https://github.com/%s/%s", owner, name), + IsArchived: r.IsArchived, + IsDisabled: r.IsDisabled, + IsPrivate: r.IsPrivate, + PushedAt: r.PushedAt, + Stars: r.StargazerCount, + Forks: r.ForkCount, + HasLicense: r.LicenseInfo != nil, + }, nil +} + +// CheckRepos queries multiple repos in sequence with rate limiting. +func (gc *GitHubChecker) CheckRepos(ctx context.Context, urls []string, batchSize int) ([]RepoInfo, []error) { + if batchSize <= 0 { + batchSize = 50 + } + + var results []RepoInfo + var errs []error + + for i, url := range urls { + owner, name, ok := ExtractGitHubRepo(url) + if !ok { + continue + } + + info, err := gc.CheckRepo(ctx, owner, name) + if err != nil { + errs = append(errs, err) + continue + } + results = append(results, info) + + if (i+1)%batchSize == 0 { + time.Sleep(1 * time.Second) + } + } + + return results, errs +} diff --git a/internal/checker/github_test.go b/internal/checker/github_test.go new file mode 100644 index 0000000..7ac8fbe --- /dev/null +++ b/internal/checker/github_test.go @@ -0,0 +1,52 @@ +package checker + +import ( + "testing" +) + +func TestExtractGitHubRepo(t *testing.T) { + tests := []struct { + url string + owner string + name string + ok bool + }{ + {"https://github.com/docker/compose", "docker", "compose", true}, + {"https://github.com/moby/moby", "moby", "moby", true}, + {"https://github.com/user/repo/", "user", "repo", true}, + {"https://github.com/user/repo/issues", "", "", false}, + {"https://github.com/user/repo/wiki", "", "", false}, + {"https://github.com/apps/dependabot", "", "", false}, + {"https://example.com/not-github", "", "", false}, + {"https://github.com/user", "", "", false}, + } + + for _, tt := range tests { + owner, name, ok := ExtractGitHubRepo(tt.url) + if ok != tt.ok { + t.Errorf("ExtractGitHubRepo(%q): ok = %v, want %v", tt.url, ok, tt.ok) + continue + } + if ok { + if owner != tt.owner || name != tt.name { + t.Errorf("ExtractGitHubRepo(%q) = (%q, %q), want (%q, %q)", tt.url, owner, name, tt.owner, tt.name) + } + } + } +} + +func TestPartitionLinks(t *testing.T) { + urls := []string{ + "https://github.com/docker/compose", + "https://example.com/tool", + "https://github.com/moby/moby", + "https://github.com/user/repo/issues", + } + gh, ext := PartitionLinks(urls) + if len(gh) != 2 { + t.Errorf("github links = %d, want 2", len(gh)) + } + if len(ext) != 2 { + t.Errorf("external links = %d, want 2", len(ext)) + } +} diff --git a/internal/checker/http.go b/internal/checker/http.go new file mode 100644 index 0000000..3e17929 --- /dev/null +++ b/internal/checker/http.go @@ -0,0 +1,111 @@ +package checker + +import ( + "context" + "net/http" + "sync" + "time" + + "github.com/veggiemonk/awesome-docker/internal/cache" +) + +const ( + defaultTimeout = 30 * time.Second + defaultConcurrency = 10 + userAgent = "awesome-docker-checker/1.0" +) + +// LinkResult holds the result of checking a single URL. +type LinkResult struct { + URL string + OK bool + StatusCode int + Redirected bool + RedirectURL string + Error string +} + +// CheckLink checks a single URL. Uses HEAD first, falls back to GET. +func CheckLink(url string, client *http.Client) LinkResult { + result := LinkResult{URL: url} + + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + // Try HEAD first + req, err := http.NewRequestWithContext(ctx, http.MethodHead, url, nil) + if err != nil { + result.Error = err.Error() + return result + } + req.Header.Set("User-Agent", userAgent) + + // Track redirects + var finalURL string + origCheckRedirect := client.CheckRedirect + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + finalURL = req.URL.String() + if len(via) >= 10 { + return http.ErrUseLastResponse + } + return nil + } + defer func() { client.CheckRedirect = origCheckRedirect }() + + resp, err := client.Do(req) + if err != nil { + // Fallback to GET + req, err2 := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err2 != nil { + result.Error = err.Error() + return result + } + req.Header.Set("User-Agent", userAgent) + resp, err = client.Do(req) + if err != nil { + result.Error = err.Error() + return result + } + } + defer resp.Body.Close() + + result.StatusCode = resp.StatusCode + result.OK = resp.StatusCode >= 200 && resp.StatusCode < 400 + + if finalURL != "" && finalURL != url { + result.Redirected = true + result.RedirectURL = finalURL + } + + return result +} + +// CheckLinks checks multiple URLs concurrently. +func CheckLinks(urls []string, concurrency int, exclude *cache.ExcludeList) []LinkResult { + if concurrency <= 0 { + concurrency = defaultConcurrency + } + + results := make([]LinkResult, len(urls)) + sem := make(chan struct{}, concurrency) + var wg sync.WaitGroup + + for i, url := range urls { + if exclude != nil && exclude.IsExcluded(url) { + results[i] = LinkResult{URL: url, OK: true} + continue + } + + wg.Add(1) + go func(idx int, u string) { + defer wg.Done() + sem <- struct{}{} + defer func() { <-sem }() + client := &http.Client{Timeout: defaultTimeout} + results[idx] = CheckLink(u, client) + }(i, url) + } + + wg.Wait() + return results +} diff --git a/internal/checker/http_test.go b/internal/checker/http_test.go new file mode 100644 index 0000000..b8eef45 --- /dev/null +++ b/internal/checker/http_test.go @@ -0,0 +1,80 @@ +package checker + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestCheckLinkOK(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + result := CheckLink(server.URL, &http.Client{}) + if !result.OK { + t.Errorf("expected OK, got status %d, error: %s", result.StatusCode, result.Error) + } +} + +func TestCheckLink404(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + })) + defer server.Close() + + result := CheckLink(server.URL, &http.Client{}) + if result.OK { + t.Error("expected not OK for 404") + } + if result.StatusCode != 404 { + t.Errorf("status = %d, want 404", result.StatusCode) + } +} + +func TestCheckLinkRedirect(t *testing.T) { + final := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer final.Close() + + redir := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, final.URL, http.StatusMovedPermanently) + })) + defer redir.Close() + + result := CheckLink(redir.URL, &http.Client{}) + if !result.OK { + t.Errorf("expected OK after following redirect, error: %s", result.Error) + } + if !result.Redirected { + t.Error("expected Redirected = true") + } +} + +func TestCheckLinks(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/bad" { + w.WriteHeader(http.StatusNotFound) + return + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + urls := []string{server.URL + "/good", server.URL + "/bad", server.URL + "/also-good"} + results := CheckLinks(urls, 2, nil) + if len(results) != 3 { + t.Fatalf("results = %d, want 3", len(results)) + } + + for _, r := range results { + if r.URL == server.URL+"/bad" && r.OK { + t.Error("expected /bad to not be OK") + } + if r.URL == server.URL+"/good" && !r.OK { + t.Error("expected /good to be OK") + } + } +} From 804da83d7ba752dcba9db348a3d2c74dc7f9e7c0 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:21:37 +0100 Subject: [PATCH 07/29] feat: add health scorer with status classification and report generation Co-Authored-By: Claude Opus 4.6 --- internal/scorer/scorer.go | 133 +++++++++++++++++++++++++++++++++ internal/scorer/scorer_test.go | 100 +++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 internal/scorer/scorer.go create mode 100644 internal/scorer/scorer_test.go diff --git a/internal/scorer/scorer.go b/internal/scorer/scorer.go new file mode 100644 index 0000000..c91aaf1 --- /dev/null +++ b/internal/scorer/scorer.go @@ -0,0 +1,133 @@ +package scorer + +import ( + "fmt" + "strings" + "time" + + "github.com/veggiemonk/awesome-docker/internal/cache" + "github.com/veggiemonk/awesome-docker/internal/checker" +) + +// Status represents the health status of an entry. +type Status string + +const ( + StatusHealthy Status = "healthy" + StatusInactive Status = "inactive" // 1-2 years since last push + StatusStale Status = "stale" // 2+ years since last push + StatusArchived Status = "archived" + StatusDead Status = "dead" // disabled or 404 +) + +// ScoredEntry is a repo with its computed health status. +type ScoredEntry struct { + URL string + Name string + Status Status + Stars int + Forks int + LastPush time.Time +} + +// Score computes the health status of a GitHub repo. +func Score(info checker.RepoInfo) Status { + if info.IsDisabled { + return StatusDead + } + if info.IsArchived { + return StatusArchived + } + + twoYearsAgo := time.Now().AddDate(-2, 0, 0) + oneYearAgo := time.Now().AddDate(-1, 0, 0) + + if info.PushedAt.Before(twoYearsAgo) { + return StatusStale + } + if info.PushedAt.Before(oneYearAgo) { + return StatusInactive + } + return StatusHealthy +} + +// ScoreAll scores a batch of repo infos. +func ScoreAll(infos []checker.RepoInfo) []ScoredEntry { + results := make([]ScoredEntry, len(infos)) + for i, info := range infos { + results[i] = ScoredEntry{ + URL: info.URL, + Name: fmt.Sprintf("%s/%s", info.Owner, info.Name), + Status: Score(info), + Stars: info.Stars, + Forks: info.Forks, + LastPush: info.PushedAt, + } + } + return results +} + +// ToCacheEntries converts scored entries to cache format. +func ToCacheEntries(scored []ScoredEntry) []cache.HealthEntry { + entries := make([]cache.HealthEntry, len(scored)) + now := time.Now().UTC() + for i, s := range scored { + entries[i] = cache.HealthEntry{ + URL: s.URL, + Name: s.Name, + Status: string(s.Status), + Stars: s.Stars, + Forks: s.Forks, + LastPush: s.LastPush, + CheckedAt: now, + } + } + return entries +} + +// GenerateReport produces a Markdown health report. +func GenerateReport(scored []ScoredEntry) string { + var b strings.Builder + + groups := map[Status][]ScoredEntry{} + for _, s := range scored { + groups[s.Status] = append(groups[s.Status], s) + } + + fmt.Fprintf(&b, "# Health Report\n\n") + fmt.Fprintf(&b, "**Generated:** %s\n\n", time.Now().UTC().Format(time.RFC3339)) + fmt.Fprintf(&b, "**Total:** %d repositories\n\n", len(scored)) + + fmt.Fprintf(&b, "## Summary\n\n") + fmt.Fprintf(&b, "- Healthy: %d\n", len(groups[StatusHealthy])) + fmt.Fprintf(&b, "- Inactive (1-2 years): %d\n", len(groups[StatusInactive])) + fmt.Fprintf(&b, "- Stale (2+ years): %d\n", len(groups[StatusStale])) + fmt.Fprintf(&b, "- Archived: %d\n", len(groups[StatusArchived])) + fmt.Fprintf(&b, "- Dead: %d\n\n", len(groups[StatusDead])) + + writeSection := func(title string, status Status, limit int) { + entries := groups[status] + if len(entries) == 0 { + return + } + fmt.Fprintf(&b, "## %s\n\n", title) + count := len(entries) + if limit > 0 && count > limit { + count = limit + } + for _, e := range entries[:count] { + fmt.Fprintf(&b, "- [%s](%s) - Stars: %d - Last push: %s\n", + e.Name, e.URL, e.Stars, e.LastPush.Format("2006-01-02")) + } + if len(entries) > count { + fmt.Fprintf(&b, "\n... and %d more\n", len(entries)-count) + } + b.WriteString("\n") + } + + writeSection("Archived (should mark :skull:)", StatusArchived, 0) + writeSection("Stale (2+ years inactive)", StatusStale, 50) + writeSection("Inactive (1-2 years)", StatusInactive, 30) + + return b.String() +} diff --git a/internal/scorer/scorer_test.go b/internal/scorer/scorer_test.go new file mode 100644 index 0000000..1aab44a --- /dev/null +++ b/internal/scorer/scorer_test.go @@ -0,0 +1,100 @@ +package scorer + +import ( + "strings" + "testing" + "time" + + "github.com/veggiemonk/awesome-docker/internal/checker" +) + +func TestScoreHealthy(t *testing.T) { + info := checker.RepoInfo{ + PushedAt: time.Now().AddDate(0, -3, 0), + IsArchived: false, + Stars: 100, + HasLicense: true, + } + status := Score(info) + if status != StatusHealthy { + t.Errorf("status = %q, want %q", status, StatusHealthy) + } +} + +func TestScoreInactive(t *testing.T) { + info := checker.RepoInfo{ + PushedAt: time.Now().AddDate(-1, -6, 0), + IsArchived: false, + } + status := Score(info) + if status != StatusInactive { + t.Errorf("status = %q, want %q", status, StatusInactive) + } +} + +func TestScoreStale(t *testing.T) { + info := checker.RepoInfo{ + PushedAt: time.Now().AddDate(-3, 0, 0), + IsArchived: false, + } + status := Score(info) + if status != StatusStale { + t.Errorf("status = %q, want %q", status, StatusStale) + } +} + +func TestScoreArchived(t *testing.T) { + info := checker.RepoInfo{ + PushedAt: time.Now(), + IsArchived: true, + } + status := Score(info) + if status != StatusArchived { + t.Errorf("status = %q, want %q", status, StatusArchived) + } +} + +func TestScoreDisabled(t *testing.T) { + info := checker.RepoInfo{ + IsDisabled: true, + } + status := Score(info) + if status != StatusDead { + t.Errorf("status = %q, want %q", status, StatusDead) + } +} + +func TestGenerateReport(t *testing.T) { + results := []ScoredEntry{ + {URL: "https://github.com/a/a", Name: "a/a", Status: StatusHealthy, Stars: 100, LastPush: time.Now()}, + {URL: "https://github.com/b/b", Name: "b/b", Status: StatusArchived, Stars: 50, LastPush: time.Now()}, + {URL: "https://github.com/c/c", Name: "c/c", Status: StatusStale, Stars: 10, LastPush: time.Now().AddDate(-3, 0, 0)}, + } + report := GenerateReport(results) + if !strings.Contains(report, "Healthy: 1") { + t.Error("report should contain 'Healthy: 1'") + } + if !strings.Contains(report, "Archived: 1") { + t.Error("report should contain 'Archived: 1'") + } + if !strings.Contains(report, "Stale") { + t.Error("report should contain 'Stale'") + } +} + +func TestScoreAll(t *testing.T) { + infos := []checker.RepoInfo{ + {Owner: "a", Name: "a", PushedAt: time.Now(), Stars: 10}, + {Owner: "b", Name: "b", PushedAt: time.Now().AddDate(-3, 0, 0), Stars: 5}, + } + scored := ScoreAll(infos) + if len(scored) != 2 { + t.Fatalf("scored = %d, want 2", len(scored)) + } + if scored[0].Status != StatusHealthy { + t.Errorf("first = %q, want healthy", scored[0].Status) + } + if scored[1].Status != StatusStale { + t.Errorf("second = %q, want stale", scored[1].Status) + } +} From ed04ff40179788ff2a7e78d55f7f5d5e904fa950 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:22:16 +0100 Subject: [PATCH 08/29] feat: add website builder using goldmark (replaces build.js) Co-Authored-By: Claude Opus 4.6 --- go.mod | 1 + go.sum | 2 + internal/builder/builder.go | 51 ++++++++++++++ internal/builder/builder_test.go | 113 +++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 internal/builder/builder.go create mode 100644 internal/builder/builder_test.go diff --git a/go.mod b/go.mod index f608100..b72fbff 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed // indirect github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf // indirect github.com/spf13/pflag v1.0.9 // indirect + github.com/yuin/goldmark v1.7.16 // indirect golang.org/x/oauth2 v0.35.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8c787c0..0c38e50 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= +github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= diff --git a/internal/builder/builder.go b/internal/builder/builder.go new file mode 100644 index 0000000..872072e --- /dev/null +++ b/internal/builder/builder.go @@ -0,0 +1,51 @@ +package builder + +import ( + "bytes" + "fmt" + "os" + "strings" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/renderer/html" +) + +// Build converts a Markdown file to HTML using a template. +// The template must contain a placeholder element that will be replaced with the rendered content. +func Build(markdownPath, templatePath, outputPath string) error { + md, err := os.ReadFile(markdownPath) + if err != nil { + return fmt.Errorf("read markdown: %w", err) + } + + tmpl, err := os.ReadFile(templatePath) + if err != nil { + return fmt.Errorf("read template: %w", err) + } + + // Convert markdown to HTML + gm := goldmark.New( + goldmark.WithExtensions(extension.GFM), + goldmark.WithRendererOptions(html.WithUnsafe()), + ) + var buf bytes.Buffer + if err := gm.Convert(md, &buf); err != nil { + return fmt.Errorf("convert markdown: %w", err) + } + + // Inject into template — support both placeholder formats + output := string(tmpl) + replacements := []struct{ old, new string }{ + {`
`, `
` + buf.String() + `
`}, + {`
`, `
` + buf.String() + `
`}, + } + for _, r := range replacements { + output = strings.Replace(output, r.old, r.new, 1) + } + + if err := os.WriteFile(outputPath, []byte(output), 0644); err != nil { + return fmt.Errorf("write output: %w", err) + } + return nil +} diff --git a/internal/builder/builder_test.go b/internal/builder/builder_test.go new file mode 100644 index 0000000..cdf992d --- /dev/null +++ b/internal/builder/builder_test.go @@ -0,0 +1,113 @@ +package builder + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestBuild(t *testing.T) { + dir := t.TempDir() + + md := "# Test List\n\n- [Example](https://example.com) - A test entry.\n" + mdPath := filepath.Join(dir, "README.md") + if err := os.WriteFile(mdPath, []byte(md), 0644); err != nil { + t.Fatal(err) + } + + tmpl := ` + + +
+ +` + tmplPath := filepath.Join(dir, "template.html") + if err := os.WriteFile(tmplPath, []byte(tmpl), 0644); err != nil { + t.Fatal(err) + } + + outPath := filepath.Join(dir, "index.html") + if err := Build(mdPath, tmplPath, outPath); err != nil { + t.Fatalf("Build failed: %v", err) + } + + content, err := os.ReadFile(outPath) + if err != nil { + t.Fatal(err) + } + + html := string(content) + if !strings.Contains(html, "Test List") { + t.Error("expected 'Test List' in output") + } + if !strings.Contains(html, "https://example.com") { + t.Error("expected link in output") + } +} + +func TestBuildWithSectionPlaceholder(t *testing.T) { + dir := t.TempDir() + + md := "# Hello\n\nWorld.\n" + mdPath := filepath.Join(dir, "README.md") + if err := os.WriteFile(mdPath, []byte(md), 0644); err != nil { + t.Fatal(err) + } + + // This matches the actual template format + tmpl := ` + + +
+ +` + tmplPath := filepath.Join(dir, "template.html") + if err := os.WriteFile(tmplPath, []byte(tmpl), 0644); err != nil { + t.Fatal(err) + } + + outPath := filepath.Join(dir, "index.html") + if err := Build(mdPath, tmplPath, outPath); err != nil { + t.Fatalf("Build failed: %v", err) + } + + content, err := os.ReadFile(outPath) + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(content), "Hello") { + t.Error("expected 'Hello' in output") + } + if !strings.Contains(string(content), `class="main-content"`) { + t.Error("expected section class preserved") + } +} + +func TestBuildRealREADME(t *testing.T) { + mdPath := "../../README.md" + tmplPath := "../../config/website.tmpl.html" + if _, err := os.Stat(mdPath); err != nil { + t.Skip("README.md not found") + } + if _, err := os.Stat(tmplPath); err != nil { + t.Skip("website template not found") + } + + dir := t.TempDir() + outPath := filepath.Join(dir, "index.html") + + if err := Build(mdPath, tmplPath, outPath); err != nil { + t.Fatalf("Build failed: %v", err) + } + + info, err := os.Stat(outPath) + if err != nil { + t.Fatal(err) + } + if info.Size() < 10000 { + t.Errorf("output too small: %d bytes", info.Size()) + } + t.Logf("Generated %d bytes", info.Size()) +} From 83211a492337b23e9bb77b54391d69136ab30d1e Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:23:25 +0100 Subject: [PATCH 09/29] feat: wire all packages into cobra CLI with lint, check, health, build, report, validate commands Co-Authored-By: Claude Opus 4.6 --- cmd/awesome-docker/main.go | 290 ++++++++++++++++++++++++++++++++++++- 1 file changed, 287 insertions(+), 3 deletions(-) diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 1ac12ff..01c5beb 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -1,10 +1,26 @@ package main import ( + "context" "fmt" "os" "github.com/spf13/cobra" + "github.com/veggiemonk/awesome-docker/internal/builder" + "github.com/veggiemonk/awesome-docker/internal/cache" + "github.com/veggiemonk/awesome-docker/internal/checker" + "github.com/veggiemonk/awesome-docker/internal/linter" + "github.com/veggiemonk/awesome-docker/internal/parser" + "github.com/veggiemonk/awesome-docker/internal/scorer" +) + +const ( + readmePath = "README.md" + excludePath = "config/exclude.yaml" + templatePath = "config/website.tmpl.html" + healthCachePath = "config/health_cache.yaml" + websiteOutput = "website/index.html" + version = "0.1.0" ) func main() { @@ -12,12 +28,280 @@ func main() { Use: "awesome-docker", Short: "Quality tooling for the awesome-docker curated list", } + root.AddCommand( - &cobra.Command{Use: "version", Short: "Print version", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("awesome-docker v0.1.0") - }}, + versionCmd(), + lintCmd(), + checkCmd(), + healthCmd(), + buildCmd(), + reportCmd(), + validateCmd(), ) + if err := root.Execute(); err != nil { os.Exit(1) } } + +func versionCmd() *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "Print version", + Run: func(cmd *cobra.Command, args []string) { fmt.Printf("awesome-docker v%s\n", version) }, + } +} + +func parseReadme() (parser.Document, error) { + f, err := os.Open(readmePath) + if err != nil { + return parser.Document{}, err + } + defer f.Close() + return parser.Parse(f) +} + +func collectURLs(sections []parser.Section, urls *[]string) { + for _, s := range sections { + for _, e := range s.Entries { + *urls = append(*urls, e.URL) + } + collectURLs(s.Children, urls) + } +} + +func lintCmd() *cobra.Command { + var fix bool + cmd := &cobra.Command{ + Use: "lint", + Short: "Validate README formatting", + RunE: func(cmd *cobra.Command, args []string) error { + doc, err := parseReadme() + if err != nil { + return fmt.Errorf("parse: %w", err) + } + + result := linter.Lint(doc) + for _, issue := range result.Issues { + fmt.Println(issue) + } + + if result.Errors > 0 { + fmt.Printf("\n%d errors, %d warnings\n", result.Errors, result.Warnings) + if !fix { + return fmt.Errorf("lint failed with %d errors", result.Errors) + } + fmt.Println("Auto-fix mode: --fix is not yet fully implemented for file rewriting") + } else { + fmt.Printf("OK: %d warnings\n", result.Warnings) + } + + return nil + }, + } + cmd.Flags().BoolVar(&fix, "fix", false, "Auto-fix formatting issues") + return cmd +} + +func checkCmd() *cobra.Command { + var prMode bool + cmd := &cobra.Command{ + Use: "check", + Short: "Check links for reachability", + RunE: func(cmd *cobra.Command, args []string) error { + doc, err := parseReadme() + if err != nil { + return fmt.Errorf("parse: %w", err) + } + + var urls []string + collectURLs(doc.Sections, &urls) + + exclude, _ := cache.LoadExcludeList(excludePath) + + ghURLs, extURLs := checker.PartitionLinks(urls) + + fmt.Printf("Checking %d external links...\n", len(extURLs)) + results := checker.CheckLinks(extURLs, 10, exclude) + var broken []checker.LinkResult + var redirected []checker.LinkResult + for _, r := range results { + if !r.OK { + broken = append(broken, r) + } + if r.Redirected { + redirected = append(redirected, r) + } + } + + if !prMode { + token := os.Getenv("GITHUB_TOKEN") + if token != "" { + fmt.Printf("Checking %d GitHub repositories...\n", len(ghURLs)) + gc := checker.NewGitHubChecker(token) + _, errs := gc.CheckRepos(context.Background(), ghURLs, 50) + for _, e := range errs { + fmt.Printf(" GitHub error: %v\n", e) + } + } else { + fmt.Println("GITHUB_TOKEN not set, skipping GitHub repo checks") + } + } + + if len(redirected) > 0 { + fmt.Printf("\n%d redirected links (consider updating):\n", len(redirected)) + for _, r := range redirected { + fmt.Printf(" %s -> %s\n", r.URL, r.RedirectURL) + } + } + + if len(broken) > 0 { + fmt.Printf("\n%d broken links:\n", len(broken)) + for _, r := range broken { + fmt.Printf(" %s -> %d %s\n", r.URL, r.StatusCode, r.Error) + } + return fmt.Errorf("found %d broken links", len(broken)) + } + + fmt.Println("All links OK") + return nil + }, + } + cmd.Flags().BoolVar(&prMode, "pr", false, "PR mode: skip GitHub API checks") + return cmd +} + +func healthCmd() *cobra.Command { + return &cobra.Command{ + Use: "health", + Short: "Score repository health and update cache", + RunE: func(cmd *cobra.Command, args []string) error { + token := os.Getenv("GITHUB_TOKEN") + if token == "" { + return fmt.Errorf("GITHUB_TOKEN environment variable is required") + } + + doc, err := parseReadme() + if err != nil { + return fmt.Errorf("parse: %w", err) + } + + var urls []string + collectURLs(doc.Sections, &urls) + ghURLs, _ := checker.PartitionLinks(urls) + + fmt.Printf("Scoring %d GitHub repositories...\n", len(ghURLs)) + gc := checker.NewGitHubChecker(token) + infos, errs := gc.CheckRepos(context.Background(), ghURLs, 50) + for _, e := range errs { + fmt.Printf(" error: %v\n", e) + } + + scored := scorer.ScoreAll(infos) + cacheEntries := scorer.ToCacheEntries(scored) + + hc, _ := cache.LoadHealthCache(healthCachePath) + hc.Merge(cacheEntries) + if err := cache.SaveHealthCache(healthCachePath, hc); err != nil { + return fmt.Errorf("save cache: %w", err) + } + + fmt.Printf("Cache updated: %d entries in %s\n", len(hc.Entries), healthCachePath) + return nil + }, + } +} + +func buildCmd() *cobra.Command { + return &cobra.Command{ + Use: "build", + Short: "Generate website from README", + RunE: func(cmd *cobra.Command, args []string) error { + if err := builder.Build(readmePath, templatePath, websiteOutput); err != nil { + return err + } + fmt.Printf("Website built: %s\n", websiteOutput) + return nil + }, + } +} + +func reportCmd() *cobra.Command { + return &cobra.Command{ + Use: "report", + Short: "Generate health report from cache", + RunE: func(cmd *cobra.Command, args []string) error { + hc, err := cache.LoadHealthCache(healthCachePath) + if err != nil { + return fmt.Errorf("load cache: %w", err) + } + if len(hc.Entries) == 0 { + return fmt.Errorf("no cache data, run 'health' first") + } + + var scored []scorer.ScoredEntry + for _, e := range hc.Entries { + scored = append(scored, scorer.ScoredEntry{ + URL: e.URL, + Name: e.Name, + Status: scorer.Status(e.Status), + Stars: e.Stars, + LastPush: e.LastPush, + }) + } + + report := scorer.GenerateReport(scored) + fmt.Print(report) + return nil + }, + } +} + +func validateCmd() *cobra.Command { + return &cobra.Command{ + Use: "validate", + Short: "PR validation: lint + check --pr", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("=== Linting ===") + doc, err := parseReadme() + if err != nil { + return fmt.Errorf("parse: %w", err) + } + + result := linter.Lint(doc) + for _, issue := range result.Issues { + fmt.Println(issue) + } + if result.Errors > 0 { + fmt.Printf("\n%d errors, %d warnings\n", result.Errors, result.Warnings) + return fmt.Errorf("lint failed with %d errors", result.Errors) + } + fmt.Printf("Lint OK: %d warnings\n", result.Warnings) + + fmt.Println("\n=== Checking links (PR mode) ===") + var urls []string + collectURLs(doc.Sections, &urls) + exclude, _ := cache.LoadExcludeList(excludePath) + _, extURLs := checker.PartitionLinks(urls) + + fmt.Printf("Checking %d external links...\n", len(extURLs)) + results := checker.CheckLinks(extURLs, 10, exclude) + var broken []checker.LinkResult + for _, r := range results { + if !r.OK { + broken = append(broken, r) + } + } + if len(broken) > 0 { + fmt.Printf("\n%d broken links:\n", len(broken)) + for _, r := range broken { + fmt.Printf(" %s -> %d %s\n", r.URL, r.StatusCode, r.Error) + } + return fmt.Errorf("found %d broken links", len(broken)) + } + + fmt.Println("\nValidation passed") + return nil + }, + } +} From e5d55947754d136901d1392b7f5a73d7e12bf9b2 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:26:48 +0100 Subject: [PATCH 10/29] feat: update all GitHub Actions workflows from Node.js to Go Replace Node.js setup, npm install, and node/npm commands with Go setup, go build, and the new awesome-docker CLI binary in all four workflow files: pull_request, broken_links, health_report, and deploy-pages. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/broken_links.yml | 70 ++++++----------------------- .github/workflows/deploy-pages.yml | 18 ++++---- .github/workflows/health_report.yml | 60 +++++++++++-------------- .github/workflows/pull_request.yml | 22 ++++----- 4 files changed, 55 insertions(+), 115 deletions(-) diff --git a/.github/workflows/broken_links.yml b/.github/workflows/broken_links.yml index f320d62..678b89e 100644 --- a/.github/workflows/broken_links.yml +++ b/.github/workflows/broken_links.yml @@ -2,7 +2,6 @@ name: Broken Links Report on: schedule: - # Run every Saturday at 2 AM UTC - cron: "0 2 * * 6" workflow_dispatch: @@ -14,68 +13,37 @@ jobs: issues: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 + - uses: actions/checkout@v4 - - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # ratchet:actions/setup-node@v6.2.0 + - uses: actions/setup-go@v5 with: - node-version: lts/* + go-version: "1.22" - - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # ratchet:actions/cache@v5.0.3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - - name: Install Dependencies - run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline + - name: Build + run: go build -o awesome-docker ./cmd/awesome-docker - name: Run Link Check id: link_check run: | - npm test > link_check_output.txt 2>&1 || true - if grep -q "❌ ERROR" link_check_output.txt; then - echo "has_errors=true" >> $GITHUB_OUTPUT + ./awesome-docker check > link_check_output.txt 2>&1 || true + if grep -q "broken links" link_check_output.txt; then + echo "has_errors=true" >> "$GITHUB_OUTPUT" else - echo "has_errors=false" >> $GITHUB_OUTPUT + echo "has_errors=false" >> "$GITHUB_OUTPUT" fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create/Update Issue for Broken Links if: steps.link_check.outputs.has_errors == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 + uses: actions/github-script@v7 with: script: | const fs = require('fs'); const output = fs.readFileSync('link_check_output.txt', 'utf8'); - // Extract error information - const errorMatch = output.match(/❌ ERROR[\s\S]*$/); - const errorInfo = errorMatch ? errorMatch[0] : 'Link check failed - see workflow logs'; + const issueBody = `# Broken Links Detected\n\nThe weekly link check found broken or inaccessible links.\n\n\`\`\`\n${output}\n\`\`\`\n\n## Action Required\n\n- Update the URL if the resource moved\n- Remove the entry if permanently unavailable\n- Add to \`config/exclude.yaml\` if a known false positive\n\n---\n*Auto-generated by broken_links.yml*`; - const issueBody = `# 🔗 Broken Links Detected - - The weekly link check has found broken or inaccessible links in the repository. - - ## Error Details - - \`\`\` - ${errorInfo} - \`\`\` - - ## Action Required - - Please review and fix the broken links above. Options: - - Update the URL if the resource moved - - Remove the entry if it's permanently unavailable - - Add to \`tests/exclude_in_test.json\` if it's a known false positive - - --- - *Auto-generated by [broken_links.yml](https://github.com/veggiemonk/awesome-docker/blob/master/.github/workflows/broken_links.yml)* - `; - - // Check for existing issue const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, @@ -91,21 +59,19 @@ jobs: issue_number: issues.data[0].number, body: issueBody }); - console.log(`Updated issue #${issues.data[0].number}`); } else { - const issue = await github.rest.issues.create({ + await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, - title: '🔗 Broken Links Detected - Action Required', + title: 'Broken Links Detected', body: issueBody, labels: ['broken-links', 'bug'] }); - console.log(`Created issue #${issue.data.number}`); } - name: Close Issue if No Errors if: steps.link_check.outputs.has_errors == 'false' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 + uses: actions/github-script@v7 with: script: | const issues = await github.rest.issues.listForRepo({ @@ -115,7 +81,6 @@ jobs: labels: 'broken-links', per_page: 1 }); - if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, @@ -124,11 +89,4 @@ jobs: state: 'closed', state_reason: 'completed' }); - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issues.data[0].number, - body: '✅ All links are now working! Closing this issue.' - }); - console.log(`Closed issue #${issues.data[0].number}`); } diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 5ec560a..9d90e25 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -20,22 +20,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 + uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # ratchet:actions/setup-node@v6.2.0 + - uses: actions/setup-go@v5 with: - node-version-file: '.nvmrc' - cache: 'npm' + go-version: "1.22" - - name: Install dependencies - run: npm ci + - name: Build CLI + run: go build -o awesome-docker ./cmd/awesome-docker - name: Build website - run: npm run build + run: ./awesome-docker build - name: Upload artifact - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # ratchet:actions/upload-pages-artifact@v4 + uses: actions/upload-pages-artifact@v4 with: path: ./website @@ -48,4 +46,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # ratchet:actions/deploy-pages@v4 + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/health_report.yml b/.github/workflows/health_report.yml index 5eac611..3a95606 100644 --- a/.github/workflows/health_report.yml +++ b/.github/workflows/health_report.yml @@ -2,56 +2,52 @@ name: Weekly Health Report on: schedule: - # Run every Monday at 9 AM UTC - cron: "0 9 * * 1" - workflow_dispatch: # Allow manual trigger + workflow_dispatch: jobs: health-check: runs-on: ubuntu-latest permissions: - contents: write + contents: read issues: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 + - uses: actions/checkout@v4 - - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # ratchet:actions/setup-node@v6.2.0 + - uses: actions/setup-go@v5 with: - node-version: lts/* + go-version: "1.22" - - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # ratchet:actions/cache@v5.0.3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- + - name: Build + run: go build -o awesome-docker ./cmd/awesome-docker - - name: Install Dependencies - run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline - - - name: Run Health Check - run: node tests/health_check.mjs + - name: Run Health Scoring + run: ./awesome-docker health continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload Health Report - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # ratchet:actions/upload-artifact@v5 - with: - name: health-report - path: HEALTH_REPORT.md + - name: Generate Report + id: report + run: | + ./awesome-docker report > health_report.txt 2>&1 || true + if [ -s health_report.txt ]; then + echo "has_report=true" >> "$GITHUB_OUTPUT" + else + echo "has_report=false" >> "$GITHUB_OUTPUT" + fi - - name: Create Issue with Health Report - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 + - name: Create/Update Issue with Health Report + if: steps.report.outputs.has_report == 'true' + uses: actions/github-script@v7 with: script: | const fs = require('fs'); + const report = fs.readFileSync('health_report.txt', 'utf8'); - // Read the health report - const report = fs.readFileSync('HEALTH_REPORT.md', 'utf8'); + const issueBody = report + '\n\n---\n*Auto-generated weekly by health_report.yml*'; - // Check if there's already an open issue const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, @@ -60,25 +56,19 @@ jobs: per_page: 1 }); - const issueBody = report + '\n\n---\n*This report is auto-generated weekly. See [health_check.mjs](https://github.com/veggiemonk/awesome-docker/blob/master/tests/health_check.mjs) for details.*'; - if (issues.data.length > 0) { - // Update existing issue await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, body: issueBody }); - console.log(`Updated issue #${issues.data[0].number}`); } else { - // Create new issue - const issue = await github.rest.issues.create({ + await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, - title: '🏥 Weekly Health Report - Repository Maintenance Needed', + title: 'Weekly Health Report - Repository Maintenance Needed', body: issueBody, labels: ['health-report', 'maintenance'] }); - console.log(`Created issue #${issue.data.number}`); } diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 041e5b1..bc613fc 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -11,22 +11,16 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2 - - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # ratchet:actions/setup-node@v6.2.0 - with: - node-version: lts/* + - uses: actions/checkout@v4 - - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # ratchet:actions/cache@v5.0.3 - id: cache + - uses: actions/setup-go@v5 with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- + go-version: "1.22" - - name: Install Dependencies - # if: steps.cache.outputs.cache-hit != 'true' - run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline - - run: npm run test-pr + - name: Build + run: go build -o awesome-docker ./cmd/awesome-docker + + - name: Validate + run: ./awesome-docker validate env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 0816049273a33da46d1e8a8ee927c38a50e0f909 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:31:57 +0100 Subject: [PATCH 11/29] feat: implement lint --fix and standardize README Add FixFile() to rewrite README entries: capitalize descriptions, add trailing periods, remove author attributions, and sort entries alphabetically within each section. Update parser regex to handle entries with markers between URL and description separator. Fix linter to check first letter (not first character) for capitalization. ~480 entries standardized across the README. Co-Authored-By: Claude Opus 4.6 --- README.md | 950 +++++++++++++++++----------------- cmd/awesome-docker/main.go | 6 +- internal/linter/fixer.go | 144 ++++++ internal/linter/fixer_test.go | 140 +++++ internal/linter/rules.go | 21 +- internal/parser/parser.go | 13 +- 6 files changed, 792 insertions(+), 482 deletions(-) create mode 100644 internal/linter/fixer.go create mode 100644 internal/linter/fixer_test.go diff --git a/README.md b/README.md index e65cb96..acae942 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) # Where to start - [Benefits of using Docker](https://semaphore.io/blog/docker-benefits) for development and delivery, with a practical roadmap for adoption. -- [Bootstrapping Microservices](https://www.manning.com/books/bootstrapping-microservices-with-docker-kubernetes-and-terraform) by [Ashley Davis](https://twitter.com/ashleydavis75) - A practical and project-based guide to building applications with microservices, starts by building a Docker image for a single microservice and publishing it to a private container registry, finishes by deploying a complete microservices application to a production Kubernetes cluster. +- [Bootstrapping Microservices](https://www.manning.com/books/bootstrapping-microservices-with-docker-kubernetes-and-terraform) - A practical and project-based guide to building applications with microservices, starts by building a Docker image for a single microservice and publishing it to a private container registry, finishes by deploying a complete microservices application to a production Kubernetes cluster. - [Docker Curriculum](https://github.com/prakhar1989/docker-curriculum): A comprehensive tutorial for getting started with Docker. Teaches how to use Docker and deploy dockerized apps on AWS with Elastic Beanstalk and Elastic Container Service. - [Docker Documentation](https://docs.docker.com/): the official documentation. - [Docker for beginners](https://github.com/groda/big_data/blob/master/docker_for_beginners.md): A tutorial for beginners who need to learn the basics of Docker—from "Hello world!" to basic interactions with containers, with simple explanations of the underlying concepts. @@ -108,7 +108,7 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Introduction à Docker](https://blog.stephane-robert.info/docs/conteneurs/moteurs-conteneurs/docker/) A dedicated section to master Docker on a French site about DevSecOps: From the basics to best practices, including optimizing, securing your containers... - [Learn Docker](https://github.com/dwyl/learn-docker): step-by-step tutorial and more resources (video, articles, cheat sheets) by [@dwyl](https://github.com/dwyl) -- [Learn Docker (Visually)](https://pagertree.com/learn/docker/overview) - A beginner-focused high-level overview of all the major components of Docker and how they fit together. Lots of high-quality images, examples, and resources. +- [Learn Docker (Visually)](https://pagertree.com/learn/docker/overview) - A beginner-focused high-level overview of all the major components of Docker and how they fit together. Lots of high-quality images, examples, and resources. - [Play With Docker](https://training.play-with-docker.com/): PWD is a great way to get started with Docker from beginner to advanced users. Docker runs directly in your browser. - [Practical Guide about Docker Commands in Spanish](https://github.com/brunocascio/docker-espanol) This Spanish guide contains the use of basic docker commands with real life examples. - [Setting Python Development Environment with VScode and Docker](https://github.com/RamiKrispin/vscode-python): A step-by-step tutorial for setting up a dockerized Python development environment with VScode, Docker, and the Dev Container extension. @@ -125,11 +125,11 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) # Where to start (Windows) - [Docker on Windows behind a firewall](https://toedter.com/2015/05/11/docker-on-windows-behind-a-firewall/) by [@kaitoedter](https://twitter.com/kaitoedter) -- [Docker Reference Architecture: Modernizing Traditional .NET Framework Applications](https://docs.mirantis.com/containers/v3.0/dockeree-ref-arch/app-dev/modernize-dotnet-apps.html) - You will learn to identify the types of .NET Framework applications that are good candidates for containerization, the "lift-and-shift" approach to containerization. +- [Docker Reference Architecture: Modernizing Traditional .NET Framework Applications](https://docs.mirantis.com/containers/v3.0/dockeree-ref-arch/app-dev/modernize-dotnet-apps.html) - You will learn to identify the types of .NET Framework applications that are good candidates for containerization, the "lift-and-shift" approach to containerization. - [Docker with Microsoft SQL 2016 + ASP.NET](https://blog.alexellis.io/docker-does-sql2016-aspnet/) Demonstration running ASP.NET and SQL Server workloads in Docker - [Exploring ASP.NET Core with Docker in both Linux and Windows Containers](https://www.hanselman.com/blog/exploring-aspnet-core-with-docker-in-both-linux-and-windows-containers) Running ASP.NET Core apps in Linux and Windows containers, using [Docker for Windows][docker-for-windows] - [Running a Legacy ASP.NET App in a Windows Container](https://blog.sixeyed.com/dockerizing-nerd-dinner-part-1-running-a-legacy-asp-net-app-in-a-windows-container/) Steps for Dockerizing a legacy ASP.NET app and running as a Windows container -- [Windows Containers and Docker: The 101](https://www.youtube.com/watch?v=N7SG2wEyQtM) :movie_camera: - A 20-minute overview, using Docker to run PowerShell, ASP.NET Core and ASP.NET apps +- [Windows Containers and Docker: The 101](https://www.youtube.com/watch?v=N7SG2wEyQtM) - A 20-minute overview, using Docker to run PowerShell, ASP.NET Core and ASP.NET apps. - [Windows Containers Quick Start](https://learn.microsoft.com/en-us/virtualization/windowscontainers/about/) Overview of Windows containers, drilling down to Quick Starts for Windows 10 and Windows Server 2016 --- @@ -153,216 +153,216 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Container Composition -- [bocker](https://github.com/icy/bocker) (2) :skull: - Write Dockerfile completely in Bash. Extensible and simple. --> Reusable by [@icy](https://github.com/icy) -- [bocker](https://github.com/p8952/bocker) (1) :skull: - Docker implemented in 100 lines of bash by [p8952](https://github.com/p8952) -- [box](https://github.com/box-builder/box) :skull: - Build Dockerfile images with a mruby DSL, includes flattening and layer manipulation -- [Capitan](https://github.com/byrnedo/capitan) - Composable docker orchestration with added scripting support by [@byrnedo]. -- [compose_plantuml](https://github.com/funkwerk/compose_plantuml) :skull: - Generate Plantuml graphs from docker-compose files by [@funkwerk](https://github.com/funkwerk) -- [Composerize](https://github.com/magicmark/composerize) - Convert docker run commands into docker-compose files -- [crowdr](https://github.com/polonskiy/crowdr) - Tool for managing multiple Docker containers (`docker-compose` alternative) by [@polonskiy](https://github.com/polonskiy/) -- [ctk](https://github.com/ctk-hq/ctk) :construction: - Visual composer for container based workloads. By [@corpulent](https://github.com/corpulent) -- [docker-compose-graphviz](https://github.com/abesto/docker-compose-graphviz) :skull: - Turn a docker-compose.yml files into Graphviz .dot files by [@abesto](https://github.com/abesto) -- [docker-config-update](https://github.com/sudo-bmitch/docker-config-update) - Utility to update docker configs and secrets for deploying in a compose file by [@sudo-bmitch](https://github.com/sudo-bmitch) -- [draw-compose](https://github.com/Alexis-benoist/draw-compose) :skull: - Utility to draw a schema of a docker compose by [@Alexis-benoist](https://github.com/Alexis-benoist) -- [elsy](https://github.com/cisco/elsy) - An opinionated, multi-language, build tool based on Docker and Docker Compose -- [habitus](https://github.com/cloud66-oss/habitus) - A Build Flow Tool for Docker by [@cloud66](https://github.com/cloud66) -- [kompose](https://github.com/kubernetes/kompose) - Go from Docker Compose to Kubernetes -- [LLM Harbor](https://github.com/av/harbor) - A CLI and companion app to effortlessly run LLM backends, APIs, frontends, and services with one command. By [@av](https://github.com/av) -- [Maestro](https://github.com/toscanini/maestro) :skull: - Maestro provides the ability to easily launch, orchestrate and manage multiple Docker containers as single unit by [@tascanini](https://github.com/toscanini) -- [percheron](https://github.com/ashmckenzie/percheron) :skull: - Organise your Docker containers with muscle and intelligence by [@ashmckenzie](https://github.com/ashmckenzie) -- [plash](https://github.com/ihucos/plash) - A container run and build engine - runs inside docker. -- [podman-compose](https://github.com/containers/podman-compose) - a script to run docker-compose.yml using podman by [@containers][containers] -- [rocker-compose](https://github.com/grammarly/rocker-compose) :skull: - Docker composition tool with idempotency features for deploying apps composed of multiple containers. By[@grammarly]. -- [rocker](https://github.com/grammarly/rocker) :skull: - Extended Dockerfile builder. Supports multiple FROMs, MOUNTS, templates, etc. by [@grammarly]. +- [bocker](https://github.com/icy/bocker) - :skull: Write Dockerfile completely in Bash. Extensible and simple. --> Reusable. +- [bocker](https://github.com/p8952/bocker) - :skull: Docker implemented in 100 lines of bash by [p8952](https://github.com/p8952). +- [box](https://github.com/box-builder/box) - :skull: Build Dockerfile images with a mruby DSL, includes flattening and layer manipulation. +- [Capitan](https://github.com/byrnedo/capitan) - Composable docker orchestration with added scripting support by [@byrnedo]. +- [compose_plantuml](https://github.com/funkwerk/compose_plantuml) - :skull: Generate Plantuml graphs from docker-compose files. +- [Composerize](https://github.com/magicmark/composerize) - Convert docker run commands into docker-compose files. +- [crowdr](https://github.com/polonskiy/crowdr) - Tool for managing multiple Docker containers (`docker-compose` alternative). +- [ctk](https://github.com/ctk-hq/ctk) - :construction: Visual composer for container based workloads. By [@corpulent](https://github.com/corpulent). +- [docker-compose-graphviz](https://github.com/abesto/docker-compose-graphviz) - :skull: Turn a docker-compose.yml files into Graphviz .dot files. +- [docker-config-update](https://github.com/sudo-bmitch/docker-config-update) - Utility to update docker configs and secrets for deploying in a compose file. +- [draw-compose](https://github.com/Alexis-benoist/draw-compose) - :skull: Utility to draw a schema of a docker compose. +- [elsy](https://github.com/cisco/elsy) - An opinionated, multi-language, build tool based on Docker and Docker Compose. +- [habitus](https://github.com/cloud66-oss/habitus) - A Build Flow Tool for Docker. +- [kompose](https://github.com/kubernetes/kompose) - Go from Docker Compose to Kubernetes. +- [LLM Harbor](https://github.com/av/harbor) - A CLI and companion app to effortlessly run LLM backends, APIs, frontends, and services with one command. By [@av](https://github.com/av). +- [Maestro](https://github.com/toscanini/maestro) - :skull: Maestro provides the ability to easily launch, orchestrate and manage multiple Docker containers as single unit. +- [percheron](https://github.com/ashmckenzie/percheron) - :skull: Organise your Docker containers with muscle and intelligence. +- [plash](https://github.com/ihucos/plash) - A container run and build engine - runs inside docker. +- [podman-compose](https://github.com/containers/podman-compose) - A script to run docker-compose.yml using podman. +- [rocker](https://github.com/grammarly/rocker) - :skull: Extended Dockerfile builder. Supports multiple FROMs, MOUNTS, templates, etc. by [@grammarly]. +- [rocker-compose](https://github.com/grammarly/rocker-compose) - :skull: Docker composition tool with idempotency features for deploying apps composed of multiple containers. By[@grammarly]. - [Smalte](https://github.com/roquie/smalte) – Dynamically configure applications that require static configuration in docker container. By [@roquie](https://github.com/roquie) -- [Stacker](https://github.com/stacker/stacker-cli) :skull: - Docker Compose Templates. Stacker provides an abstraction layer over Docker Compose and a better DX (developer experience). -- [Stitchocker](https://github.com/alexaandrov/stitchocker) - A lightweight and fast command line utility for conveniently grouping your docker-compose multiple container services. By [@alexaandrov](https://github.com/alexaandrov) -- [Zodiac](https://github.com/CenturyLinkLabs/zodiac) :skull: - A lightweight tool for easy deployment and rollback of dockerized applications. By [@CenturyLinkLabs][centurylinklabs] +- [Stacker](https://github.com/stacker/stacker-cli) - :skull: Docker Compose Templates. Stacker provides an abstraction layer over Docker Compose and a better DX (developer experience). +- [Stitchocker](https://github.com/alexaandrov/stitchocker) - A lightweight and fast command line utility for conveniently grouping your docker-compose multiple container services. By [@alexaandrov](https://github.com/alexaandrov). +- [Zodiac](https://github.com/CenturyLinkLabs/zodiac) - :skull: A lightweight tool for easy deployment and rollback of dockerized applications. By [@CenturyLinkLabs][centurylinklabs]. ### Deployment and Infrastructure -- [awesome-stacks](https://github.com/ethibox/awesome-stacks) - Deploy 150+ open-source web apps with one Docker command -- [blackfish](https://gitlab.com/blackfish/blackfish) - a CoreOS VM to build swarm clusters for Dev & Production by [@blackfish](https://gitlab.com/blackfish/) -- [BosnD](https://gitlab.com/n0r1sk/bosnd) - BosnD, the boatswain daemon - A dynamic configuration file writer & service reloader for dynamically changing container environments. -- [Centurion](https://github.com/newrelic/centurion) - Centurion is a mass deployment tool for Docker fleets. It takes containers from a Docker registry and runs them on a fleet of hosts with the correct environment variables, host volume mappings, and port mappings. By [@newrelic](https://github.com/newrelic) -- [Clocker](https://github.com/brooklyncentral/clocker) - Clocker creates and manages a Docker cloud infrastructure. Clocker supports single-click deployments and runtime management of multi-node applications that run as containers distributed across multiple hosts, on both Docker and Marathon. It leverages [Calico][calico] and [Weave][weave] for networking and [Brooklyn](https://brooklyn.apache.org/) for application blueprints. By [@brooklyncentral](https://github.com/brooklyncentral) -- [Conduit](https://github.com/ehazlett/conduit) - Experimental deployment system for Docker by [@ehazlett](https://github.com/ehazlett) -- [depcon](https://github.com/ContainX/depcon) - Depcon is written in Go and allows you to easily deploy Docker containers to Apache Mesos/Marathon, Amazon ECS and Kubernetes. By [@ContainX][containx] -- [deploy](https://github.com/ttiny/deploy) :skull: - Git and Docker deployment tool. A middle ground between simple Docker composition tools and full blown cluster orchestration by [@ttiny](https://github.com/ttiny) -- [docker-to-iac](https://github.com/deploystackio/docker-to-iac) - Translate docker run and commit into Infrastructure as Code templates for AWS, Render.com and DigitalOcean by [@DeployStack](https://github.com/deploystackio) -- [dockit](https://github.com/humblec/dockit) :skull: - Do docker actions and Deploy gluster containers! By [@humblec](https://github.com/humblec) -- [gitkube](https://github.com/hasura/gitkube) - Gitkube is a tool for building and deploying docker images on Kubernetes using `git push`. By [@Hasura](https://github.com/hasura/). -- [Grafeas](https://github.com/grafeas/grafeas) - A common API for metadata about containers, from image and build details to security vulnerabilities. By [grafeas](https://github.com/grafeas) -- [Longshoreman](https://github.com/longshoreman/longshoreman) :skull: - Longshoreman automates application deployment using Docker. Just create a Docker repository (or use a service), configure the cluster using AWS or Digital Ocean (or whatever you like) and deploy applications using a Heroku-like CLI tool. By [longshoreman](https://github.com/longshoreman) -- [swarm-ansible](https://github.com/LombardiDaniel/swarm-ansible?tab=readme-ov-file) - Swarm-Ansible bootstraps a production-ready swarm cluster using ansible. Comes with tools to automate CI, help monitoring and traefik pre-configured for SSL certificates and simple-auth. Comes with a private registry and more! -- [SwarmManagement](https://github.com/hansehe/SwarmManagement) - Swarm Management is a python application, installed with pip. The application makes it easy to manage a Docker Swarm by configuring a single yaml file describing which stacks to deploy, and which networks, configs or secrets to create. -- [werf](https://github.com/werf/werf) - werf is a CI/CD tool for building Docker images efficiently and deploying them to Kubernetes using GitOps by [@flant](https://github.com/flant) +- [awesome-stacks](https://github.com/ethibox/awesome-stacks) - Deploy 150+ open-source web apps with one Docker command. +- [blackfish](https://gitlab.com/blackfish/blackfish) - A CoreOS VM to build swarm clusters for Dev & Production. +- [BosnD](https://gitlab.com/n0r1sk/bosnd) - BosnD, the boatswain daemon - A dynamic configuration file writer & service reloader for dynamically changing container environments. +- [Centurion](https://github.com/newrelic/centurion) - Centurion is a mass deployment tool for Docker fleets. It takes containers from a Docker registry and runs them on a fleet of hosts with the correct environment variables, host volume mappings, and port mappings. By [@newrelic](https://github.com/newrelic). +- [Clocker](https://github.com/brooklyncentral/clocker) - Clocker creates and manages a Docker cloud infrastructure. Clocker supports single-click deployments and runtime management of multi-node applications that run as containers distributed across multiple hosts, on both Docker and Marathon. It leverages [Calico][calico] and [Weave][weave] for networking and [Brooklyn](https://brooklyn.apache.org/) for application blueprints. By [@brooklyncentral](https://github.com/brooklyncentral). +- [Conduit](https://github.com/ehazlett/conduit) - Experimental deployment system for Docker. +- [depcon](https://github.com/ContainX/depcon) - Depcon is written in Go and allows you to easily deploy Docker containers to Apache Mesos/Marathon, Amazon ECS and Kubernetes. By [@ContainX][containx]. +- [deploy](https://github.com/ttiny/deploy) - :skull: Git and Docker deployment tool. A middle ground between simple Docker composition tools and full blown cluster orchestration. +- [docker-to-iac](https://github.com/deploystackio/docker-to-iac) - Translate docker run and commit into Infrastructure as Code templates for AWS, Render.com and DigitalOcean. +- [dockit](https://github.com/humblec/dockit) - :skull: Do docker actions and Deploy gluster containers! By [@humblec](https://github.com/humblec). +- [gitkube](https://github.com/hasura/gitkube) - Gitkube is a tool for building and deploying docker images on Kubernetes using `git push`. By [@Hasura](https://github.com/hasura/). +- [Grafeas](https://github.com/grafeas/grafeas) - A common API for metadata about containers, from image and build details to security vulnerabilities. By [grafeas](https://github.com/grafeas). +- [Longshoreman](https://github.com/longshoreman/longshoreman) - :skull: Longshoreman automates application deployment using Docker. Just create a Docker repository (or use a service), configure the cluster using AWS or Digital Ocean (or whatever you like) and deploy applications using a Heroku-like CLI tool. By [longshoreman](https://github.com/longshoreman). +- [swarm-ansible](https://github.com/LombardiDaniel/swarm-ansible?tab=readme-ov-file) - Swarm-Ansible bootstraps a production-ready swarm cluster using ansible. Comes with tools to automate CI, help monitoring and traefik pre-configured for SSL certificates and simple-auth. Comes with a private registry and more!. +- [SwarmManagement](https://github.com/hansehe/SwarmManagement) - Swarm Management is a python application, installed with pip. The application makes it easy to manage a Docker Swarm by configuring a single yaml file describing which stacks to deploy, and which networks, configs or secrets to create. +- [werf](https://github.com/werf/werf) - Werf is a CI/CD tool for building Docker images efficiently and deploying them to Kubernetes using GitOps. ### Monitoring - [Autoheal](https://github.com/willfarrell/docker-autoheal) - Monitor and restart unhealthy docker containers automatically. - [Axibase Collector](https://axibase.com/docs/axibase-collector/) - Axibase Collector streams performance counters, configuration changes and lifecycle events from the Docker engine(s) into Axibase Time Series Database for roll-up dashboards and integration with upstream monitoring systems. -- [cAdvisor](https://github.com/google/cadvisor) - Analyzes resource usage and performance characteristics of running containers. Created by [@Google][google] +- [cAdvisor](https://github.com/google/cadvisor) - Analyzes resource usage and performance characteristics of running containers. - [Checkmate](https://github.com/bluewave-labs/checkmate) - Checkmate is an open-source, self-hosted tool designed to track and monitor server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. -- [DLIA](https://github.com/zorak1103/dlia) - DLIA is an AI-powered Docker log monitoring agent that uses Large Language Models (LLMs) to intelligently analyze container logs, detect anomalies, and provide contextual insights over time. By [@zorak1103](https://github.com/zorak1103) -- [Docker-Alertd](https://github.com/deltaskelta/docker-alertd) - Monitor and send alerts based on docker container resource usage/statistics -- [Docker-Flow-Monitor](https://github.com/docker-flow/docker-flow-monitor) - Reconfigures Prometheus when a new service is updated or deployed automatically by [@docker-flow][docker-flow] -- [Dockerana](https://github.com/dockerana/dockerana) :skull: - packaged version of Graphite and Grafana, specifically targeted at metrics from Docker. +- [DLIA](https://github.com/zorak1103/dlia) - DLIA is an AI-powered Docker log monitoring agent that uses Large Language Models (LLMs) to intelligently analyze container logs, detect anomalies, and provide contextual insights over time. By [@zorak1103](https://github.com/zorak1103). +- [Docker-Alertd](https://github.com/deltaskelta/docker-alertd) - Monitor and send alerts based on docker container resource usage/statistics. +- [Docker-Flow-Monitor](https://github.com/docker-flow/docker-flow-monitor) - Reconfigures Prometheus when a new service is updated or deployed automatically. +- [Dockerana](https://github.com/dockerana/dockerana) - :skull: Packaged version of Graphite and Grafana, specifically targeted at metrics from Docker. - [DockProc](https://gitlab.com/n0r1sk/dockproc) - I/O monitoring for containers on processlevel. -- [dockprom](https://github.com/stefanprodan/dockprom) - Docker hosts and containers monitoring with Prometheus, Grafana, cAdvisor, NodeExporter and AlertManager by [@stefanprodan](https://github.com/stefanprodan) -- [Doku](https://github.com/amerkurev/doku) - Doku is a simple web-based application that allows you to monitor Docker disk usage. [@amerkurev](https://github.com/amerkurev) -- [Dozzle](dozzle) - Monitor container logs in real-time with a browser or mobile device. [@amir20](https://github.com/amir20) -- [Dynatrace](https://www.dynatrace.com/solutions/container-monitoring/) :heavy_dollar_sign: - Monitor containerized applications without installing agents or modifying your Run commands -- [Glances](https://github.com/nicolargo/glances) - A cross-platform curses-based system monitoring tool written in Python by [@nicolargo](https://github.com/nicolargo) -- [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [@vegasbrianc][vegasbrianc] +- [dockprom](https://github.com/stefanprodan/dockprom) - Docker hosts and containers monitoring with Prometheus, Grafana, cAdvisor, NodeExporter and AlertManager. +- [Doku](https://github.com/amerkurev/doku) - Doku is a simple web-based application that allows you to monitor Docker disk usage. [@amerkurev](https://github.com/amerkurev). +- [Dozzle](dozzle) - Monitor container logs in real-time with a browser or mobile device. [@amir20](https://github.com/amir20). +- [Dynatrace](https://www.dynatrace.com/solutions/container-monitoring/) - :heavy_dollar_sign: Monitor containerized applications without installing agents or modifying your Run commands. +- [Glances](https://github.com/nicolargo/glances) - A cross-platform curses-based system monitoring tool written in Python. +- [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [@vegasbrianc][vegasbrianc]. - [HertzBeat](https://github.com/dromara/hertzbeat) - An open-source real-time monitoring system with custom-monitor and agentless. -- [InfluxDB, cAdvisor, Grafana](https://github.com/vegasbrianc/docker-monitoring) - InfluxDB Time series DB in combination with Grafana and cAdvisor by [@vegasbrianc][vegasbrianc] -- [LogJam](https://github.com/gocardless/logjam) - :skull: Logjam is a log forwarder designed to listen on a local port, receive log entries over UDP, and forward these messages on to a log collection server (such as logstash) by [@gocardless](https://github.com/gocardless) -- [Logspout](https://github.com/gliderlabs/logspout) - Log routing for Docker container logs by [@gliderlabs][gliderlabs] -- [monit-docker](https://github.com/decryptus/monit-docker) - Monitor docker containers resources usage or status and execute docker commands or inside containers. [@decryptus][decryptus] -- [NexClipper](https://github.com/NexClipper/NexClipper) - NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes by [@Nexclipper](https://github.com/NexClipper) +- [InfluxDB, cAdvisor, Grafana](https://github.com/vegasbrianc/docker-monitoring) - InfluxDB Time series DB in combination with Grafana and cAdvisor. +- [LogJam](https://github.com/gocardless/logjam) - :skull: Logjam is a log forwarder designed to listen on a local port, receive log entries over UDP, and forward these messages on to a log collection server (such as logstash). +- [Logspout](https://github.com/gliderlabs/logspout) - Log routing for Docker container logs. +- [monit-docker](https://github.com/decryptus/monit-docker) - Monitor docker containers resources usage or status and execute docker commands or inside containers. [@decryptus][decryptus]. +- [NexClipper](https://github.com/NexClipper/NexClipper) - NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes. - [Out-of-the-box Host/Container Monitoring/Logging/Alerting Stack](https://github.com/uschtwill/docker_monitoring_logging_alerting) - Docker host and container monitoring, logging and alerting out of the box using cAdvisor, Prometheus, Grafana for monitoring, Elasticsearch, Kibana and Logstash for logging and elastalert and Alertmanager for alerting. Set up in 5 Minutes. Secure mode for production use with built-in [Automated Nginx Reverse Proxy (jwilder's)][nginxproxy]. -- [Sidekick](https://github.com/runsidekick/sidekick) 💲 - Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. -- [SuperVisor CPM](https://t0xic0der.medium.com/simply-accessible-container-performance-monitoring-with-supervisor-7fb47f925f3b) [Frontend Service](https://github.com/t0xic0der/supervisor-frontend-service/) and [Driver Service](https://github.com/t0xic0der/supervisor-driver-service/) :construction: - A simple and accessible FOSS container performance monitoring service written in Python by [@t0xic0der](https://github.com/t0xic0der/) +- [Sidekick](https://github.com/runsidekick/sidekick) - Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. +- [SuperVisor CPM](https://t0xic0der.medium.com/simply-accessible-container-performance-monitoring-with-supervisor-7fb47f925f3b) - :construction: A simple and accessible FOSS container performance monitoring service written in Python. - [SwarmAlert](https://github.com/gpulido/SwarmAlert) - Monitors a Docker Swarm and sends Pushover alerts when it finds a container with no healthy service task running. -- [Zabbix Docker module](https://github.com/monitoringartist/Zabbix-Docker-Monitoring) - Zabbix module that provides discovery of running containers, CPU/memory/blk IO/net container metrics. Systemd Docker and LXC execution driver is also supported. It's a dynamically linked shared object library, so its performance is (~10x) better, than any script solution. - [Zabbix Docker](https://github.com/gomex/docker-zabbix) - Monitor containers automatically using zabbix LLD feature. +- [Zabbix Docker module](https://github.com/monitoringartist/Zabbix-Docker-Monitoring) - Zabbix module that provides discovery of running containers, CPU/memory/blk IO/net container metrics. Systemd Docker and LXC execution driver is also supported. It's a dynamically linked shared object library, so its performance is (~10x) better, than any script solution. ### Networking - [Calico][calico] - Calico is a pure layer 3 virtual network that allows containers over multiple docker-hosts to talk to each other. -- [Flannel](https://github.com/coreos/flannel/) - Flannel is a virtual network that gives a subnet to each host for use with container runtimes. By [@coreos][coreos] -- [Freeflow](https://github.com/Microsoft/Freeflow) - High performance container overlay networks on Linux. Enabling RDMA (on both InfiniBand and RoCE) and accelerating TCP to bare metal performance. By [@Microsoft](https://github.com/Microsoft) -- [MyIP](https://github.com/jason5ng32/MyIP) - All in one IP Toolbox. Easy to check all your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more. By [@jason5ng32](https://github.com/jason5ng32) -- [netshoot](https://github.com/nicolaka/netshoot) - The netshoot container has a powerful set of networking tools to help troubleshoot Docker networking issues by [@nicolaka](https://github.com/nicolaka) -- [Pipework](https://github.com/jpetazzo/pipework) - Software-Defined Networking for Linux Containers, Pipework works with "plain" LXC containers, and with the awesome Docker. By [@jpetazzo][jpetazzo] +- [Flannel](https://github.com/coreos/flannel/) - Flannel is a virtual network that gives a subnet to each host for use with container runtimes. By [@coreos][coreos]. +- [Freeflow](https://github.com/Microsoft/Freeflow) - High performance container overlay networks on Linux. Enabling RDMA (on both InfiniBand and RoCE) and accelerating TCP to bare metal performance. By [@Microsoft](https://github.com/Microsoft). +- [MyIP](https://github.com/jason5ng32/MyIP) - All in one IP Toolbox. Easy to check all your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more. By [@jason5ng32](https://github.com/jason5ng32). +- [netshoot](https://github.com/nicolaka/netshoot) - The netshoot container has a powerful set of networking tools to help troubleshoot Docker networking issues. +- [Pipework](https://github.com/jpetazzo/pipework) - Software-Defined Networking for Linux Containers, Pipework works with "plain" LXC containers, and with the awesome Docker. By [@jpetazzo][jpetazzo]. - [Weave][weave] (The Docker network) :skull: - Weave creates a virtual network that connects Docker containers deployed across multiple hosts. ### Orchestration -- [Ansible Linux Docker](https://github.com/Peco602/ansible-linux-docker) - Run Ansible from a Linux container. By [@Peco602][peco602] -- [athena](https://github.com/athena-oss/athena) - An automation platform with a plugin architecture that allows you to easily create and share services. -- [blimp](https://github.com/tubesandlube/blimp) :skull: - Uses Docker Machine to easily move a container from one Docker host to another, show containers running against all of your hosts, replicate a container across multiple hosts and more by [@defermat](https://github.com/defermat) and [@schvin](https://github.com/schvin) -- [CloudSlang](https://github.com/CloudSlang/cloud-slang) - CloudSlang is a workflow engine to create Docker process automation -- [clusterdock](https://github.com/clusterdock/clusterdock) - Docker container orchestration to enable the testing of long-running cluster deployments -- [Crane](https://github.com/Dataman-Cloud/crane) - Control plane based on docker built-in swarm [@Dataman-Cloud](https://github.com/Dataman-Cloud) -- [Docker Flow Swarm Listener](https://github.com/docker-flow/docker-flow-swarm-listener) - Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [@docker-flow][docker-flow] -- [docker rollout](https://github.com/Wowu/docker-rollout) - Zero downtime deployment for Docker Compose services by [@Wowu](https://github.com/Wowu) -- [gantryd](https://github.com/DevTable/gantryd) :skull: - A framework for easy management of docker-based components across machines by [@DevTable](https://github.com/DevTable) -- [Haven](https://github.com/codeabovelab/haven-platform) - Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [@codeabovelab](https://github.com/codeabovelab) -- [Helios](https://github.com/spotify/helios) :skull: - A simple platform for deploying and managing containers across an entire fleet of servers by [@spotify][spotify] -- [Kontena](https://github.com/kontena/kontena) :skull: - The developer friendly container and micro services platform. Works on any cloud, easy to setup, simple to use. -- [Kubernetes](https://github.com/kubernetes/kubernetes) - Open source orchestration system for Docker containers by Google -- [ManageIQ](https://github.com/ManageIQ/manageiq) - Discover, optimize and control your hybrid IT. By [ManageIQ](https://github.com/ManageIQ) -- [Mantl](https://github.com/mantl/mantl) - :skull: Mantl is a modern platform for rapidly deploying globally distributed services -- [Marathon](https://github.com/mesosphere/marathon) - :skull: Marathon is a private PaaS built on Mesos. It automatically handles hardware or software failures and ensures that an app is "always on" -- [Mesos](https://github.com/apache/mesos) - Resource/Job scheduler for containers, VM's and physical hosts [@apache](https://mesos.apache.org/) -- [Nebula](https://github.com/nebula-orchestrator) - A Docker orchestration tool designed to manage massive scale distributed clusters. -- [Nomad](https://github.com/hashicorp/nomad) - Easily deploy applications at any scale. A Distributed, Highly Available, Datacenter-Aware Scheduler by [@hashicorp](https://github.com/hashicorp) -- [Panamax](https://github.com/CenturyLinkLabs/panamax-ui) :skull: - An open-source project that makes deploying complex containerized apps as easy as Drag-and-Drop by [@CenturyLinkLabs][centurylinklabs]. -- [Rancher](https://github.com/rancher/rancher) - An open source project that provides a complete platform for operating Docker in production by [@rancher][rancher]. -- [RedHerd Framework](https://github.com/redherd-project/redherd-framework) - RedHerd is a collaborative and serverless framework for orchestrating a geographically distributed group of assets capable of simulating complex offensive cyberspace operations. By [@RedHerdProject](https://github.com/redherd-project). -- [Swarm-cronjob](https://github.com/crazy-max/swarm-cronjob) - Create jobs on a time-based schedule on Swarm by [@crazy-max] +- [Ansible Linux Docker](https://github.com/Peco602/ansible-linux-docker) - Run Ansible from a Linux container. By [@Peco602][peco602]. +- [athena](https://github.com/athena-oss/athena) - An automation platform with a plugin architecture that allows you to easily create and share services. +- [blimp](https://github.com/tubesandlube/blimp) - :skull: Uses Docker Machine to easily move a container from one Docker host to another, show containers running against all of your hosts, replicate a container across multiple hosts and more by [@defermat](https://github.com/defermat) and [@schvin](https://github.com/schvin). +- [CloudSlang](https://github.com/CloudSlang/cloud-slang) - CloudSlang is a workflow engine to create Docker process automation. +- [clusterdock](https://github.com/clusterdock/clusterdock) - Docker container orchestration to enable the testing of long-running cluster deployments. +- [Crane](https://github.com/Dataman-Cloud/crane) - Control plane based on docker built-in swarm [@Dataman-Cloud](https://github.com/Dataman-Cloud). +- [Docker Flow Swarm Listener](https://github.com/docker-flow/docker-flow-swarm-listener) - Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [@docker-flow][docker-flow]. +- [docker rollout](https://github.com/Wowu/docker-rollout) - Zero downtime deployment for Docker Compose services. +- [gantryd](https://github.com/DevTable/gantryd) - :skull: A framework for easy management of docker-based components across machines. +- [Haven](https://github.com/codeabovelab/haven-platform) - Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [@codeabovelab](https://github.com/codeabovelab). +- [Helios](https://github.com/spotify/helios) - :skull: A simple platform for deploying and managing containers across an entire fleet of servers. +- [Kontena](https://github.com/kontena/kontena) - :skull: The developer friendly container and micro services platform. Works on any cloud, easy to setup, simple to use. +- [Kubernetes](https://github.com/kubernetes/kubernetes) - Open source orchestration system for Docker containers by Google. +- [ManageIQ](https://github.com/ManageIQ/manageiq) - Discover, optimize and control your hybrid IT. By [ManageIQ](https://github.com/ManageIQ). +- [Mantl](https://github.com/mantl/mantl) - :skull: Mantl is a modern platform for rapidly deploying globally distributed services. +- [Marathon](https://github.com/mesosphere/marathon) - :skull: Marathon is a private PaaS built on Mesos. It automatically handles hardware or software failures and ensures that an app is "always on". +- [Mesos](https://github.com/apache/mesos) - Resource/Job scheduler for containers, VM's and physical hosts [@apache](https://mesos.apache.org/). +- [Nebula](https://github.com/nebula-orchestrator) - A Docker orchestration tool designed to manage massive scale distributed clusters. +- [Nomad](https://github.com/hashicorp/nomad) - Easily deploy applications at any scale. A Distributed, Highly Available, Datacenter-Aware Scheduler. +- [Panamax](https://github.com/CenturyLinkLabs/panamax-ui) - :skull: An open-source project that makes deploying complex containerized apps as easy as Drag-and-Drop. +- [Rancher](https://github.com/rancher/rancher) - An open source project that provides a complete platform for operating Docker in production. +- [RedHerd Framework](https://github.com/redherd-project/redherd-framework) - RedHerd is a collaborative and serverless framework for orchestrating a geographically distributed group of assets capable of simulating complex offensive cyberspace operations. By [@RedHerdProject](https://github.com/redherd-project). +- [Swarm-cronjob](https://github.com/crazy-max/swarm-cronjob) - Create jobs on a time-based schedule on Swarm by [@crazy-max]. ### PaaS -- [Atlantis](https://github.com/ooyala/atlantis) :skull: - Atlantis is an Open Source PaaS for HTTP applications built on Docker and written in Go -- [caprover](https://github.com/caprover/caprover) - [previously known as CaptainDuckDuck] Automated Scalable Webserver Package (automated Docker+nginx) - Heroku on Steroids -- [Convox Rack](https://github.com/convox/rack) - Convox Rack is open source PaaS built on top of expert infrastructure automation and devops best practices. -- [Dcw](https://github.com/pbertera/dcw) - Docker-compose SSH wrapper: a very poor man PaaS, exposing the docker-compose and custom-container commands defined in container labels. -- [Dokku](https://github.com/dokku/dokku) - Docker powered mini-Heroku that helps you build and manage the lifecycle of applications (originally by [@progrium][progrium]) -- [Empire](https://github.com/remind101/empire) - A PaaS built on top of Amazon EC2 Container Service (ECS) -- [Exoframe](https://github.com/exoframejs/exoframe) - A self-hosted tool that allows simple one-command deployments using Docker -- [Flynn](https://github.com/flynn/flynn) :skull: - A next generation open source platform as a service -- [Hephy Workflow](https://github.com/teamhephy/workflow) - Open source PaaS for Kubernetes that adds a developer-friendly layer to any Kubernetes cluster, making it easy to deploy and manage applications. Fork of [Deis Workflow](https://github.com/deis/workflow) -- [Krane](https://github.com/krane/krane) - Toolset for managing container workloads on remote servers -- [Nanobox](https://github.com/nanobox-io/nanobox) :heavy_dollar_sign: - An application development platform that creates local environments that can then be deployed and scaled in the cloud. +- [Atlantis](https://github.com/ooyala/atlantis) - :skull: Atlantis is an Open Source PaaS for HTTP applications built on Docker and written in Go. +- [caprover](https://github.com/caprover/caprover) - [Previously known as CaptainDuckDuck] Automated Scalable Webserver Package (automated Docker+nginx) - Heroku on Steroids. +- [Convox Rack](https://github.com/convox/rack) - Convox Rack is open source PaaS built on top of expert infrastructure automation and devops best practices. +- [Dcw](https://github.com/pbertera/dcw) - Docker-compose SSH wrapper: a very poor man PaaS, exposing the docker-compose and custom-container commands defined in container labels. +- [Dokku](https://github.com/dokku/dokku) - Docker powered mini-Heroku that helps you build and manage the lifecycle of applications (originally by [@progrium][progrium]). +- [Empire](https://github.com/remind101/empire) - A PaaS built on top of Amazon EC2 Container Service (ECS). +- [Exoframe](https://github.com/exoframejs/exoframe) - A self-hosted tool that allows simple one-command deployments using Docker. +- [Flynn](https://github.com/flynn/flynn) - :skull: A next generation open source platform as a service. +- [Hephy Workflow](https://github.com/teamhephy/workflow) - Open source PaaS for Kubernetes that adds a developer-friendly layer to any Kubernetes cluster, making it easy to deploy and manage applications. Fork of [Deis Workflow](https://github.com/deis/workflow). +- [Krane](https://github.com/krane/krane) - Toolset for managing container workloads on remote servers. +- [Nanobox](https://github.com/nanobox-io/nanobox) - :heavy_dollar_sign: An application development platform that creates local environments that can then be deployed and scaled in the cloud. - [OpenShift][openshift] - An open source PaaS built on [Kubernetes][kubernetes] and optimized for Dockerized app development and deployment by [Red Hat](https://www.redhat.com/en) -- [Tsuru](https://github.com/tsuru/tsuru) - Tsuru is an extensible and open source Platform as a Service software +- [Tsuru](https://github.com/tsuru/tsuru) - Tsuru is an extensible and open source Platform as a Service software. ### Reverse Proxy -- [BunkerWeb](https://github.com/bunkerity/bunkerweb) - Open-source and next-gen Web Application Firewall (WAF). By [Bunkerity](https://www.bunkerity.com) -- [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) - Caddy-based reverse proxy, configured with service or container labels. By [@lucaslorentz](https://github.com/lucaslorentz) -- [caddy-docker-upstreams](https://github.com/invzhi/caddy-docker-upstreams) - Docker upstreams module for Caddy, configured with container labels. By [@invzhi](https://github.com/invzhi) -- [Docker Dnsmasq Updater](https://github.com/moonbuggy/docker-dnsmasq-updater) - Update a remote dnsmasq server with Docker container hostnames. -- [docker-flow-proxy](https://github.com/docker-flow/docker-flow-proxy) - Reconfigures proxy every time a new service is deployed, or when a service is scaled. By [@docker-flow][docker-flow] -- [docker-proxy](https://github.com/silarsis/docker-proxy) :skull: - Transparent proxy for docker containers, run in a docker container. By [@silarsis](https://github.com/silarsis) -- [fabio](https://github.com/fabiolb/fabio) - A fast, modern, zero-conf load balancing HTTP(S) router for deploying microservices managed by consul. By [@magiconair](https://github.com/magiconair) (Frank Schroeder) -- [h2o-proxy](https://github.com/zchee/h2o-proxy) :skull: - Automated H2O reverse proxy for Docker containers. An alternative to [jwilder/nginx-proxy][nginxproxy] by [@zchee](https://github.com/zchee) -- [Let's Encrypt Nginx-proxy Companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion) - A lightweight companion container for the nginx-proxy. It allow the creation/renewal of Let's Encrypt certificates automatically. By [@JrCs](https://github.com/JrCs) -- [mesh-router](https://github.com/Yundera/mesh-router) - Free domain(nsl.sh) provider for Docker containers with automatic HTTPS routing. Uses Wireguard VPN to securely route subdomain requests across networks. Ideal for self-hosted NAS and cloud deployments. By [@Yundera](https://github.com/Yundera) -- [muguet](https://github.com/mattallty/muguet) :skull: - DNS Server & Reverse proxy for Docker environments. By [@mattallty](https://github.com/mattallty) -- [Nginx Proxy Manager](https://github.com/jc21/nginx-proxy-manager) - A beautiful web interface for proxying web based services with SSL. By [@jc21](https://github.com/jc21) +- [BunkerWeb](https://github.com/bunkerity/bunkerweb) - Open-source and next-gen Web Application Firewall (WAF). By [Bunkerity](https://www.bunkerity.com). +- [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) - Caddy-based reverse proxy, configured with service or container labels. By [@lucaslorentz](https://github.com/lucaslorentz). +- [caddy-docker-upstreams](https://github.com/invzhi/caddy-docker-upstreams) - Docker upstreams module for Caddy, configured with container labels. By [@invzhi](https://github.com/invzhi). +- [Docker Dnsmasq Updater](https://github.com/moonbuggy/docker-dnsmasq-updater) - Update a remote dnsmasq server with Docker container hostnames. +- [docker-flow-proxy](https://github.com/docker-flow/docker-flow-proxy) - Reconfigures proxy every time a new service is deployed, or when a service is scaled. By [@docker-flow][docker-flow]. +- [docker-proxy](https://github.com/silarsis/docker-proxy) - :skull: Transparent proxy for docker containers, run in a docker container. By [@silarsis](https://github.com/silarsis). +- [fabio](https://github.com/fabiolb/fabio) - A fast, modern, zero-conf load balancing HTTP(S) router for deploying microservices managed by consul. By [@magiconair](https://github.com/magiconair) (Frank Schroeder). +- [h2o-proxy](https://github.com/zchee/h2o-proxy) - :skull: Automated H2O reverse proxy for Docker containers. An alternative to [jwilder/nginx-proxy][nginxproxy]. +- [Let's Encrypt Nginx-proxy Companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion) - A lightweight companion container for the nginx-proxy. It allow the creation/renewal of Let's Encrypt certificates automatically. By [@JrCs](https://github.com/JrCs). +- [mesh-router](https://github.com/Yundera/mesh-router) - Free domain(nsl.sh) provider for Docker containers with automatic HTTPS routing. Uses Wireguard VPN to securely route subdomain requests across networks. Ideal for self-hosted NAS and cloud deployments. By [@Yundera](https://github.com/Yundera). +- [muguet](https://github.com/mattallty/muguet) - :skull: DNS Server & Reverse proxy for Docker environments. By [@mattallty](https://github.com/mattallty). +- [Nginx Proxy Manager](https://github.com/jc21/nginx-proxy-manager) - A beautiful web interface for proxying web based services with SSL. By [@jc21](https://github.com/jc21). - [nginx-proxy][nginxproxy] - Automated nginx proxy for Docker containers using docker-gen by [@jwilder][jwilder] -- [OpenResty Manager](https://github.com/Safe3/openresty-manager) - The easiest using, powerful and beautiful OpenResty Manager(Nginx Enhanced Version), open source alternative to OpenResty Edge. By [@Safe3](https://github.com/Safe3/) -- [Swarm Ingress Router](https://github.com/tpbowden/swarm-ingress-router) :skull: - Route DNS names to Swarm services based on labels. By [@tpbowden](https://github.com/tpbowden/) -- [Swarm Router](https://github.com/flavioaiello/swarm-router) - A «zero config» service name based router for docker swarm mode with a fresh and more secure approach. By [@flavioaiello](https://github.com/flavioaiello) -- [Træfɪk](https://github.com/containous/traefik) - Automated reverse proxy and load-balancer for Docker, Mesos, Consul, Etcd... By [@EmileVauge](https://github.com/emilevauge) +- [OpenResty Manager](https://github.com/Safe3/openresty-manager) - The easiest using, powerful and beautiful OpenResty Manager(Nginx Enhanced Version), open source alternative to OpenResty Edge. By [@Safe3](https://github.com/Safe3/). +- [Swarm Ingress Router](https://github.com/tpbowden/swarm-ingress-router) - :skull: Route DNS names to Swarm services based on labels. By [@tpbowden](https://github.com/tpbowden/). +- [Swarm Router](https://github.com/flavioaiello/swarm-router) - A «zero config» service name based router for docker swarm mode with a fresh and more secure approach. By [@flavioaiello](https://github.com/flavioaiello). +- [Træfɪk](https://github.com/containous/traefik) - Automated reverse proxy and load-balancer for Docker, Mesos, Consul, Etcd... By [@EmileVauge](https://github.com/emilevauge). ### Runtime -- [aind](https://github.com/aind-containers/aind) - :skull: AinD launches Android apps in Docker, by nesting Anbox containers inside Docker by [@aind-containers](https://github.com/aind-containers) -- [cri-o](https://github.com/cri-o/cri-o) - Open Container Initiative-based implementation of Kubernetes Container Runtime Interface by [cri-o](https://github.com/cri-o) -- [lxc](https://github.com/lxc/lxc) - LXC - Linux Containers -- [podman](https://github.com/containers/libpod) - libpod is a library used to create container pods. Home of Podman by [@containers][containers] -- [rlxc](https://github.com/brauner/rlxc) - LXC binary written in Rust by [@brauner](https://github.com/brauner) -- [runtime-tools](https://github.com/opencontainers/runtime-tools) - oci-runtime-tool is a collection of tools for working with the OCI runtime specification by [@opencontainers](https://github.com/opencontainers) +- [aind](https://github.com/aind-containers/aind) - :skull: AinD launches Android apps in Docker, by nesting Anbox containers inside Docker. +- [cri-o](https://github.com/cri-o/cri-o) - Open Container Initiative-based implementation of Kubernetes Container Runtime Interface by [cri-o](https://github.com/cri-o). +- [lxc](https://github.com/lxc/lxc) - LXC - Linux Containers. +- [podman](https://github.com/containers/libpod) - Libpod is a library used to create container pods. Home of Podman. +- [rlxc](https://github.com/brauner/rlxc) - LXC binary written in Rust. +- [runtime-tools](https://github.com/opencontainers/runtime-tools) - Oci-runtime-tool is a collection of tools for working with the OCI runtime specification. ### Security -- [Anchor](https://github.com/SongStitch/anchor/) - A tool to ensure reproducible builds by pinning dependencies inside your Dockerfiles [@SongStitch](https://github.com/songStitch/) -- [Anchor Enterprise](https://anchore.com/) :heavy_dollar_sign: - Analyze images for CVE vulnerabilities and against custom security policies by [@Anchor](https://github.com/anchore) -- [Aqua Security](https://www.aquasec.com) :heavy_dollar_sign: - Securing container-based applications from Dev to Production on any platform -- [bane](https://github.com/genuinetools/bane) - AppArmor profile generator for Docker containers by [@genuinetools][genuinetools] -- [buildcage](https://github.com/dash14/buildcage) - Restricts outbound network access during Docker builds to prevent supply chain attacks, working as a drop-in BuildKit remote driver for Docker Buildx, with ready-to-use GitHub Actions by [@dash14](https://github.com/dash14) -- [CetusGuard](https://github.com/hectorm/cetusguard) - CetusGuard is a tool that protects the Docker daemon socket by filtering calls to its API endpoints -- [CIS Docker Benchmark](https://github.com/dev-sec/cis-docker-benchmark) - This [InSpec][inspec] compliance profile implement the CIS Docker 1.12.0 Benchmark in an automated way to provide security best-practice tests around Docker daemon and containers in a production environment. By [@dev-sec](https://github.com/dev-sec) -- [Checkov](https://github.com/bridgecrewio/checkov) - Static analysis for infrastructure as code manifests (Terraform, Kubernetes, Cloudformation, Helm, Dockerfile, Kustomize) find security misconfiguration and fix them. By [@bridgecrew](https://github.com/bridgecrewio) -- [Clair](https://github.com/quay/clair) - Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers. By [@coreos][coreos] -- [crowdsec-blocklist-import](https://github.com/wolffcatskyy/crowdsec-blocklist-import) - Aggregates 36 free threat intelligence feeds into 120k+ malicious IPs for CrowdSec bouncers, providing 10-20x more blocks than default lists. By [@wolffcatskyy](https://github.com/wolffcatskyy) -- [Dagda](https://github.com/eliasgranderubio/dagda) - Dagda is a tool to perform static analysis of known vulnerabilities, trojans, viruses, malware & other malicious threats in docker images/containers and to monitor the docker daemon and running docker containers for detecting anomalous activities. By [@eliasgranderubio](https://github.com/eliasgranderubio) -- [Deepfence Enterprise](https://deepfence.io) :heavy_dollar_sign: - Full life cycle Cloud Native Workload Protection platform for kubernetes, virtual machines and serverless. By [@deepfence][deepfence] -- [Deepfence Threat Mapper](https://github.com/deepfence/ThreatMapper) - Powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless. By [@deepfence][deepfence] -- [docker-bench-security](https://github.com/docker/docker-bench-security) - script that checks for dozens of common best-practices around deploying Docker containers in production. By [@docker][docker] -- [docker-explorer](https://github.com/google/docker-explorer) - A tool to help forensicate offline docker acquisitions by [@Google][google] -- [docker-lock](https://github.com/safe-waters/docker-lock) - A cli-plugin for docker to automatically manage image digests by tracking them in a separate Lockfile. By [@safe-waters][safe-waters] -- [dvwassl](https://github.com/Peco602/dvwassl) - SSL-enabled Damn Vulnerable Web App to test Web Application Firewalls. By [@Peco602][peco602] -- [KICS](https://github.com/checkmarx/kics) - an infrastructure-as-code scanning tool, find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle. Can be extended for additional policies. By [Checkmarx](https://github.com/Checkmarx) -- [notary](https://github.com/theupdateframework/notary) - a server and a client for running and interacting with trusted collections. By [@TUF](https://github.com/theupdateframework) -- [oscap-docker](https://github.com/OpenSCAP/openscap) - OpenSCAP provides oscap-docker tool which is used to scan Docker containers and images. By [OpenSCAP](https://github.com/OpenSCAP) -- [Prisma Cloud](https://www.paloaltonetworks.com/prisma/cloud) :heavy_dollar_sign: - (previously Twistlock Security Suite) detects vulnerabilities, hardens container images, and enforces security policies across the lifecycle of applications. -- [Syft](https://github.com/anchore/syft) - CLI tool and library for generating a Software Bill of Materials (SBOM) from container images and filesystems. -- [segspec](https://github.com/dormstern/segspec) - Extracts network dependencies from Docker Compose, Kubernetes manifests, Helm charts, and other config files to generate Kubernetes NetworkPolicies with evidence tracing. By [@dormstern](https://github.com/dormstern) -- [Sysdig Falco](https://github.com/falcosecurity/falco) - Sysdig Falco is an open source container security monitor. It can monitor application, container, host, and network activity and alert on unauthorized activity. -- [Sysdig Secure](https://www.sysdig.com/solutions/cloud-detection-and-response-cdr) :heavy_dollar_sign: - Sysdig Secure addresses run-time security through behavioral monitoring and defense, and provides deep forensics based on open source Sysdig for incident response. -- [Trend Micro DeepSecurity](https://www.trendmicro.com/en_us/business/products/hybrid-cloud/deep-security.html) :heavy_dollar_sign: - Trend Micro DeepSecurity offers runtime protection for container workloads and hosts as well as preruntime scanning of images to identify vulnerabilities, malware and content such as hardcoded secrets. -- [Trivy](https://github.com/aquasecurity/trivy) - Aqua Security's open source simple and comprehensive vulnerability scanner for containers (suitable for CI). +- [Anchor](https://github.com/SongStitch/anchor/) - A tool to ensure reproducible builds by pinning dependencies inside your Dockerfiles [@SongStitch](https://github.com/songStitch/). +- [Anchor Enterprise](https://anchore.com/) - :heavy_dollar_sign: Analyze images for CVE vulnerabilities and against custom security policies. +- [Aqua Security](https://www.aquasec.com) - :heavy_dollar_sign: Securing container-based applications from Dev to Production on any platform. +- [bane](https://github.com/genuinetools/bane) - AppArmor profile generator for Docker containers. +- [buildcage](https://github.com/dash14/buildcage) - Restricts outbound network access during Docker builds to prevent supply chain attacks, working as a drop-in BuildKit remote driver for Docker Buildx, with ready-to-use GitHub Actions. +- [CetusGuard](https://github.com/hectorm/cetusguard) - CetusGuard is a tool that protects the Docker daemon socket by filtering calls to its API endpoints. +- [Checkov](https://github.com/bridgecrewio/checkov) - Static analysis for infrastructure as code manifests (Terraform, Kubernetes, Cloudformation, Helm, Dockerfile, Kustomize) find security misconfiguration and fix them. By [@bridgecrew](https://github.com/bridgecrewio). +- [CIS Docker Benchmark](https://github.com/dev-sec/cis-docker-benchmark) - This [InSpec][inspec] compliance profile implement the CIS Docker 1.12.0 Benchmark in an automated way to provide security best-practice tests around Docker daemon and containers in a production environment. By [@dev-sec](https://github.com/dev-sec). +- [Clair](https://github.com/quay/clair) - Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers. By [@coreos][coreos]. +- [crowdsec-blocklist-import](https://github.com/wolffcatskyy/crowdsec-blocklist-import) - Aggregates 36 free threat intelligence feeds into 120k+ malicious IPs for CrowdSec bouncers, providing 10-20x more blocks than default lists. By [@wolffcatskyy](https://github.com/wolffcatskyy). +- [Dagda](https://github.com/eliasgranderubio/dagda) - Dagda is a tool to perform static analysis of known vulnerabilities, trojans, viruses, malware & other malicious threats in docker images/containers and to monitor the docker daemon and running docker containers for detecting anomalous activities. By [@eliasgranderubio](https://github.com/eliasgranderubio). +- [Deepfence Enterprise](https://deepfence.io) - :heavy_dollar_sign: Full life cycle Cloud Native Workload Protection platform for kubernetes, virtual machines and serverless. By [@deepfence][deepfence]. +- [Deepfence Threat Mapper](https://github.com/deepfence/ThreatMapper) - Powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless. By [@deepfence][deepfence]. +- [docker-bench-security](https://github.com/docker/docker-bench-security) - Script that checks for dozens of common best-practices around deploying Docker containers in production. By [@docker][docker]. +- [docker-explorer](https://github.com/google/docker-explorer) - A tool to help forensicate offline docker acquisitions. +- [docker-lock](https://github.com/safe-waters/docker-lock) - A cli-plugin for docker to automatically manage image digests by tracking them in a separate Lockfile. By [@safe-waters][safe-waters]. +- [dvwassl](https://github.com/Peco602/dvwassl) - SSL-enabled Damn Vulnerable Web App to test Web Application Firewalls. By [@Peco602][peco602]. +- [KICS](https://github.com/checkmarx/kics) - An infrastructure-as-code scanning tool, find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle. Can be extended for additional policies. By [Checkmarx](https://github.com/Checkmarx). +- [notary](https://github.com/theupdateframework/notary) - A server and a client for running and interacting with trusted collections. By [@TUF](https://github.com/theupdateframework). +- [oscap-docker](https://github.com/OpenSCAP/openscap) - OpenSCAP provides oscap-docker tool which is used to scan Docker containers and images. By [OpenSCAP](https://github.com/OpenSCAP). +- [Prisma Cloud](https://www.paloaltonetworks.com/prisma/cloud) - :heavy_dollar_sign: (Previously Twistlock Security Suite) detects vulnerabilities, hardens container images, and enforces security policies across the lifecycle of applications. +- [segspec](https://github.com/dormstern/segspec) - Extracts network dependencies from Docker Compose, Kubernetes manifests, Helm charts, and other config files to generate Kubernetes NetworkPolicies with evidence tracing. By [@dormstern](https://github.com/dormstern). +- [Syft](https://github.com/anchore/syft) - CLI tool and library for generating a Software Bill of Materials (SBOM) from container images and filesystems. +- [Sysdig Falco](https://github.com/falcosecurity/falco) - Sysdig Falco is an open source container security monitor. It can monitor application, container, host, and network activity and alert on unauthorized activity. +- [Sysdig Secure](https://www.sysdig.com/solutions/cloud-detection-and-response-cdr) - :heavy_dollar_sign: Sysdig Secure addresses run-time security through behavioral monitoring and defense, and provides deep forensics based on open source Sysdig for incident response. +- [Trend Micro DeepSecurity](https://www.trendmicro.com/en_us/business/products/hybrid-cloud/deep-security.html) - :heavy_dollar_sign: Trend Micro DeepSecurity offers runtime protection for container workloads and hosts as well as preruntime scanning of images to identify vulnerabilities, malware and content such as hardcoded secrets. +- [Trivy](https://github.com/aquasecurity/trivy) - Aqua Security's open source simple and comprehensive vulnerability scanner for containers (suitable for CI). ### Service Discovery - [docker-consul](https://github.com/gliderlabs/docker-consul) by [@progrium][progrium] -- [docker-dns](https://github.com/bytesharky/docker-dns) - Lightweight DNS forwarder for Docker containers, resolves container names with custom suffixes (e.g. `.docker`) on the host to simplify service discovery by [@bytesharky](https://github.com/bytesharky) -- [etcd](https://github.com/etcd-io/etcd) - Distributed reliable key-value store for the most critical data of a distributed system by [@etcd-io](https://github.com/etcd-io) (former part of CoreOS) -- [istio](https://github.com/istio/istio) - An open platform to connect, manage, and secure microservices by [@istio](https://github.com/istio) -- [proxy](https://github.com/factorish/proxy) :skull: - lightweight nginx based load balancer self using service discovery provided by registrator. by [@factorish](https://github.com/factorish) -- [registrator](https://github.com/gliderlabs/registrator) - Service registry bridge for Docker by [@gliderlabs][gliderlabs] and [@progrium][progrium] +- [docker-dns](https://github.com/bytesharky/docker-dns) - Lightweight DNS forwarder for Docker containers, resolves container names with custom suffixes (e.g. `.docker`) on the host to simplify service discovery. +- [etcd](https://github.com/etcd-io/etcd) - Distributed reliable key-value store for the most critical data of a distributed system by [@etcd-io](https://github.com/etcd-io) (former part of CoreOS). +- [istio](https://github.com/istio/istio) - An open platform to connect, manage, and secure microservices. +- [proxy](https://github.com/factorish/proxy) - :skull: Lightweight nginx based load balancer self using service discovery provided by registrator. +- [registrator](https://github.com/gliderlabs/registrator) - Service registry bridge for Docker by [@gliderlabs][gliderlabs] and [@progrium][progrium]. ### Volume Management / Data - [Blockbridge](https://github.com/blockbridge/blockbridge-docker-volume) :heavy_dollar_sign:- The Blockbridge plugin is a volume plugin that provides access to an extensible set of container-based persistent storage options. It supports single and multi-host Docker environments with features that include tenant isolation, automated provisioning, encryption, secure deletion, snapshots and QoS. By [@blockbridge](https://github.com/blockbridge) -- [Convoy](https://github.com/rancher/convoy) :skull: - an open-source Docker volume driver that can snapshot, backup and restore Docker volumes anywhere. By [@rancher][rancher] -- [Docker Machine NFS](https://github.com/adlogix/docker-machine-nfs) :skull: - Activates NFS for an existing boot2docker box created through Docker Machine on OS X. -- [Docker Unison](https://github.com/leighmcculloch/docker-unison) - :skull: A docker volume container using Unison for fast two-way folder sync. Created as an alternative to slow boot2docker volumes on OS X. By [@leighmcculloch](https://github.com/leighmcculloch) +- [Convoy](https://github.com/rancher/convoy) - :skull: An open-source Docker volume driver that can snapshot, backup and restore Docker volumes anywhere. By [@rancher][rancher]. +- [Docker Machine NFS](https://github.com/adlogix/docker-machine-nfs) - :skull: Activates NFS for an existing boot2docker box created through Docker Machine on OS X. +- [Docker Unison](https://github.com/leighmcculloch/docker-unison) - :skull: A docker volume container using Unison for fast two-way folder sync. Created as an alternative to slow boot2docker volumes on OS X. By [@leighmcculloch](https://github.com/leighmcculloch). - - [Label Backup](https://github.com/resulgg/label-backup) - A lightweight, Docker-aware backup agent that automatically discovers and backs up containerized databases (PostgreSQL, MySQL, MongoDB, Redis) based on Docker labels. Supports local storage and S3-compatible destinations with flexible scheduling via cron expressions. - [Docker Volume Backup](https://github.com/offen/docker-volume-backup) Backup Docker volumes locally or to any S3 compatible storage. By [@offen](https://github.com/offen) - [Local Persist](https://github.com/MatchbookLab/local-persist) Specify a mountpoint for your local volumes (created via `docker volume create`) so that files will always persist and so you can mount to different directories in different containers. -- [Minio](https://github.com/minio/minio) - S3 compatible object storage server in Docker containers +- [Minio](https://github.com/minio/minio) - S3 compatible object storage server in Docker containers. - [Netshare](https://github.com/ContainX/docker-volume-netshare) Docker NFS, AWS EFS, Ceph & Samba/CIFS Volume Plugin. By [@ContainX][containx] -- [portworx](https://portworx.com) :heavy_dollar_sign: - Decentralized storage solution for persistent, shared and replicated volumes. -- [quobyte](https://www.quobyte.com/) :heavy_dollar_sign: - fully fault-tolerant distributed file system with a docker volume driver +- [portworx](https://portworx.com) - :heavy_dollar_sign: Decentralized storage solution for persistent, shared and replicated volumes. +- [quobyte](https://www.quobyte.com/) - :heavy_dollar_sign: Fully fault-tolerant distributed file system with a docker volume driver. - [REX-Ray](https://github.com/rexray/rexray) provides a vendor agnostic storage orchestration engine. The primary design goal is to provide persistent storage for Docker, Kubernetes, and Mesos. By[@thecodeteam](https://github.com/thecodeteam) (DELL Technologies) -- [Storidge](https://github.com/Storidge/quick-start) :heavy_dollar_sign: - Software-defined Persistent Storage for Kubernetes and Docker Swarm +- [Storidge](https://github.com/Storidge/quick-start) - :heavy_dollar_sign: Software-defined Persistent Storage for Kubernetes and Docker Swarm. ### User Interface @@ -370,103 +370,103 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - JetBrains IDEs (IntelliJ IDEA, GoLand, WebStorm, CLion etc.) has [built-in Docker plugin](https://www.jetbrains.com/help/idea/docker.html#managing-images) - Eclipse [Docker Tooling plugin](https://www.eclipse.org/community/eclipse_newsletter/2016/july/article2.php) -- [denops-docker.vim](https://github.com/skanehira/denops-docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira] -- [docker.vim](https://github.com/skanehira/docker.vim) :skull: - Manage docker containers and images in Vim. By [@skanehira] +- [denops-docker.vim](https://github.com/skanehira/denops-docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira]. +- [docker.vim](https://github.com/skanehira/docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira]. - [docker.el](https://github.com/Silex/docker.el) Manage docker from Emacs by [@Silex](https://github.com/Silex) #### Desktop Native desktop applications for managing and monitoring docker hosts and clusters -- [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Official native app. Only for Windows and MacOS -- [Docker DB Manager](https://github.com/AbianS/docker-db-manager) - Desktop app for managing Docker database containers with visual interface and one-click operations. -- [Dockeron](https://github.com/dockeron/dockeron) :skull: - A project built on Electron + Vue.js for Docker on desktop. [@fluency03](https://github.com/fluency03) -- [DockStation](https://github.com/DockStation/dockstation) - A developer centric UI to configure, monitor, and manage services and containers [@dock_station](https://twitter.com/dock_station) -- [Lifeboat](https://github.com/jplhomer/lifeboat) - :skull: An easy way to launch Docker projects with a graphical interface on your Mac. [@jplhomer](https://github.com/jplhomer) -- [Simple Docker UI](https://github.com/felixgborrego/simple-docker-ui) - built on Electron. By [@felixgborrego](https://github.com/felixgborrego/) -- [Stevedore](https://github.com/slonopotamus/stevedore) - Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [@slonopotamus](https://github.com/slonopotamus) +- [Docker DB Manager](https://github.com/AbianS/docker-db-manager) - Desktop app for managing Docker database containers with visual interface and one-click operations. +- [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Official native app. Only for Windows and MacOS. +- [Dockeron](https://github.com/dockeron/dockeron) - :skull: A project built on Electron + Vue.js for Docker on desktop. [@fluency03](https://github.com/fluency03). +- [DockStation](https://github.com/DockStation/dockstation) - A developer centric UI to configure, monitor, and manage services and containers [@dock_station](https://twitter.com/dock_station). +- [Lifeboat](https://github.com/jplhomer/lifeboat) - :skull: An easy way to launch Docker projects with a graphical interface on your Mac. [@jplhomer](https://github.com/jplhomer). +- [Simple Docker UI](https://github.com/felixgborrego/simple-docker-ui) - Built on Electron. By [@felixgborrego](https://github.com/felixgborrego/). +- [Stevedore](https://github.com/slonopotamus/stevedore) - Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [@slonopotamus](https://github.com/slonopotamus). #### Terminal ##### Terminal UI -- [ctop (1)](https://github.com/yadutaf/ctop) - :skull: A command line / text based Linux Containers monitoring tool that works just like you expect (Python) by [@yadutaf](https://github.com/yadutaf) -- [ctop (2)](https://github.com/bcicen/ctop) - :skull: Top-like interface for container metrics (Golang) by [@bcicen](https://github.com/bcicen/) -- [d4s](https://github.com/jr-k/d4s) - A fast, keyboard-driven terminal UI to manage Docker containers, Compose stacks, and Swarm services with the ergonomics of K9s by [@jr-k](https://github.com/jr-k/) -- [dive](https://github.com/wagoodman/dive) - A tool for exploring each layer in a docker image. By [wagoodman](https://github.com/wagoodman). +- [ctop (1)](https://github.com/yadutaf/ctop) - :skull: A command line / text based Linux Containers monitoring tool that works just like you expect (Python). +- [ctop (2)](https://github.com/bcicen/ctop) - :skull: Top-like interface for container metrics (Golang). +- [d4s](https://github.com/jr-k/d4s) - A fast, keyboard-driven terminal UI to manage Docker containers, Compose stacks, and Swarm services with the ergonomics of K9s. +- [dive](https://github.com/wagoodman/dive) - A tool for exploring each layer in a docker image. By [wagoodman](https://github.com/wagoodman). - [dockdash](https://github.com/byrnedo/dockdash) detailed stats. By [@byrnedo] -- [Docker-mon](https://github.com/icecrime/docker-mon) :skull: - Console-based Docker monitoring by [@icecrime](https://github.com/icecrime) -- [dockly](https://github.com/lirantal/dockly) - An interactive shell UI for managing Docker containers by [@lirantal](https://github.com/lirantal) -- [DockMate](https://github.com/shubh-io/dockmate) - Lightweight terminal-based Docker and Podman manager with a text-based user interface, by [@shubh-io](https://github.com/shubh-io). -- [DockSTARTer](https://github.com/GhostWriters/DockSTARTer) - DockSTARTer helps you get started with home server apps running in Docker by [GhostWriters](https://github.com/GhostWriters) -- [docui](https://github.com/skanehira/docui) - :skull: An interactive shell UI for managing Docker containers. Also works in Windows. By [@skanehira] -- [dprs](https://github.com/durableprogramming/dprs) - A developer-focused TUI for managing Docker containers with real-time log streaming and container management. Built with Rust. By [@durableprogramming](https://github.com/durableprogramming) -- [dry](https://github.com/moncho/dry) - An interactive CLI for Docker containers by [@moncho](https://github.com/moncho) -- [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box by [@ajay-dsan](https://github.com/ajayd-san) -- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [@jesseduffield](https://github.com/jesseduffield) -- [lazyjournal](https://github.com/Lifailon/lazyjournal) - A interface for reading and filtering the logs output of Docker and Podman containers like [Dozzle](dozzle) but for the terminal with support for fuzzy find, regex and output coloring -- [oxker](https://github.com/mrjackwills/oxker) - A simple tui to view & control docker containers. Written in [Rust](https://rust-lang.org/), making heavy use of [ratatui](https://github.com/tui-rs-revival/ratatui) & [Bollard](https://github.com/fussybeaver/bollard), by [@mrjackwills](https://github.com/mrjackwills) -- [sen](https://github.com/TomasTomecek/sen) - :skull: Terminal user interface for docker engine, by [@TomasTomecek][tomastomecek] +- [Docker-mon](https://github.com/icecrime/docker-mon) - :skull: Console-based Docker monitoring. +- [dockly](https://github.com/lirantal/dockly) - An interactive shell UI for managing Docker containers. +- [DockMate](https://github.com/shubh-io/dockmate) - Lightweight terminal-based Docker and Podman manager with a text-based user interface,. +- [DockSTARTer](https://github.com/GhostWriters/DockSTARTer) - DockSTARTer helps you get started with home server apps running in Docker by [GhostWriters](https://github.com/GhostWriters). +- [docui](https://github.com/skanehira/docui) - :skull: An interactive shell UI for managing Docker containers. Also works in Windows. By [@skanehira]. +- [dprs](https://github.com/durableprogramming/dprs) - A developer-focused TUI for managing Docker containers with real-time log streaming and container management. Built with Rust. By [@durableprogramming](https://github.com/durableprogramming). +- [dry](https://github.com/moncho/dry) - An interactive CLI for Docker containers. +- [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box. +- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [@jesseduffield](https://github.com/jesseduffield). +- [lazyjournal](https://github.com/Lifailon/lazyjournal) - A interface for reading and filtering the logs output of Docker and Podman containers like [Dozzle](dozzle) but for the terminal with support for fuzzy find, regex and output coloring. +- [oxker](https://github.com/mrjackwills/oxker) - A simple tui to view & control docker containers. Written in [Rust](https://rust-lang.org/), making heavy use of [ratatui](https://github.com/tui-rs-revival/ratatui) & [Bollard](https://github.com/fussybeaver/bollard),. +- [sen](https://github.com/TomasTomecek/sen) - :skull: Terminal user interface for docker engine,. ##### CLI tools -- [captain](https://github.com/jenssegers/captain) - Easily start and stop docker compose projects from any directory. By [@jenssegers](https://github.com/jenssegers) -- [dcinja](https://github.com/Falldog/dcinja) - The powerful and smallest binary size of template engine for docker command line environment. By [@Falldog](https://github.com/Falldog) -- [dcp](https://github.com/exdx/dcp) - A simple tool for copying files from container filesystems. By [@exdx](https://github.com/exdx) -- [dctl](https://github.com/FabienD/docker-stack) - dctl is a Cli tool that helps developers by allowing them to execute all docker compose commands anywhere in the terminal, and more. By [FabienD](https://github.com/FabienD) -- [decompose](https://github.com/s0rg/decompose) - Reverse-engineering tool for docker environments. By [@s0rg](https://github.com/s0rg) -- [docker-captain](https://github.com/lucabello/docker-captain) - A friendly CLI to manage multiple Docker Compose deployments with style — powered by Typer, Rich, questionary, and sh. -- [docker-ls](https://github.com/mayflower/docker-ls) - CLI tools for browsing and manipulating docker registries by [@mayflower](https://github.com/mayflower) -- [docker pushrm](https://github.com/christian-korneck/docker-pushrm) - A Docker CLI plugin that lets you push the README.md file from the current directory to Docker Hub. Also supports Quay and Harbor. By [@christian-korneck](https://github.com/christian-korneck) -- [dockersql](https://github.com/crosbymichael/dockersql) - :skull: A command line interface to query Docker using SQL by [@crosbymichael](https://github.com/crosbymichael) -- [DVM](https://github.com/howtowhale/dvm) - Docker version manager by [@howtowhale](https://github.com/howtowhale) -- [goinside](https://github.com/iamsoorena/goinside) - Get inside a running docker container easily. by [@iamsoorena](https://github.com/iamsoorena) -- [ns-enter](https://github.com/jpetazzo/nsenter) - :skull: no more ssh, enter name spaces of container by [@jpetazzo][jpetazzo] -- [Pdocker](https://github.com/g31s/Pdocker) - A simple tool to manage and maintain Docker for personal projects by [@g31s](https://github.com/g31s) -- [proco](https://github.com/shiwaforce/poco) - Proco will help you to organise and manage Docker, Docker-Compose, Kubernetes projects of any complexity using simple YAML config files to shorten the route from finding your project to initialising it in your local environment. by [@shiwaforce](https://github.com/shiwaforce) -- [reg](https://github.com/genuinetools/reg) - :skull: Docker registry v2 command line client by [@genuinetools][genuinetools] -- [scuba](https://github.com/JonathonReinhart/scuba) - Transparently use Docker containers to encapsulate software build environments, by [@JonathonReinhart](https://github.com/JonathonReinhart) -- [skopeo](https://github.com/containers/skopeo) - Work with remote images registries - retrieving information, images, signing content by [@containers][containers] -- [supdock](https://github.com/segersniels/supdock) - Allows for slightly more visual usage of Docker with an interactive prompt. By [@segersniels](https://github.com/segersniels) -- [tsaotun](https://github.com/qazbnm456/tsaotun) - Python based Assistance for Docker by [@qazbnm456](https://github.com/qazbnm456) -- [wharfee](https://github.com/j-bennet/wharfee) - :skull: Autocompletion and syntax highlighting for Docker commands. by [@j-bennet](https://github.com/j-bennet) +- [captain](https://github.com/jenssegers/captain) - Easily start and stop docker compose projects from any directory. By [@jenssegers](https://github.com/jenssegers). +- [dcinja](https://github.com/Falldog/dcinja) - The powerful and smallest binary size of template engine for docker command line environment. By [@Falldog](https://github.com/Falldog). +- [dcp](https://github.com/exdx/dcp) - A simple tool for copying files from container filesystems. By [@exdx](https://github.com/exdx). +- [dctl](https://github.com/FabienD/docker-stack) - Dctl is a Cli tool that helps developers by allowing them to execute all docker compose commands anywhere in the terminal, and more. By [FabienD](https://github.com/FabienD). +- [decompose](https://github.com/s0rg/decompose) - Reverse-engineering tool for docker environments. By [@s0rg](https://github.com/s0rg). +- [docker pushrm](https://github.com/christian-korneck/docker-pushrm) - A Docker CLI plugin that lets you push the README.md file from the current directory to Docker Hub. Also supports Quay and Harbor. By [@christian-korneck](https://github.com/christian-korneck). +- [docker-captain](https://github.com/lucabello/docker-captain) - A friendly CLI to manage multiple Docker Compose deployments with style — powered by Typer, Rich, questionary, and sh. +- [docker-ls](https://github.com/mayflower/docker-ls) - CLI tools for browsing and manipulating docker registries. +- [dockersql](https://github.com/crosbymichael/dockersql) - :skull: A command line interface to query Docker using SQL. +- [DVM](https://github.com/howtowhale/dvm) - Docker version manager. +- [goinside](https://github.com/iamsoorena/goinside) - Get inside a running docker container easily. +- [ns-enter](https://github.com/jpetazzo/nsenter) - :skull: No more ssh, enter name spaces of container. +- [Pdocker](https://github.com/g31s/Pdocker) - A simple tool to manage and maintain Docker for personal projects. +- [proco](https://github.com/shiwaforce/poco) - Proco will help you to organise and manage Docker, Docker-Compose, Kubernetes projects of any complexity using simple YAML config files to shorten the route from finding your project to initialising it in your local environment. +- [reg](https://github.com/genuinetools/reg) - :skull: Docker registry v2 command line client. +- [scuba](https://github.com/JonathonReinhart/scuba) - Transparently use Docker containers to encapsulate software build environments,. +- [skopeo](https://github.com/containers/skopeo) - Work with remote images registries - retrieving information, images, signing content. +- [supdock](https://github.com/segersniels/supdock) - Allows for slightly more visual usage of Docker with an interactive prompt. By [@segersniels](https://github.com/segersniels). +- [tsaotun](https://github.com/qazbnm456/tsaotun) - Python based Assistance for Docker. +- [wharfee](https://github.com/j-bennet/wharfee) - :skull: Autocompletion and syntax highlighting for Docker commands. ##### Other -- [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) - Search the Docker Registry with the Dext smart launcher. By [@vutran](https://github.com/vutran) -- [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) - SSH Server for Docker containers ~ Because every container should be accessible. By [@jeroenpeeters](https://github.com/jeroenpeeters) -- [dockercraft](https://github.com/docker/dockercraft) - :skull: Docker + Minecraft = Dockercraft by [@docker][docker] +- [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) - Search the Docker Registry with the Dext smart launcher. By [@vutran](https://github.com/vutran). +- [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) - SSH Server for Docker containers ~ Because every container should be accessible. By [@jeroenpeeters](https://github.com/jeroenpeeters). +- [dockercraft](https://github.com/docker/dockercraft) - :skull: Docker + Minecraft = Dockercraft. - [dockerfile-mode](https://github.com/spotify/dockerfile-mode) An emacs mode for handling Dockerfiles by [@spotify][spotify] -- [MultiDocker](https://github.com/marty90/multidocker) - Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. -- [Powerline-Docker](https://github.com/adrianmo/powerline-docker) - A Powerline segment for showing the status of Docker containers by [@adrianmo](https://github.com/adrianmo) +- [MultiDocker](https://github.com/marty90/multidocker) - Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. +- [Powerline-Docker](https://github.com/adrianmo/powerline-docker) - A Powerline segment for showing the status of Docker containers. #### Web -- [Admiral](https://github.com/vmware/admiral) - :skull: Admiral™ is a highly scalable and very lightweight Container Management platform for deploying and managing container based applications. By [VMWare][vmware] -- [CASA](https://github.com/knrdl/casa) - Outsource the administration of a handful of containers to your co-workers, by [@knrdl](https://github.com/knrdl) -- [Container Web TTY](https://github.com/wrfly/container-web-tty) - Connect your containers via a web-tty [@wrfly](https://github.com/wrfly) -- [dockemon](https://github.com/ProductiveOps/dokemon) - Docker Container Management GUI by [@productiveops](https://github.com/ProductiveOps) -- [Docker Compose UI](https://github.com/francescou/docker-compose-ui) - :skull: Manage docker-compose via HTTP. docker-compose-ui runs in a Docker container, mounts the hosts docker socket and exposes a RESTful API and AngularJS GUI -- [Docker Registry Browser](https://github.com/klausmeyer/docker-registry-browser) - Web Interface for the Docker Registry HTTP API v2 by [@klausmeyer](https://github.com/klausmeyer) -- [Docker Registry UI (Joxit)](https://github.com/Joxit/docker-registry-ui) - :skull: The simplest and cleanest UI for private registries by [@Joxit](https://github.com/Joxit) -- [Docker Registry UI](https://github.com/atcol/docker-registry-ui) - A web UI for easy private/local Docker Registry integration by [@atcol](https://github.com/atcol) -- [docker-registry-web](https://github.com/mkuchin/docker-registry-web) - Web UI, authentication service and event recorder for private docker registry v2 by [@mkuchin](https://github.com/mkuchin) -- [docker-swarm-visualizer](https://github.com/dockersamples/docker-swarm-visualizer) - Visualizes Docker services on a Docker Swarm (for running demos). -- [dockering-on-rails](https://github.com/Electrofenster/dockerding-on-rails) :skull: - Simple Web-Interface for Docker with a lot of features by [@Electrofenster](https://github.com/Electrofenster/) -- [DockerSurfer](https://github.com/Simone-Erba/DockerSurfer) :skull: - A web service for analyze and browse dependencies between Docker images in the Docker registry, by [@Simone-Erba](https://github.com/Simone-Erba/) -- [dockge](https://github.com/louislam/dockge) - easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager by [@louislam](https://github.com/louislam). -- [Komodo](https://github.com/mbecker20/komodo) - A tool to build and deploy software on many servers -- [Kubevious](https://github.com/kubevious/kubevious) - A highly visual web UI for Kubernetes which renders configuration and state in an application centric way by [@rubenhak](https://github.com/rubenhak). -- [Mafl](https://github.com/hywax/mafl) - Minimalistic flexible homepage by [@hywax](https://github.com/hywax/) -- [netdata](https://github.com/netdata/netdata) - Real-time performance monitoring -- [OctoLinker](https://github.com/OctoLinker/OctoLinker) - A browser extension for GitHub that makes the image name in a `Dockerfile` clickable and redirect you to the related Docker Hub page. -- [Portainer](https://github.com/portainer/portainer) - A lightweight management UI for managing your Docker hosts or Docker Swarm clusters by [@portainer](https://github.com/portainer) -- [Rapid Dashboard](https://github.com/ozlerhakan/rapid) - A simple query dashboard to use Docker Remote API by [@ozlerhakan](https://github.com/ozlerhakan/) -- [Seagull](https://github.com/tobegit3hub/seagull) - Friendly Web UI to monitor docker daemon. by [@tobegit3hub](https://github.com/tobegit3hub) -- [Swarmpit](https://github.com/swarmpit/swarmpit) - Swarmpit provides simple and easy to use interface for your Docker Swarm cluster. You can manage your stacks, services, secrets, volumes, networks etc. -- [Swirl](https://github.com/cuigh/swirl) - Swirl is a web management tool for Docker, focused on swarm cluster By [@cuigh](https://github.com/cuigh/) -- [Theia](https://github.com/eclipse-theia/theia) - Extensible platform to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technologies. -- [usulnet](https://github.com/fr4nsys/usulnet) - A complete and modern Docker management platform designed for sysadmin, devops with enterprise grade tools, cve scanner, ssh, rdp on web and much more. By [@fr4nsys](https://github.com/fr4nsys) -- [Yacht](https://github.com/SelfhostedPro/Yacht) :construction: - A Web UI for docker that focuses on templates and ease of use in order to make deployments as easy as possible. By [@SelfhostedPro](https://github.com/SelfhostedPro) +- [Admiral](https://github.com/vmware/admiral) - :skull: Admiral™ is a highly scalable and very lightweight Container Management platform for deploying and managing container based applications. By [VMWare][vmware]. +- [CASA](https://github.com/knrdl/casa) - Outsource the administration of a handful of containers to your co-workers,. +- [Container Web TTY](https://github.com/wrfly/container-web-tty) - Connect your containers via a web-tty [@wrfly](https://github.com/wrfly). +- [dockemon](https://github.com/ProductiveOps/dokemon) - Docker Container Management GUI. +- [Docker Compose UI](https://github.com/francescou/docker-compose-ui) - :skull: Manage docker-compose via HTTP. docker-compose-ui runs in a Docker container, mounts the hosts docker socket and exposes a RESTful API and AngularJS GUI. +- [Docker Registry Browser](https://github.com/klausmeyer/docker-registry-browser) - Web Interface for the Docker Registry HTTP API v2. +- [Docker Registry UI](https://github.com/atcol/docker-registry-ui) - A web UI for easy private/local Docker Registry integration. +- [Docker Registry UI (Joxit)](https://github.com/Joxit/docker-registry-ui) - :skull: The simplest and cleanest UI for private registries. +- [docker-registry-web](https://github.com/mkuchin/docker-registry-web) - Web UI, authentication service and event recorder for private docker registry v2. +- [docker-swarm-visualizer](https://github.com/dockersamples/docker-swarm-visualizer) - Visualizes Docker services on a Docker Swarm (for running demos). +- [dockering-on-rails](https://github.com/Electrofenster/dockerding-on-rails) - :skull: Simple Web-Interface for Docker with a lot of features. +- [DockerSurfer](https://github.com/Simone-Erba/DockerSurfer) - :skull: A web service for analyze and browse dependencies between Docker images in the Docker registry,. +- [dockge](https://github.com/louislam/dockge) - Easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. +- [Komodo](https://github.com/mbecker20/komodo) - A tool to build and deploy software on many servers. +- [Kubevious](https://github.com/kubevious/kubevious) - A highly visual web UI for Kubernetes which renders configuration and state in an application centric way. +- [Mafl](https://github.com/hywax/mafl) - Minimalistic flexible homepage. +- [netdata](https://github.com/netdata/netdata) - Real-time performance monitoring. +- [OctoLinker](https://github.com/OctoLinker/OctoLinker) - A browser extension for GitHub that makes the image name in a `Dockerfile` clickable and redirect you to the related Docker Hub page. +- [Portainer](https://github.com/portainer/portainer) - A lightweight management UI for managing your Docker hosts or Docker Swarm clusters. +- [Rapid Dashboard](https://github.com/ozlerhakan/rapid) - A simple query dashboard to use Docker Remote API. +- [Seagull](https://github.com/tobegit3hub/seagull) - Friendly Web UI to monitor docker daemon. +- [Swarmpit](https://github.com/swarmpit/swarmpit) - Swarmpit provides simple and easy to use interface for your Docker Swarm cluster. You can manage your stacks, services, secrets, volumes, networks etc. +- [Swirl](https://github.com/cuigh/swirl) - Swirl is a web management tool for Docker, focused on swarm cluster By [@cuigh](https://github.com/cuigh/). +- [Theia](https://github.com/eclipse-theia/theia) - Extensible platform to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technologies. +- [usulnet](https://github.com/fr4nsys/usulnet) - A complete and modern Docker management platform designed for sysadmin, devops with enterprise grade tools, cve scanner, ssh, rdp on web and much more. By [@fr4nsys](https://github.com/fr4nsys). +- [Yacht](https://github.com/SelfhostedPro/Yacht) - :construction: A Web UI for docker that focuses on templates and ease of use in order to make deployments as easy as possible. By [@SelfhostedPro](https://github.com/SelfhostedPro). ## Docker Images @@ -474,72 +474,72 @@ Native desktop applications for managing and monitoring docker hosts and cluster Tools and applications that are either installed inside containers or designed to be run as a [sidecar](https://learn.microsoft.com/en-us/azure/architecture/patterns/sidecar) -- [amicontained](https://github.com/genuinetools/amicontained) - Container introspection tool. Find out what container runtime is being used as well as features available by [@genuinetools][genuinetools] -- [Chaperone](https://github.com/garywiz/chaperone) - A single PID1 process designed for docker containers. Does user management, log management, startup, zombie reaping, all in one small package. by [@garywiz](https://github.com/garywiz) -- [ckron](https://github.com/nicomt/ckron) - A cron-style job scheduler for docker, by [@nicomt](https://github.com/nicomt) +- [amicontained](https://github.com/genuinetools/amicontained) - Container introspection tool. Find out what container runtime is being used as well as features available. +- [Chaperone](https://github.com/garywiz/chaperone) - A single PID1 process designed for docker containers. Does user management, log management, startup, zombie reaping, all in one small package. +- [ckron](https://github.com/nicomt/ckron) - A cron-style job scheduler for docker,. - [CoreOS][coreos] - Linux for Massive Server Deployments -- [distroless](https://github.com/GoogleContainerTools/distroless) - Language focused docker images, minus the operating system, by [@GoogleContainerTools][googlecontainertools] -- [docker-alpine](https://github.com/gliderlabs/docker-alpine) - A super small Docker base image _(5MB)_ using Alpine Linux by [@gliderlabs][gliderlabs] -- [docker-gen](https://github.com/jwilder/docker-gen) - Generate files from docker container meta-data by [@jwilder][jwilder] -- [dockerize](https://github.com/powerman/dockerize) - Utility to simplify running applications in docker containers by [@jwilder][jwilder], [@powerman][powerman] -- [GoSu](https://github.com/tianon/gosu) - Run this specific application as this specific user and get out of the pipeline (entrypoint script tool) by [@tianon](https://github.com/tianon) -- [is-docker](https://github.com/sindresorhus/is-docker) - Check if the process is running inside a Docker container by [@sindresorhus][sindresorhus] -- [lstags](https://github.com/ivanilves/lstags) - sync Docker images across registries by [@ivanilves](https://github.com/ivanilves) -- [microcheck](https://github.com/tarampampam/microcheck) - Lightweight health check utilities for Docker containers (75 KB instead of 9.3 MB for httpcheck versus cURL) in pure C - http(s), port checks, and parallel execution are included. by [@tarampampam](https://github.com/tarampampam) -- [NVIDIA-Docker](https://github.com/NVIDIA/nvidia-docker) - :skull: The NVIDIA Container Runtime for Docker by [@NVIDIA][nvidia] -- [Ofelia](https://github.com/mcuadros/ofelia/) - Ofelia is a modern and low footprint job scheduler for docker environments, built on Go. Ofelia aims to be a replacement for the old fashioned cron. Supports configuration from container labels and/or configuration files. -- [SparkView](https://github.com/beyondssl/sparkview-container) - Access VMs, desktops, servers or applications anytime and from anywhere, without complex and costly client roll-outs or user management. -- [su-exec](https://github.com/ncopa/su-exec) - This is a simple tool that will simply execute a program with different privileges. The program will be executed directly and not run as a child, like su and sudo does, which avoids TTY and signal issues. Why reinvent gosu? This does more or less exactly the same thing as gosu but it is only 10kb instead of 1.8MB. By [ncopa](https://github.com/ncopa) -- [sue](https://github.com/theAkito/sue) - Executes a program as a user different from the user running sue. This is a maintainable alternative to ncopa/su-exec, which is the better tianon/gosu. This one is far better (higher performance, smaller size), than the original gosu, however it is far easier to maintain, than su-exec, which is written in plain C. Made by [Akito][akito] -- [supercronic](https://github.com/aptible/supercronic) - crontab-compatible job runner, designed specifically to run in containers by [@aptible](https://github.com/aptible/) -- [TrivialRC](https://github.com/vorakl/TrivialRC) - A minimalistic Runtime Configuration system and process manager for containers [@vorakl](https://github.com/vorakl) +- [distroless](https://github.com/GoogleContainerTools/distroless) - Language focused docker images, minus the operating system,. +- [docker-alpine](https://github.com/gliderlabs/docker-alpine) - A super small Docker base image _(5MB)_ using Alpine Linux. +- [docker-gen](https://github.com/jwilder/docker-gen) - Generate files from docker container meta-data. +- [dockerize](https://github.com/powerman/dockerize) - Utility to simplify running applications in docker containers by [@jwilder][jwilder], [@powerman][powerman]. +- [GoSu](https://github.com/tianon/gosu) - Run this specific application as this specific user and get out of the pipeline (entrypoint script tool). +- [is-docker](https://github.com/sindresorhus/is-docker) - Check if the process is running inside a Docker container. +- [lstags](https://github.com/ivanilves/lstags) - Sync Docker images across registries. +- [microcheck](https://github.com/tarampampam/microcheck) - Lightweight health check utilities for Docker containers (75 KB instead of 9.3 MB for httpcheck versus cURL) in pure C - http(s), port checks, and parallel execution are included. +- [NVIDIA-Docker](https://github.com/NVIDIA/nvidia-docker) - :skull: The NVIDIA Container Runtime for Docker. +- [Ofelia](https://github.com/mcuadros/ofelia/) - Ofelia is a modern and low footprint job scheduler for docker environments, built on Go. Ofelia aims to be a replacement for the old fashioned cron. Supports configuration from container labels and/or configuration files. +- [SparkView](https://github.com/beyondssl/sparkview-container) - Access VMs, desktops, servers or applications anytime and from anywhere, without complex and costly client roll-outs or user management. +- [su-exec](https://github.com/ncopa/su-exec) - This is a simple tool that will simply execute a program with different privileges. The program will be executed directly and not run as a child, like su and sudo does, which avoids TTY and signal issues. Why reinvent gosu? This does more or less exactly the same thing as gosu but it is only 10kb instead of 1.8MB. By [ncopa](https://github.com/ncopa). +- [sue](https://github.com/theAkito/sue) - Executes a program as a user different from the user running sue. This is a maintainable alternative to ncopa/su-exec, which is the better tianon/gosu. This one is far better (higher performance, smaller size), than the original gosu, however it is far easier to maintain, than su-exec, which is written in plain C. Made by [Akito][akito]. +- [supercronic](https://github.com/aptible/supercronic) - Crontab-compatible job runner, designed specifically to run in containers. +- [TrivialRC](https://github.com/vorakl/TrivialRC) - A minimalistic Runtime Configuration system and process manager for containers [@vorakl](https://github.com/vorakl). ### Builder Applications designed to help or simplify building **new** images -- [ansible-bender](https://github.com/ansible-community/ansible-bender) - A tool utilising `ansible` and `buildah` by [@TomasTomecek][tomastomecek] -- [buildah](https://github.com/containers/buildah) - A tool that facilitates building OCI images by [@containers][containers] -- [BuildKit](https://github.com/moby/buildkit) - Concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit by [@moby project](https://github.com/moby) -- [cekit](https://github.com/cekit/cekit) - A tool used by openshift to build base images using different build engines by [@cekit](https://github.com/cekit). -- [container-diff](https://github.com/GoogleContainerTools/container-diff) - :skull: An image tool for comparing and analyzing container images by [@GoogleContainerTools][googlecontainertools] -- [container-factory](https://github.com/mutable/container-factory) - Produces Docker images from tarballs of application source code by [@mutable](https://github.com/mutable) -- [copy-docker-image](https://github.com/mdlavin/copy-docker-image) - Copy a Docker image between registries without a full Docker installation by [@mdlavin](https://github.com/mdlavin) -- [Derrick](https://github.com/alibaba/derrick) - A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [@alibaba](https://github.com/alibaba). -- [dlayer](https://github.com/orisano/dlayer) - docker layer analyzer by [@orisano](https://github.com/orisano) -- [docker-companion](https://github.com/mudler/docker-companion) - A command line tool written in Golang to squash and unpack docker images by [@mudler](https://github.com/mudler/) -- [docker-make](https://github.com/CtripCloud/docker-make) - Build, tag,and push a bunch of related docker images via a single command. -- [docker-replay](https://github.com/bcicen/docker-replay) - Generate `docker run`command and options from running containers. By [bcicen](https://github.com/bcicen) -- [docker-repack](https://github.com/orf/docker-repack) - Repacks a Docker image into a smaller, more efficient version that makes it significantly faster to pull. By [orf](https://github.com/orf) -- [DockerMake](https://github.com/avirshup/DockerMake) - A reproducible Docker image build system for complex software stacks. By [@avirshup](https://github.com/avirshup) +- [ansible-bender](https://github.com/ansible-community/ansible-bender) - A tool utilising `ansible` and `buildah`. +- [buildah](https://github.com/containers/buildah) - A tool that facilitates building OCI images. +- [BuildKit](https://github.com/moby/buildkit) - Concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit. +- [cekit](https://github.com/cekit/cekit) - A tool used by openshift to build base images using different build engines. +- [container-diff](https://github.com/GoogleContainerTools/container-diff) - :skull: An image tool for comparing and analyzing container images. +- [container-factory](https://github.com/mutable/container-factory) - Produces Docker images from tarballs of application source code. +- [copy-docker-image](https://github.com/mdlavin/copy-docker-image) - Copy a Docker image between registries without a full Docker installation. +- [Derrick](https://github.com/alibaba/derrick) - A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [@alibaba](https://github.com/alibaba). +- [dlayer](https://github.com/orisano/dlayer) - Docker layer analyzer. +- [docker-companion](https://github.com/mudler/docker-companion) - A command line tool written in Golang to squash and unpack docker images. +- [docker-make](https://github.com/CtripCloud/docker-make) - Build, tag,and push a bunch of related docker images via a single command. +- [docker-repack](https://github.com/orf/docker-repack) - Repacks a Docker image into a smaller, more efficient version that makes it significantly faster to pull. By [orf](https://github.com/orf). +- [docker-replay](https://github.com/bcicen/docker-replay) - Generate `docker run`command and options from running containers. By [bcicen](https://github.com/bcicen). +- [DockerMake](https://github.com/avirshup/DockerMake) - A reproducible Docker image build system for complex software stacks. By [@avirshup](https://github.com/avirshup). - [DockerSlim](https://github.com/docker-slim/docker-slim) shrinks fat Docker images creating the smallest possible images. -- [Dockly](https://github.com/swipely/dockly) - Dockly is a gem made to ease the pain of packaging an application in Docker by [@swipely](https://github.com/swipely/) -- [dockramp](https://github.com/jlhawn/dockramp) :skull: - Proof of Concept: A Client Driven Docker Image Builder by [@jlhawn](https://github.com/jlhawn) -- [essex](https://github.com/utensils/essex) - Boilerplate for Docker Based Projects: Essex is a CLI utility written in bash to quickly setup clean and consistent Docker projects with Makefile driven workflows. [@jamesbrink](https://github.com/jamesbrink) -- [HPC Container Maker](https://github.com/NVIDIA/hpc-container-maker) - Generates Dockerfiles from a high level Python recipe, including building blocks for High-Performance Computing components by [@NVIDIA][nvidia] -- [img](https://github.com/genuinetools/img) - Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder by [@genuinetools][genuinetools] -- [kaniko](https://github.com/GoogleContainerTools/kaniko) - Build Container Images In Kubernetes. By [@GoogleContainerTools][googlecontainertools] -- [makisu](https://github.com/uber/makisu) - :skull: Uber's fast and flexible unprivileged image builder for Mesos and Kubernetes, with distributed cache support. By [@uber](https://github.com/uber) -- [packer](https://developer.hashicorp.com/packer/integrations/hashicorp/docker/latest/components/builder/docker) - Hashicorp tool to build machine images including docker image integrated with configuration management tools like chef, puppet, ansible -- [portainer](https://github.com/duedil-ltd/portainer) - Apache Mesos framework for building Docker images by [@duedil-ltd](https://github.com/duedil-ltd) -- [Production-Ready Python Containers :heavy_dollar_sign:](https://pythonspeed.com/products/pythoncontainer/) - A template for creating production-ready Docker images for Python applications. -- [RAUDI](https://github.com/cybersecsi/RAUDI) - A tool to automatically update (and optionally push to Docker Hub) Docker Images for 3rd party software whenever theres is a new release/update/commit. By [@SecSI](https://github.com/cybersecsi) -- [runlike](https://github.com/lavie/runlike) - Generate `docker run`command and options from running containers by [@lavie](https://github.com/lavie) -- [SkinnyWhale](https://github.com/djosephsen/skinnywhale) :skull: - Skinnywhale helps you make smaller (as in megabytes) Docker containers. -- [Smith](https://github.com/oracle/smith) - :skull: A Micocontainer Builder and can perform multi-stage builds after the image is built [Oracle][oracle] -- [userdef](https://github.com/theAkito/userdef) - An advanced `adduser` for your Alpine based Docker images. Made by [Akito][akito] -- [Whaler](https://github.com/P3GLEG/Whaler) - Program to reverse Docker images into Dockerfiles by [@P3GLEG](https://github.com/P3GLEG/). -- [Whales](https://github.com/Gueils/whales) - A tool to automatically dockerize your applications by [@icalialabs](https://github.com/IcaliaLabs). +- [Dockly](https://github.com/swipely/dockly) - Dockly is a gem made to ease the pain of packaging an application in Docker. +- [dockramp](https://github.com/jlhawn/dockramp) - :skull: Proof of Concept: A Client Driven Docker Image Builder. +- [essex](https://github.com/utensils/essex) - Boilerplate for Docker Based Projects: Essex is a CLI utility written in bash to quickly setup clean and consistent Docker projects with Makefile driven workflows. [@jamesbrink](https://github.com/jamesbrink). +- [HPC Container Maker](https://github.com/NVIDIA/hpc-container-maker) - Generates Dockerfiles from a high level Python recipe, including building blocks for High-Performance Computing components. +- [img](https://github.com/genuinetools/img) - Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder. +- [kaniko](https://github.com/GoogleContainerTools/kaniko) - Build Container Images In Kubernetes. By [@GoogleContainerTools][googlecontainertools]. +- [makisu](https://github.com/uber/makisu) - :skull: Uber's fast and flexible unprivileged image builder for Mesos and Kubernetes, with distributed cache support. By [@uber](https://github.com/uber). +- [packer](https://developer.hashicorp.com/packer/integrations/hashicorp/docker/latest/components/builder/docker) - Hashicorp tool to build machine images including docker image integrated with configuration management tools like chef, puppet, ansible. +- [portainer](https://github.com/duedil-ltd/portainer) - Apache Mesos framework for building Docker images. +- [Production-Ready Python Containers :heavy_dollar_sign:](https://pythonspeed.com/products/pythoncontainer/) - A template for creating production-ready Docker images for Python applications. +- [RAUDI](https://github.com/cybersecsi/RAUDI) - A tool to automatically update (and optionally push to Docker Hub) Docker Images for 3rd party software whenever theres is a new release/update/commit. By [@SecSI](https://github.com/cybersecsi). +- [runlike](https://github.com/lavie/runlike) - Generate `docker run`command and options from running containers. +- [SkinnyWhale](https://github.com/djosephsen/skinnywhale) - :skull: Skinnywhale helps you make smaller (as in megabytes) Docker containers. +- [Smith](https://github.com/oracle/smith) - :skull: A Micocontainer Builder and can perform multi-stage builds after the image is built [Oracle][oracle]. +- [userdef](https://github.com/theAkito/userdef) - An advanced `adduser` for your Alpine based Docker images. Made by [Akito][akito]. +- [Whaler](https://github.com/P3GLEG/Whaler) - Program to reverse Docker images into Dockerfiles. +- [Whales](https://github.com/Gueils/whales) - A tool to automatically dockerize your applications. ### Dockerfile -- [chaperone-docker](https://github.com/garywiz/chaperone-docker) - A set of images using the Chaperone process manager, including a lean Alpine image, LAMP, LEMP, and bare-bones base kits. +- [chaperone-docker](https://github.com/garywiz/chaperone-docker) - A set of images using the Chaperone process manager, including a lean Alpine image, LAMP, LEMP, and bare-bones base kits. - [Dockerfile Generator](https://github.com/ozankasikci/dockerfile-generator) `dfg` is both a Go library and an executable that produces valid Dockerfiles using various input channels. -- [Dockerfile Project](https://dockerfile.github.io/) - Trusted Automated Docker Builds. Dockerfile Project maintains a central repository of Dockerfile for various popular open source software services runnable on a Docker container. -- [dockerfilegraph](https://github.com/patrickhoefler/dockerfilegraph) - Visualize your multi-stage Dockerfiles. By [@PatrickHoefler](https://github.com/patrickhoefler) -- [Dockershelf](https://github.com/Dockershelf/dockershelf) - A repository that serves as a collector for docker recipes that are universal, efficient and slim. Images are updated, tested and published daily via a Travis cron job. Maintained by [@CollageLabs](https://github.com/CollageLabs). -- [dockmoor](https://github.com/MeneDev/dockmoor) :skull: - Manage docker image references and help to create reproducible builds with Docker. By [@MeneDev](https://github.com/MeneDev) -- [Vektorcloud](https://github.com/vektorcloud) - A collection of minimal, Alpine-based Docker images +- [Dockerfile Project](https://dockerfile.github.io/) - Trusted Automated Docker Builds. Dockerfile Project maintains a central repository of Dockerfile for various popular open source software services runnable on a Docker container. +- [dockerfilegraph](https://github.com/patrickhoefler/dockerfilegraph) - Visualize your multi-stage Dockerfiles. By [@PatrickHoefler](https://github.com/patrickhoefler). +- [Dockershelf](https://github.com/Dockershelf/dockershelf) - A repository that serves as a collector for docker recipes that are universal, efficient and slim. Images are updated, tested and published daily via a Travis cron job. +- [dockmoor](https://github.com/MeneDev/dockmoor) - :skull: Manage docker image references and help to create reproducible builds with Docker. By [@MeneDev](https://github.com/MeneDev). +- [Vektorcloud](https://github.com/vektorcloud) - A collection of minimal, Alpine-based Docker images. Examples by: @@ -555,247 +555,247 @@ Examples by: ### Linter -- [Dockadvisor](https://github.com/deckrun/dockadvisor) - Lightweight Dockerfile linter with 60+ rules, quality scoring, and security checks by [@deckrun](https://github.com/deckrun) -- [docker-image-size-limit](https://github.com/wemake-services/docker-image-size-limit) - A tool to keep an eye on your docker images size. -- [Dockerfile Linter action](https://github.com/buddy-works/dockerfile-linter) - The linter lets you verify Dockerfile syntax to make sure it follows the best practices for building efficient Docker images. -- [dockfmt](https://github.com/jessfraz/dockfmt) :construction: - Dockerfile formatter and parser by [@jessfraz][jessfraz] -- [FROM:latest](https://github.com/replicatedhq/dockerfilelint) - An opinionated Dockerfile linter by [@replicatedhq](https://github.com/replicatedhq) -- [Hadolint](https://github.com/hadolint/hadolint) - A Dockerfile linter that checks for best practices, common mistakes, and is also able to lint any bash written in `RUN` instructions; by [@lukasmartinelli](https://github.com/lukasmartinelli) -- [Whale-linter](https://github.com/jeromepin/whale-linter) - :skull: A simple and small Dockerfile linter written in Python3+ without dependencies by [@jeromepin](https://github.com/jeromepin) +- [Dockadvisor](https://github.com/deckrun/dockadvisor) - Lightweight Dockerfile linter with 60+ rules, quality scoring, and security checks. +- [docker-image-size-limit](https://github.com/wemake-services/docker-image-size-limit) - A tool to keep an eye on your docker images size. +- [Dockerfile Linter action](https://github.com/buddy-works/dockerfile-linter) - The linter lets you verify Dockerfile syntax to make sure it follows the best practices for building efficient Docker images. +- [dockfmt](https://github.com/jessfraz/dockfmt) - :construction: Dockerfile formatter and parser. +- [FROM:latest](https://github.com/replicatedhq/dockerfilelint) - An opinionated Dockerfile linter. +- [Hadolint](https://github.com/hadolint/hadolint) - A Dockerfile linter that checks for best practices, common mistakes, and is also able to lint any bash written in `RUN` instructions;. +- [Whale-linter](https://github.com/jeromepin/whale-linter) - :skull: A simple and small Dockerfile linter written in Python3+ without dependencies. ### Metadata -- [opencontainer](https://github.com/opencontainers/image-spec/blob/master/annotations.md) - A convention and shared namespace for Docker labels defined by OCI Image Spec. +- [opencontainer](https://github.com/opencontainers/image-spec/blob/master/annotations.md) - A convention and shared namespace for Docker labels defined by OCI Image Spec. ### Registry Services to securely store your Docker images. -- [Amazon Elastic Container Registry :heavy_dollar_sign:](https://aws.amazon.com/ecr/) - Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images. -- [Azure Container Registry :heavy_dollar_sign:](https://azure.microsoft.com/en-us/products/container-registry/#overview) - Manage a Docker private registry as a first-class Azure resource -- [CargoOS](https://github.com/RedCoolBeans/cargos-buildroot) - A bare essential OS for running the Docker Engine on bare metal or Cloud. By [@RedCoolBeans](https://github.com/RedCoolBeans) -- [cleanreg](https://github.com/hcguersoy/cleanreg) - A small tool to delete image manifests from a Docker Registry implementing the API v2, dereferencing them for the GC by [@hcguersoy](https://github.com/hcguersoy) -- [Cloudsmith :heavy_dollar_sign:](https://cloudsmith.com/product/formats/docker-registry) - A fully managed package management SaaS, with first-class support for public and private Docker registries (and many others, incl. Helm charts for the Kubernetes ecosystem). Has a generous free-tier and is also completely free for open-source. -- [Container Registry Service :heavy_dollar_sign:](https://container-registry.com/) - Harbor based Container Management Solution as a Service for teams and organizations. Free tier offers 1 GB storage for private repositories. -- [Cycle.io :heavy_dollar_sign:](https://cycle.io/) - Bare-metal container hosting. -- [DigitalOcean :heavy_dollar_sign:](https://www.digitalocean.com/products/container-registry) - DigitalOcean Container Registry. +- [Amazon Elastic Container Registry :heavy_dollar_sign:](https://aws.amazon.com/ecr/) - Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images. +- [Azure Container Registry :heavy_dollar_sign:](https://azure.microsoft.com/en-us/products/container-registry/#overview) - Manage a Docker private registry as a first-class Azure resource. +- [CargoOS](https://github.com/RedCoolBeans/cargos-buildroot) - A bare essential OS for running the Docker Engine on bare metal or Cloud. By [@RedCoolBeans](https://github.com/RedCoolBeans). +- [cleanreg](https://github.com/hcguersoy/cleanreg) - A small tool to delete image manifests from a Docker Registry implementing the API v2, dereferencing them for the GC. +- [Cloudsmith :heavy_dollar_sign:](https://cloudsmith.com/product/formats/docker-registry) - A fully managed package management SaaS, with first-class support for public and private Docker registries (and many others, incl. Helm charts for the Kubernetes ecosystem). Has a generous free-tier and is also completely free for open-source. +- [Container Registry Service :heavy_dollar_sign:](https://container-registry.com/) - Harbor based Container Management Solution as a Service for teams and organizations. Free tier offers 1 GB storage for private repositories. +- [Cycle.io :heavy_dollar_sign:](https://cycle.io/) - Bare-metal container hosting. +- [DigitalOcean :heavy_dollar_sign:](https://www.digitalocean.com/products/container-registry) - DigitalOcean Container Registry. - [Docker Hub](https://hub.docker.com/) provided by Docker Inc. - [Docker Registry v2][distribution] - The Docker toolset to pack, ship, store, and deliver content -- [Docket](https://github.com/netvarun/docket) - Custom docker registry that allows for lightning fast deploys through bittorrent by [@netvarun](https://github.com/netvarun/) -- [Dragonfly](https://github.com/dragonflyoss/Dragonfly2) - Provide efficient, stable and secure file distribution and image acceleration based on p2p technology. +- [Docket](https://github.com/netvarun/docket) - Custom docker registry that allows for lightning fast deploys through bittorrent. +- [Dragonfly](https://github.com/dragonflyoss/Dragonfly2) - Provide efficient, stable and secure file distribution and image acceleration based on p2p technology. - [GCP Artifact Registry :heavy_dollar_sign:](https://cloud.google.com/artifact-registry/docs) Fast, private Docker image storage on Google Cloud Platform. -- [Gitea Container Registry](https://docs.gitea.com/usage/packages/container) - Integrated Docker registry in Gitea, ideal for private, small-scale image hosting. -- [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) - GitHub's solution for storing and managing Docker images, with tight integration into GitHub Actions. -- [GitLab Container Registry](https://docs.gitlab.com/user/packages/container_registry/) - Registry focused on using its images in GitLab CI +- [Gitea Container Registry](https://docs.gitea.com/usage/packages/container) - Integrated Docker registry in Gitea, ideal for private, small-scale image hosting. +- [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) - GitHub's solution for storing and managing Docker images, with tight integration into GitHub Actions. +- [GitLab Container Registry](https://docs.gitlab.com/user/packages/container_registry/) - Registry focused on using its images in GitLab CI. - [Harbor](https://github.com/goharbor/harbor) An open source trusted cloud native registry project that stores, signs, and scans content. Supports replication, user management, access control and activity auditing. By [CNCF](https://www.cncf.io) formerly [VMWare][vmware] -- [JFrog Artifactory :heavy_dollar_sign:](https://jfrog.com/artifactory/) - Artifact Repository Manager, can be used as private Docker Registry as well -- [Kraken](https://github.com/uber/kraken) - Uber's Highly scalable P2P docker registry, capable of distributing TBs of data in seconds. -- [nscr](https://github.com/jhstatewide/nscr) - A light-weight, self-contained container registry that's easy to run and maintain. -- [Quay.io :heavy_dollar_sign:](https://quay.io/) (part of CoreOS) - Secure hosting for private Docker repositories -- [Registryo](https://github.com/inmagik/registryo) - UI and token based authentication server for onpremise docker registry -- [RepoFlow](https://www.repoflow.io) - A simple and easy-to-use package management platform with Docker support alongside other formats like PyPI, Maven, npm, and Helm. Includes smart search, built-in Docker image scanning, and a great free option for both self-hosted and cloud use. -- [Rescoyl](https://github.com/noteed/rescoyl) - Private Docker registry (free and open source) by [@noteed](https://github.com/noteed) -- [Sonatype Nexus Repository](https://www.sonatype.com/products/sonatype-nexus-repository) - Manage binaries and build artifacts across your software supply chain. +- [JFrog Artifactory :heavy_dollar_sign:](https://jfrog.com/artifactory/) - Artifact Repository Manager, can be used as private Docker Registry as well. +- [Kraken](https://github.com/uber/kraken) - Uber's Highly scalable P2P docker registry, capable of distributing TBs of data in seconds. +- [nscr](https://github.com/jhstatewide/nscr) - A light-weight, self-contained container registry that's easy to run and maintain. +- [Quay.io :heavy_dollar_sign:](https://quay.io/) - Secure hosting for private Docker repositories. +- [Registryo](https://github.com/inmagik/registryo) - UI and token based authentication server for onpremise docker registry. +- [RepoFlow](https://www.repoflow.io) - A simple and easy-to-use package management platform with Docker support alongside other formats like PyPI, Maven, npm, and Helm. Includes smart search, built-in Docker image scanning, and a great free option for both self-hosted and cloud use. +- [Rescoyl](https://github.com/noteed/rescoyl) - Private Docker registry (free and open source). +- [Sonatype Nexus Repository](https://www.sonatype.com/products/sonatype-nexus-repository) - Manage binaries and build artifacts across your software supply chain. ## Development with Docker ### API Client -- [ahab](https://github.com/instacart/ahab) - Docker event handling with Python by [@instacart](https://github.com/instacart) -- [clj-docker-client](https://github.com/into-docker/clj-docker-client) :skull: - Idiomatic Clojure client for the Docker remote API. By [@lispyclouds][lispyclouds] -- [contajners](https://github.com/lispyclouds/contajners) - An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [@lispyclouds][lispyclouds] -- [Docker Client for JVM](https://github.com/gesellix/docker-client) - A Docker remote api client library for the JVM, written in Groovy by [@gesellix][gesellix] -- [Docker Client TypeScript](https://gitlab.com/masaeedu/docker-client) - Docker API client for JavaScript, automatically generated from Swagger API definition from moby repository. By [@masaeedu](https://github.com/masaeedu) -- [docker-client](https://github.com/spotify/docker-client) :skull: - Java client for the Docker remote API. By [@spotify][spotify] -- [docker-controller-bot](https://github.com/dgongut/docker-controller-bot) - Telegram bot to control docker containers. By [@dgongut](https://github.com/dgongut/) -- [docker-it-scala](https://github.com/whisklabs/docker-it-scala) - Docker integration testing kit with Scala by [@whisklabs](https://github.com/whisklabs) -- [docker-java-api](https://github.com/amihaiemil/docker-java-api) - Lightweight, truly object-oriented, Java client for Docker's API. By [@amihaiemil](https://github.com/amihaiemil) -- [docker-maven-plugin](https://github.com/fabric8io/docker-maven-plugin) - A Maven plugin for running and creating Docker images by [@fabric8io](https://github.com/fabric8io) -- [Docker-PowerShell](https://github.com/Microsoft/Docker-PowerShell) - :skull: PowerShell Module for Docker -- [Docker.DotNet](https://github.com/Microsoft/Docker.DotNet) - C#/.NET HTTP client for the Docker remote API by [@ahmetb](https://github.com/ahmetb) -- [Docker.Registry.DotNet](https://github.com/ChangemakerStudios/Docker.Registry.DotNet) - .NET (C#) Client Library for interacting with a Docker Registry API (v2) [@rquackenbush](https://github.com/rquackenbush) -- [dockerfile-maven](https://github.com/spotify/dockerfile-maven) - :skull: A Maven plugin for building and pushing Docker images by [@spotify][spotify] -- [dockerode](https://github.com/apocas/dockerode) - Docker Remote API node.js module by [@apocas](https://github.com/apocas) -- [DoMonit](https://github.com/eon01/DoMonit) - A simple Docker Monitoring wrapper For Docker API -- [go-dockerclient](https://github.com/fsouza/go-dockerclient/) - Go HTTP client for the Docker remote API by [@fsouza](https://github.com/fsouza/) -- [Gradle Docker plugin](https://github.com/gesellix/gradle-docker-plugin) - A Docker remote api plugin for Gradle by [@gesellix][gesellix] -- [libcompose](https://github.com/docker/libcompose) - :skull: Go library for Docker Compose. -- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) :construction: - Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [@greenled](https://github.com/greenled). -- [sbt-docker-compose](https://github.com/Tapad/sbt-docker-compose) - :skull: Integrates Docker Compose functionality into sbt by [@kurtkopchik](https://github.com/kurtkopchik/) -- [sbt-docker](https://github.com/marcuslonnberg/sbt-docker) - Create Docker images directly from sbt by [@marcuslonnberg](https://github.com/marcuslonnberg) +- [ahab](https://github.com/instacart/ahab) - Docker event handling with Python. +- [clj-docker-client](https://github.com/into-docker/clj-docker-client) - :skull: Idiomatic Clojure client for the Docker remote API. By [@lispyclouds][lispyclouds]. +- [contajners](https://github.com/lispyclouds/contajners) - An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [@lispyclouds][lispyclouds]. +- [Docker Client for JVM](https://github.com/gesellix/docker-client) - A Docker remote api client library for the JVM, written in Groovy. +- [Docker Client TypeScript](https://gitlab.com/masaeedu/docker-client) - Docker API client for JavaScript, automatically generated from Swagger API definition from moby repository. By [@masaeedu](https://github.com/masaeedu). +- [docker-client](https://github.com/spotify/docker-client) - :skull: Java client for the Docker remote API. By [@spotify][spotify]. +- [docker-controller-bot](https://github.com/dgongut/docker-controller-bot) - Telegram bot to control docker containers. By [@dgongut](https://github.com/dgongut/). +- [docker-it-scala](https://github.com/whisklabs/docker-it-scala) - Docker integration testing kit with Scala. +- [docker-java-api](https://github.com/amihaiemil/docker-java-api) - Lightweight, truly object-oriented, Java client for Docker's API. By [@amihaiemil](https://github.com/amihaiemil). +- [docker-maven-plugin](https://github.com/fabric8io/docker-maven-plugin) - A Maven plugin for running and creating Docker images. +- [Docker-PowerShell](https://github.com/Microsoft/Docker-PowerShell) - :skull: PowerShell Module for Docker. +- [Docker.DotNet](https://github.com/Microsoft/Docker.DotNet) - C#/.NET HTTP client for the Docker remote API. +- [Docker.Registry.DotNet](https://github.com/ChangemakerStudios/Docker.Registry.DotNet) - .NET (C#) Client Library for interacting with a Docker Registry API (v2) [@rquackenbush](https://github.com/rquackenbush). +- [dockerfile-maven](https://github.com/spotify/dockerfile-maven) - :skull: A Maven plugin for building and pushing Docker images. +- [dockerode](https://github.com/apocas/dockerode) - Docker Remote API node.js module. +- [DoMonit](https://github.com/eon01/DoMonit) - A simple Docker Monitoring wrapper For Docker API. +- [go-dockerclient](https://github.com/fsouza/go-dockerclient/) - Go HTTP client for the Docker remote API. +- [Gradle Docker plugin](https://github.com/gesellix/gradle-docker-plugin) - A Docker remote api plugin for Gradle. +- [libcompose](https://github.com/docker/libcompose) - :skull: Go library for Docker Compose. +- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - :construction: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [@greenled](https://github.com/greenled). +- [sbt-docker](https://github.com/marcuslonnberg/sbt-docker) - Create Docker images directly from sbt. +- [sbt-docker-compose](https://github.com/Tapad/sbt-docker-compose) - :skull: Integrates Docker Compose functionality into sbt. ### CI/CD -- [Buddy :heavy_dollar_sign:](https://buddy.works) - The best of Git, build & deployment tools combined into one powerful tool that supercharged our development. -- [Captain](https://github.com/harbur/captain) - Convert your Git workflow to Docker containers ready for Continuous Delivery by [@harbur](https://github.com/harbur). -- [Cyclone](https://github.com/caicloud/cyclone) - Powerful workflow engine and end-to-end pipeline solutions implemented with native Kubernetes resources by [@caicloud](https://github.com/caicloud). -- [Defang](https://github.com/DefangLabs/defang) - Deploy Docker Compose to your favorite cloud in minutes by [@DefangLabs](https://github.com/DefangLabs) -- [Depot :heavy_dollar_sign:](https://depot.dev) - Build Docker images fast, in the cloud. Blazing fast compute, automatic intelligent caching, and zero configuration. [Done in seconds](https://depot.dev/#benchmarks). -- [Diun](https://github.com/crazy-max/diun) - Receive notifications when an image or repository is updated on a Docker registry by [@crazy-max]. -- [dockcheck](https://github.com/mag37/dockcheck) - A script checking updates for docker images without pulling then auto-update selected/all containers. With notifications, pruning and more. -- [Drydock](https://github.com/CodesWhat/drydock) - Open-source container update monitoring with web dashboard, 15 registries, 16 notification triggers, and security scanning. Drop-in WUD replacement. By [@CodesWhat](https://github.com/CodesWhat) -- [Docker plugin for Jenkins](https://github.com/jenkinsci/docker-plugin/) - The aim of the docker plugin is to be able to use a docker host to dynamically provision a slave, run a single build, then tear-down that slave. -- [Drone](https://github.com/drone/drone) - Continuous integration server built on Docker and configured using YAML files. -- [Gantry](https://github.com/shizunge/gantry) - Automatically update selected Docker swarm services. -- [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) - GitLab has integrated CI to test, build and deploy your code with the use of GitLab runners. -- [GOCD-Docker](https://github.com/gocd/gocd-docker) :skull: - Go Server and Agent in docker containers to provision. -- [Jaypore CI](https://github.com/theSage21/jaypore_ci) - Simple, very flexible, powerful CI / CD / automation system configured in Python. Offline and local first. -- [Kraken CI](https://github.com/Kraken-CI/kraken) - Modern CI/CD, open-source, on-premise system that is highly scalable and focused on testing. One of its executors is Docker. Developed by [@Kraken-CI](https://github.com/Kraken-CI). -- [Microservices Continuous Deployment](https://github.com/francescou/docker-continuous-deployment) - Continuous deployment of a microservices application. -- [mu](https://github.com/stelligent/mu) - Tool to configure CI/CD of your container applications via AWS CodePipeline, CodeBuild and ECS [@Stelligent](https://github.com/stelligent) -- [Ouroboros](https://github.com/pyouroboros/ouroboros) :skull: - Automatically update running Docker containers with notifications -- [Popper](https://github.com/systemslab/popper) - Github actions workflow (HCL syntax) execution engine. -- [Screwdriver :heavy_dollar_sign:](https://screwdriver.cd/) - Yahoo's OpenSource buildplatform designed for Continous Delivery. -- [Skipper](https://github.com/Stratoscale/skipper) - Easily dockerize your Git repository by [@Stratoscale](https://github.com/Stratoscale) -- [SwarmCI](https://github.com/ghostsquad/swarmci) - Create a distributed, isolated task pipeline in your Docker Swarm. -- [Tekton CD](https://tekton.dev/) - A cloud-native pipeline resource. -- [Watchtower](https://github.com/containrrr/watchtower) :skull: - Automatically update running Docker containers +- [Buddy :heavy_dollar_sign:](https://buddy.works) - The best of Git, build & deployment tools combined into one powerful tool that supercharged our development. +- [Captain](https://github.com/harbur/captain) - Convert your Git workflow to Docker containers ready for Continuous Delivery. +- [Cyclone](https://github.com/caicloud/cyclone) - Powerful workflow engine and end-to-end pipeline solutions implemented with native Kubernetes resources. +- [Defang](https://github.com/DefangLabs/defang) - Deploy Docker Compose to your favorite cloud in minutes. +- [Depot :heavy_dollar_sign:](https://depot.dev) - Build Docker images fast, in the cloud. Blazing fast compute, automatic intelligent caching, and zero configuration. [Done in seconds](https://depot.dev/#benchmarks). +- [Diun](https://github.com/crazy-max/diun) - Receive notifications when an image or repository is updated on a Docker registry by [@crazy-max]. +- [dockcheck](https://github.com/mag37/dockcheck) - A script checking updates for docker images without pulling then auto-update selected/all containers. With notifications, pruning and more. +- [Docker plugin for Jenkins](https://github.com/jenkinsci/docker-plugin/) - The aim of the docker plugin is to be able to use a docker host to dynamically provision a slave, run a single build, then tear-down that slave. +- [Drone](https://github.com/drone/drone) - Continuous integration server built on Docker and configured using YAML files. +- [Drydock](https://github.com/CodesWhat/drydock) - Open-source container update monitoring with web dashboard, 15 registries, 16 notification triggers, and security scanning. Drop-in WUD replacement. By [@CodesWhat](https://github.com/CodesWhat). +- [Gantry](https://github.com/shizunge/gantry) - Automatically update selected Docker swarm services. +- [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) - GitLab has integrated CI to test, build and deploy your code with the use of GitLab runners. +- [GOCD-Docker](https://github.com/gocd/gocd-docker) - :skull: Go Server and Agent in docker containers to provision. +- [Jaypore CI](https://github.com/theSage21/jaypore_ci) - Simple, very flexible, powerful CI / CD / automation system configured in Python. Offline and local first. +- [Kraken CI](https://github.com/Kraken-CI/kraken) - Modern CI/CD, open-source, on-premise system that is highly scalable and focused on testing. One of its executors is Docker. Developed. +- [Microservices Continuous Deployment](https://github.com/francescou/docker-continuous-deployment) - Continuous deployment of a microservices application. +- [mu](https://github.com/stelligent/mu) - Tool to configure CI/CD of your container applications via AWS CodePipeline, CodeBuild and ECS [@Stelligent](https://github.com/stelligent). +- [Ouroboros](https://github.com/pyouroboros/ouroboros) - :skull: Automatically update running Docker containers with notifications. +- [Popper](https://github.com/systemslab/popper) - Github actions workflow (HCL syntax) execution engine. +- [Screwdriver :heavy_dollar_sign:](https://screwdriver.cd/) - Yahoo's OpenSource buildplatform designed for Continous Delivery. +- [Skipper](https://github.com/Stratoscale/skipper) - Easily dockerize your Git repository. +- [SwarmCI](https://github.com/ghostsquad/swarmci) - Create a distributed, isolated task pipeline in your Docker Swarm. +- [Tekton CD](https://tekton.dev/) - A cloud-native pipeline resource. +- [Watchtower](https://github.com/containrrr/watchtower) - :skull: Automatically update running Docker containers. ### Development Environment -- [batect](https://github.com/batect/batect) - :skull: build and testing environments as code tool: Dockerised build and testing environments made easy by [@charleskorn](https://github.com/charleskorn) -- [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [@TechnologyAdvice](https://github.com/TechnologyAdvice)) -- [Boot2Docker](https://github.com/boot2docker/boot2docker) :skull: - Docker for OSX and Windows -- [coder](https://github.com/coder/coder) - remote development machines powered by Terraform or Docker by [@coder](https://github.com/coder) -- [construi](https://github.com/lstephen/construi) - Run your builds inside a Docker defined environment by [@lstephen](https://github.com/lstephen) -- [Crashcart](https://github.com/oracle/crashcart) - :skull: Sideload Linux binaries into a running container for troubleshooting by [@Oracle][oracle] -- [dde](https://github.com/whatwedo/dde) :construction: - Local development environment toolset based on Docker. By [@whatwedo](https://github.com/whatwedo) -- [Devstep](https://github.com/fgrehm/devstep) :skull: - Development environments powered by Docker and buildpacks by [@fgrehm][fgrehm] -- [Dinghy](https://github.com/codekitchen/dinghy) - :skull: An alternative way to use Docker on Mac OS X using Docker Machine with virtualbox, vmware, xhyve or parallels -- [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [@bibendi](https://github.com/bibendi) -- [DLite](https://github.com/nlf/dlite) :skull: - Simplest way to use Docker on OSX, no VM needed. By [@nlf](https://github.com/nlf) -- [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [@dnephin](https://github.com/dnephin) -- [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [@NandoQuintana](https://github.com/nandoquintana). -- [Docker osx dev](https://github.com/brikis98/docker-osx-dev) :skull: - A productive development environment with Docker on OS X by [@brikis98](https://github.com/brikis98) -- [Docker-Arch](https://github.com/Ph3nol/Docker-Arch) - Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [@Ph3nol](https://github.com/ph3nol) -- [Docker-sync](https://github.com/EugenMayer/docker-sync) - Drastically improves performance ([50-70x](https://github.com/EugenMayer/docker-sync/wiki/4.-Performance)) when using Docker for development on Mac OS X/Windows and Linux while sharing code to the container. By [@EugenMayer](https://github.com/EugenMayer) -- [docker-vm](https://github.com/shyiko/docker-vm) - Simple and transparent alternative to boot2docker (backed by Vagrant) by [@shyiko](https://github.com/shyiko) -- [DockerBuildManagement](https://github.com/DIPSAS/DockerBuildManagement) - :skull: Build Management is a python application, installed with pip. The application makes it easy to manage a build system based on Docker by configuring a single yaml file describing how to build, test, run or publish a containerized solution. -- [DockerDL](https://github.com/matifali/dockerdl) - Deep Learning Docker Images. Don't waste time setting up a deep learning env when you can get a deep learning environment with everything pre-installed. -- [Dusty](https://github.com/gamechanger/dusty) - :skull: Managed Docker development environments on OS X -- [Eclipse Che](https://github.com/eclipse/che) - Developer workspace server with Docker runtimes, cloud IDE, next-generation Eclipse IDE -- [EnvCLI](https://github.com/EnvCLI/EnvCLI) - Replace your local installation of Node, Go, ... with project-specific docker containers. By [@EnvCLI](https://github.com/EnvCLI) -- [ESP32 Linux - Docker builder](https://github.com/hpsaturn/esp32s3-linux) - Container solution to compile Linux and develop it for ESP32 microcontrollers - By [@Hpsaturn](https://github.com/hpsaturn) -- [footloose](https://github.com/weaveworks/footloose) - :skull: Spin containers that look like Virtual Machines - By [@dlespiau](https://github.com/dlespiau) -- [forward2docker](https://github.com/bsideup/forward2docker) :skull: - Utility to auto forward a port from localhost into ports on Docker containers running in a boot2docker VM by [@bsideup](https://github.com/bsideup) -- [Gebug](https://github.com/moshebe/gebug) - A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. -- [Kitt](https://github.com/senges/kitt) - A portable and disposable Shell environment, based on Docker and Nix. By [@senges](https://github.com/senges) -- [Lando](https://github.com/lando/lando) - Lando is for developers who want to quickly specify and painlessly spin up the services and tools needed to develop their projects. By [Tandem](https://www.thinktandem.io/) -- [Rust Universal Compiler](https://github.com/Peco602/rust-universal-compiler) - Container solution to compile Rust projects for Linux, macOS and Windows. By [@Peco602][peco602] -- [uniget](https://github.com/uniget-org/cli) - uni(versal)get, the installer and updater for container tools and beyond (formerly docker-setup). By [@nicholasdille](https://github.com/nicholasdille) -- [Vagga](https://github.com/tailhook/vagga) - Vagga is a containerisation tool without daemons. It is a fully-userspace container engine inspired by Vagrant and Docker, specialized for development environments by [@tailhook](https://github.com/tailhook/) -- [Zsh-in-Docker](https://github.com/deluan/zsh-in-docker) - Install Zsh, Oh-My-Zsh and plugins inside a Docker container with one line! By [Deluan](https://www.deluan.com) +- [batect](https://github.com/batect/batect) - :skull: Build and testing environments as code tool: Dockerised build and testing environments made easy. +- [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [@TechnologyAdvice](https://github.com/TechnologyAdvice)). +- [Boot2Docker](https://github.com/boot2docker/boot2docker) - :skull: Docker for OSX and Windows. +- [coder](https://github.com/coder/coder) - Remote development machines powered by Terraform or Docker. +- [construi](https://github.com/lstephen/construi) - Run your builds inside a Docker defined environment. +- [Crashcart](https://github.com/oracle/crashcart) - :skull: Sideload Linux binaries into a running container for troubleshooting. +- [dde](https://github.com/whatwedo/dde) - :construction: Local development environment toolset based on Docker. By [@whatwedo](https://github.com/whatwedo). +- [Devstep](https://github.com/fgrehm/devstep) - :skull: Development environments powered by Docker and buildpacks. +- [Dinghy](https://github.com/codekitchen/dinghy) - :skull: An alternative way to use Docker on Mac OS X using Docker Machine with virtualbox, vmware, xhyve or parallels. +- [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [@bibendi](https://github.com/bibendi). +- [DLite](https://github.com/nlf/dlite) - :skull: Simplest way to use Docker on OSX, no VM needed. By [@nlf](https://github.com/nlf). +- [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [@dnephin](https://github.com/dnephin). +- [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [@NandoQuintana](https://github.com/nandoquintana). +- [Docker osx dev](https://github.com/brikis98/docker-osx-dev) - :skull: A productive development environment with Docker on OS X. +- [Docker-Arch](https://github.com/Ph3nol/Docker-Arch) - Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [@Ph3nol](https://github.com/ph3nol). +- [Docker-sync](https://github.com/EugenMayer/docker-sync) - Drastically improves performance ([50-70x](https://github.com/EugenMayer/docker-sync/wiki/4.-Performance)) when using Docker for development on Mac OS X/Windows and Linux while sharing code to the container. By [@EugenMayer](https://github.com/EugenMayer). +- [docker-vm](https://github.com/shyiko/docker-vm) - Simple and transparent alternative to boot2docker (backed by Vagrant). +- [DockerBuildManagement](https://github.com/DIPSAS/DockerBuildManagement) - :skull: Build Management is a python application, installed with pip. The application makes it easy to manage a build system based on Docker by configuring a single yaml file describing how to build, test, run or publish a containerized solution. +- [DockerDL](https://github.com/matifali/dockerdl) - Deep Learning Docker Images. Don't waste time setting up a deep learning env when you can get a deep learning environment with everything pre-installed. +- [Dusty](https://github.com/gamechanger/dusty) - :skull: Managed Docker development environments on OS X. +- [Eclipse Che](https://github.com/eclipse/che) - Developer workspace server with Docker runtimes, cloud IDE, next-generation Eclipse IDE. +- [EnvCLI](https://github.com/EnvCLI/EnvCLI) - Replace your local installation of Node, Go, ... with project-specific docker containers. By [@EnvCLI](https://github.com/EnvCLI). +- [ESP32 Linux - Docker builder](https://github.com/hpsaturn/esp32s3-linux) - Container solution to compile Linux and develop it for ESP32 microcontrollers - By [@Hpsaturn](https://github.com/hpsaturn). +- [footloose](https://github.com/weaveworks/footloose) - :skull: Spin containers that look like Virtual Machines - By [@dlespiau](https://github.com/dlespiau). +- [forward2docker](https://github.com/bsideup/forward2docker) - :skull: Utility to auto forward a port from localhost into ports on Docker containers running in a boot2docker VM. +- [Gebug](https://github.com/moshebe/gebug) - A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. +- [Kitt](https://github.com/senges/kitt) - A portable and disposable Shell environment, based on Docker and Nix. By [@senges](https://github.com/senges). +- [Lando](https://github.com/lando/lando) - Lando is for developers who want to quickly specify and painlessly spin up the services and tools needed to develop their projects. By [Tandem](https://www.thinktandem.io/). +- [Rust Universal Compiler](https://github.com/Peco602/rust-universal-compiler) - Container solution to compile Rust projects for Linux, macOS and Windows. By [@Peco602][peco602]. +- [uniget](https://github.com/uniget-org/cli) - Uni(versal)get, the installer and updater for container tools and beyond (formerly docker-setup). By [@nicholasdille](https://github.com/nicholasdille). +- [Vagga](https://github.com/tailhook/vagga) - Vagga is a containerisation tool without daemons. It is a fully-userspace container engine inspired by Vagrant and Docker, specialized for development environments. +- [Zsh-in-Docker](https://github.com/deluan/zsh-in-docker) - Install Zsh, Oh-My-Zsh and plugins inside a Docker container with one line! By [Deluan](https://www.deluan.com). ### Garbage Collection -- [caduc](https://github.com/tjamet/caduc) - A docker garbage collector cleaning stuff you did not use recently -- [Docker Clean](https://github.com/ZZROTDesign/docker-clean) - A script that cleans Docker containers, images and volumes by [@zzrotdesign](https://github.com/ZZROTDesign) -- [docker_gc](https://github.com/pdacity/docker_gc) - Image for automatic removing unused Docker Swarm objects. Also works just as Docker Service by [@pdacity](https://github.com/pdacity) -- [Docker-cleanup](https://github.com/meltwater/docker-cleanup) :skull: - Automatic Docker image, container and volume cleanup by [@meltwater](https://github.com/meltwater) -- [docker-custodian](https://github.com/Yelp/docker-custodian) - Keep docker hosts tidy. By [@Yelp](https://github.com/Yelp) -- [docker-garby](https://github.com/konstruktoid/docker-garby) - :skull: Docker garbage collection script by [@konstruktoid](https://github.com/konstruktoid). -- [docker-gc](https://github.com/spotify/docker-gc) :skull: - A cron job that will delete old stopped containers and unused images by [@spotify][spotify] -- [Docuum](https://github.com/stepchowfun/docuum) - Least recently used (LRU) eviction of Docker images by [@stepchowfun](https://github.com/stepchowfun) -- [sherdock](https://github.com/rancher/sherdock) :skull: - Automatic GC of images based on regexp by [@rancher][rancher] +- [caduc](https://github.com/tjamet/caduc) - A docker garbage collector cleaning stuff you did not use recently. +- [Docker Clean](https://github.com/ZZROTDesign/docker-clean) - A script that cleans Docker containers, images and volumes. +- [Docker-cleanup](https://github.com/meltwater/docker-cleanup) - :skull: Automatic Docker image, container and volume cleanup. +- [docker-custodian](https://github.com/Yelp/docker-custodian) - Keep docker hosts tidy. By [@Yelp](https://github.com/Yelp). +- [docker-garby](https://github.com/konstruktoid/docker-garby) - :skull: Docker garbage collection script. +- [docker-gc](https://github.com/spotify/docker-gc) - :skull: A cron job that will delete old stopped containers and unused images. +- [docker_gc](https://github.com/pdacity/docker_gc) - Image for automatic removing unused Docker Swarm objects. Also works just as Docker Service. +- [Docuum](https://github.com/stepchowfun/docuum) - Least recently used (LRU) eviction of Docker images. +- [sherdock](https://github.com/rancher/sherdock) - :skull: Automatic GC of images based on regexp. ### Serverless -- [AMP](https://github.com/appcelerator-archive/amp) :skull: - The open source unified CaaS/FaaS platform for Docker, batteries included. By [@Appcelerator](https://github.com/appcelerator-archive) -- [Apache OpenWhisk](https://github.com/apache/openwhisk) - a serverless, open source cloud platform that executes functions in response to events at any scale. By [@apache](https://github.com/apache) -- [Docker-Lambda](https://github.com/lambci/docker-lambda) - :skull: Docker images and test runners that replicate the live AWS Lambda environment. By [@lamb-ci](https://github.com/lambci) -- [Funker](https://github.com/bfirsh/funker-example-voting-app) - Functions as Docker containers example voting app. By [@bfirsh](https://github.com/bfirsh) -- [IronFunctions](https://github.com/iron-io/functions) - The serverless microservices platform FaaS (Functions as a Service) which uses Docker containers to run Any language or AWS Lambda functions -- [Koyeb](https://www.koyeb.com/) :heavy_dollar_sign: - Koyeb is a developer-friendly serverless platform to deploy apps globally. Seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. -- [OpenFaaS](https://github.com/openfaas/faas) - A complete serverless functions framework for Docker and Kubernetes. By [OpenFaaS](https://github.com/openfaas) -- [SCAR](https://github.com/grycap/scar) - Serverless Container-aware Architectures (SCAR) is a serverless framework that allows easy deployment and execution of containers (e.g. Docker) in Serverless environments (e.g. Lambda) by [@grycap](https://github.com/grycap) +- [AMP](https://github.com/appcelerator-archive/amp) - :skull: The open source unified CaaS/FaaS platform for Docker, batteries included. By [@Appcelerator](https://github.com/appcelerator-archive). +- [Apache OpenWhisk](https://github.com/apache/openwhisk) - A serverless, open source cloud platform that executes functions in response to events at any scale. By [@apache](https://github.com/apache). +- [Docker-Lambda](https://github.com/lambci/docker-lambda) - :skull: Docker images and test runners that replicate the live AWS Lambda environment. By [@lamb-ci](https://github.com/lambci). +- [Funker](https://github.com/bfirsh/funker-example-voting-app) - Functions as Docker containers example voting app. By [@bfirsh](https://github.com/bfirsh). +- [IronFunctions](https://github.com/iron-io/functions) - The serverless microservices platform FaaS (Functions as a Service) which uses Docker containers to run Any language or AWS Lambda functions. +- [Koyeb](https://www.koyeb.com/) - :heavy_dollar_sign: Koyeb is a developer-friendly serverless platform to deploy apps globally. Seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. +- [OpenFaaS](https://github.com/openfaas/faas) - A complete serverless functions framework for Docker and Kubernetes. By [OpenFaaS](https://github.com/openfaas). +- [SCAR](https://github.com/grycap/scar) - Serverless Container-aware Architectures (SCAR) is a serverless framework that allows easy deployment and execution of containers (e.g. Docker) in Serverless environments (e.g. Lambda). ### Testing -- [Container Structure Test](https://github.com/GoogleContainerTools/container-structure-test) - A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [@GoogleContainerTools][googlecontainertools] -- [dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. -- [DockerSpec](https://github.com/zuazo/dockerspec) - A small Ruby Gem to run RSpec and Serverspec, Infrataster and Capybara tests against Dockerfiles or Docker images easily. By [@zuazo](https://github.com/zuazo) -- [Dockunit](https://github.com/dockunit/platform) :skull: - Docker based integration tests. A simple Node based utility for running Docker based unit tests. By [@dockunit](https://github.com/dockunit) -- [EZDC](https://github.com/lynchborg/ezdc) - Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [@byrnedo] +- [Container Structure Test](https://github.com/GoogleContainerTools/container-structure-test) - A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [@GoogleContainerTools][googlecontainertools]. +- [dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. +- [DockerSpec](https://github.com/zuazo/dockerspec) - A small Ruby Gem to run RSpec and Serverspec, Infrataster and Capybara tests against Dockerfiles or Docker images easily. By [@zuazo](https://github.com/zuazo). +- [Dockunit](https://github.com/dockunit/platform) - :skull: Docker based integration tests. A simple Node based utility for running Docker based unit tests. By [@dockunit](https://github.com/dockunit). +- [EZDC](https://github.com/lynchborg/ezdc) - Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [@byrnedo]. - [InSpec][inspec] - InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements. By [@chef](https://github.com/chef) -- [Kurtosis](https://github.com/kurtosis-tech/kurtosis) - A composable build system for multi-container test environments that provides developers with: a powerful Python-like SDK for environment configuration, a compile-time validator to verify environment behavior & setup, and a runtime for environment execution, monitoring, & debugging capabilities. By [Kurtosis](https://www.kurtosis.com/) -- [Pull Dog](https://github.com/apps/pull-dog) - A GitHub app that automatically creates Docker-based test environments for your pull requests, from your docker-compose files. Not open source. -- [Pumba](https://github.com/alexei-led/pumba) - Chaos testing tool for Docker. Can be deployed on kubernetes and CoreOS cluster. By [@alexei-led](https://github.com/alexei-led) +- [Kurtosis](https://github.com/kurtosis-tech/kurtosis) - A composable build system for multi-container test environments that provides developers with: a powerful Python-like SDK for environment configuration, a compile-time validator to verify environment behavior & setup, and a runtime for environment execution, monitoring, & debugging capabilities. By [Kurtosis](https://www.kurtosis.com/). +- [Pull Dog](https://github.com/apps/pull-dog) - A GitHub app that automatically creates Docker-based test environments for your pull requests, from your docker-compose files. Not open source. +- [Pumba](https://github.com/alexei-led/pumba) - Chaos testing tool for Docker. Can be deployed on kubernetes and CoreOS cluster. By [@alexei-led](https://github.com/alexei-led). ### Wrappers -- [Ansible](https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html) - Manage the life cycle of Docker containers. By RedHat -- [Azk](https://github.com/azukiapp/azk) - :skull: Orchestrate development environments on your local machine by [@azukiapp](https://github.com/azukiapp) -- [Beluga](https://github.com/cortexmedia/Beluga) :skull: - CLI to deploy docker containers on a single server or low amount of servers. By [@cortextmedia](https://github.com/cortexmedia) -- [dexec](https://github.com/docker-exec/dexec) - Command line interface written in Go for running code with Docker Exec images. -- [dockerized](https://github.com/benzaita/dockerized-cli) - Seamlessly execute commands in a container. -- [Dray](https://github.com/CenturyLinkLabs/dray) - An engine for managing the execution of container-based workflows by [@CenturyLinkLabs][centurylinklabs] -- [FuGu](https://github.com/mattes/fugu) :skull: - Docker run wrapper without orchestration by [@mattes](https://github.com/mattes) -- [Hokusai](https://github.com/artsy/hokusai) - A Docker + Kubernetes CLI for application developers; used to containerize an application and to manage its lifecycle throughout development, testing, and release cycles. From [@artsy](https://github.com/artsy) -- [Preevy](https://github.com/livecycle/preevy) - Preview environments for Docker and Docker Compose projects. Test your changes and get feedback from devs and non-devs (Product/Design) by deploying pull requests to the your cloud provider as part of your CI pipeline. -- [Shutit](https://github.com/ianmiell/shutit) - Tool for building and maintaining complex Docker deployments by [@ianmiell](https://github.com/ianmiell) -- [subuser](https://github.com/subuser-security/subuser) - Makes it easy to securely and portably run graphical desktop applications in Docker -- [T.A.D.S. boilerplate](https://github.com/Thomvaill/tads-boilerplate) - :skull: The power of Ansible and Terraform + the simplicity of Docker Swarm = Infrastructure as Code and DevOps best practices. By [@Thomvaill](https://github.com/Thomvaill) -- [Terraform cloud-init config](https://github.com/christippett/terraform-cloudinit-container-server) - Terraform module for deploying a single Docker image or `docker-compose.yaml` file to any Cloud™ VM -- [Turbo](https://github.com/ramitsurana/turbo) - Simple and Powerful utility for docker. By [@ramitsurana][ramitsurana] -- [udocker](https://github.com/indigo-dc/udocker) - A tool to execute simple docker containers in batch or interactive systems without root privileges by [@inidigo-dc](https://github.com/indigo-dc) -- [Vagrant - Docker provider](https://developer.hashicorp.com/vagrant/docs/providers/docker/basics) - Good starting point is [vagrant-docker-example](https://github.com/bubenkoff/vagrant-docker-example) by [@bubenkoff](https://github.com/bubenkoff) +- [Ansible](https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html) - Manage the life cycle of Docker containers. By RedHat. +- [Azk](https://github.com/azukiapp/azk) - :skull: Orchestrate development environments on your local machine. +- [Beluga](https://github.com/cortexmedia/Beluga) - :skull: CLI to deploy docker containers on a single server or low amount of servers. By [@cortextmedia](https://github.com/cortexmedia). +- [dexec](https://github.com/docker-exec/dexec) - Command line interface written in Go for running code with Docker Exec images. +- [dockerized](https://github.com/benzaita/dockerized-cli) - Seamlessly execute commands in a container. +- [Dray](https://github.com/CenturyLinkLabs/dray) - An engine for managing the execution of container-based workflows. +- [FuGu](https://github.com/mattes/fugu) - :skull: Docker run wrapper without orchestration. +- [Hokusai](https://github.com/artsy/hokusai) - A Docker + Kubernetes CLI for application developers; used to containerize an application and to manage its lifecycle throughout development, testing, and release cycles. From [@artsy](https://github.com/artsy). +- [Preevy](https://github.com/livecycle/preevy) - Preview environments for Docker and Docker Compose projects. Test your changes and get feedback from devs and non-devs (Product/Design) by deploying pull requests to the your cloud provider as part of your CI pipeline. +- [Shutit](https://github.com/ianmiell/shutit) - Tool for building and maintaining complex Docker deployments. +- [subuser](https://github.com/subuser-security/subuser) - Makes it easy to securely and portably run graphical desktop applications in Docker. +- [T.A.D.S. boilerplate](https://github.com/Thomvaill/tads-boilerplate) - :skull: The power of Ansible and Terraform + the simplicity of Docker Swarm = Infrastructure as Code and DevOps best practices. By [@Thomvaill](https://github.com/Thomvaill). +- [Terraform cloud-init config](https://github.com/christippett/terraform-cloudinit-container-server) - Terraform module for deploying a single Docker image or `docker-compose.yaml` file to any Cloud™ VM. +- [Turbo](https://github.com/ramitsurana/turbo) - Simple and Powerful utility for docker. By [@ramitsurana][ramitsurana]. +- [udocker](https://github.com/indigo-dc/udocker) - A tool to execute simple docker containers in batch or interactive systems without root privileges. +- [Vagrant - Docker provider](https://developer.hashicorp.com/vagrant/docs/providers/docker/basics) - Good starting point is [vagrant-docker-example](https://github.com/bubenkoff/vagrant-docker-example). ## Services based on Docker (mostly :heavy_dollar_sign:) ### CI Services -- [CircleCI](https://circleci.com/) :heavy_dollar_sign: - Push or pull Docker images from your build environment, or build and run containers right on CircleCI. -- [CodeFresh](https://codefresh.io) :heavy_dollar_sign: - Everything you need to build, test, and share your Docker applications. Provides automated end to end testing. -- [CodeShip](https://www.cloudbees.com/products/codeship) :heavy_dollar_sign: - Work with your established Docker workflows while automating your testing and deployment tasks with our hosted platform dedicated to speed and security. -- [ConcourseCI](https://concourse-ci.org) :heavy_dollar_sign: - A CI SaaS platform for developers and DevOps teams pipeline oriented. +- [CircleCI](https://circleci.com/) - :heavy_dollar_sign: Push or pull Docker images from your build environment, or build and run containers right on CircleCI. +- [CodeFresh](https://codefresh.io) - :heavy_dollar_sign: Everything you need to build, test, and share your Docker applications. Provides automated end to end testing. +- [CodeShip](https://www.cloudbees.com/products/codeship) - :heavy_dollar_sign: Work with your established Docker workflows while automating your testing and deployment tasks with our hosted platform dedicated to speed and security. +- [ConcourseCI](https://concourse-ci.org) - :heavy_dollar_sign: A CI SaaS platform for developers and DevOps teams pipeline oriented. - [Semaphore CI](https://semaphore.io/) :heavy_dollar_sign: — A high-performance cloud solution that makes it easy to build, test and ship your containers to production. -- [TravisCI](https://www.travis-ci.com/) :heavy_dollar_sign: - A Free github projects continuous integration Saas platform for developers and Devops. +- [TravisCI](https://www.travis-ci.com/) - :heavy_dollar_sign: A Free github projects continuous integration Saas platform for developers and Devops. ### CaaS -- [Amazon ECS](https://aws.amazon.com/ecs/) :heavy_dollar_sign: - A management service on EC2 that supports Docker containers. -- [Appfleet](https://appfleet.com/) :heavy_dollar_sign: - Edge platform to deploy and manage containerized services globally. The system will route the traffic to the closest location for lower latency. -- [Azure AKS](https://azure.microsoft.com/en-us/products/kubernetes-service/) :heavy_dollar_sign: - Simplify Kubernetes management, deployment, and operations. Use a fully managed Kubernetes container orchestration service. -- [Cloud 66](https://www.cloud66.com) :heavy_dollar_sign: - Full-stack hosted container management as a service -- [Giant Swarm](https://www.giantswarm.io/) :heavy_dollar_sign: - Simple microservice infrastructure. Deploy your containers in seconds. -- [Google Container Engine](https://cloud.google.com/kubernetes-engine/docs/) :heavy_dollar_sign: - Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes]. -- [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) :heavy_dollar_sign: - Integrated platform for data and containers built on Apache Mesos by [@mesosphere](https://d2iq.com) -- [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) :heavy_dollar_sign: - Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud -- [Triton](https://www.joyent.com/) :heavy_dollar_sign: - Elastic container-native infrastructure by Joyent. -- [Virtuozzo Application Platform](https://www.virtuozzo.com/application-platform-partners/) :heavy_dollar_sign: - Deploy and manage your projects with turnkey PaaS across a wide network of reliable service providers +- [Amazon ECS](https://aws.amazon.com/ecs/) - :heavy_dollar_sign: A management service on EC2 that supports Docker containers. +- [Appfleet](https://appfleet.com/) - :heavy_dollar_sign: Edge platform to deploy and manage containerized services globally. The system will route the traffic to the closest location for lower latency. +- [Azure AKS](https://azure.microsoft.com/en-us/products/kubernetes-service/) - :heavy_dollar_sign: Simplify Kubernetes management, deployment, and operations. Use a fully managed Kubernetes container orchestration service. +- [Cloud 66](https://www.cloud66.com) - :heavy_dollar_sign: Full-stack hosted container management as a service. +- [Giant Swarm](https://www.giantswarm.io/) - :heavy_dollar_sign: Simple microservice infrastructure. Deploy your containers in seconds. +- [Google Container Engine](https://cloud.google.com/kubernetes-engine/docs/) - :heavy_dollar_sign: Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes]. +- [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) - :heavy_dollar_sign: Integrated platform for data and containers built on Apache Mesos. +- [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) - :heavy_dollar_sign: Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud. +- [Triton](https://www.joyent.com/) - :heavy_dollar_sign: Elastic container-native infrastructure by Joyent. +- [Virtuozzo Application Platform](https://www.virtuozzo.com/application-platform-partners/) - :heavy_dollar_sign: Deploy and manage your projects with turnkey PaaS across a wide network of reliable service providers. ### Monitoring Services -- [AppDynamics](https://github.com/Appdynamics/docker-monitoring-extension) - Docker Monitoring extension gathers metrics from the Docker Remote API, either using Unix Socket or TCP. -- [Better Stack](https://betterstack.com/community/guides/scaling-docker/) :heavy_dollar_sign: - A Docker-compatible observability stack that delivers robust log aggregation and uptime monitoring capabilities for various software application. -- [Broadcom Docker Monitoring](https://www.broadcom.com/info/aiops/docker-monitoring) :heavy_dollar_sign: - Agile Operations solutions from Broadcom deliver the modern Docker monitoring businesses need to accelerate and optimize the performance of microservices and the dynamic Docker environments running them. Monitor both the Docker environment and apps that run inside them. (former CA Technologies) +- [AppDynamics](https://github.com/Appdynamics/docker-monitoring-extension) - Docker Monitoring extension gathers metrics from the Docker Remote API, either using Unix Socket or TCP. +- [Better Stack](https://betterstack.com/community/guides/scaling-docker/) - :heavy_dollar_sign: A Docker-compatible observability stack that delivers robust log aggregation and uptime monitoring capabilities for various software application. +- [Broadcom Docker Monitoring](https://www.broadcom.com/info/aiops/docker-monitoring) - :heavy_dollar_sign: Agile Operations solutions from Broadcom deliver the modern Docker monitoring businesses need to accelerate and optimize the performance of microservices and the dynamic Docker environments running them. Monitor both the Docker environment and apps that run inside them. (former CA Technologies). - [Collecting docker logs and stats with Splunk](https://www.splunk.com/en_us/blog/tips-and-tricks/collecting-docker-logs-and-stats-with-splunk.html) -- [Datadog](https://www.datadoghq.com/) :heavy_dollar_sign: - Datadog is a full-stack monitoring service for large-scale cloud environments that aggregates metrics/events from servers, databases, and applications. It includes support for Docker, Kubernetes, and Mesos. -- [DockStat](https://github.com/its4nik/dockstat) :construction: - A full fletched (WIP) Docker management solution featuring plugin support and community integration by [its4nik](https://github.com/its4nik) -- [Prometheus](https://prometheus.io/) :heavy_dollar_sign: - Open-source service monitoring system and time series database -- [Site24x7](https://www.site24x7.com/docker-monitoring.html) :heavy_dollar_sign: - Docker Monitoring for DevOps and IT is a SaaS Pay per Host model -- [SPM for Docker](https://github.com/sematext/sematext-agent-docker) :heavy_dollar_sign: - Monitoring of host and container metrics, Docker events and logs. Automatic log parser. Anomaly Detection and alerting for metrics and logs. [@sematext](https://github.com/sematext) -- [Sysdig Monitor](https://www.sysdig.com/products/monitor) :heavy_dollar_sign: - Sysdig Monitor can be used as either software or a SaaS service to monitor, alert, and troubleshoot containers using system calls. It has container-specific features for Docker and Kubernetes. +- [Datadog](https://www.datadoghq.com/) - :heavy_dollar_sign: Datadog is a full-stack monitoring service for large-scale cloud environments that aggregates metrics/events from servers, databases, and applications. It includes support for Docker, Kubernetes, and Mesos. +- [DockStat](https://github.com/its4nik/dockstat) - :construction: A full fletched (WIP) Docker management solution featuring plugin support and community integration by [its4nik](https://github.com/its4nik). +- [Prometheus](https://prometheus.io/) - :heavy_dollar_sign: Open-source service monitoring system and time series database. +- [Site24x7](https://www.site24x7.com/docker-monitoring.html) - :heavy_dollar_sign: Docker Monitoring for DevOps and IT is a SaaS Pay per Host model. +- [SPM for Docker](https://github.com/sematext/sematext-agent-docker) - :heavy_dollar_sign: Monitoring of host and container metrics, Docker events and logs. Automatic log parser. Anomaly Detection and alerting for metrics and logs. [@sematext](https://github.com/sematext). +- [Sysdig Monitor](https://www.sysdig.com/products/monitor) - :heavy_dollar_sign: Sysdig Monitor can be used as either software or a SaaS service to monitor, alert, and troubleshoot containers using system calls. It has container-specific features for Docker and Kubernetes. # Useful Resources - **[Valuable Docker Links](http://nane.kratzke.pages.mylab.th-luebeck.de/about/blog/2014/08/24/valuable-docker-links/)** High quality articles about docker! **MUST SEE** - [Cloud Native Landscape](https://github.com/cncf/landscape) -- [Docker Blog](https://www.docker.com/blog/) - regular updates about Docker, the community and tools +- [Docker Blog](https://www.docker.com/blog/) - Regular updates about Docker, the community and tools. - [Docker Certification](https://intellipaat.com/docker-training-course/?US) :heavy_dollar_sign: will help you to will Learn Docker containerization, running Docker containers, Image creation, Dockerfile, Docker orchestration, security best practices, and more through hands-on projects and case studies and helps to clear Docker Certified Associate. -- [Docker dev bookmarks](https://www.codever.dev/search?q=docker) - use the tag [docker](https://www.codever.dev/bookmarks/t/docker) +- [Docker dev bookmarks](https://www.codever.dev/search?q=docker) - Use the tag [docker](https://www.codever.dev/bookmarks/t/docker). - [Docker in Action, Second Edition](https://www.manning.com/books/docker-in-action-second-edition) - [Docker in Practice, Second Edition](https://www.manning.com/books/docker-in-practice-second-edition) -- [Docker packaging guide for Python](https://pythonspeed.com/docker/) - a series of detailed articles on the specifics of Docker packaging for Python. +- [Docker packaging guide for Python](https://pythonspeed.com/docker/) - A series of detailed articles on the specifics of Docker packaging for Python. - [Learn Docker in a Month of Lunches](https://www.manning.com/books/learn-docker-in-a-month-of-lunches) -- [Learn Docker](https://coursesity.com/blog/best-docker-tutorials/) - Learn Docker - curated list of the top online docker tutorials and courses. +- [Learn Docker](https://coursesity.com/blog/best-docker-tutorials/) - Learn Docker - curated list of the top online docker tutorials and courses. - [Programming Community Curated Resources for learning Docker](https://hackr.io/tutorials/learn-docker) ## Awesome Lists -- [Awesome CI/CD](https://github.com/cicdops/awesome-ciandcd) - Not specific to docker but relevant. -- [Awesome Compose](https://github.com/docker/awesome-compose) - Docker Compose samples +- [Awesome CI/CD](https://github.com/cicdops/awesome-ciandcd) - Not specific to docker but relevant. +- [Awesome Compose](https://github.com/docker/awesome-compose) - Docker Compose samples. - [Awesome Kubernetes](https://github.com/ramitsurana/awesome-kubernetes) by [@ramitsurana][ramitsurana] - [Awesome Linux Container](https://github.com/Friz-zy/awesome-linux-containers) more general about container than this repo, by [@Friz-zy](https://github.com/Friz-zy). - [Awesome Selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted) list of Free Software network services and web applications which can be hosted locally by running in a classical way (setup local web server and run applications from there) or in a Docker container. By [@Kickball](https://github.com/Kickball) @@ -811,9 +811,9 @@ Services to securely store your Docker images. ## Good Tips - [Docker Caveats](http://docker-saigon.github.io/post/Docker-Caveats/) What You Should Know About Running Docker In Production (written 11 APRIL 2016) **MUST SEE** -- [Docker Containers on the Desktop](https://blog.jessfraz.com/post/docker-containers-on-the-desktop/) - The **funniest way** to learn about docker by [@jessfraz][jessfraz] who also gave a [presentation](https://www.youtube.com/watch?v=1qlLUf7KtAw) about it @ DockerCon 2015 +- [Docker Containers on the Desktop](https://blog.jessfraz.com/post/docker-containers-on-the-desktop/) - The **funniest way** to learn about docker by [@jessfraz][jessfraz] who also gave a [presentation](https://www.youtube.com/watch?v=1qlLUf7KtAw) about it @ DockerCon 2015. - [Docker vs. VMs? Combining Both for Cloud Portability Nirvana](https://www.flexera.com/blog/finops/) -- [Dockerfile best practices](https://github.com/hexops/dockerfile) - This repository has best-practices for writing Dockerfiles +- [Dockerfile best practices](https://github.com/hexops/dockerfile) - This repository has best-practices for writing Dockerfiles. - [Don't Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files](https://medium.com/@kinghuang/docker-compose-anchors-aliases-extensions-a1e4105d70bd) by [@King Chung Huang](https://github.com/kinghuang) - [GUI Apps with Docker](http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/) by [@fgrehm][fgrehm] diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 01c5beb..1e8bd48 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -91,7 +91,11 @@ func lintCmd() *cobra.Command { if !fix { return fmt.Errorf("lint failed with %d errors", result.Errors) } - fmt.Println("Auto-fix mode: --fix is not yet fully implemented for file rewriting") + count, err := linter.FixFile(readmePath) + if err != nil { + return fmt.Errorf("fix: %w", err) + } + fmt.Printf("Fixed %d lines in %s\n", count, readmePath) } else { fmt.Printf("OK: %d warnings\n", result.Warnings) } diff --git a/internal/linter/fixer.go b/internal/linter/fixer.go new file mode 100644 index 0000000..edb22e0 --- /dev/null +++ b/internal/linter/fixer.go @@ -0,0 +1,144 @@ +package linter + +import ( + "bufio" + "fmt" + "os" + "regexp" + "strings" + + "github.com/veggiemonk/awesome-docker/internal/parser" +) + +// attributionRe matches trailing author attributions like: +// +// by [@author](url), by [@author][ref], by @author +// +// Also handles "Created by", "Maintained by" etc. +var attributionRe = regexp.MustCompile(`\s+(?:(?:[Cc]reated|[Mm]aintained|[Bb]uilt)\s+)?by\s+\[@[^\]]+\](?:\([^)]*\)|\[[^\]]*\])\.?$`) + +// bareAttributionRe matches: by @author at end of line (no link). +var bareAttributionRe = regexp.MustCompile(`\s+by\s+@\w+\.?$`) + +// RemoveAttribution strips author attribution from a description string. +func RemoveAttribution(desc string) string { + desc = attributionRe.ReplaceAllString(desc, "") + desc = bareAttributionRe.ReplaceAllString(desc, "") + return strings.TrimSpace(desc) +} + +// FormatEntry reconstructs a markdown list line from a parsed Entry. +func FormatEntry(e parser.Entry) string { + desc := e.Description + var markers []string + for _, m := range e.Markers { + switch m { + case parser.MarkerAbandoned: + markers = append(markers, ":skull:") + case parser.MarkerPaid: + markers = append(markers, ":heavy_dollar_sign:") + case parser.MarkerWIP: + markers = append(markers, ":construction:") + } + } + if len(markers) > 0 { + desc = strings.Join(markers, " ") + " " + desc + } + return fmt.Sprintf("- [%s](%s) - %s", e.Name, e.URL, desc) +} + +// entryGroup tracks a consecutive run of entry lines. +type entryGroup struct { + startIdx int // index in lines slice + entries []parser.Entry +} + +// FixFile reads the README, fixes entries (capitalize, period, remove attribution, +// sort), and writes the result back. +func FixFile(path string) (int, error) { + f, err := os.Open(path) + if err != nil { + return 0, err + } + defer f.Close() + + var lines []string + scanner := bufio.NewScanner(f) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return 0, err + } + + // Identify entry groups (consecutive parsed entry lines) + var groups []entryGroup + var current *entryGroup + fixCount := 0 + + for i, line := range lines { + entry, err := parser.ParseEntry(line, i+1) + if err != nil { + // Not an entry — close any active group + if current != nil { + groups = append(groups, *current) + current = nil + } + continue + } + if current == nil { + current = &entryGroup{startIdx: i} + } + current.entries = append(current.entries, entry) + } + if current != nil { + groups = append(groups, *current) + } + + // Process each group: fix entries, sort, replace lines + for _, g := range groups { + var fixed []parser.Entry + for _, e := range g.entries { + f := FixEntry(e) + f.Description = RemoveAttribution(f.Description) + // Re-apply period after removing attribution (it may have been stripped) + if len(f.Description) > 0 && !strings.HasSuffix(f.Description, ".") { + f.Description += "." + } + fixed = append(fixed, f) + } + + sorted := SortEntries(fixed) + + for j, e := range sorted { + newLine := FormatEntry(e) + idx := g.startIdx + j + if lines[idx] != newLine { + fixCount++ + lines[idx] = newLine + } + } + } + + if fixCount == 0 { + return 0, nil + } + + // Write back + out, err := os.Create(path) + if err != nil { + return 0, err + } + defer out.Close() + + w := bufio.NewWriter(out) + for i, line := range lines { + w.WriteString(line) + if i < len(lines)-1 { + w.WriteString("\n") + } + } + // Preserve trailing newline if original had one + w.WriteString("\n") + return fixCount, w.Flush() +} diff --git a/internal/linter/fixer_test.go b/internal/linter/fixer_test.go new file mode 100644 index 0000000..ae37ef0 --- /dev/null +++ b/internal/linter/fixer_test.go @@ -0,0 +1,140 @@ +package linter + +import ( + "os" + "strings" + "testing" + + "github.com/veggiemonk/awesome-docker/internal/parser" +) + +func TestRemoveAttribution(t *testing.T) { + tests := []struct { + input string + want string + }{ + { + "Tool for managing containers by [@author](https://github.com/author)", + "Tool for managing containers", + }, + { + "Tool for managing containers by [@author][author]", + "Tool for managing containers", + }, + { + "Tool for managing containers by @author", + "Tool for managing containers", + }, + { + "Analyzes resource usage. Created by [@Google][google]", + "Analyzes resource usage.", + }, + { + "A tool by [@someone](https://example.com).", + "A tool", + }, + { + "step-by-step tutorial and more resources", + "step-by-step tutorial and more resources", + }, + { + "No attribution here", + "No attribution here", + }, + } + + for _, tt := range tests { + got := RemoveAttribution(tt.input) + if got != tt.want { + t.Errorf("RemoveAttribution(%q) = %q, want %q", tt.input, got, tt.want) + } + } +} + +func TestFormatEntry(t *testing.T) { + e := parser.Entry{ + Name: "Portainer", + URL: "https://github.com/portainer/portainer", + Description: "Management UI for Docker.", + } + got := FormatEntry(e) + want := "- [Portainer](https://github.com/portainer/portainer) - Management UI for Docker." + if got != want { + t.Errorf("FormatEntry = %q, want %q", got, want) + } +} + +func TestFormatEntryWithMarkers(t *testing.T) { + e := parser.Entry{ + Name: "OldTool", + URL: "https://github.com/old/tool", + Description: "A deprecated tool.", + Markers: []parser.Marker{parser.MarkerAbandoned}, + } + got := FormatEntry(e) + want := "- [OldTool](https://github.com/old/tool) - :skull: A deprecated tool." + if got != want { + t.Errorf("FormatEntry = %q, want %q", got, want) + } +} + +func TestFixFile(t *testing.T) { + content := `# Awesome Docker + +## Tools + +- [Zebra](https://example.com/zebra) - a tool by [@author](https://github.com/author) +- [Alpha](https://example.com/alpha) - another tool + +## Other + +Some text here. +` + tmp, err := os.CreateTemp("", "readme-*.md") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + if _, err := tmp.WriteString(content); err != nil { + t.Fatal(err) + } + tmp.Close() + + count, err := FixFile(tmp.Name()) + if err != nil { + t.Fatal(err) + } + + if count == 0 { + t.Fatal("expected fixes, got 0") + } + + data, err := os.ReadFile(tmp.Name()) + if err != nil { + t.Fatal(err) + } + result := string(data) + + // Check sorting: Alpha should come before Zebra + alphaIdx := strings.Index(result, "[Alpha]") + zebraIdx := strings.Index(result, "[Zebra]") + if alphaIdx > zebraIdx { + t.Error("expected Alpha before Zebra after sort") + } + + // Check capitalization + if !strings.Contains(result, "- A tool.") { + t.Errorf("expected capitalized description, got:\n%s", result) + } + + // Check attribution removed + if strings.Contains(result, "@author") { + t.Errorf("expected attribution removed, got:\n%s", result) + } + + // Check period added + if !strings.Contains(result, "Another tool.") { + t.Errorf("expected period added, got:\n%s", result) + } +} diff --git a/internal/linter/rules.go b/internal/linter/rules.go index 03bc1b2..3cf8f5b 100644 --- a/internal/linter/rules.go +++ b/internal/linter/rules.go @@ -47,7 +47,7 @@ func (i Issue) String() string { func CheckEntry(e parser.Entry) []Issue { var issues []Issue - if len(e.Description) > 0 && !unicode.IsUpper(rune(e.Description[0])) { + if first, ok := firstLetter(e.Description); ok && !unicode.IsUpper(first) { issues = append(issues, Issue{ Rule: RuleDescriptionCapital, Severity: SeverityError, @@ -106,13 +106,28 @@ func CheckDuplicates(entries []parser.Entry) []Issue { return issues } +// firstLetter returns the first unicode letter in s and true, or zero and false if none. +func firstLetter(s string) (rune, bool) { + for _, r := range s { + if unicode.IsLetter(r) { + return r, true + } + } + return 0, false +} + // FixEntry returns a copy of the entry with auto-fixable issues corrected. func FixEntry(e parser.Entry) parser.Entry { fixed := e if len(fixed.Description) > 0 { - // Capitalize first letter + // Capitalize first letter (find it, may not be at index 0) runes := []rune(fixed.Description) - runes[0] = unicode.ToUpper(runes[0]) + for i, r := range runes { + if unicode.IsLetter(r) { + runes[i] = unicode.ToUpper(r) + break + } + } fixed.Description = string(runes) // Ensure period at end diff --git a/internal/parser/parser.go b/internal/parser/parser.go index fdc0854..7fbb093 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -9,7 +9,11 @@ import ( ) // entryRe matches: - [Name](URL) - Description -var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s+-\s+(.+)$`) +// Also handles optional markers/text between URL and " - " separator, e.g.: +// +// - [Name](URL) :skull: - Description +// - [Name](URL) (2) :skull: - Description +var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)(.*?)\s+-\s+(.+)$`) // headingRe matches markdown headings: # Title, ## Title, etc. var headingRe = regexp.MustCompile(`^(#{1,6})\s+(.+?)(?:\s*)?$`) @@ -27,12 +31,15 @@ func ParseEntry(line string, lineNum int) (Entry, error) { return Entry{}, fmt.Errorf("line %d: not a valid entry: %q", lineNum, line) } - desc := m[3] + middle := m[3] // text between URL closing paren and " - " + desc := m[4] var markers []Marker + // Extract markers from both the middle section and the description for text, marker := range markerMap { - if strings.Contains(desc, text) { + if strings.Contains(middle, text) || strings.Contains(desc, text) { markers = append(markers, marker) + middle = strings.ReplaceAll(middle, text, "") desc = strings.ReplaceAll(desc, text, "") } } From 8956f1d29249fb78d4de1d541eb197d83cc24406 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:33:06 +0100 Subject: [PATCH 12/29] chore: remove Node.js tooling, update maintenance docs Remove package.json, build.js, tests/*.mjs, .nvmrc, and the old website template. Update MAINTENANCE.md with Go CLI commands. Switch dependabot from npm to gomod. Co-Authored-By: Claude Opus 4.6 --- .github/MAINTENANCE.md | 31 +- .github/dependabot.yml | 8 +- .nvmrc | 1 - build.js | 51 --- package-lock.json | 619 ------------------------------------- package.json | 30 -- tests/common.mjs | 108 ------- tests/exclude_in_test.json | 17 - tests/health_check.mjs | 206 ------------ tests/pull_request.mjs | 69 ----- tests/test_all.mjs | 127 -------- website/index.tmpl.html | 229 -------------- 12 files changed, 22 insertions(+), 1474 deletions(-) delete mode 100644 .nvmrc delete mode 100644 build.js delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 tests/common.mjs delete mode 100644 tests/exclude_in_test.json delete mode 100644 tests/health_check.mjs delete mode 100644 tests/pull_request.mjs delete mode 100644 tests/test_all.mjs delete mode 100644 website/index.tmpl.html diff --git a/.github/MAINTENANCE.md b/.github/MAINTENANCE.md index 5fe3268..2dfa90d 100644 --- a/.github/MAINTENANCE.md +++ b/.github/MAINTENANCE.md @@ -30,7 +30,7 @@ This guide helps maintainers keep the awesome-docker list up-to-date and high-qu 4. Remove projects that are truly abandoned/broken ### Quarterly Deep Dive (Every 3 months) -1. Run: `npm run health-check` for detailed report +1. Run: `./awesome-docker health` then `./awesome-docker report` for detailed report 2. Review project categories - are they still relevant? 3. Check for popular new Docker tools to add 4. Update documentation links if newer versions exist @@ -39,25 +39,34 @@ This guide helps maintainers keep the awesome-docker list up-to-date and high-qu 1. Remove all `:skull:` projects older than 1 year 2. Review CONTRIBUTING.md guidelines 3. Update year references in documentation -4. Check Node.js version requirements ## 🛠️ Maintenance Commands ```bash -# Test all links (requires GITHUB_TOKEN) -npm test +# Build the CLI +go build -o awesome-docker ./cmd/awesome-docker -# Test PR changes only -npm run test-pr +# Lint README formatting (add --fix to auto-fix) +./awesome-docker lint +./awesome-docker lint --fix -# Generate health report (requires GITHUB_TOKEN) -npm run health-check +# Check all links (requires GITHUB_TOKEN for GitHub repos) +./awesome-docker check + +# PR validation (lint + external link check) +./awesome-docker validate + +# Score repository health (requires GITHUB_TOKEN) +./awesome-docker health + +# Generate health report from cache +./awesome-docker report # Build the website -npm run build +./awesome-docker build -# Update dependencies -npm update +# Run tests +go test ./... ``` ## 📊 Quality Standards diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a409b84..0f049c8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,17 +1,13 @@ version: 2 updates: - # Enable version updates for npm - - package-ecosystem: "npm" - # Look for `package.json` and `lock` files in the `root` directory + # Enable version updates for Go modules + - package-ecosystem: "gomod" directory: "/" - # Check the npm registry for updates every day (weekdays) schedule: interval: "weekly" # Enable version updates for GitHub Actions - package-ecosystem: "github-actions" - # Workflow files stored in the default location of `.github/workflows` - # You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`. directory: "/" schedule: interval: "weekly" diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index b009dfb..0000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -lts/* diff --git a/build.js b/build.js deleted file mode 100644 index 898314a..0000000 --- a/build.js +++ /dev/null @@ -1,51 +0,0 @@ -const fs = require('fs-extra'); -const cheerio = require('cheerio'); -const showdown = require('showdown'); - -process.env.NODE_ENV = 'production'; - -const LOG = { - error: (...args) => console.error('❌ ERROR', { ...args }), - debug: (...args) => { - if (process.env.DEBUG) console.log('💡 DEBUG: ', { ...args }); - }, -}; -const handleFailure = (err) => { - LOG.error(err); - process.exit(1); -}; - -process.on('unhandledRejection', handleFailure); - -// --- FILES -const README = 'README.md'; -const WEBSITE_FOLDER = 'website'; -const indexTemplate = `${WEBSITE_FOLDER}/index.tmpl.html`; -const indexDestination = `${WEBSITE_FOLDER}/index.html`; - -async function processIndex() { - const converter = new showdown.Converter(); - converter.setFlavor('github'); - - try { - LOG.debug('Loading files...', { indexTemplate, README }); - const template = await fs.readFile(indexTemplate, 'utf8'); - const markdown = await fs.readFile(README, 'utf8'); - - LOG.debug('Merging files...'); - const $ = cheerio.load(template); - $('#md').append(converter.makeHtml(markdown)); - - LOG.debug('Writing index.html'); - await fs.outputFile(indexDestination, $.html(), 'utf8'); - LOG.debug('DONE 👍'); - } catch (err) { - handleFailure(err); - } -} - -async function main() { - await processIndex(); -} - -main(); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b41c74e..0000000 --- a/package-lock.json +++ /dev/null @@ -1,619 +0,0 @@ -{ - "name": "awesome-docker-website", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "awesome-docker-website", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "cheerio": "1.2.0", - "draftlog": "1.0.13", - "fs-extra": "11.3.3", - "node-fetch": "3.3.2", - "rimraf": "6.1.3", - "showdown": "^2.1.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", - "license": "MIT", - "dependencies": { - "jackspeak": "^4.2.3" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/cheerio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", - "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "encoding-sniffer": "^0.2.1", - "htmlparser2": "^10.1.0", - "parse5": "^7.3.0", - "parse5-htmlparser2-tree-adapter": "^7.1.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^7.19.0", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=20.18.1" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/draftlog": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/draftlog/-/draftlog-1.0.13.tgz", - "integrity": "sha512-GeMWOpXERBpfVDK6v7m0x1hPg8+g8ZsZWqJl2T17wHqrm4h8fnjiZmXcnCrmwogAc6R3YTxFXax15wezfuyCUw==", - "license": "MIT" - }, - "node_modules/encoding-sniffer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", - "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/glob": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", - "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.0", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/htmlparser2": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", - "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "entities": "^7.0.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/minimatch": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", - "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/showdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", - "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", - "license": "MIT", - "dependencies": { - "commander": "^9.0.0" - }, - "bin": { - "showdown": "bin/showdown.js" - }, - "funding": { - "type": "individual", - "url": "https://www.paypal.me/tiviesantos" - } - }, - "node_modules/undici": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.19.1.tgz", - "integrity": "sha512-Gpq0iNm5M6cQWlyHQv9MV+uOj1jWk7LpkoE5vSp/7zjb4zMdAcUD+VL5y0nH4p9EbUklq00eVIIX/XcDHzu5xg==", - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index f3faf18..0000000 --- a/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "awesome-docker-website", - "version": "1.0.0", - "description": "A curated list of Docker resources and projects Inspired by @sindresorhus and improved by amazing contributors", - "main": "build.js", - "scripts": { - "build": "rimraf ./dist/ && node build.js", - "test-pr": "node tests/pull_request.mjs", - "test": "node tests/test_all.mjs", - "health-check": "node tests/health_check.mjs" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/veggiemonk/awesome-docker.git" - }, - "author": "Julien Bisconti ", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/veggiemonk/awesome-docker/issues" - }, - "homepage": "https://github.com/veggiemonk/awesome-docker#readme", - "dependencies": { - "cheerio": "1.2.0", - "draftlog": "1.0.13", - "fs-extra": "11.3.3", - "node-fetch": "3.3.2", - "rimraf": "6.1.3", - "showdown": "^2.1.0" - } -} diff --git a/tests/common.mjs b/tests/common.mjs deleted file mode 100644 index 7afc01e..0000000 --- a/tests/common.mjs +++ /dev/null @@ -1,108 +0,0 @@ -import fetch from 'node-fetch'; -import { isRedirect } from 'node-fetch'; -import {readFileSync} from 'fs'; - -const LINKS_OPTIONS = { - redirect: 'manual', - headers: { - 'Content-Type': 'application/json', - 'user-agent': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', - }, - timeout: 60000, // 1m - signal: AbortSignal.timeout(60000), -}; - -const LOG = { - error: (...args) => console.error('❌ ERROR', args), - error_string: (...args) => - console.error('❌ ERROR', JSON.stringify({ ...args }, null, ' ')), - debug: (...args) => { - if (process.env.DEBUG) console.log('>>> DEBUG: ', { ...args }); - }, - debug_string: (...args) => { - if (process.env.DEBUG) - console.log('>>> DEBUG: ', JSON.stringify({ ...args }, null, ' ')); - }, -}; - -const handleFailure = (error) => { - console.error(`${error.message}: ${error.stack}`, { error }); - process.exit(1); -}; - -process.on('unhandledRejection', handleFailure); - -const extract_all_links = (markdown) => { - // if you have a problem and you try to solve it with a regex, - // now you have two problems - // TODO: replace this mess with a mardown parser ? - const re = /(((https:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w\-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/@\-\\\w]*))?)/g; - return markdown.match(re); -}; - -const find_duplicates = (arr) => { - const hm = {}; - const dup = []; - arr.forEach((e) => { - if (hm[e]) dup.push(e); - else hm[e] = true; - }); - return dup; -}; - -const partition = (arr, func) => { - const ap = [[], []]; - arr.forEach((e) => (func(e) ? ap[0].push(e) : ap[1].push(e))); - return ap; -}; - -async function fetch_link(url) { - try { - const { headers, ok, status, statusText } = await fetch(url, LINKS_OPTIONS); - const redirect = isRedirect(status) ? { redirect: { src: url, dst: headers.get("location") } } : {}; - return [url, { ok, status: statusText, ...redirect }]; - } catch (error) { - return [url, { ok: false, status: error.message }]; - } -} - -async function batch_fetch({ arr, get, post_filter_func, BATCH_SIZE = 8 }) { - const result = []; - /* eslint-disable no-await-in-loop */ - for (let i = 0; i < arr.length; i += BATCH_SIZE) { - const batch = arr.slice(i, i + BATCH_SIZE); - LOG.debug_string({ batch }); - let res = await Promise.all(batch.map(get)); - console.log(`batch fetched...${i + BATCH_SIZE}`); - res = post_filter_func ? res.filter(post_filter_func) : res; - LOG.debug_string({ res }); - result.push(...res); - } - return result; -} - -const data = readFileSync('./tests/exclude_in_test.json') -const exclude = JSON.parse(data) -const exclude_length = exclude.length; -const exclude_from_list = (link) => { - let is_excluded = false; - for (let i = 0; i < exclude_length; i += 1) { - if (link.startsWith(exclude[i])) { - is_excluded = true; - break; - } - } - return is_excluded; -}; - -export default { - LOG, - handleFailure, - extract_all_links, - find_duplicates, - partition, - fetch_link, - batch_fetch, - exclude_from_list, -}; diff --git a/tests/exclude_in_test.json b/tests/exclude_in_test.json deleted file mode 100644 index 099e764..0000000 --- a/tests/exclude_in_test.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - "https://vimeo.com", - "https://travis-ci.org/veggiemonk/awesome-docker.svg", - "https://github.com/apps/", - "https://twitter.com", - "https://www.meetup.com/", - "https://cycle.io/", - "https://www.manning.com/", - "https://deepfence.io", - "https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg", - "https://www.se-radio.net/2017/05/se-radio-episode-290-diogo-monica-on-docker-security", - "https://www.reddit.com/r/docker/", - "https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615", - "https://www.youtube.com/playlist", - "https://www.aquasec.com", - "https://cloudsmith.com" -] diff --git a/tests/health_check.mjs b/tests/health_check.mjs deleted file mode 100644 index cb5b4d3..0000000 --- a/tests/health_check.mjs +++ /dev/null @@ -1,206 +0,0 @@ -import fs from 'fs-extra'; -import fetch from 'node-fetch'; -import helper from './common.mjs'; - -const README = 'README.md'; -const GITHUB_GQL_API = 'https://api.github.com/graphql'; -const TOKEN = process.env.GITHUB_TOKEN || ''; - -if (!TOKEN) { - console.error('GITHUB_TOKEN environment variable is required'); - process.exit(1); -} - -const Authorization = `token ${TOKEN}`; - -const LOG = { - info: (...args) => console.log('ℹ️ ', ...args), - warn: (...args) => console.warn('⚠️ ', ...args), - error: (...args) => console.error('❌', ...args), -}; - -// Extract GitHub repos from links -const extract_repos = (arr) => - arr - .map((e) => e.substr('https://github.com/'.length).split('/')) - .filter((r) => r.length === 2 && r[1] !== ''); - -// Generate GraphQL query to check repo health -const generate_health_query = (repos) => { - const repoQueries = repos.map(([owner, name]) => { - const safeName = `repo_${owner.replace(/(-|\.)/g, '_')}_${name.replace(/(-|\.)/g, '_')}`; - return `${safeName}: repository(owner: "${owner}", name:"${name}"){ - nameWithOwner - isArchived - pushedAt - createdAt - stargazerCount - forkCount - isDisabled - isFork - isLocked - isPrivate - }`; - }).join('\n'); - - return `query REPO_HEALTH { ${repoQueries} }`; -}; - -// Batch repos into smaller chunks for GraphQL -function* batchRepos(repos, size = 50) { - for (let i = 0; i < repos.length; i += size) { - yield repos.slice(i, i + size); - } -} - -async function checkRepoHealth(repos) { - const results = { - archived: [], - stale: [], // No commits in 2+ years - inactive: [], // No commits in 1-2 years - healthy: [], - disabled: [], - total: repos.length, - }; - - const twoYearsAgo = new Date(); - twoYearsAgo.setFullYear(twoYearsAgo.getFullYear() - 2); - - const oneYearAgo = new Date(); - oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1); - - LOG.info(`Checking health of ${repos.length} repositories...`); - - for (const batch of batchRepos(repos)) { - const query = generate_health_query(batch); - const options = { - method: 'POST', - headers: { - Authorization, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ query }), - }; - - try { - const response = await fetch(GITHUB_GQL_API, options); - const data = await response.json(); - - if (data.errors) { - LOG.error('GraphQL errors:', data.errors); - continue; - } - - for (const [key, repo] of Object.entries(data.data)) { - if (!repo) continue; - - const pushedAt = new Date(repo.pushedAt); - const repoInfo = { - name: repo.nameWithOwner, - pushedAt: repo.pushedAt, - stars: repo.stargazerCount, - url: `https://github.com/${repo.nameWithOwner}`, - }; - - if (repo.isArchived) { - results.archived.push(repoInfo); - } else if (repo.isDisabled) { - results.disabled.push(repoInfo); - } else if (pushedAt < twoYearsAgo) { - results.stale.push(repoInfo); - } else if (pushedAt < oneYearAgo) { - results.inactive.push(repoInfo); - } else { - results.healthy.push(repoInfo); - } - } - } catch (error) { - LOG.error('Batch fetch error:', error.message); - } - - // Rate limiting - wait a bit between batches - await new Promise(resolve => setTimeout(resolve, 1000)); - } - - return results; -} - -function generateReport(results) { - const report = []; - - report.push('# 🏥 Awesome Docker - Health Check Report\n'); - report.push(`**Generated:** ${new Date().toISOString()}\n`); - report.push(`**Total Repositories:** ${results.total}\n`); - - report.push('\n## 📊 Summary\n'); - report.push(`- ✅ Healthy (updated in last year): ${results.healthy.length}`); - report.push(`- ⚠️ Inactive (1-2 years): ${results.inactive.length}`); - report.push(`- 🪦 Stale (2+ years): ${results.stale.length}`); - report.push(`- 📦 Archived: ${results.archived.length}`); - report.push(`- 🚫 Disabled: ${results.disabled.length}\n`); - - if (results.archived.length > 0) { - report.push('\n## 📦 Archived Repositories (Should mark as :skull:)\n'); - results.archived.forEach(repo => { - report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`); - }); - } - - if (results.stale.length > 0) { - report.push('\n## 🪦 Stale Repositories (No activity in 2+ years)\n'); - results.stale.slice(0, 50).forEach(repo => { - report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`); - }); - if (results.stale.length > 50) { - report.push(`\n... and ${results.stale.length - 50} more`); - } - } - - if (results.inactive.length > 0) { - report.push('\n## ⚠️ Inactive Repositories (No activity in 1-2 years)\n'); - report.push('_These may still be stable/complete projects - review individually_\n'); - results.inactive.slice(0, 30).forEach(repo => { - report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`); - }); - if (results.inactive.length > 30) { - report.push(`\n... and ${results.inactive.length - 30} more`); - } - } - - return report.join('\n'); -} - -async function main() { - const markdown = await fs.readFile(README, 'utf8'); - let links = helper.extract_all_links(markdown); - - const github_links = links.filter(link => - link.startsWith('https://github.com') && - !helper.exclude_from_list(link) && - !link.includes('/issues') && - !link.includes('/pull') && - !link.includes('/wiki') && - !link.includes('#') - ); - - const repos = extract_repos(github_links); - const results = await checkRepoHealth(repos); - - const report = generateReport(results); - - // Save report - await fs.writeFile('HEALTH_REPORT.md', report); - LOG.info('Health report saved to HEALTH_REPORT.md'); - - // Also print summary to console - console.log('\n' + report); - - // Exit with error if there are actionable items - if (results.archived.length > 0 || results.stale.length > 10) { - LOG.warn(`Found ${results.archived.length} archived and ${results.stale.length} stale repos`); - process.exit(1); - } -} - -console.log('Starting health check...'); -main(); diff --git a/tests/pull_request.mjs b/tests/pull_request.mjs deleted file mode 100644 index 9ad470d..0000000 --- a/tests/pull_request.mjs +++ /dev/null @@ -1,69 +0,0 @@ -import fs from 'fs-extra'; -import helper from './common.mjs'; - -console.log({ - DEBUG: process.env.DEBUG || false, -}); - -const README = 'README.md'; - -async function main() { - const has_error = { - show: false, - duplicates: '', - other_links_error: '', - }; - const markdown = await fs.readFile(README, 'utf8'); - let links = helper.extract_all_links(markdown); - links = links.filter((l) => !helper.exclude_from_list(l)); // exclude websites - helper.LOG.debug_string({ links }); - - console.log(`total links to check ${links.length}`); - - console.log('checking for duplicates links...'); - - const duplicates = helper.find_duplicates(links); - if (duplicates.length > 0) { - has_error.show = true; - has_error.duplicates = duplicates; - } - helper.LOG.debug_string({ duplicates }); - const [github_links, external_links] = helper.partition(links, (link) => - link.startsWith('https://github.com'), - ); - - console.log(`checking ${external_links.length} external links...`); - - const external_links_error = await helper.batch_fetch({ - arr: external_links, - get: helper.fetch_link, - post_filter_func: (x) => !x[1].ok, - BATCH_SIZE: 8, - }); - if (external_links_error.length > 0) { - has_error.show = true; - has_error.other_links_error = external_links_error; - } - - console.log(`checking ${github_links.length} GitHub repositories...`); - - console.log( - `skipping GitHub repository check. Run "npm run test" to execute them manually.`, - ); - - console.log({ - TEST_PASSED: !has_error.show, - EXTERNAL_LINKS: external_links.length, - }); - - if (has_error.show) { - helper.LOG.error_string(has_error); - process.exit(1); - } -} - -console.log('starting...'); -main().catch((error) => { - console.error('Fatal error:', error); - process.exit(1); -}); diff --git a/tests/test_all.mjs b/tests/test_all.mjs deleted file mode 100644 index 3130660..0000000 --- a/tests/test_all.mjs +++ /dev/null @@ -1,127 +0,0 @@ -import fs from 'fs-extra'; -import fetch from 'node-fetch'; -import helper from './common.mjs'; - -function envvar_undefined(variable_name) { - throw new Error(`${variable_name} must be defined`); -} - -console.log({ - DEBUG: process.env.DEBUG || false, -}); - -const README = 'README.md'; -const GITHUB_GQL_API = 'https://api.github.com/graphql'; -const TOKEN = process.env.GITHUB_TOKEN || envvar_undefined('GITHUB_TOKEN'); - -const Authorization = `token ${TOKEN}`; - -const make_GQL_options = (query) => ({ - method: 'POST', - headers: { - Authorization, - 'Content-Type': 'application/json', - 'user-agent': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', - }, - body: JSON.stringify({ query }), -}); - -const extract_repos = (arr) => - arr - .map((e) => e.substr('https://github.com/'.length).split('/')) - .filter((r) => r.length === 2 && r[1] !== ''); - -const generate_GQL_query = (arr) => - `query AWESOME_REPOS{ ${arr - .map( - ([owner, name]) => - `repo_${owner.replace(/(-|\.)/g, '_')}_${name.replace( - /(-|\.)/g, - '_', - )}: repository(owner: "${owner}", name:"${name}"){ nameWithOwner isArchived } `, - ) - .join('')} }`; - -async function main() { - const has_error = { - show: false, - duplicates: '', - other_links_error: '', - github_repos: '', - }; - const markdown = await fs.readFile(README, 'utf8'); - let links = helper.extract_all_links(markdown); - links = links.filter((l) => !helper.exclude_from_list(l)); // exclude websites - helper.LOG.debug_string({ links }); - - console.log(`total links to check ${links.length}`); - - console.log('checking for duplicates links...'); - - const duplicates = helper.find_duplicates(links); - if (duplicates.length > 0) { - has_error.show = true; - has_error.duplicates = duplicates; - } - helper.LOG.debug_string({ duplicates }); - const [github_links, external_links] = helper.partition(links, (link) => - link.startsWith('https://github.com'), - ); - - console.log(`checking ${external_links.length} external links...`); - - const external_links_error = await helper.batch_fetch({ - arr: external_links, - get: helper.fetch_link, - post_filter_func: (x) => !x[1].ok, - BATCH_SIZE: 8, - }); - if (external_links_error.length > 0) { - has_error.show = true; - has_error.other_links_error = external_links_error; - } - - console.log(`checking ${github_links.length} GitHub repositories...`); - - const repos = extract_repos(github_links); - const query = generate_GQL_query(repos); - const options = make_GQL_options(query); - const gql_response = await fetch(GITHUB_GQL_API, options).then((r) => - r.json(), - ); - if (gql_response.errors) { - has_error.show = true; - has_error.github_repos = gql_response.errors; - } - - // Check for archived repositories - console.log('checking for archived repositories...'); - const archived_repos = []; - if (gql_response.data) { - for (const [key, repo] of Object.entries(gql_response.data)) { - if (repo && repo.isArchived) { - archived_repos.push(repo.nameWithOwner); - } - } - } - if (archived_repos.length > 0) { - console.warn(`⚠️ Found ${archived_repos.length} archived repositories that should be marked with :skull:`); - console.warn('Archived repos:', archived_repos); - // Don't fail the build, just warn - } - - console.log({ - TEST_PASSED: has_error.show, - GITHUB_REPOSITORY: github_links.length, - EXTERNAL_LINKS: external_links.length, - }); - - if (has_error.show) { - helper.LOG.error_string(has_error); - process.exit(1); - } -} - -console.log('starting...'); -main(); diff --git a/website/index.tmpl.html b/website/index.tmpl.html deleted file mode 100644 index 94e88e0..0000000 --- a/website/index.tmpl.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - Awesome-docker - - - - - - - - - - - -
- - - - - From 8bb3147e4efbe3d43dfcad4b747b51c33eb99755 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:45:13 +0100 Subject: [PATCH 13/29] fix: prevent false link-check failures and harden health/workflow errors Address three review findings from the Go rewrite:\n\n- checker: update PartitionLinks to only classify HTTP(S) URLs as external links.\n This skips markdown-relative targets (for example and anchors) so\n non-URL entries are no longer sent to HTTP validation and do not produce\n deterministic "unsupported protocol scheme" failures.\n\n- health command: stop ignoring LoadHealthCache errors.\n Return a user-facing "load cache" error when the cache file is unreadable\n or invalid instead of allowing a nil cache panic on Merge.\n\n- broken links workflow: remove masked execution behavior from the link check\n step. Capture awesome-docker check exit code, set has_errors=true on any\n non-zero exit, and expose the exit code in the generated issue body so\n checker failures are visible and cannot incorrectly close the tracking issue.\n\nTest coverage updates:\n- extend checker partition test to include markdown-relative/anchor targets\n and verify they are not treated as external URLs.\n- add cache test for invalid YAML load failure. --- .github/workflows/broken_links.yml | 22 ++++++++++++++++------ cmd/awesome-docker/main.go | 5 ++++- internal/cache/cache_test.go | 16 ++++++++++++++++ internal/checker/github.go | 13 +++++++++++-- internal/checker/github_test.go | 2 ++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/.github/workflows/broken_links.yml b/.github/workflows/broken_links.yml index 678b89e..5cc6c77 100644 --- a/.github/workflows/broken_links.yml +++ b/.github/workflows/broken_links.yml @@ -25,12 +25,21 @@ jobs: - name: Run Link Check id: link_check run: | - ./awesome-docker check > link_check_output.txt 2>&1 || true - if grep -q "broken links" link_check_output.txt; then - echo "has_errors=true" >> "$GITHUB_OUTPUT" - else - echo "has_errors=false" >> "$GITHUB_OUTPUT" + set +e + ./awesome-docker check > link_check_output.txt 2>&1 + exit_code=$? + set -e + + has_errors=false + if [ "$exit_code" -ne 0 ]; then + has_errors=true fi + if grep -qi "broken links" link_check_output.txt; then + has_errors=true + fi + + echo "has_errors=$has_errors" >> "$GITHUB_OUTPUT" + echo "check_exit_code=$exit_code" >> "$GITHUB_OUTPUT" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -41,8 +50,9 @@ jobs: script: | const fs = require('fs'); const output = fs.readFileSync('link_check_output.txt', 'utf8'); + const exitCode = '${{ steps.link_check.outputs.check_exit_code }}'; - const issueBody = `# Broken Links Detected\n\nThe weekly link check found broken or inaccessible links.\n\n\`\`\`\n${output}\n\`\`\`\n\n## Action Required\n\n- Update the URL if the resource moved\n- Remove the entry if permanently unavailable\n- Add to \`config/exclude.yaml\` if a known false positive\n\n---\n*Auto-generated by broken_links.yml*`; + const issueBody = `# Broken Links Detected\n\nThe weekly link check found broken links or the checker failed to execute cleanly.\n\nChecker exit code: ${exitCode}\n\n\`\`\`\n${output}\n\`\`\`\n\n## Action Required\n\n- Update the URL if the resource moved\n- Remove the entry if permanently unavailable\n- Add to \`config/exclude.yaml\` if a known false positive\n- Investigate checker failures when exit code is non-zero\n\n---\n*Auto-generated by broken_links.yml*`; const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 1e8bd48..2a7b9eb 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -204,7 +204,10 @@ func healthCmd() *cobra.Command { scored := scorer.ScoreAll(infos) cacheEntries := scorer.ToCacheEntries(scored) - hc, _ := cache.LoadHealthCache(healthCachePath) + hc, err := cache.LoadHealthCache(healthCachePath) + if err != nil { + return fmt.Errorf("load cache: %w", err) + } hc.Merge(cacheEntries) if err := cache.SaveHealthCache(healthCachePath, hc); err != nil { return fmt.Errorf("save cache: %w", err) diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 03ec514..a868743 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -78,6 +78,22 @@ func TestLoadHealthCacheMissing(t *testing.T) { } } +func TestLoadHealthCacheInvalidYAML(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "health.yaml") + if err := os.WriteFile(path, []byte("entries:\n - url: [not yaml"), 0644); err != nil { + t.Fatal(err) + } + + hc, err := LoadHealthCache(path) + if err == nil { + t.Fatal("expected error for invalid YAML") + } + if hc != nil { + t.Fatal("expected nil cache on invalid YAML") + } +} + func TestMerge(t *testing.T) { hc := &HealthCache{ Entries: []HealthEntry{ diff --git a/internal/checker/github.go b/internal/checker/github.go index e1f1dac..146240e 100644 --- a/internal/checker/github.go +++ b/internal/checker/github.go @@ -3,6 +3,7 @@ package checker import ( "context" "fmt" + "net/url" "strings" "time" @@ -43,12 +44,20 @@ func ExtractGitHubRepo(url string) (owner, name string, ok bool) { return parts[0], parts[1], true } -// PartitionLinks separates URLs into GitHub repos and external links. +func isHTTPURL(raw string) bool { + u, err := url.Parse(raw) + if err != nil { + return false + } + return u.Scheme == "http" || u.Scheme == "https" +} + +// PartitionLinks separates URLs into GitHub repos and external HTTP(S) links. func PartitionLinks(urls []string) (github, external []string) { for _, url := range urls { if _, _, ok := ExtractGitHubRepo(url); ok { github = append(github, url) - } else { + } else if isHTTPURL(url) { external = append(external, url) } } diff --git a/internal/checker/github_test.go b/internal/checker/github_test.go index 7ac8fbe..8e751d0 100644 --- a/internal/checker/github_test.go +++ b/internal/checker/github_test.go @@ -41,6 +41,8 @@ func TestPartitionLinks(t *testing.T) { "https://example.com/tool", "https://github.com/moby/moby", "https://github.com/user/repo/issues", + "dozzle", + "#projects", } gh, ext := PartitionLinks(urls) if len(gh) != 2 { From 0bea35576a5701f69cd6c3c56ee9c4fc2e27e03a Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Fri, 27 Feb 2026 23:59:26 +0100 Subject: [PATCH 14/29] chore(readme): apply purge-archive archived-entry removals --- README.md | 51 --------------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/README.md b/README.md index acae942..48f2397 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [@vegasbrianc][vegasbrianc]. - [HertzBeat](https://github.com/dromara/hertzbeat) - An open-source real-time monitoring system with custom-monitor and agentless. - [InfluxDB, cAdvisor, Grafana](https://github.com/vegasbrianc/docker-monitoring) - InfluxDB Time series DB in combination with Grafana and cAdvisor. -- [LogJam](https://github.com/gocardless/logjam) - :skull: Logjam is a log forwarder designed to listen on a local port, receive log entries over UDP, and forward these messages on to a log collection server (such as logstash). - [Logspout](https://github.com/gliderlabs/logspout) - Log routing for Docker container logs. - [monit-docker](https://github.com/decryptus/monit-docker) - Monitor docker containers resources usage or status and execute docker commands or inside containers. [@decryptus][decryptus]. - [NexClipper](https://github.com/NexClipper/NexClipper) - NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes. @@ -248,14 +247,10 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Crane](https://github.com/Dataman-Cloud/crane) - Control plane based on docker built-in swarm [@Dataman-Cloud](https://github.com/Dataman-Cloud). - [Docker Flow Swarm Listener](https://github.com/docker-flow/docker-flow-swarm-listener) - Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [@docker-flow][docker-flow]. - [docker rollout](https://github.com/Wowu/docker-rollout) - Zero downtime deployment for Docker Compose services. -- [gantryd](https://github.com/DevTable/gantryd) - :skull: A framework for easy management of docker-based components across machines. - [Haven](https://github.com/codeabovelab/haven-platform) - Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [@codeabovelab](https://github.com/codeabovelab). -- [Helios](https://github.com/spotify/helios) - :skull: A simple platform for deploying and managing containers across an entire fleet of servers. - [Kontena](https://github.com/kontena/kontena) - :skull: The developer friendly container and micro services platform. Works on any cloud, easy to setup, simple to use. - [Kubernetes](https://github.com/kubernetes/kubernetes) - Open source orchestration system for Docker containers by Google. - [ManageIQ](https://github.com/ManageIQ/manageiq) - Discover, optimize and control your hybrid IT. By [ManageIQ](https://github.com/ManageIQ). -- [Mantl](https://github.com/mantl/mantl) - :skull: Mantl is a modern platform for rapidly deploying globally distributed services. -- [Marathon](https://github.com/mesosphere/marathon) - :skull: Marathon is a private PaaS built on Mesos. It automatically handles hardware or software failures and ensures that an app is "always on". - [Mesos](https://github.com/apache/mesos) - Resource/Job scheduler for containers, VM's and physical hosts [@apache](https://mesos.apache.org/). - [Nebula](https://github.com/nebula-orchestrator) - A Docker orchestration tool designed to manage massive scale distributed clusters. - [Nomad](https://github.com/hashicorp/nomad) - Easily deploy applications at any scale. A Distributed, Highly Available, Datacenter-Aware Scheduler. @@ -266,7 +261,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### PaaS -- [Atlantis](https://github.com/ooyala/atlantis) - :skull: Atlantis is an Open Source PaaS for HTTP applications built on Docker and written in Go. - [caprover](https://github.com/caprover/caprover) - [Previously known as CaptainDuckDuck] Automated Scalable Webserver Package (automated Docker+nginx) - Heroku on Steroids. - [Convox Rack](https://github.com/convox/rack) - Convox Rack is open source PaaS built on top of expert infrastructure automation and devops best practices. - [Dcw](https://github.com/pbertera/dcw) - Docker-compose SSH wrapper: a very poor man PaaS, exposing the docker-compose and custom-container commands defined in container labels. @@ -351,12 +345,8 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Volume Management / Data - [Blockbridge](https://github.com/blockbridge/blockbridge-docker-volume) :heavy_dollar_sign:- The Blockbridge plugin is a volume plugin that provides access to an extensible set of container-based persistent storage options. It supports single and multi-host Docker environments with features that include tenant isolation, automated provisioning, encryption, secure deletion, snapshots and QoS. By [@blockbridge](https://github.com/blockbridge) -- [Convoy](https://github.com/rancher/convoy) - :skull: An open-source Docker volume driver that can snapshot, backup and restore Docker volumes anywhere. By [@rancher][rancher]. -- [Docker Machine NFS](https://github.com/adlogix/docker-machine-nfs) - :skull: Activates NFS for an existing boot2docker box created through Docker Machine on OS X. -- [Docker Unison](https://github.com/leighmcculloch/docker-unison) - :skull: A docker volume container using Unison for fast two-way folder sync. Created as an alternative to slow boot2docker volumes on OS X. By [@leighmcculloch](https://github.com/leighmcculloch). - - [Label Backup](https://github.com/resulgg/label-backup) - A lightweight, Docker-aware backup agent that automatically discovers and backs up containerized databases (PostgreSQL, MySQL, MongoDB, Redis) based on Docker labels. Supports local storage and S3-compatible destinations with flexible scheduling via cron expressions. - [Docker Volume Backup](https://github.com/offen/docker-volume-backup) Backup Docker volumes locally or to any S3 compatible storage. By [@offen](https://github.com/offen) -- [Local Persist](https://github.com/MatchbookLab/local-persist) Specify a mountpoint for your local volumes (created via `docker volume create`) so that files will always persist and so you can mount to different directories in different containers. - [Minio](https://github.com/minio/minio) - S3 compatible object storage server in Docker containers. - [Netshare](https://github.com/ContainX/docker-volume-netshare) Docker NFS, AWS EFS, Ceph & Samba/CIFS Volume Plugin. By [@ContainX][containx] - [portworx](https://portworx.com) - :heavy_dollar_sign: Decentralized storage solution for persistent, shared and replicated volumes. @@ -371,7 +361,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - JetBrains IDEs (IntelliJ IDEA, GoLand, WebStorm, CLion etc.) has [built-in Docker plugin](https://www.jetbrains.com/help/idea/docker.html#managing-images) - Eclipse [Docker Tooling plugin](https://www.eclipse.org/community/eclipse_newsletter/2016/july/article2.php) - [denops-docker.vim](https://github.com/skanehira/denops-docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira]. -- [docker.vim](https://github.com/skanehira/docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira]. - [docker.el](https://github.com/Silex/docker.el) Manage docker from Emacs by [@Silex](https://github.com/Silex) #### Desktop @@ -380,16 +369,12 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [Docker DB Manager](https://github.com/AbianS/docker-db-manager) - Desktop app for managing Docker database containers with visual interface and one-click operations. - [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Official native app. Only for Windows and MacOS. -- [Dockeron](https://github.com/dockeron/dockeron) - :skull: A project built on Electron + Vue.js for Docker on desktop. [@fluency03](https://github.com/fluency03). -- [DockStation](https://github.com/DockStation/dockstation) - A developer centric UI to configure, monitor, and manage services and containers [@dock_station](https://twitter.com/dock_station). -- [Lifeboat](https://github.com/jplhomer/lifeboat) - :skull: An easy way to launch Docker projects with a graphical interface on your Mac. [@jplhomer](https://github.com/jplhomer). - [Simple Docker UI](https://github.com/felixgborrego/simple-docker-ui) - Built on Electron. By [@felixgborrego](https://github.com/felixgborrego/). - [Stevedore](https://github.com/slonopotamus/stevedore) - Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [@slonopotamus](https://github.com/slonopotamus). #### Terminal ##### Terminal UI -- [ctop (1)](https://github.com/yadutaf/ctop) - :skull: A command line / text based Linux Containers monitoring tool that works just like you expect (Python). - [ctop (2)](https://github.com/bcicen/ctop) - :skull: Top-like interface for container metrics (Golang). - [d4s](https://github.com/jr-k/d4s) - A fast, keyboard-driven terminal UI to manage Docker containers, Compose stacks, and Swarm services with the ergonomics of K9s. - [dive](https://github.com/wagoodman/dive) - A tool for exploring each layer in a docker image. By [wagoodman](https://github.com/wagoodman). @@ -398,7 +383,6 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [dockly](https://github.com/lirantal/dockly) - An interactive shell UI for managing Docker containers. - [DockMate](https://github.com/shubh-io/dockmate) - Lightweight terminal-based Docker and Podman manager with a text-based user interface,. - [DockSTARTer](https://github.com/GhostWriters/DockSTARTer) - DockSTARTer helps you get started with home server apps running in Docker by [GhostWriters](https://github.com/GhostWriters). -- [docui](https://github.com/skanehira/docui) - :skull: An interactive shell UI for managing Docker containers. Also works in Windows. By [@skanehira]. - [dprs](https://github.com/durableprogramming/dprs) - A developer-focused TUI for managing Docker containers with real-time log streaming and container management. Built with Rust. By [@durableprogramming](https://github.com/durableprogramming). - [dry](https://github.com/moncho/dry) - An interactive CLI for Docker containers. - [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box. @@ -420,7 +404,6 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [dockersql](https://github.com/crosbymichael/dockersql) - :skull: A command line interface to query Docker using SQL. - [DVM](https://github.com/howtowhale/dvm) - Docker version manager. - [goinside](https://github.com/iamsoorena/goinside) - Get inside a running docker container easily. -- [ns-enter](https://github.com/jpetazzo/nsenter) - :skull: No more ssh, enter name spaces of container. - [Pdocker](https://github.com/g31s/Pdocker) - A simple tool to manage and maintain Docker for personal projects. - [proco](https://github.com/shiwaforce/poco) - Proco will help you to organise and manage Docker, Docker-Compose, Kubernetes projects of any complexity using simple YAML config files to shorten the route from finding your project to initialising it in your local environment. - [reg](https://github.com/genuinetools/reg) - :skull: Docker registry v2 command line client. @@ -434,24 +417,19 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) - Search the Docker Registry with the Dext smart launcher. By [@vutran](https://github.com/vutran). - [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) - SSH Server for Docker containers ~ Because every container should be accessible. By [@jeroenpeeters](https://github.com/jeroenpeeters). -- [dockercraft](https://github.com/docker/dockercraft) - :skull: Docker + Minecraft = Dockercraft. - [dockerfile-mode](https://github.com/spotify/dockerfile-mode) An emacs mode for handling Dockerfiles by [@spotify][spotify] - [MultiDocker](https://github.com/marty90/multidocker) - Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. - [Powerline-Docker](https://github.com/adrianmo/powerline-docker) - A Powerline segment for showing the status of Docker containers. #### Web -- [Admiral](https://github.com/vmware/admiral) - :skull: Admiral™ is a highly scalable and very lightweight Container Management platform for deploying and managing container based applications. By [VMWare][vmware]. - [CASA](https://github.com/knrdl/casa) - Outsource the administration of a handful of containers to your co-workers,. - [Container Web TTY](https://github.com/wrfly/container-web-tty) - Connect your containers via a web-tty [@wrfly](https://github.com/wrfly). - [dockemon](https://github.com/ProductiveOps/dokemon) - Docker Container Management GUI. -- [Docker Compose UI](https://github.com/francescou/docker-compose-ui) - :skull: Manage docker-compose via HTTP. docker-compose-ui runs in a Docker container, mounts the hosts docker socket and exposes a RESTful API and AngularJS GUI. - [Docker Registry Browser](https://github.com/klausmeyer/docker-registry-browser) - Web Interface for the Docker Registry HTTP API v2. -- [Docker Registry UI](https://github.com/atcol/docker-registry-ui) - A web UI for easy private/local Docker Registry integration. - [Docker Registry UI (Joxit)](https://github.com/Joxit/docker-registry-ui) - :skull: The simplest and cleanest UI for private registries. - [docker-registry-web](https://github.com/mkuchin/docker-registry-web) - Web UI, authentication service and event recorder for private docker registry v2. - [docker-swarm-visualizer](https://github.com/dockersamples/docker-swarm-visualizer) - Visualizes Docker services on a Docker Swarm (for running demos). -- [dockering-on-rails](https://github.com/Electrofenster/dockerding-on-rails) - :skull: Simple Web-Interface for Docker with a lot of features. - [DockerSurfer](https://github.com/Simone-Erba/DockerSurfer) - :skull: A web service for analyze and browse dependencies between Docker images in the Docker registry,. - [dockge](https://github.com/louislam/dockge) - Easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. - [Komodo](https://github.com/mbecker20/komodo) - A tool to build and deploy software on many servers. @@ -486,7 +464,6 @@ Tools and applications that are either installed inside containers or designed t - [is-docker](https://github.com/sindresorhus/is-docker) - Check if the process is running inside a Docker container. - [lstags](https://github.com/ivanilves/lstags) - Sync Docker images across registries. - [microcheck](https://github.com/tarampampam/microcheck) - Lightweight health check utilities for Docker containers (75 KB instead of 9.3 MB for httpcheck versus cURL) in pure C - http(s), port checks, and parallel execution are included. -- [NVIDIA-Docker](https://github.com/NVIDIA/nvidia-docker) - :skull: The NVIDIA Container Runtime for Docker. - [Ofelia](https://github.com/mcuadros/ofelia/) - Ofelia is a modern and low footprint job scheduler for docker environments, built on Go. Ofelia aims to be a replacement for the old fashioned cron. Supports configuration from container labels and/or configuration files. - [SparkView](https://github.com/beyondssl/sparkview-container) - Access VMs, desktops, servers or applications anytime and from anywhere, without complex and costly client roll-outs or user management. - [su-exec](https://github.com/ncopa/su-exec) - This is a simple tool that will simply execute a program with different privileges. The program will be executed directly and not run as a child, like su and sudo does, which avoids TTY and signal issues. Why reinvent gosu? This does more or less exactly the same thing as gosu but it is only 10kb instead of 1.8MB. By [ncopa](https://github.com/ncopa). @@ -502,7 +479,6 @@ Applications designed to help or simplify building **new** images - [buildah](https://github.com/containers/buildah) - A tool that facilitates building OCI images. - [BuildKit](https://github.com/moby/buildkit) - Concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit. - [cekit](https://github.com/cekit/cekit) - A tool used by openshift to build base images using different build engines. -- [container-diff](https://github.com/GoogleContainerTools/container-diff) - :skull: An image tool for comparing and analyzing container images. - [container-factory](https://github.com/mutable/container-factory) - Produces Docker images from tarballs of application source code. - [copy-docker-image](https://github.com/mdlavin/copy-docker-image) - Copy a Docker image between registries without a full Docker installation. - [Derrick](https://github.com/alibaba/derrick) - A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [@alibaba](https://github.com/alibaba). @@ -511,22 +487,18 @@ Applications designed to help or simplify building **new** images - [docker-make](https://github.com/CtripCloud/docker-make) - Build, tag,and push a bunch of related docker images via a single command. - [docker-repack](https://github.com/orf/docker-repack) - Repacks a Docker image into a smaller, more efficient version that makes it significantly faster to pull. By [orf](https://github.com/orf). - [docker-replay](https://github.com/bcicen/docker-replay) - Generate `docker run`command and options from running containers. By [bcicen](https://github.com/bcicen). -- [DockerMake](https://github.com/avirshup/DockerMake) - A reproducible Docker image build system for complex software stacks. By [@avirshup](https://github.com/avirshup). - [DockerSlim](https://github.com/docker-slim/docker-slim) shrinks fat Docker images creating the smallest possible images. - [Dockly](https://github.com/swipely/dockly) - Dockly is a gem made to ease the pain of packaging an application in Docker. - [dockramp](https://github.com/jlhawn/dockramp) - :skull: Proof of Concept: A Client Driven Docker Image Builder. - [essex](https://github.com/utensils/essex) - Boilerplate for Docker Based Projects: Essex is a CLI utility written in bash to quickly setup clean and consistent Docker projects with Makefile driven workflows. [@jamesbrink](https://github.com/jamesbrink). - [HPC Container Maker](https://github.com/NVIDIA/hpc-container-maker) - Generates Dockerfiles from a high level Python recipe, including building blocks for High-Performance Computing components. - [img](https://github.com/genuinetools/img) - Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder. -- [kaniko](https://github.com/GoogleContainerTools/kaniko) - Build Container Images In Kubernetes. By [@GoogleContainerTools][googlecontainertools]. -- [makisu](https://github.com/uber/makisu) - :skull: Uber's fast and flexible unprivileged image builder for Mesos and Kubernetes, with distributed cache support. By [@uber](https://github.com/uber). - [packer](https://developer.hashicorp.com/packer/integrations/hashicorp/docker/latest/components/builder/docker) - Hashicorp tool to build machine images including docker image integrated with configuration management tools like chef, puppet, ansible. - [portainer](https://github.com/duedil-ltd/portainer) - Apache Mesos framework for building Docker images. - [Production-Ready Python Containers :heavy_dollar_sign:](https://pythonspeed.com/products/pythoncontainer/) - A template for creating production-ready Docker images for Python applications. - [RAUDI](https://github.com/cybersecsi/RAUDI) - A tool to automatically update (and optionally push to Docker Hub) Docker Images for 3rd party software whenever theres is a new release/update/commit. By [@SecSI](https://github.com/cybersecsi). - [runlike](https://github.com/lavie/runlike) - Generate `docker run`command and options from running containers. - [SkinnyWhale](https://github.com/djosephsen/skinnywhale) - :skull: Skinnywhale helps you make smaller (as in megabytes) Docker containers. -- [Smith](https://github.com/oracle/smith) - :skull: A Micocontainer Builder and can perform multi-stage builds after the image is built [Oracle][oracle]. - [userdef](https://github.com/theAkito/userdef) - An advanced `adduser` for your Alpine based Docker images. Made by [Akito][akito]. - [Whaler](https://github.com/P3GLEG/Whaler) - Program to reverse Docker images into Dockerfiles. - [Whales](https://github.com/Gueils/whales) - A tool to automatically dockerize your applications. @@ -538,7 +510,6 @@ Applications designed to help or simplify building **new** images - [Dockerfile Project](https://dockerfile.github.io/) - Trusted Automated Docker Builds. Dockerfile Project maintains a central repository of Dockerfile for various popular open source software services runnable on a Docker container. - [dockerfilegraph](https://github.com/patrickhoefler/dockerfilegraph) - Visualize your multi-stage Dockerfiles. By [@PatrickHoefler](https://github.com/patrickhoefler). - [Dockershelf](https://github.com/Dockershelf/dockershelf) - A repository that serves as a collector for docker recipes that are universal, efficient and slim. Images are updated, tested and published daily via a Travis cron job. -- [dockmoor](https://github.com/MeneDev/dockmoor) - :skull: Manage docker image references and help to create reproducible builds with Docker. By [@MeneDev](https://github.com/MeneDev). - [Vektorcloud](https://github.com/vektorcloud) - A collection of minimal, Alpine-based Docker images. Examples by: @@ -561,7 +532,6 @@ Examples by: - [dockfmt](https://github.com/jessfraz/dockfmt) - :construction: Dockerfile formatter and parser. - [FROM:latest](https://github.com/replicatedhq/dockerfilelint) - An opinionated Dockerfile linter. - [Hadolint](https://github.com/hadolint/hadolint) - A Dockerfile linter that checks for best practices, common mistakes, and is also able to lint any bash written in `RUN` instructions;. -- [Whale-linter](https://github.com/jeromepin/whale-linter) - :skull: A simple and small Dockerfile linter written in Python3+ without dependencies. ### Metadata @@ -602,27 +572,21 @@ Services to securely store your Docker images. ### API Client - [ahab](https://github.com/instacart/ahab) - Docker event handling with Python. -- [clj-docker-client](https://github.com/into-docker/clj-docker-client) - :skull: Idiomatic Clojure client for the Docker remote API. By [@lispyclouds][lispyclouds]. - [contajners](https://github.com/lispyclouds/contajners) - An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [@lispyclouds][lispyclouds]. - [Docker Client for JVM](https://github.com/gesellix/docker-client) - A Docker remote api client library for the JVM, written in Groovy. - [Docker Client TypeScript](https://gitlab.com/masaeedu/docker-client) - Docker API client for JavaScript, automatically generated from Swagger API definition from moby repository. By [@masaeedu](https://github.com/masaeedu). -- [docker-client](https://github.com/spotify/docker-client) - :skull: Java client for the Docker remote API. By [@spotify][spotify]. - [docker-controller-bot](https://github.com/dgongut/docker-controller-bot) - Telegram bot to control docker containers. By [@dgongut](https://github.com/dgongut/). - [docker-it-scala](https://github.com/whisklabs/docker-it-scala) - Docker integration testing kit with Scala. - [docker-java-api](https://github.com/amihaiemil/docker-java-api) - Lightweight, truly object-oriented, Java client for Docker's API. By [@amihaiemil](https://github.com/amihaiemil). - [docker-maven-plugin](https://github.com/fabric8io/docker-maven-plugin) - A Maven plugin for running and creating Docker images. -- [Docker-PowerShell](https://github.com/Microsoft/Docker-PowerShell) - :skull: PowerShell Module for Docker. - [Docker.DotNet](https://github.com/Microsoft/Docker.DotNet) - C#/.NET HTTP client for the Docker remote API. - [Docker.Registry.DotNet](https://github.com/ChangemakerStudios/Docker.Registry.DotNet) - .NET (C#) Client Library for interacting with a Docker Registry API (v2) [@rquackenbush](https://github.com/rquackenbush). -- [dockerfile-maven](https://github.com/spotify/dockerfile-maven) - :skull: A Maven plugin for building and pushing Docker images. - [dockerode](https://github.com/apocas/dockerode) - Docker Remote API node.js module. - [DoMonit](https://github.com/eon01/DoMonit) - A simple Docker Monitoring wrapper For Docker API. - [go-dockerclient](https://github.com/fsouza/go-dockerclient/) - Go HTTP client for the Docker remote API. - [Gradle Docker plugin](https://github.com/gesellix/gradle-docker-plugin) - A Docker remote api plugin for Gradle. -- [libcompose](https://github.com/docker/libcompose) - :skull: Go library for Docker Compose. - [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - :construction: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [@greenled](https://github.com/greenled). - [sbt-docker](https://github.com/marcuslonnberg/sbt-docker) - Create Docker images directly from sbt. -- [sbt-docker-compose](https://github.com/Tapad/sbt-docker-compose) - :skull: Integrates Docker Compose functionality into sbt. ### CI/CD @@ -638,7 +602,6 @@ Services to securely store your Docker images. - [Drydock](https://github.com/CodesWhat/drydock) - Open-source container update monitoring with web dashboard, 15 registries, 16 notification triggers, and security scanning. Drop-in WUD replacement. By [@CodesWhat](https://github.com/CodesWhat). - [Gantry](https://github.com/shizunge/gantry) - Automatically update selected Docker swarm services. - [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) - GitLab has integrated CI to test, build and deploy your code with the use of GitLab runners. -- [GOCD-Docker](https://github.com/gocd/gocd-docker) - :skull: Go Server and Agent in docker containers to provision. - [Jaypore CI](https://github.com/theSage21/jaypore_ci) - Simple, very flexible, powerful CI / CD / automation system configured in Python. Offline and local first. - [Kraken CI](https://github.com/Kraken-CI/kraken) - Modern CI/CD, open-source, on-premise system that is highly scalable and focused on testing. One of its executors is Docker. Developed. - [Microservices Continuous Deployment](https://github.com/francescou/docker-continuous-deployment) - Continuous deployment of a microservices application. @@ -653,30 +616,21 @@ Services to securely store your Docker images. ### Development Environment -- [batect](https://github.com/batect/batect) - :skull: Build and testing environments as code tool: Dockerised build and testing environments made easy. - [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [@TechnologyAdvice](https://github.com/TechnologyAdvice)). -- [Boot2Docker](https://github.com/boot2docker/boot2docker) - :skull: Docker for OSX and Windows. - [coder](https://github.com/coder/coder) - Remote development machines powered by Terraform or Docker. - [construi](https://github.com/lstephen/construi) - Run your builds inside a Docker defined environment. -- [Crashcart](https://github.com/oracle/crashcart) - :skull: Sideload Linux binaries into a running container for troubleshooting. - [dde](https://github.com/whatwedo/dde) - :construction: Local development environment toolset based on Docker. By [@whatwedo](https://github.com/whatwedo). -- [Devstep](https://github.com/fgrehm/devstep) - :skull: Development environments powered by Docker and buildpacks. -- [Dinghy](https://github.com/codekitchen/dinghy) - :skull: An alternative way to use Docker on Mac OS X using Docker Machine with virtualbox, vmware, xhyve or parallels. - [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [@bibendi](https://github.com/bibendi). - [DLite](https://github.com/nlf/dlite) - :skull: Simplest way to use Docker on OSX, no VM needed. By [@nlf](https://github.com/nlf). - [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [@dnephin](https://github.com/dnephin). - [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [@NandoQuintana](https://github.com/nandoquintana). -- [Docker osx dev](https://github.com/brikis98/docker-osx-dev) - :skull: A productive development environment with Docker on OS X. - [Docker-Arch](https://github.com/Ph3nol/Docker-Arch) - Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [@Ph3nol](https://github.com/ph3nol). - [Docker-sync](https://github.com/EugenMayer/docker-sync) - Drastically improves performance ([50-70x](https://github.com/EugenMayer/docker-sync/wiki/4.-Performance)) when using Docker for development on Mac OS X/Windows and Linux while sharing code to the container. By [@EugenMayer](https://github.com/EugenMayer). - [docker-vm](https://github.com/shyiko/docker-vm) - Simple and transparent alternative to boot2docker (backed by Vagrant). -- [DockerBuildManagement](https://github.com/DIPSAS/DockerBuildManagement) - :skull: Build Management is a python application, installed with pip. The application makes it easy to manage a build system based on Docker by configuring a single yaml file describing how to build, test, run or publish a containerized solution. - [DockerDL](https://github.com/matifali/dockerdl) - Deep Learning Docker Images. Don't waste time setting up a deep learning env when you can get a deep learning environment with everything pre-installed. -- [Dusty](https://github.com/gamechanger/dusty) - :skull: Managed Docker development environments on OS X. - [Eclipse Che](https://github.com/eclipse/che) - Developer workspace server with Docker runtimes, cloud IDE, next-generation Eclipse IDE. - [EnvCLI](https://github.com/EnvCLI/EnvCLI) - Replace your local installation of Node, Go, ... with project-specific docker containers. By [@EnvCLI](https://github.com/EnvCLI). - [ESP32 Linux - Docker builder](https://github.com/hpsaturn/esp32s3-linux) - Container solution to compile Linux and develop it for ESP32 microcontrollers - By [@Hpsaturn](https://github.com/hpsaturn). -- [footloose](https://github.com/weaveworks/footloose) - :skull: Spin containers that look like Virtual Machines - By [@dlespiau](https://github.com/dlespiau). - [forward2docker](https://github.com/bsideup/forward2docker) - :skull: Utility to auto forward a port from localhost into ports on Docker containers running in a boot2docker VM. - [Gebug](https://github.com/moshebe/gebug) - A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. - [Kitt](https://github.com/senges/kitt) - A portable and disposable Shell environment, based on Docker and Nix. By [@senges](https://github.com/senges). @@ -690,19 +644,14 @@ Services to securely store your Docker images. - [caduc](https://github.com/tjamet/caduc) - A docker garbage collector cleaning stuff you did not use recently. - [Docker Clean](https://github.com/ZZROTDesign/docker-clean) - A script that cleans Docker containers, images and volumes. -- [Docker-cleanup](https://github.com/meltwater/docker-cleanup) - :skull: Automatic Docker image, container and volume cleanup. - [docker-custodian](https://github.com/Yelp/docker-custodian) - Keep docker hosts tidy. By [@Yelp](https://github.com/Yelp). -- [docker-garby](https://github.com/konstruktoid/docker-garby) - :skull: Docker garbage collection script. -- [docker-gc](https://github.com/spotify/docker-gc) - :skull: A cron job that will delete old stopped containers and unused images. - [docker_gc](https://github.com/pdacity/docker_gc) - Image for automatic removing unused Docker Swarm objects. Also works just as Docker Service. - [Docuum](https://github.com/stepchowfun/docuum) - Least recently used (LRU) eviction of Docker images. -- [sherdock](https://github.com/rancher/sherdock) - :skull: Automatic GC of images based on regexp. ### Serverless - [AMP](https://github.com/appcelerator-archive/amp) - :skull: The open source unified CaaS/FaaS platform for Docker, batteries included. By [@Appcelerator](https://github.com/appcelerator-archive). - [Apache OpenWhisk](https://github.com/apache/openwhisk) - A serverless, open source cloud platform that executes functions in response to events at any scale. By [@apache](https://github.com/apache). -- [Docker-Lambda](https://github.com/lambci/docker-lambda) - :skull: Docker images and test runners that replicate the live AWS Lambda environment. By [@lamb-ci](https://github.com/lambci). - [Funker](https://github.com/bfirsh/funker-example-voting-app) - Functions as Docker containers example voting app. By [@bfirsh](https://github.com/bfirsh). - [IronFunctions](https://github.com/iron-io/functions) - The serverless microservices platform FaaS (Functions as a Service) which uses Docker containers to run Any language or AWS Lambda functions. - [Koyeb](https://www.koyeb.com/) - :heavy_dollar_sign: Koyeb is a developer-friendly serverless platform to deploy apps globally. Seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. From 0f00303939fdfb906d472d10958136bff91b2bf4 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:02:21 +0100 Subject: [PATCH 15/29] style(readme): sync purge-archive cleanup conventions --- README.md | 357 +++++++++++++++++++++++------------------------------- 1 file changed, 150 insertions(+), 207 deletions(-) diff --git a/README.md b/README.md index 48f2397..801a47d 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,6 @@ All the links are monitored and tested with a home baked [Node.js script](https: - [Videos](#videos) - [Communities and Meetups](#communities-and-meetups) - [Brazilian](#brazilian) - - [Chinese](#chinese) - [English](#english) - [Russian](#russian) - [Spanish](#spanish) @@ -82,7 +81,6 @@ All the links are monitored and tested with a home baked [Node.js script](https: # Legend -- Abandoned :skull: - Beta :construction: - Monetized :heavy_dollar_sign: @@ -107,24 +105,23 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Dockerlings](https://github.com/furkan/dockerlings): Learn docker from inside your terminal, with a modern TUI and bite sized exercises (by [furkan](https://github.com/furkan)) - [Introduction à Docker](https://blog.stephane-robert.info/docs/conteneurs/moteurs-conteneurs/docker/) A dedicated section to master Docker on a French site about DevSecOps: From the basics to best practices, including optimizing, securing your containers... -- [Learn Docker](https://github.com/dwyl/learn-docker): step-by-step tutorial and more resources (video, articles, cheat sheets) by [@dwyl](https://github.com/dwyl) +- [Learn Docker](https://github.com/dwyl/learn-docker): step-by-step tutorial and more resources (video, articles, cheat sheets) by [dwyl](https://github.com/dwyl) - [Learn Docker (Visually)](https://pagertree.com/learn/docker/overview) - A beginner-focused high-level overview of all the major components of Docker and how they fit together. Lots of high-quality images, examples, and resources. - [Play With Docker](https://training.play-with-docker.com/): PWD is a great way to get started with Docker from beginner to advanced users. Docker runs directly in your browser. - [Practical Guide about Docker Commands in Spanish](https://github.com/brunocascio/docker-espanol) This Spanish guide contains the use of basic docker commands with real life examples. - [Setting Python Development Environment with VScode and Docker](https://github.com/RamiKrispin/vscode-python): A step-by-step tutorial for setting up a dockerized Python development environment with VScode, Docker, and the Dev Container extension. - [The Docker Handbook](https://docker-handbook.farhan.dev/) An open-source book that teaches you the fundamentals, best practices and some intermediate Docker functionalities. The book is hosted on [fhsinchy/the-docker-handbook](https://github.com/fhsinchy/the-docker-handbook) and the projects are hosted on [fhsinchy/docker-handbook-projects](https://github.com/fhsinchy/docker-handbook-projects) repository. - **Cheatsheets** by -- [@eon01](https://github.com/eon01/DockerCheatSheet) -- [@dimonomid](https://github.com/dimonomid/docker-quick-ref) (PDF) -- [@JensPiegsa](https://github.com/JensPiegsa/docker-cheat-sheet) -- [@wsargent](https://github.com/wsargent/docker-cheat-sheet) (Most popular) +- [eon01](https://github.com/eon01/DockerCheatSheet) +- [dimonomid](https://github.com/dimonomid/docker-quick-ref) (PDF) +- [JensPiegsa](https://github.com/JensPiegsa/docker-cheat-sheet) +- [wsargent](https://github.com/wsargent/docker-cheat-sheet) (Most popular) # Where to start (Windows) -- [Docker on Windows behind a firewall](https://toedter.com/2015/05/11/docker-on-windows-behind-a-firewall/) by [@kaitoedter](https://twitter.com/kaitoedter) +- [Docker on Windows behind a firewall](https://toedter.com/2015/05/11/docker-on-windows-behind-a-firewall/) by [kaitoedter](https://twitter.com/kaitoedter) - [Docker Reference Architecture: Modernizing Traditional .NET Framework Applications](https://docs.mirantis.com/containers/v3.0/dockeree-ref-arch/app-dev/modernize-dotnet-apps.html) - You will learn to identify the types of .NET Framework applications that are good candidates for containerization, the "lift-and-shift" approach to containerization. - [Docker with Microsoft SQL 2016 + ASP.NET](https://blog.alexellis.io/docker-does-sql2016-aspnet/) Demonstration running ASP.NET and SQL Server workloads in Docker - [Exploring ASP.NET Core with Docker in both Linux and Windows Containers](https://www.hanselman.com/blog/exploring-aspnet-core-with-docker-in-both-linux-and-windows-containers) Running ASP.NET Core apps in Linux and Windows containers, using [Docker for Windows][docker-for-windows] @@ -145,55 +142,38 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Moby](https://github.com/moby/moby) - [Docker Images](https://hub.docker.com) - [Docker Compose](https://github.com/docker/compose/) (Define and run multi-container applications with Docker) -- [Docker Machine](https://github.com/docker/machine) :skull: (Machine management for a container-centric world) - [Docker Registry][distribution] (The Docker toolset to pack, ship, store, and deliver content) -- [Docker Swarm](https://github.com/docker/swarm) :skull: (Swarm: a Docker-native clustering system) ## Container Operations ### Container Composition -- [bocker](https://github.com/icy/bocker) - :skull: Write Dockerfile completely in Bash. Extensible and simple. --> Reusable. -- [bocker](https://github.com/p8952/bocker) - :skull: Docker implemented in 100 lines of bash by [p8952](https://github.com/p8952). -- [box](https://github.com/box-builder/box) - :skull: Build Dockerfile images with a mruby DSL, includes flattening and layer manipulation. -- [Capitan](https://github.com/byrnedo/capitan) - Composable docker orchestration with added scripting support by [@byrnedo]. -- [compose_plantuml](https://github.com/funkwerk/compose_plantuml) - :skull: Generate Plantuml graphs from docker-compose files. +- [Capitan](https://github.com/byrnedo/capitan) - Composable docker orchestration with added scripting support by [byrnedo]. - [Composerize](https://github.com/magicmark/composerize) - Convert docker run commands into docker-compose files. - [crowdr](https://github.com/polonskiy/crowdr) - Tool for managing multiple Docker containers (`docker-compose` alternative). -- [ctk](https://github.com/ctk-hq/ctk) - :construction: Visual composer for container based workloads. By [@corpulent](https://github.com/corpulent). -- [docker-compose-graphviz](https://github.com/abesto/docker-compose-graphviz) - :skull: Turn a docker-compose.yml files into Graphviz .dot files. +- [ctk](https://github.com/ctk-hq/ctk) - :construction: Visual composer for container based workloads. By [corpulent](https://github.com/corpulent). - [docker-config-update](https://github.com/sudo-bmitch/docker-config-update) - Utility to update docker configs and secrets for deploying in a compose file. -- [draw-compose](https://github.com/Alexis-benoist/draw-compose) - :skull: Utility to draw a schema of a docker compose. - [elsy](https://github.com/cisco/elsy) - An opinionated, multi-language, build tool based on Docker and Docker Compose. - [habitus](https://github.com/cloud66-oss/habitus) - A Build Flow Tool for Docker. - [kompose](https://github.com/kubernetes/kompose) - Go from Docker Compose to Kubernetes. -- [LLM Harbor](https://github.com/av/harbor) - A CLI and companion app to effortlessly run LLM backends, APIs, frontends, and services with one command. By [@av](https://github.com/av). -- [Maestro](https://github.com/toscanini/maestro) - :skull: Maestro provides the ability to easily launch, orchestrate and manage multiple Docker containers as single unit. -- [percheron](https://github.com/ashmckenzie/percheron) - :skull: Organise your Docker containers with muscle and intelligence. +- [LLM Harbor](https://github.com/av/harbor) - A CLI and companion app to effortlessly run LLM backends, APIs, frontends, and services with one command. By [av](https://github.com/av). - [plash](https://github.com/ihucos/plash) - A container run and build engine - runs inside docker. - [podman-compose](https://github.com/containers/podman-compose) - A script to run docker-compose.yml using podman. -- [rocker](https://github.com/grammarly/rocker) - :skull: Extended Dockerfile builder. Supports multiple FROMs, MOUNTS, templates, etc. by [@grammarly]. -- [rocker-compose](https://github.com/grammarly/rocker-compose) - :skull: Docker composition tool with idempotency features for deploying apps composed of multiple containers. By[@grammarly]. -- [Smalte](https://github.com/roquie/smalte) – Dynamically configure applications that require static configuration in docker container. By [@roquie](https://github.com/roquie) -- [Stacker](https://github.com/stacker/stacker-cli) - :skull: Docker Compose Templates. Stacker provides an abstraction layer over Docker Compose and a better DX (developer experience). -- [Stitchocker](https://github.com/alexaandrov/stitchocker) - A lightweight and fast command line utility for conveniently grouping your docker-compose multiple container services. By [@alexaandrov](https://github.com/alexaandrov). -- [Zodiac](https://github.com/CenturyLinkLabs/zodiac) - :skull: A lightweight tool for easy deployment and rollback of dockerized applications. By [@CenturyLinkLabs][centurylinklabs]. +- [Smalte](https://github.com/roquie/smalte) – Dynamically configure applications that require static configuration in docker container. By [roquie](https://github.com/roquie) +- [Stitchocker](https://github.com/alexaandrov/stitchocker) - A lightweight and fast command line utility for conveniently grouping your docker-compose multiple container services. By [alexaandrov](https://github.com/alexaandrov). ### Deployment and Infrastructure - [awesome-stacks](https://github.com/ethibox/awesome-stacks) - Deploy 150+ open-source web apps with one Docker command. - [blackfish](https://gitlab.com/blackfish/blackfish) - A CoreOS VM to build swarm clusters for Dev & Production. - [BosnD](https://gitlab.com/n0r1sk/bosnd) - BosnD, the boatswain daemon - A dynamic configuration file writer & service reloader for dynamically changing container environments. -- [Centurion](https://github.com/newrelic/centurion) - Centurion is a mass deployment tool for Docker fleets. It takes containers from a Docker registry and runs them on a fleet of hosts with the correct environment variables, host volume mappings, and port mappings. By [@newrelic](https://github.com/newrelic). -- [Clocker](https://github.com/brooklyncentral/clocker) - Clocker creates and manages a Docker cloud infrastructure. Clocker supports single-click deployments and runtime management of multi-node applications that run as containers distributed across multiple hosts, on both Docker and Marathon. It leverages [Calico][calico] and [Weave][weave] for networking and [Brooklyn](https://brooklyn.apache.org/) for application blueprints. By [@brooklyncentral](https://github.com/brooklyncentral). +- [Centurion](https://github.com/newrelic/centurion) - Centurion is a mass deployment tool for Docker fleets. It takes containers from a Docker registry and runs them on a fleet of hosts with the correct environment variables, host volume mappings, and port mappings. By [newrelic](https://github.com/newrelic). +- [Clocker](https://github.com/brooklyncentral/clocker) - Clocker creates and manages a Docker cloud infrastructure. Clocker supports single-click deployments and runtime management of multi-node applications that run as containers distributed across multiple hosts, on both Docker and Marathon. It leverages [Calico][calico] and [Weave][weave] for networking and [Brooklyn](https://brooklyn.apache.org/) for application blueprints. By [brooklyncentral](https://github.com/brooklyncentral). - [Conduit](https://github.com/ehazlett/conduit) - Experimental deployment system for Docker. -- [depcon](https://github.com/ContainX/depcon) - Depcon is written in Go and allows you to easily deploy Docker containers to Apache Mesos/Marathon, Amazon ECS and Kubernetes. By [@ContainX][containx]. -- [deploy](https://github.com/ttiny/deploy) - :skull: Git and Docker deployment tool. A middle ground between simple Docker composition tools and full blown cluster orchestration. +- [depcon](https://github.com/ContainX/depcon) - Depcon is written in Go and allows you to easily deploy Docker containers to Apache Mesos/Marathon, Amazon ECS and Kubernetes. By [ContainX][containx]. - [docker-to-iac](https://github.com/deploystackio/docker-to-iac) - Translate docker run and commit into Infrastructure as Code templates for AWS, Render.com and DigitalOcean. -- [dockit](https://github.com/humblec/dockit) - :skull: Do docker actions and Deploy gluster containers! By [@humblec](https://github.com/humblec). -- [gitkube](https://github.com/hasura/gitkube) - Gitkube is a tool for building and deploying docker images on Kubernetes using `git push`. By [@Hasura](https://github.com/hasura/). +- [gitkube](https://github.com/hasura/gitkube) - Gitkube is a tool for building and deploying docker images on Kubernetes using `git push`. By [Hasura](https://github.com/hasura/). - [Grafeas](https://github.com/grafeas/grafeas) - A common API for metadata about containers, from image and build details to security vulnerabilities. By [grafeas](https://github.com/grafeas). -- [Longshoreman](https://github.com/longshoreman/longshoreman) - :skull: Longshoreman automates application deployment using Docker. Just create a Docker repository (or use a service), configure the cluster using AWS or Digital Ocean (or whatever you like) and deploy applications using a Heroku-like CLI tool. By [longshoreman](https://github.com/longshoreman). - [swarm-ansible](https://github.com/LombardiDaniel/swarm-ansible?tab=readme-ov-file) - Swarm-Ansible bootstraps a production-ready swarm cluster using ansible. Comes with tools to automate CI, help monitoring and traefik pre-configured for SSL certificates and simple-auth. Comes with a private registry and more!. - [SwarmManagement](https://github.com/hansehe/SwarmManagement) - Swarm Management is a python application, installed with pip. The application makes it easy to manage a Docker Swarm by configuring a single yaml file describing which stacks to deploy, and which networks, configs or secrets to create. - [werf](https://github.com/werf/werf) - Werf is a CI/CD tool for building Docker images efficiently and deploying them to Kubernetes using GitOps. @@ -204,21 +184,20 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Axibase Collector](https://axibase.com/docs/axibase-collector/) - Axibase Collector streams performance counters, configuration changes and lifecycle events from the Docker engine(s) into Axibase Time Series Database for roll-up dashboards and integration with upstream monitoring systems. - [cAdvisor](https://github.com/google/cadvisor) - Analyzes resource usage and performance characteristics of running containers. - [Checkmate](https://github.com/bluewave-labs/checkmate) - Checkmate is an open-source, self-hosted tool designed to track and monitor server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. -- [DLIA](https://github.com/zorak1103/dlia) - DLIA is an AI-powered Docker log monitoring agent that uses Large Language Models (LLMs) to intelligently analyze container logs, detect anomalies, and provide contextual insights over time. By [@zorak1103](https://github.com/zorak1103). +- [DLIA](https://github.com/zorak1103/dlia) - DLIA is an AI-powered Docker log monitoring agent that uses Large Language Models (LLMs) to intelligently analyze container logs, detect anomalies, and provide contextual insights over time. By [zorak1103](https://github.com/zorak1103). - [Docker-Alertd](https://github.com/deltaskelta/docker-alertd) - Monitor and send alerts based on docker container resource usage/statistics. - [Docker-Flow-Monitor](https://github.com/docker-flow/docker-flow-monitor) - Reconfigures Prometheus when a new service is updated or deployed automatically. -- [Dockerana](https://github.com/dockerana/dockerana) - :skull: Packaged version of Graphite and Grafana, specifically targeted at metrics from Docker. - [DockProc](https://gitlab.com/n0r1sk/dockproc) - I/O monitoring for containers on processlevel. - [dockprom](https://github.com/stefanprodan/dockprom) - Docker hosts and containers monitoring with Prometheus, Grafana, cAdvisor, NodeExporter and AlertManager. -- [Doku](https://github.com/amerkurev/doku) - Doku is a simple web-based application that allows you to monitor Docker disk usage. [@amerkurev](https://github.com/amerkurev). -- [Dozzle](dozzle) - Monitor container logs in real-time with a browser or mobile device. [@amir20](https://github.com/amir20). +- [Doku](https://github.com/amerkurev/doku) - Doku is a simple web-based application that allows you to monitor Docker disk usage. [amerkurev](https://github.com/amerkurev). +- [Dozzle](dozzle) - Monitor container logs in real-time with a browser or mobile device. [amir20](https://github.com/amir20). - [Dynatrace](https://www.dynatrace.com/solutions/container-monitoring/) - :heavy_dollar_sign: Monitor containerized applications without installing agents or modifying your Run commands. - [Glances](https://github.com/nicolargo/glances) - A cross-platform curses-based system monitoring tool written in Python. -- [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [@vegasbrianc][vegasbrianc]. +- [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [vegasbrianc][vegasbrianc]. - [HertzBeat](https://github.com/dromara/hertzbeat) - An open-source real-time monitoring system with custom-monitor and agentless. - [InfluxDB, cAdvisor, Grafana](https://github.com/vegasbrianc/docker-monitoring) - InfluxDB Time series DB in combination with Grafana and cAdvisor. - [Logspout](https://github.com/gliderlabs/logspout) - Log routing for Docker container logs. -- [monit-docker](https://github.com/decryptus/monit-docker) - Monitor docker containers resources usage or status and execute docker commands or inside containers. [@decryptus][decryptus]. +- [monit-docker](https://github.com/decryptus/monit-docker) - Monitor docker containers resources usage or status and execute docker commands or inside containers. [decryptus][decryptus]. - [NexClipper](https://github.com/NexClipper/NexClipper) - NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes. - [Out-of-the-box Host/Container Monitoring/Logging/Alerting Stack](https://github.com/uschtwill/docker_monitoring_logging_alerting) - Docker host and container monitoring, logging and alerting out of the box using cAdvisor, Prometheus, Grafana for monitoring, Elasticsearch, Kibana and Logstash for logging and elastalert and Alertmanager for alerting. Set up in 5 Minutes. Secure mode for production use with built-in [Automated Nginx Reverse Proxy (jwilder's)][nginxproxy]. - [Sidekick](https://github.com/runsidekick/sidekick) - Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. @@ -230,44 +209,39 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Networking - [Calico][calico] - Calico is a pure layer 3 virtual network that allows containers over multiple docker-hosts to talk to each other. -- [Flannel](https://github.com/coreos/flannel/) - Flannel is a virtual network that gives a subnet to each host for use with container runtimes. By [@coreos][coreos]. -- [Freeflow](https://github.com/Microsoft/Freeflow) - High performance container overlay networks on Linux. Enabling RDMA (on both InfiniBand and RoCE) and accelerating TCP to bare metal performance. By [@Microsoft](https://github.com/Microsoft). -- [MyIP](https://github.com/jason5ng32/MyIP) - All in one IP Toolbox. Easy to check all your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more. By [@jason5ng32](https://github.com/jason5ng32). +- [Flannel](https://github.com/coreos/flannel/) - Flannel is a virtual network that gives a subnet to each host for use with container runtimes. By [coreos][coreos]. +- [Freeflow](https://github.com/Microsoft/Freeflow) - High performance container overlay networks on Linux. Enabling RDMA (on both InfiniBand and RoCE) and accelerating TCP to bare metal performance. By [Microsoft](https://github.com/Microsoft). +- [MyIP](https://github.com/jason5ng32/MyIP) - All in one IP Toolbox. Easy to check all your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more. By [jason5ng32](https://github.com/jason5ng32). - [netshoot](https://github.com/nicolaka/netshoot) - The netshoot container has a powerful set of networking tools to help troubleshoot Docker networking issues. -- [Pipework](https://github.com/jpetazzo/pipework) - Software-Defined Networking for Linux Containers, Pipework works with "plain" LXC containers, and with the awesome Docker. By [@jpetazzo][jpetazzo]. -- [Weave][weave] (The Docker network) :skull: - Weave creates a virtual network that connects Docker containers deployed across multiple hosts. +- [Pipework](https://github.com/jpetazzo/pipework) - Software-Defined Networking for Linux Containers, Pipework works with "plain" LXC containers, and with the awesome Docker. By [jpetazzo][jpetazzo]. ### Orchestration -- [Ansible Linux Docker](https://github.com/Peco602/ansible-linux-docker) - Run Ansible from a Linux container. By [@Peco602][peco602]. +- [Ansible Linux Docker](https://github.com/Peco602/ansible-linux-docker) - Run Ansible from a Linux container. By [Peco602][peco602]. - [athena](https://github.com/athena-oss/athena) - An automation platform with a plugin architecture that allows you to easily create and share services. -- [blimp](https://github.com/tubesandlube/blimp) - :skull: Uses Docker Machine to easily move a container from one Docker host to another, show containers running against all of your hosts, replicate a container across multiple hosts and more by [@defermat](https://github.com/defermat) and [@schvin](https://github.com/schvin). - [CloudSlang](https://github.com/CloudSlang/cloud-slang) - CloudSlang is a workflow engine to create Docker process automation. - [clusterdock](https://github.com/clusterdock/clusterdock) - Docker container orchestration to enable the testing of long-running cluster deployments. -- [Crane](https://github.com/Dataman-Cloud/crane) - Control plane based on docker built-in swarm [@Dataman-Cloud](https://github.com/Dataman-Cloud). -- [Docker Flow Swarm Listener](https://github.com/docker-flow/docker-flow-swarm-listener) - Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [@docker-flow][docker-flow]. +- [Crane](https://github.com/Dataman-Cloud/crane) - Control plane based on docker built-in swarm [Dataman-Cloud](https://github.com/Dataman-Cloud). +- [Docker Flow Swarm Listener](https://github.com/docker-flow/docker-flow-swarm-listener) - Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [docker-flow][docker-flow]. - [docker rollout](https://github.com/Wowu/docker-rollout) - Zero downtime deployment for Docker Compose services. -- [Haven](https://github.com/codeabovelab/haven-platform) - Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [@codeabovelab](https://github.com/codeabovelab). -- [Kontena](https://github.com/kontena/kontena) - :skull: The developer friendly container and micro services platform. Works on any cloud, easy to setup, simple to use. +- [Haven](https://github.com/codeabovelab/haven-platform) - Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [codeabovelab](https://github.com/codeabovelab). - [Kubernetes](https://github.com/kubernetes/kubernetes) - Open source orchestration system for Docker containers by Google. - [ManageIQ](https://github.com/ManageIQ/manageiq) - Discover, optimize and control your hybrid IT. By [ManageIQ](https://github.com/ManageIQ). -- [Mesos](https://github.com/apache/mesos) - Resource/Job scheduler for containers, VM's and physical hosts [@apache](https://mesos.apache.org/). +- [Mesos](https://github.com/apache/mesos) - Resource/Job scheduler for containers, VM's and physical hosts [apache](https://mesos.apache.org/). - [Nebula](https://github.com/nebula-orchestrator) - A Docker orchestration tool designed to manage massive scale distributed clusters. - [Nomad](https://github.com/hashicorp/nomad) - Easily deploy applications at any scale. A Distributed, Highly Available, Datacenter-Aware Scheduler. -- [Panamax](https://github.com/CenturyLinkLabs/panamax-ui) - :skull: An open-source project that makes deploying complex containerized apps as easy as Drag-and-Drop. - [Rancher](https://github.com/rancher/rancher) - An open source project that provides a complete platform for operating Docker in production. -- [RedHerd Framework](https://github.com/redherd-project/redherd-framework) - RedHerd is a collaborative and serverless framework for orchestrating a geographically distributed group of assets capable of simulating complex offensive cyberspace operations. By [@RedHerdProject](https://github.com/redherd-project). -- [Swarm-cronjob](https://github.com/crazy-max/swarm-cronjob) - Create jobs on a time-based schedule on Swarm by [@crazy-max]. +- [RedHerd Framework](https://github.com/redherd-project/redherd-framework) - RedHerd is a collaborative and serverless framework for orchestrating a geographically distributed group of assets capable of simulating complex offensive cyberspace operations. By [RedHerdProject](https://github.com/redherd-project). +- [Swarm-cronjob](https://github.com/crazy-max/swarm-cronjob) - Create jobs on a time-based schedule on Swarm by [crazy-max]. ### PaaS - [caprover](https://github.com/caprover/caprover) - [Previously known as CaptainDuckDuck] Automated Scalable Webserver Package (automated Docker+nginx) - Heroku on Steroids. - [Convox Rack](https://github.com/convox/rack) - Convox Rack is open source PaaS built on top of expert infrastructure automation and devops best practices. - [Dcw](https://github.com/pbertera/dcw) - Docker-compose SSH wrapper: a very poor man PaaS, exposing the docker-compose and custom-container commands defined in container labels. -- [Dokku](https://github.com/dokku/dokku) - Docker powered mini-Heroku that helps you build and manage the lifecycle of applications (originally by [@progrium][progrium]). +- [Dokku](https://github.com/dokku/dokku) - Docker powered mini-Heroku that helps you build and manage the lifecycle of applications (originally by [progrium][progrium]). - [Empire](https://github.com/remind101/empire) - A PaaS built on top of Amazon EC2 Container Service (ECS). - [Exoframe](https://github.com/exoframejs/exoframe) - A self-hosted tool that allows simple one-command deployments using Docker. -- [Flynn](https://github.com/flynn/flynn) - :skull: A next generation open source platform as a service. - [Hephy Workflow](https://github.com/teamhephy/workflow) - Open source PaaS for Kubernetes that adds a developer-friendly layer to any Kubernetes cluster, making it easy to deploy and manage applications. Fork of [Deis Workflow](https://github.com/deis/workflow). - [Krane](https://github.com/krane/krane) - Toolset for managing container workloads on remote servers. - [Nanobox](https://github.com/nanobox-io/nanobox) - :heavy_dollar_sign: An application development platform that creates local environments that can then be deployed and scaled in the cloud. @@ -277,26 +251,21 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Reverse Proxy - [BunkerWeb](https://github.com/bunkerity/bunkerweb) - Open-source and next-gen Web Application Firewall (WAF). By [Bunkerity](https://www.bunkerity.com). -- [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) - Caddy-based reverse proxy, configured with service or container labels. By [@lucaslorentz](https://github.com/lucaslorentz). -- [caddy-docker-upstreams](https://github.com/invzhi/caddy-docker-upstreams) - Docker upstreams module for Caddy, configured with container labels. By [@invzhi](https://github.com/invzhi). +- [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) - Caddy-based reverse proxy, configured with service or container labels. By [lucaslorentz](https://github.com/lucaslorentz). +- [caddy-docker-upstreams](https://github.com/invzhi/caddy-docker-upstreams) - Docker upstreams module for Caddy, configured with container labels. By [invzhi](https://github.com/invzhi). - [Docker Dnsmasq Updater](https://github.com/moonbuggy/docker-dnsmasq-updater) - Update a remote dnsmasq server with Docker container hostnames. -- [docker-flow-proxy](https://github.com/docker-flow/docker-flow-proxy) - Reconfigures proxy every time a new service is deployed, or when a service is scaled. By [@docker-flow][docker-flow]. -- [docker-proxy](https://github.com/silarsis/docker-proxy) - :skull: Transparent proxy for docker containers, run in a docker container. By [@silarsis](https://github.com/silarsis). -- [fabio](https://github.com/fabiolb/fabio) - A fast, modern, zero-conf load balancing HTTP(S) router for deploying microservices managed by consul. By [@magiconair](https://github.com/magiconair) (Frank Schroeder). -- [h2o-proxy](https://github.com/zchee/h2o-proxy) - :skull: Automated H2O reverse proxy for Docker containers. An alternative to [jwilder/nginx-proxy][nginxproxy]. -- [Let's Encrypt Nginx-proxy Companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion) - A lightweight companion container for the nginx-proxy. It allow the creation/renewal of Let's Encrypt certificates automatically. By [@JrCs](https://github.com/JrCs). -- [mesh-router](https://github.com/Yundera/mesh-router) - Free domain(nsl.sh) provider for Docker containers with automatic HTTPS routing. Uses Wireguard VPN to securely route subdomain requests across networks. Ideal for self-hosted NAS and cloud deployments. By [@Yundera](https://github.com/Yundera). -- [muguet](https://github.com/mattallty/muguet) - :skull: DNS Server & Reverse proxy for Docker environments. By [@mattallty](https://github.com/mattallty). -- [Nginx Proxy Manager](https://github.com/jc21/nginx-proxy-manager) - A beautiful web interface for proxying web based services with SSL. By [@jc21](https://github.com/jc21). -- [nginx-proxy][nginxproxy] - Automated nginx proxy for Docker containers using docker-gen by [@jwilder][jwilder] -- [OpenResty Manager](https://github.com/Safe3/openresty-manager) - The easiest using, powerful and beautiful OpenResty Manager(Nginx Enhanced Version), open source alternative to OpenResty Edge. By [@Safe3](https://github.com/Safe3/). -- [Swarm Ingress Router](https://github.com/tpbowden/swarm-ingress-router) - :skull: Route DNS names to Swarm services based on labels. By [@tpbowden](https://github.com/tpbowden/). -- [Swarm Router](https://github.com/flavioaiello/swarm-router) - A «zero config» service name based router for docker swarm mode with a fresh and more secure approach. By [@flavioaiello](https://github.com/flavioaiello). -- [Træfɪk](https://github.com/containous/traefik) - Automated reverse proxy and load-balancer for Docker, Mesos, Consul, Etcd... By [@EmileVauge](https://github.com/emilevauge). +- [docker-flow-proxy](https://github.com/docker-flow/docker-flow-proxy) - Reconfigures proxy every time a new service is deployed, or when a service is scaled. By [docker-flow][docker-flow]. +- [fabio](https://github.com/fabiolb/fabio) - A fast, modern, zero-conf load balancing HTTP(S) router for deploying microservices managed by consul. By [magiconair](https://github.com/magiconair) (Frank Schroeder). +- [Let's Encrypt Nginx-proxy Companion](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion) - A lightweight companion container for the nginx-proxy. It allow the creation/renewal of Let's Encrypt certificates automatically. By [JrCs](https://github.com/JrCs). +- [mesh-router](https://github.com/Yundera/mesh-router) - Free domain(nsl.sh) provider for Docker containers with automatic HTTPS routing. Uses Wireguard VPN to securely route subdomain requests across networks. Ideal for self-hosted NAS and cloud deployments. By [Yundera](https://github.com/Yundera). +- [Nginx Proxy Manager](https://github.com/jc21/nginx-proxy-manager) - A beautiful web interface for proxying web based services with SSL. By [jc21](https://github.com/jc21). +- [nginx-proxy][nginxproxy] - Automated nginx proxy for Docker containers using docker-gen by [jwilder][jwilder] +- [OpenResty Manager](https://github.com/Safe3/openresty-manager) - The easiest using, powerful and beautiful OpenResty Manager(Nginx Enhanced Version), open source alternative to OpenResty Edge. By [Safe3](https://github.com/Safe3/). +- [Swarm Router](https://github.com/flavioaiello/swarm-router) - A «zero config» service name based router for docker swarm mode with a fresh and more secure approach. By [flavioaiello](https://github.com/flavioaiello). +- [Træfɪk](https://github.com/containous/traefik) - Automated reverse proxy and load-balancer for Docker, Mesos, Consul, Etcd... By [EmileVauge](https://github.com/emilevauge). ### Runtime -- [aind](https://github.com/aind-containers/aind) - :skull: AinD launches Android apps in Docker, by nesting Anbox containers inside Docker. - [cri-o](https://github.com/cri-o/cri-o) - Open Container Initiative-based implementation of Kubernetes Container Runtime Interface by [cri-o](https://github.com/cri-o). - [lxc](https://github.com/lxc/lxc) - LXC - Linux Containers. - [podman](https://github.com/containers/libpod) - Libpod is a library used to create container pods. Home of Podman. @@ -305,28 +274,28 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Security -- [Anchor](https://github.com/SongStitch/anchor/) - A tool to ensure reproducible builds by pinning dependencies inside your Dockerfiles [@SongStitch](https://github.com/songStitch/). +- [Anchor](https://github.com/SongStitch/anchor/) - A tool to ensure reproducible builds by pinning dependencies inside your Dockerfiles [SongStitch](https://github.com/songStitch/). - [Anchor Enterprise](https://anchore.com/) - :heavy_dollar_sign: Analyze images for CVE vulnerabilities and against custom security policies. - [Aqua Security](https://www.aquasec.com) - :heavy_dollar_sign: Securing container-based applications from Dev to Production on any platform. - [bane](https://github.com/genuinetools/bane) - AppArmor profile generator for Docker containers. - [buildcage](https://github.com/dash14/buildcage) - Restricts outbound network access during Docker builds to prevent supply chain attacks, working as a drop-in BuildKit remote driver for Docker Buildx, with ready-to-use GitHub Actions. - [CetusGuard](https://github.com/hectorm/cetusguard) - CetusGuard is a tool that protects the Docker daemon socket by filtering calls to its API endpoints. -- [Checkov](https://github.com/bridgecrewio/checkov) - Static analysis for infrastructure as code manifests (Terraform, Kubernetes, Cloudformation, Helm, Dockerfile, Kustomize) find security misconfiguration and fix them. By [@bridgecrew](https://github.com/bridgecrewio). -- [CIS Docker Benchmark](https://github.com/dev-sec/cis-docker-benchmark) - This [InSpec][inspec] compliance profile implement the CIS Docker 1.12.0 Benchmark in an automated way to provide security best-practice tests around Docker daemon and containers in a production environment. By [@dev-sec](https://github.com/dev-sec). -- [Clair](https://github.com/quay/clair) - Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers. By [@coreos][coreos]. -- [crowdsec-blocklist-import](https://github.com/wolffcatskyy/crowdsec-blocklist-import) - Aggregates 36 free threat intelligence feeds into 120k+ malicious IPs for CrowdSec bouncers, providing 10-20x more blocks than default lists. By [@wolffcatskyy](https://github.com/wolffcatskyy). -- [Dagda](https://github.com/eliasgranderubio/dagda) - Dagda is a tool to perform static analysis of known vulnerabilities, trojans, viruses, malware & other malicious threats in docker images/containers and to monitor the docker daemon and running docker containers for detecting anomalous activities. By [@eliasgranderubio](https://github.com/eliasgranderubio). -- [Deepfence Enterprise](https://deepfence.io) - :heavy_dollar_sign: Full life cycle Cloud Native Workload Protection platform for kubernetes, virtual machines and serverless. By [@deepfence][deepfence]. -- [Deepfence Threat Mapper](https://github.com/deepfence/ThreatMapper) - Powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless. By [@deepfence][deepfence]. -- [docker-bench-security](https://github.com/docker/docker-bench-security) - Script that checks for dozens of common best-practices around deploying Docker containers in production. By [@docker][docker]. +- [Checkov](https://github.com/bridgecrewio/checkov) - Static analysis for infrastructure as code manifests (Terraform, Kubernetes, Cloudformation, Helm, Dockerfile, Kustomize) find security misconfiguration and fix them. By [bridgecrew](https://github.com/bridgecrewio). +- [CIS Docker Benchmark](https://github.com/dev-sec/cis-docker-benchmark) - This [InSpec][inspec] compliance profile implement the CIS Docker 1.12.0 Benchmark in an automated way to provide security best-practice tests around Docker daemon and containers in a production environment. By [dev-sec](https://github.com/dev-sec). +- [Clair](https://github.com/quay/clair) - Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers. By [coreos][coreos]. +- [crowdsec-blocklist-import](https://github.com/wolffcatskyy/crowdsec-blocklist-import) - Aggregates 36 free threat intelligence feeds into 120k+ malicious IPs for CrowdSec bouncers, providing 10-20x more blocks than default lists. By [wolffcatskyy](https://github.com/wolffcatskyy). +- [Dagda](https://github.com/eliasgranderubio/dagda) - Dagda is a tool to perform static analysis of known vulnerabilities, trojans, viruses, malware & other malicious threats in docker images/containers and to monitor the docker daemon and running docker containers for detecting anomalous activities. By [eliasgranderubio](https://github.com/eliasgranderubio). +- [Deepfence Enterprise](https://deepfence.io) - :heavy_dollar_sign: Full life cycle Cloud Native Workload Protection platform for kubernetes, virtual machines and serverless. By [deepfence][deepfence]. +- [Deepfence Threat Mapper](https://github.com/deepfence/ThreatMapper) - Powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless. By [deepfence][deepfence]. +- [docker-bench-security](https://github.com/docker/docker-bench-security) - Script that checks for dozens of common best-practices around deploying Docker containers in production. By [docker][docker]. - [docker-explorer](https://github.com/google/docker-explorer) - A tool to help forensicate offline docker acquisitions. -- [docker-lock](https://github.com/safe-waters/docker-lock) - A cli-plugin for docker to automatically manage image digests by tracking them in a separate Lockfile. By [@safe-waters][safe-waters]. -- [dvwassl](https://github.com/Peco602/dvwassl) - SSL-enabled Damn Vulnerable Web App to test Web Application Firewalls. By [@Peco602][peco602]. +- [docker-lock](https://github.com/safe-waters/docker-lock) - A cli-plugin for docker to automatically manage image digests by tracking them in a separate Lockfile. By [safe-waters][safe-waters]. +- [dvwassl](https://github.com/Peco602/dvwassl) - SSL-enabled Damn Vulnerable Web App to test Web Application Firewalls. By [Peco602][peco602]. - [KICS](https://github.com/checkmarx/kics) - An infrastructure-as-code scanning tool, find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle. Can be extended for additional policies. By [Checkmarx](https://github.com/Checkmarx). -- [notary](https://github.com/theupdateframework/notary) - A server and a client for running and interacting with trusted collections. By [@TUF](https://github.com/theupdateframework). +- [notary](https://github.com/theupdateframework/notary) - A server and a client for running and interacting with trusted collections. By [TUF](https://github.com/theupdateframework). - [oscap-docker](https://github.com/OpenSCAP/openscap) - OpenSCAP provides oscap-docker tool which is used to scan Docker containers and images. By [OpenSCAP](https://github.com/OpenSCAP). - [Prisma Cloud](https://www.paloaltonetworks.com/prisma/cloud) - :heavy_dollar_sign: (Previously Twistlock Security Suite) detects vulnerabilities, hardens container images, and enforces security policies across the lifecycle of applications. -- [segspec](https://github.com/dormstern/segspec) - Extracts network dependencies from Docker Compose, Kubernetes manifests, Helm charts, and other config files to generate Kubernetes NetworkPolicies with evidence tracing. By [@dormstern](https://github.com/dormstern). +- [segspec](https://github.com/dormstern/segspec) - Extracts network dependencies from Docker Compose, Kubernetes manifests, Helm charts, and other config files to generate Kubernetes NetworkPolicies with evidence tracing. By [dormstern](https://github.com/dormstern). - [Syft](https://github.com/anchore/syft) - CLI tool and library for generating a Software Bill of Materials (SBOM) from container images and filesystems. - [Sysdig Falco](https://github.com/falcosecurity/falco) - Sysdig Falco is an open source container security monitor. It can monitor application, container, host, and network activity and alert on unauthorized activity. - [Sysdig Secure](https://www.sysdig.com/solutions/cloud-detection-and-response-cdr) - :heavy_dollar_sign: Sysdig Secure addresses run-time security through behavioral monitoring and defense, and provides deep forensics based on open source Sysdig for incident response. @@ -335,23 +304,22 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Service Discovery -- [docker-consul](https://github.com/gliderlabs/docker-consul) by [@progrium][progrium] +- [docker-consul](https://github.com/gliderlabs/docker-consul) by [progrium][progrium] - [docker-dns](https://github.com/bytesharky/docker-dns) - Lightweight DNS forwarder for Docker containers, resolves container names with custom suffixes (e.g. `.docker`) on the host to simplify service discovery. -- [etcd](https://github.com/etcd-io/etcd) - Distributed reliable key-value store for the most critical data of a distributed system by [@etcd-io](https://github.com/etcd-io) (former part of CoreOS). +- [etcd](https://github.com/etcd-io/etcd) - Distributed reliable key-value store for the most critical data of a distributed system by [etcd-io](https://github.com/etcd-io) (former part of CoreOS). - [istio](https://github.com/istio/istio) - An open platform to connect, manage, and secure microservices. -- [proxy](https://github.com/factorish/proxy) - :skull: Lightweight nginx based load balancer self using service discovery provided by registrator. -- [registrator](https://github.com/gliderlabs/registrator) - Service registry bridge for Docker by [@gliderlabs][gliderlabs] and [@progrium][progrium]. +- [registrator](https://github.com/gliderlabs/registrator) - Service registry bridge for Docker by [gliderlabs][gliderlabs] and [progrium][progrium]. ### Volume Management / Data -- [Blockbridge](https://github.com/blockbridge/blockbridge-docker-volume) :heavy_dollar_sign:- The Blockbridge plugin is a volume plugin that provides access to an extensible set of container-based persistent storage options. It supports single and multi-host Docker environments with features that include tenant isolation, automated provisioning, encryption, secure deletion, snapshots and QoS. By [@blockbridge](https://github.com/blockbridge) +- [Blockbridge](https://github.com/blockbridge/blockbridge-docker-volume) :heavy_dollar_sign:- The Blockbridge plugin is a volume plugin that provides access to an extensible set of container-based persistent storage options. It supports single and multi-host Docker environments with features that include tenant isolation, automated provisioning, encryption, secure deletion, snapshots and QoS. By [blockbridge](https://github.com/blockbridge) - - [Label Backup](https://github.com/resulgg/label-backup) - A lightweight, Docker-aware backup agent that automatically discovers and backs up containerized databases (PostgreSQL, MySQL, MongoDB, Redis) based on Docker labels. Supports local storage and S3-compatible destinations with flexible scheduling via cron expressions. -- [Docker Volume Backup](https://github.com/offen/docker-volume-backup) Backup Docker volumes locally or to any S3 compatible storage. By [@offen](https://github.com/offen) +- [Docker Volume Backup](https://github.com/offen/docker-volume-backup) Backup Docker volumes locally or to any S3 compatible storage. By [offen](https://github.com/offen) - [Minio](https://github.com/minio/minio) - S3 compatible object storage server in Docker containers. -- [Netshare](https://github.com/ContainX/docker-volume-netshare) Docker NFS, AWS EFS, Ceph & Samba/CIFS Volume Plugin. By [@ContainX][containx] +- [Netshare](https://github.com/ContainX/docker-volume-netshare) Docker NFS, AWS EFS, Ceph & Samba/CIFS Volume Plugin. By [ContainX][containx] - [portworx](https://portworx.com) - :heavy_dollar_sign: Decentralized storage solution for persistent, shared and replicated volumes. - [quobyte](https://www.quobyte.com/) - :heavy_dollar_sign: Fully fault-tolerant distributed file system with a docker volume driver. -- [REX-Ray](https://github.com/rexray/rexray) provides a vendor agnostic storage orchestration engine. The primary design goal is to provide persistent storage for Docker, Kubernetes, and Mesos. By[@thecodeteam](https://github.com/thecodeteam) (DELL Technologies) +- [REX-Ray](https://github.com/rexray/rexray) provides a vendor agnostic storage orchestration engine. The primary design goal is to provide persistent storage for Docker, Kubernetes, and Mesos. By[thecodeteam](https://github.com/thecodeteam) (DELL Technologies) - [Storidge](https://github.com/Storidge/quick-start) - :heavy_dollar_sign: Software-defined Persistent Storage for Kubernetes and Docker Swarm. ### User Interface @@ -360,8 +328,7 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - JetBrains IDEs (IntelliJ IDEA, GoLand, WebStorm, CLion etc.) has [built-in Docker plugin](https://www.jetbrains.com/help/idea/docker.html#managing-images) - Eclipse [Docker Tooling plugin](https://www.eclipse.org/community/eclipse_newsletter/2016/july/article2.php) -- [denops-docker.vim](https://github.com/skanehira/denops-docker.vim) - :skull: Manage docker containers and images in Vim. By [@skanehira]. -- [docker.el](https://github.com/Silex/docker.el) Manage docker from Emacs by [@Silex](https://github.com/Silex) +- [docker.el](https://github.com/Silex/docker.el) Manage docker from Emacs by [Silex](https://github.com/Silex) #### Desktop @@ -369,68 +336,60 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [Docker DB Manager](https://github.com/AbianS/docker-db-manager) - Desktop app for managing Docker database containers with visual interface and one-click operations. - [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Official native app. Only for Windows and MacOS. -- [Simple Docker UI](https://github.com/felixgborrego/simple-docker-ui) - Built on Electron. By [@felixgborrego](https://github.com/felixgborrego/). -- [Stevedore](https://github.com/slonopotamus/stevedore) - Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [@slonopotamus](https://github.com/slonopotamus). +- [Simple Docker UI](https://github.com/felixgborrego/simple-docker-ui) - Built on Electron. By [felixgborrego](https://github.com/felixgborrego/). +- [Stevedore](https://github.com/slonopotamus/stevedore) - Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [slonopotamus](https://github.com/slonopotamus). #### Terminal ##### Terminal UI -- [ctop (2)](https://github.com/bcicen/ctop) - :skull: Top-like interface for container metrics (Golang). - [d4s](https://github.com/jr-k/d4s) - A fast, keyboard-driven terminal UI to manage Docker containers, Compose stacks, and Swarm services with the ergonomics of K9s. - [dive](https://github.com/wagoodman/dive) - A tool for exploring each layer in a docker image. By [wagoodman](https://github.com/wagoodman). -- [dockdash](https://github.com/byrnedo/dockdash) detailed stats. By [@byrnedo] -- [Docker-mon](https://github.com/icecrime/docker-mon) - :skull: Console-based Docker monitoring. +- [dockdash](https://github.com/byrnedo/dockdash) detailed stats. By [byrnedo] - [dockly](https://github.com/lirantal/dockly) - An interactive shell UI for managing Docker containers. - [DockMate](https://github.com/shubh-io/dockmate) - Lightweight terminal-based Docker and Podman manager with a text-based user interface,. - [DockSTARTer](https://github.com/GhostWriters/DockSTARTer) - DockSTARTer helps you get started with home server apps running in Docker by [GhostWriters](https://github.com/GhostWriters). -- [dprs](https://github.com/durableprogramming/dprs) - A developer-focused TUI for managing Docker containers with real-time log streaming and container management. Built with Rust. By [@durableprogramming](https://github.com/durableprogramming). +- [dprs](https://github.com/durableprogramming/dprs) - A developer-focused TUI for managing Docker containers with real-time log streaming and container management. Built with Rust. By [durableprogramming](https://github.com/durableprogramming). - [dry](https://github.com/moncho/dry) - An interactive CLI for Docker containers. - [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box. -- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [@jesseduffield](https://github.com/jesseduffield). +- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [jesseduffield](https://github.com/jesseduffield). - [lazyjournal](https://github.com/Lifailon/lazyjournal) - A interface for reading and filtering the logs output of Docker and Podman containers like [Dozzle](dozzle) but for the terminal with support for fuzzy find, regex and output coloring. - [oxker](https://github.com/mrjackwills/oxker) - A simple tui to view & control docker containers. Written in [Rust](https://rust-lang.org/), making heavy use of [ratatui](https://github.com/tui-rs-revival/ratatui) & [Bollard](https://github.com/fussybeaver/bollard),. -- [sen](https://github.com/TomasTomecek/sen) - :skull: Terminal user interface for docker engine,. ##### CLI tools -- [captain](https://github.com/jenssegers/captain) - Easily start and stop docker compose projects from any directory. By [@jenssegers](https://github.com/jenssegers). -- [dcinja](https://github.com/Falldog/dcinja) - The powerful and smallest binary size of template engine for docker command line environment. By [@Falldog](https://github.com/Falldog). -- [dcp](https://github.com/exdx/dcp) - A simple tool for copying files from container filesystems. By [@exdx](https://github.com/exdx). +- [captain](https://github.com/jenssegers/captain) - Easily start and stop docker compose projects from any directory. By [jenssegers](https://github.com/jenssegers). +- [dcinja](https://github.com/Falldog/dcinja) - The powerful and smallest binary size of template engine for docker command line environment. By [Falldog](https://github.com/Falldog). +- [dcp](https://github.com/exdx/dcp) - A simple tool for copying files from container filesystems. By [exdx](https://github.com/exdx). - [dctl](https://github.com/FabienD/docker-stack) - Dctl is a Cli tool that helps developers by allowing them to execute all docker compose commands anywhere in the terminal, and more. By [FabienD](https://github.com/FabienD). -- [decompose](https://github.com/s0rg/decompose) - Reverse-engineering tool for docker environments. By [@s0rg](https://github.com/s0rg). -- [docker pushrm](https://github.com/christian-korneck/docker-pushrm) - A Docker CLI plugin that lets you push the README.md file from the current directory to Docker Hub. Also supports Quay and Harbor. By [@christian-korneck](https://github.com/christian-korneck). +- [decompose](https://github.com/s0rg/decompose) - Reverse-engineering tool for docker environments. By [s0rg](https://github.com/s0rg). +- [docker pushrm](https://github.com/christian-korneck/docker-pushrm) - A Docker CLI plugin that lets you push the README.md file from the current directory to Docker Hub. Also supports Quay and Harbor. By [christian-korneck](https://github.com/christian-korneck). - [docker-captain](https://github.com/lucabello/docker-captain) - A friendly CLI to manage multiple Docker Compose deployments with style — powered by Typer, Rich, questionary, and sh. - [docker-ls](https://github.com/mayflower/docker-ls) - CLI tools for browsing and manipulating docker registries. -- [dockersql](https://github.com/crosbymichael/dockersql) - :skull: A command line interface to query Docker using SQL. - [DVM](https://github.com/howtowhale/dvm) - Docker version manager. - [goinside](https://github.com/iamsoorena/goinside) - Get inside a running docker container easily. - [Pdocker](https://github.com/g31s/Pdocker) - A simple tool to manage and maintain Docker for personal projects. - [proco](https://github.com/shiwaforce/poco) - Proco will help you to organise and manage Docker, Docker-Compose, Kubernetes projects of any complexity using simple YAML config files to shorten the route from finding your project to initialising it in your local environment. -- [reg](https://github.com/genuinetools/reg) - :skull: Docker registry v2 command line client. - [scuba](https://github.com/JonathonReinhart/scuba) - Transparently use Docker containers to encapsulate software build environments,. - [skopeo](https://github.com/containers/skopeo) - Work with remote images registries - retrieving information, images, signing content. -- [supdock](https://github.com/segersniels/supdock) - Allows for slightly more visual usage of Docker with an interactive prompt. By [@segersniels](https://github.com/segersniels). +- [supdock](https://github.com/segersniels/supdock) - Allows for slightly more visual usage of Docker with an interactive prompt. By [segersniels](https://github.com/segersniels). - [tsaotun](https://github.com/qazbnm456/tsaotun) - Python based Assistance for Docker. -- [wharfee](https://github.com/j-bennet/wharfee) - :skull: Autocompletion and syntax highlighting for Docker commands. ##### Other -- [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) - Search the Docker Registry with the Dext smart launcher. By [@vutran](https://github.com/vutran). -- [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) - SSH Server for Docker containers ~ Because every container should be accessible. By [@jeroenpeeters](https://github.com/jeroenpeeters). -- [dockerfile-mode](https://github.com/spotify/dockerfile-mode) An emacs mode for handling Dockerfiles by [@spotify][spotify] +- [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) - Search the Docker Registry with the Dext smart launcher. By [vutran](https://github.com/vutran). +- [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) - SSH Server for Docker containers ~ Because every container should be accessible. By [jeroenpeeters](https://github.com/jeroenpeeters). +- [dockerfile-mode](https://github.com/spotify/dockerfile-mode) An emacs mode for handling Dockerfiles by [spotify][spotify] - [MultiDocker](https://github.com/marty90/multidocker) - Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. - [Powerline-Docker](https://github.com/adrianmo/powerline-docker) - A Powerline segment for showing the status of Docker containers. #### Web - [CASA](https://github.com/knrdl/casa) - Outsource the administration of a handful of containers to your co-workers,. -- [Container Web TTY](https://github.com/wrfly/container-web-tty) - Connect your containers via a web-tty [@wrfly](https://github.com/wrfly). +- [Container Web TTY](https://github.com/wrfly/container-web-tty) - Connect your containers via a web-tty [wrfly](https://github.com/wrfly). - [dockemon](https://github.com/ProductiveOps/dokemon) - Docker Container Management GUI. - [Docker Registry Browser](https://github.com/klausmeyer/docker-registry-browser) - Web Interface for the Docker Registry HTTP API v2. -- [Docker Registry UI (Joxit)](https://github.com/Joxit/docker-registry-ui) - :skull: The simplest and cleanest UI for private registries. - [docker-registry-web](https://github.com/mkuchin/docker-registry-web) - Web UI, authentication service and event recorder for private docker registry v2. - [docker-swarm-visualizer](https://github.com/dockersamples/docker-swarm-visualizer) - Visualizes Docker services on a Docker Swarm (for running demos). -- [DockerSurfer](https://github.com/Simone-Erba/DockerSurfer) - :skull: A web service for analyze and browse dependencies between Docker images in the Docker registry,. - [dockge](https://github.com/louislam/dockge) - Easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. - [Komodo](https://github.com/mbecker20/komodo) - A tool to build and deploy software on many servers. - [Kubevious](https://github.com/kubevious/kubevious) - A highly visual web UI for Kubernetes which renders configuration and state in an application centric way. @@ -441,10 +400,10 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [Rapid Dashboard](https://github.com/ozlerhakan/rapid) - A simple query dashboard to use Docker Remote API. - [Seagull](https://github.com/tobegit3hub/seagull) - Friendly Web UI to monitor docker daemon. - [Swarmpit](https://github.com/swarmpit/swarmpit) - Swarmpit provides simple and easy to use interface for your Docker Swarm cluster. You can manage your stacks, services, secrets, volumes, networks etc. -- [Swirl](https://github.com/cuigh/swirl) - Swirl is a web management tool for Docker, focused on swarm cluster By [@cuigh](https://github.com/cuigh/). +- [Swirl](https://github.com/cuigh/swirl) - Swirl is a web management tool for Docker, focused on swarm cluster By [cuigh](https://github.com/cuigh/). - [Theia](https://github.com/eclipse-theia/theia) - Extensible platform to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technologies. -- [usulnet](https://github.com/fr4nsys/usulnet) - A complete and modern Docker management platform designed for sysadmin, devops with enterprise grade tools, cve scanner, ssh, rdp on web and much more. By [@fr4nsys](https://github.com/fr4nsys). -- [Yacht](https://github.com/SelfhostedPro/Yacht) - :construction: A Web UI for docker that focuses on templates and ease of use in order to make deployments as easy as possible. By [@SelfhostedPro](https://github.com/SelfhostedPro). +- [usulnet](https://github.com/fr4nsys/usulnet) - A complete and modern Docker management platform designed for sysadmin, devops with enterprise grade tools, cve scanner, ssh, rdp on web and much more. By [fr4nsys](https://github.com/fr4nsys). +- [Yacht](https://github.com/SelfhostedPro/Yacht) - :construction: A Web UI for docker that focuses on templates and ease of use in order to make deployments as easy as possible. By [SelfhostedPro](https://github.com/SelfhostedPro). ## Docker Images @@ -459,7 +418,7 @@ Tools and applications that are either installed inside containers or designed t - [distroless](https://github.com/GoogleContainerTools/distroless) - Language focused docker images, minus the operating system,. - [docker-alpine](https://github.com/gliderlabs/docker-alpine) - A super small Docker base image _(5MB)_ using Alpine Linux. - [docker-gen](https://github.com/jwilder/docker-gen) - Generate files from docker container meta-data. -- [dockerize](https://github.com/powerman/dockerize) - Utility to simplify running applications in docker containers by [@jwilder][jwilder], [@powerman][powerman]. +- [dockerize](https://github.com/powerman/dockerize) - Utility to simplify running applications in docker containers by [jwilder][jwilder], [powerman][powerman]. - [GoSu](https://github.com/tianon/gosu) - Run this specific application as this specific user and get out of the pipeline (entrypoint script tool). - [is-docker](https://github.com/sindresorhus/is-docker) - Check if the process is running inside a Docker container. - [lstags](https://github.com/ivanilves/lstags) - Sync Docker images across registries. @@ -469,7 +428,7 @@ Tools and applications that are either installed inside containers or designed t - [su-exec](https://github.com/ncopa/su-exec) - This is a simple tool that will simply execute a program with different privileges. The program will be executed directly and not run as a child, like su and sudo does, which avoids TTY and signal issues. Why reinvent gosu? This does more or less exactly the same thing as gosu but it is only 10kb instead of 1.8MB. By [ncopa](https://github.com/ncopa). - [sue](https://github.com/theAkito/sue) - Executes a program as a user different from the user running sue. This is a maintainable alternative to ncopa/su-exec, which is the better tianon/gosu. This one is far better (higher performance, smaller size), than the original gosu, however it is far easier to maintain, than su-exec, which is written in plain C. Made by [Akito][akito]. - [supercronic](https://github.com/aptible/supercronic) - Crontab-compatible job runner, designed specifically to run in containers. -- [TrivialRC](https://github.com/vorakl/TrivialRC) - A minimalistic Runtime Configuration system and process manager for containers [@vorakl](https://github.com/vorakl). +- [TrivialRC](https://github.com/vorakl/TrivialRC) - A minimalistic Runtime Configuration system and process manager for containers [vorakl](https://github.com/vorakl). ### Builder @@ -481,7 +440,7 @@ Applications designed to help or simplify building **new** images - [cekit](https://github.com/cekit/cekit) - A tool used by openshift to build base images using different build engines. - [container-factory](https://github.com/mutable/container-factory) - Produces Docker images from tarballs of application source code. - [copy-docker-image](https://github.com/mdlavin/copy-docker-image) - Copy a Docker image between registries without a full Docker installation. -- [Derrick](https://github.com/alibaba/derrick) - A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [@alibaba](https://github.com/alibaba). +- [Derrick](https://github.com/alibaba/derrick) - A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [alibaba](https://github.com/alibaba). - [dlayer](https://github.com/orisano/dlayer) - Docker layer analyzer. - [docker-companion](https://github.com/mudler/docker-companion) - A command line tool written in Golang to squash and unpack docker images. - [docker-make](https://github.com/CtripCloud/docker-make) - Build, tag,and push a bunch of related docker images via a single command. @@ -489,16 +448,14 @@ Applications designed to help or simplify building **new** images - [docker-replay](https://github.com/bcicen/docker-replay) - Generate `docker run`command and options from running containers. By [bcicen](https://github.com/bcicen). - [DockerSlim](https://github.com/docker-slim/docker-slim) shrinks fat Docker images creating the smallest possible images. - [Dockly](https://github.com/swipely/dockly) - Dockly is a gem made to ease the pain of packaging an application in Docker. -- [dockramp](https://github.com/jlhawn/dockramp) - :skull: Proof of Concept: A Client Driven Docker Image Builder. -- [essex](https://github.com/utensils/essex) - Boilerplate for Docker Based Projects: Essex is a CLI utility written in bash to quickly setup clean and consistent Docker projects with Makefile driven workflows. [@jamesbrink](https://github.com/jamesbrink). +- [essex](https://github.com/utensils/essex) - Boilerplate for Docker Based Projects: Essex is a CLI utility written in bash to quickly setup clean and consistent Docker projects with Makefile driven workflows. [jamesbrink](https://github.com/jamesbrink). - [HPC Container Maker](https://github.com/NVIDIA/hpc-container-maker) - Generates Dockerfiles from a high level Python recipe, including building blocks for High-Performance Computing components. - [img](https://github.com/genuinetools/img) - Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder. - [packer](https://developer.hashicorp.com/packer/integrations/hashicorp/docker/latest/components/builder/docker) - Hashicorp tool to build machine images including docker image integrated with configuration management tools like chef, puppet, ansible. - [portainer](https://github.com/duedil-ltd/portainer) - Apache Mesos framework for building Docker images. - [Production-Ready Python Containers :heavy_dollar_sign:](https://pythonspeed.com/products/pythoncontainer/) - A template for creating production-ready Docker images for Python applications. -- [RAUDI](https://github.com/cybersecsi/RAUDI) - A tool to automatically update (and optionally push to Docker Hub) Docker Images for 3rd party software whenever theres is a new release/update/commit. By [@SecSI](https://github.com/cybersecsi). +- [RAUDI](https://github.com/cybersecsi/RAUDI) - A tool to automatically update (and optionally push to Docker Hub) Docker Images for 3rd party software whenever theres is a new release/update/commit. By [SecSI](https://github.com/cybersecsi). - [runlike](https://github.com/lavie/runlike) - Generate `docker run`command and options from running containers. -- [SkinnyWhale](https://github.com/djosephsen/skinnywhale) - :skull: Skinnywhale helps you make smaller (as in megabytes) Docker containers. - [userdef](https://github.com/theAkito/userdef) - An advanced `adduser` for your Alpine based Docker images. Made by [Akito][akito]. - [Whaler](https://github.com/P3GLEG/Whaler) - Program to reverse Docker images into Dockerfiles. - [Whales](https://github.com/Gueils/whales) - A tool to automatically dockerize your applications. @@ -508,21 +465,21 @@ Applications designed to help or simplify building **new** images - [chaperone-docker](https://github.com/garywiz/chaperone-docker) - A set of images using the Chaperone process manager, including a lean Alpine image, LAMP, LEMP, and bare-bones base kits. - [Dockerfile Generator](https://github.com/ozankasikci/dockerfile-generator) `dfg` is both a Go library and an executable that produces valid Dockerfiles using various input channels. - [Dockerfile Project](https://dockerfile.github.io/) - Trusted Automated Docker Builds. Dockerfile Project maintains a central repository of Dockerfile for various popular open source software services runnable on a Docker container. -- [dockerfilegraph](https://github.com/patrickhoefler/dockerfilegraph) - Visualize your multi-stage Dockerfiles. By [@PatrickHoefler](https://github.com/patrickhoefler). +- [dockerfilegraph](https://github.com/patrickhoefler/dockerfilegraph) - Visualize your multi-stage Dockerfiles. By [PatrickHoefler](https://github.com/patrickhoefler). - [Dockershelf](https://github.com/Dockershelf/dockershelf) - A repository that serves as a collector for docker recipes that are universal, efficient and slim. Images are updated, tested and published daily via a Travis cron job. - [Vektorcloud](https://github.com/vektorcloud) - A collection of minimal, Alpine-based Docker images. Examples by: -- [@0xy](https://gitlab.com/0xy/dockerfiles) -- [@arun-gupta](https://github.com/arun-gupta/docker-images) -- [@awesome-startup](https://github.com/awesome-startup/docker-compose) -- [@crosbymichael](https://github.com/crosbymichael/Dockerfiles) -- [@jessfraz](https://github.com/jessfraz/dockerfiles) -- [@komljen](https://github.com/komljen/dockerfile-examples) -- [@kstaken](https://github.com/kstaken/dockerfile-examples) -- [@ondrejmo](https://github.com/ondrejmo/Dockerfiles) -- [@vimagick](https://github.com/vimagick/dockerfiles) +- [0xy](https://gitlab.com/0xy/dockerfiles) +- [arun-gupta](https://github.com/arun-gupta/docker-images) +- [awesome-startup](https://github.com/awesome-startup/docker-compose) +- [crosbymichael](https://github.com/crosbymichael/Dockerfiles) +- [jessfraz](https://github.com/jessfraz/dockerfiles) +- [komljen](https://github.com/komljen/dockerfile-examples) +- [kstaken](https://github.com/kstaken/dockerfile-examples) +- [ondrejmo](https://github.com/ondrejmo/Dockerfiles) +- [vimagick](https://github.com/vimagick/dockerfiles) ### Linter @@ -543,7 +500,7 @@ Services to securely store your Docker images. - [Amazon Elastic Container Registry :heavy_dollar_sign:](https://aws.amazon.com/ecr/) - Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images. - [Azure Container Registry :heavy_dollar_sign:](https://azure.microsoft.com/en-us/products/container-registry/#overview) - Manage a Docker private registry as a first-class Azure resource. -- [CargoOS](https://github.com/RedCoolBeans/cargos-buildroot) - A bare essential OS for running the Docker Engine on bare metal or Cloud. By [@RedCoolBeans](https://github.com/RedCoolBeans). +- [CargoOS](https://github.com/RedCoolBeans/cargos-buildroot) - A bare essential OS for running the Docker Engine on bare metal or Cloud. By [RedCoolBeans](https://github.com/RedCoolBeans). - [cleanreg](https://github.com/hcguersoy/cleanreg) - A small tool to delete image manifests from a Docker Registry implementing the API v2, dereferencing them for the GC. - [Cloudsmith :heavy_dollar_sign:](https://cloudsmith.com/product/formats/docker-registry) - A fully managed package management SaaS, with first-class support for public and private Docker registries (and many others, incl. Helm charts for the Kubernetes ecosystem). Has a generous free-tier and is also completely free for open-source. - [Container Registry Service :heavy_dollar_sign:](https://container-registry.com/) - Harbor based Container Management Solution as a Service for teams and organizations. Free tier offers 1 GB storage for private repositories. @@ -572,20 +529,20 @@ Services to securely store your Docker images. ### API Client - [ahab](https://github.com/instacart/ahab) - Docker event handling with Python. -- [contajners](https://github.com/lispyclouds/contajners) - An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [@lispyclouds][lispyclouds]. +- [contajners](https://github.com/lispyclouds/contajners) - An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [lispyclouds][lispyclouds]. - [Docker Client for JVM](https://github.com/gesellix/docker-client) - A Docker remote api client library for the JVM, written in Groovy. -- [Docker Client TypeScript](https://gitlab.com/masaeedu/docker-client) - Docker API client for JavaScript, automatically generated from Swagger API definition from moby repository. By [@masaeedu](https://github.com/masaeedu). -- [docker-controller-bot](https://github.com/dgongut/docker-controller-bot) - Telegram bot to control docker containers. By [@dgongut](https://github.com/dgongut/). +- [Docker Client TypeScript](https://gitlab.com/masaeedu/docker-client) - Docker API client for JavaScript, automatically generated from Swagger API definition from moby repository. By [masaeedu](https://github.com/masaeedu). +- [docker-controller-bot](https://github.com/dgongut/docker-controller-bot) - Telegram bot to control docker containers. By [dgongut](https://github.com/dgongut/). - [docker-it-scala](https://github.com/whisklabs/docker-it-scala) - Docker integration testing kit with Scala. -- [docker-java-api](https://github.com/amihaiemil/docker-java-api) - Lightweight, truly object-oriented, Java client for Docker's API. By [@amihaiemil](https://github.com/amihaiemil). +- [docker-java-api](https://github.com/amihaiemil/docker-java-api) - Lightweight, truly object-oriented, Java client for Docker's API. By [amihaiemil](https://github.com/amihaiemil). - [docker-maven-plugin](https://github.com/fabric8io/docker-maven-plugin) - A Maven plugin for running and creating Docker images. - [Docker.DotNet](https://github.com/Microsoft/Docker.DotNet) - C#/.NET HTTP client for the Docker remote API. -- [Docker.Registry.DotNet](https://github.com/ChangemakerStudios/Docker.Registry.DotNet) - .NET (C#) Client Library for interacting with a Docker Registry API (v2) [@rquackenbush](https://github.com/rquackenbush). +- [Docker.Registry.DotNet](https://github.com/ChangemakerStudios/Docker.Registry.DotNet) - .NET (C#) Client Library for interacting with a Docker Registry API (v2) [rquackenbush](https://github.com/rquackenbush). - [dockerode](https://github.com/apocas/dockerode) - Docker Remote API node.js module. - [DoMonit](https://github.com/eon01/DoMonit) - A simple Docker Monitoring wrapper For Docker API. - [go-dockerclient](https://github.com/fsouza/go-dockerclient/) - Go HTTP client for the Docker remote API. - [Gradle Docker plugin](https://github.com/gesellix/gradle-docker-plugin) - A Docker remote api plugin for Gradle. -- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - :construction: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [@greenled](https://github.com/greenled). +- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - :construction: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [greenled](https://github.com/greenled). - [sbt-docker](https://github.com/marcuslonnberg/sbt-docker) - Create Docker images directly from sbt. ### CI/CD @@ -595,48 +552,44 @@ Services to securely store your Docker images. - [Cyclone](https://github.com/caicloud/cyclone) - Powerful workflow engine and end-to-end pipeline solutions implemented with native Kubernetes resources. - [Defang](https://github.com/DefangLabs/defang) - Deploy Docker Compose to your favorite cloud in minutes. - [Depot :heavy_dollar_sign:](https://depot.dev) - Build Docker images fast, in the cloud. Blazing fast compute, automatic intelligent caching, and zero configuration. [Done in seconds](https://depot.dev/#benchmarks). -- [Diun](https://github.com/crazy-max/diun) - Receive notifications when an image or repository is updated on a Docker registry by [@crazy-max]. +- [Diun](https://github.com/crazy-max/diun) - Receive notifications when an image or repository is updated on a Docker registry by [crazy-max]. - [dockcheck](https://github.com/mag37/dockcheck) - A script checking updates for docker images without pulling then auto-update selected/all containers. With notifications, pruning and more. - [Docker plugin for Jenkins](https://github.com/jenkinsci/docker-plugin/) - The aim of the docker plugin is to be able to use a docker host to dynamically provision a slave, run a single build, then tear-down that slave. - [Drone](https://github.com/drone/drone) - Continuous integration server built on Docker and configured using YAML files. -- [Drydock](https://github.com/CodesWhat/drydock) - Open-source container update monitoring with web dashboard, 15 registries, 16 notification triggers, and security scanning. Drop-in WUD replacement. By [@CodesWhat](https://github.com/CodesWhat). +- [Drydock](https://github.com/CodesWhat/drydock) - Open-source container update monitoring with web dashboard, 15 registries, 16 notification triggers, and security scanning. Drop-in WUD replacement. By [CodesWhat](https://github.com/CodesWhat). - [Gantry](https://github.com/shizunge/gantry) - Automatically update selected Docker swarm services. - [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) - GitLab has integrated CI to test, build and deploy your code with the use of GitLab runners. - [Jaypore CI](https://github.com/theSage21/jaypore_ci) - Simple, very flexible, powerful CI / CD / automation system configured in Python. Offline and local first. - [Kraken CI](https://github.com/Kraken-CI/kraken) - Modern CI/CD, open-source, on-premise system that is highly scalable and focused on testing. One of its executors is Docker. Developed. - [Microservices Continuous Deployment](https://github.com/francescou/docker-continuous-deployment) - Continuous deployment of a microservices application. -- [mu](https://github.com/stelligent/mu) - Tool to configure CI/CD of your container applications via AWS CodePipeline, CodeBuild and ECS [@Stelligent](https://github.com/stelligent). -- [Ouroboros](https://github.com/pyouroboros/ouroboros) - :skull: Automatically update running Docker containers with notifications. +- [mu](https://github.com/stelligent/mu) - Tool to configure CI/CD of your container applications via AWS CodePipeline, CodeBuild and ECS [Stelligent](https://github.com/stelligent). - [Popper](https://github.com/systemslab/popper) - Github actions workflow (HCL syntax) execution engine. - [Screwdriver :heavy_dollar_sign:](https://screwdriver.cd/) - Yahoo's OpenSource buildplatform designed for Continous Delivery. - [Skipper](https://github.com/Stratoscale/skipper) - Easily dockerize your Git repository. - [SwarmCI](https://github.com/ghostsquad/swarmci) - Create a distributed, isolated task pipeline in your Docker Swarm. - [Tekton CD](https://tekton.dev/) - A cloud-native pipeline resource. -- [Watchtower](https://github.com/containrrr/watchtower) - :skull: Automatically update running Docker containers. ### Development Environment -- [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [@TechnologyAdvice](https://github.com/TechnologyAdvice)). +- [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [TechnologyAdvice](https://github.com/TechnologyAdvice)). - [coder](https://github.com/coder/coder) - Remote development machines powered by Terraform or Docker. - [construi](https://github.com/lstephen/construi) - Run your builds inside a Docker defined environment. -- [dde](https://github.com/whatwedo/dde) - :construction: Local development environment toolset based on Docker. By [@whatwedo](https://github.com/whatwedo). -- [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [@bibendi](https://github.com/bibendi). -- [DLite](https://github.com/nlf/dlite) - :skull: Simplest way to use Docker on OSX, no VM needed. By [@nlf](https://github.com/nlf). -- [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [@dnephin](https://github.com/dnephin). -- [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [@NandoQuintana](https://github.com/nandoquintana). -- [Docker-Arch](https://github.com/Ph3nol/Docker-Arch) - Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [@Ph3nol](https://github.com/ph3nol). -- [Docker-sync](https://github.com/EugenMayer/docker-sync) - Drastically improves performance ([50-70x](https://github.com/EugenMayer/docker-sync/wiki/4.-Performance)) when using Docker for development on Mac OS X/Windows and Linux while sharing code to the container. By [@EugenMayer](https://github.com/EugenMayer). +- [dde](https://github.com/whatwedo/dde) - :construction: Local development environment toolset based on Docker. By [whatwedo](https://github.com/whatwedo). +- [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [bibendi](https://github.com/bibendi). +- [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [dnephin](https://github.com/dnephin). +- [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [NandoQuintana](https://github.com/nandoquintana). +- [Docker-Arch](https://github.com/Ph3nol/Docker-Arch) - Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [Ph3nol](https://github.com/ph3nol). +- [Docker-sync](https://github.com/EugenMayer/docker-sync) - Drastically improves performance ([50-70x](https://github.com/EugenMayer/docker-sync/wiki/4.-Performance)) when using Docker for development on Mac OS X/Windows and Linux while sharing code to the container. By [EugenMayer](https://github.com/EugenMayer). - [docker-vm](https://github.com/shyiko/docker-vm) - Simple and transparent alternative to boot2docker (backed by Vagrant). - [DockerDL](https://github.com/matifali/dockerdl) - Deep Learning Docker Images. Don't waste time setting up a deep learning env when you can get a deep learning environment with everything pre-installed. - [Eclipse Che](https://github.com/eclipse/che) - Developer workspace server with Docker runtimes, cloud IDE, next-generation Eclipse IDE. -- [EnvCLI](https://github.com/EnvCLI/EnvCLI) - Replace your local installation of Node, Go, ... with project-specific docker containers. By [@EnvCLI](https://github.com/EnvCLI). -- [ESP32 Linux - Docker builder](https://github.com/hpsaturn/esp32s3-linux) - Container solution to compile Linux and develop it for ESP32 microcontrollers - By [@Hpsaturn](https://github.com/hpsaturn). -- [forward2docker](https://github.com/bsideup/forward2docker) - :skull: Utility to auto forward a port from localhost into ports on Docker containers running in a boot2docker VM. +- [EnvCLI](https://github.com/EnvCLI/EnvCLI) - Replace your local installation of Node, Go, ... with project-specific docker containers. By [EnvCLI](https://github.com/EnvCLI). +- [ESP32 Linux - Docker builder](https://github.com/hpsaturn/esp32s3-linux) - Container solution to compile Linux and develop it for ESP32 microcontrollers - By [Hpsaturn](https://github.com/hpsaturn). - [Gebug](https://github.com/moshebe/gebug) - A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. -- [Kitt](https://github.com/senges/kitt) - A portable and disposable Shell environment, based on Docker and Nix. By [@senges](https://github.com/senges). +- [Kitt](https://github.com/senges/kitt) - A portable and disposable Shell environment, based on Docker and Nix. By [senges](https://github.com/senges). - [Lando](https://github.com/lando/lando) - Lando is for developers who want to quickly specify and painlessly spin up the services and tools needed to develop their projects. By [Tandem](https://www.thinktandem.io/). -- [Rust Universal Compiler](https://github.com/Peco602/rust-universal-compiler) - Container solution to compile Rust projects for Linux, macOS and Windows. By [@Peco602][peco602]. -- [uniget](https://github.com/uniget-org/cli) - Uni(versal)get, the installer and updater for container tools and beyond (formerly docker-setup). By [@nicholasdille](https://github.com/nicholasdille). +- [Rust Universal Compiler](https://github.com/Peco602/rust-universal-compiler) - Container solution to compile Rust projects for Linux, macOS and Windows. By [Peco602][peco602]. +- [uniget](https://github.com/uniget-org/cli) - Uni(versal)get, the installer and updater for container tools and beyond (formerly docker-setup). By [nicholasdille](https://github.com/nicholasdille). - [Vagga](https://github.com/tailhook/vagga) - Vagga is a containerisation tool without daemons. It is a fully-userspace container engine inspired by Vagrant and Docker, specialized for development environments. - [Zsh-in-Docker](https://github.com/deluan/zsh-in-docker) - Install Zsh, Oh-My-Zsh and plugins inside a Docker container with one line! By [Deluan](https://www.deluan.com). @@ -644,15 +597,14 @@ Services to securely store your Docker images. - [caduc](https://github.com/tjamet/caduc) - A docker garbage collector cleaning stuff you did not use recently. - [Docker Clean](https://github.com/ZZROTDesign/docker-clean) - A script that cleans Docker containers, images and volumes. -- [docker-custodian](https://github.com/Yelp/docker-custodian) - Keep docker hosts tidy. By [@Yelp](https://github.com/Yelp). +- [docker-custodian](https://github.com/Yelp/docker-custodian) - Keep docker hosts tidy. By [Yelp](https://github.com/Yelp). - [docker_gc](https://github.com/pdacity/docker_gc) - Image for automatic removing unused Docker Swarm objects. Also works just as Docker Service. - [Docuum](https://github.com/stepchowfun/docuum) - Least recently used (LRU) eviction of Docker images. ### Serverless -- [AMP](https://github.com/appcelerator-archive/amp) - :skull: The open source unified CaaS/FaaS platform for Docker, batteries included. By [@Appcelerator](https://github.com/appcelerator-archive). -- [Apache OpenWhisk](https://github.com/apache/openwhisk) - A serverless, open source cloud platform that executes functions in response to events at any scale. By [@apache](https://github.com/apache). -- [Funker](https://github.com/bfirsh/funker-example-voting-app) - Functions as Docker containers example voting app. By [@bfirsh](https://github.com/bfirsh). +- [Apache OpenWhisk](https://github.com/apache/openwhisk) - A serverless, open source cloud platform that executes functions in response to events at any scale. By [apache](https://github.com/apache). +- [Funker](https://github.com/bfirsh/funker-example-voting-app) - Functions as Docker containers example voting app. By [bfirsh](https://github.com/bfirsh). - [IronFunctions](https://github.com/iron-io/functions) - The serverless microservices platform FaaS (Functions as a Service) which uses Docker containers to run Any language or AWS Lambda functions. - [Koyeb](https://www.koyeb.com/) - :heavy_dollar_sign: Koyeb is a developer-friendly serverless platform to deploy apps globally. Seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. - [OpenFaaS](https://github.com/openfaas/faas) - A complete serverless functions framework for Docker and Kubernetes. By [OpenFaaS](https://github.com/openfaas). @@ -660,32 +612,27 @@ Services to securely store your Docker images. ### Testing -- [Container Structure Test](https://github.com/GoogleContainerTools/container-structure-test) - A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [@GoogleContainerTools][googlecontainertools]. +- [Container Structure Test](https://github.com/GoogleContainerTools/container-structure-test) - A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [GoogleContainerTools][googlecontainertools]. - [dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. -- [DockerSpec](https://github.com/zuazo/dockerspec) - A small Ruby Gem to run RSpec and Serverspec, Infrataster and Capybara tests against Dockerfiles or Docker images easily. By [@zuazo](https://github.com/zuazo). -- [Dockunit](https://github.com/dockunit/platform) - :skull: Docker based integration tests. A simple Node based utility for running Docker based unit tests. By [@dockunit](https://github.com/dockunit). -- [EZDC](https://github.com/lynchborg/ezdc) - Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [@byrnedo]. -- [InSpec][inspec] - InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements. By [@chef](https://github.com/chef) +- [DockerSpec](https://github.com/zuazo/dockerspec) - A small Ruby Gem to run RSpec and Serverspec, Infrataster and Capybara tests against Dockerfiles or Docker images easily. By [zuazo](https://github.com/zuazo). +- [EZDC](https://github.com/lynchborg/ezdc) - Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [byrnedo]. +- [InSpec][inspec] - InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements. By [chef](https://github.com/chef) - [Kurtosis](https://github.com/kurtosis-tech/kurtosis) - A composable build system for multi-container test environments that provides developers with: a powerful Python-like SDK for environment configuration, a compile-time validator to verify environment behavior & setup, and a runtime for environment execution, monitoring, & debugging capabilities. By [Kurtosis](https://www.kurtosis.com/). - [Pull Dog](https://github.com/apps/pull-dog) - A GitHub app that automatically creates Docker-based test environments for your pull requests, from your docker-compose files. Not open source. -- [Pumba](https://github.com/alexei-led/pumba) - Chaos testing tool for Docker. Can be deployed on kubernetes and CoreOS cluster. By [@alexei-led](https://github.com/alexei-led). +- [Pumba](https://github.com/alexei-led/pumba) - Chaos testing tool for Docker. Can be deployed on kubernetes and CoreOS cluster. By [alexei-led](https://github.com/alexei-led). ### Wrappers - [Ansible](https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html) - Manage the life cycle of Docker containers. By RedHat. -- [Azk](https://github.com/azukiapp/azk) - :skull: Orchestrate development environments on your local machine. -- [Beluga](https://github.com/cortexmedia/Beluga) - :skull: CLI to deploy docker containers on a single server or low amount of servers. By [@cortextmedia](https://github.com/cortexmedia). - [dexec](https://github.com/docker-exec/dexec) - Command line interface written in Go for running code with Docker Exec images. - [dockerized](https://github.com/benzaita/dockerized-cli) - Seamlessly execute commands in a container. - [Dray](https://github.com/CenturyLinkLabs/dray) - An engine for managing the execution of container-based workflows. -- [FuGu](https://github.com/mattes/fugu) - :skull: Docker run wrapper without orchestration. -- [Hokusai](https://github.com/artsy/hokusai) - A Docker + Kubernetes CLI for application developers; used to containerize an application and to manage its lifecycle throughout development, testing, and release cycles. From [@artsy](https://github.com/artsy). +- [Hokusai](https://github.com/artsy/hokusai) - A Docker + Kubernetes CLI for application developers; used to containerize an application and to manage its lifecycle throughout development, testing, and release cycles. From [artsy](https://github.com/artsy). - [Preevy](https://github.com/livecycle/preevy) - Preview environments for Docker and Docker Compose projects. Test your changes and get feedback from devs and non-devs (Product/Design) by deploying pull requests to the your cloud provider as part of your CI pipeline. - [Shutit](https://github.com/ianmiell/shutit) - Tool for building and maintaining complex Docker deployments. - [subuser](https://github.com/subuser-security/subuser) - Makes it easy to securely and portably run graphical desktop applications in Docker. -- [T.A.D.S. boilerplate](https://github.com/Thomvaill/tads-boilerplate) - :skull: The power of Ansible and Terraform + the simplicity of Docker Swarm = Infrastructure as Code and DevOps best practices. By [@Thomvaill](https://github.com/Thomvaill). - [Terraform cloud-init config](https://github.com/christippett/terraform-cloudinit-container-server) - Terraform module for deploying a single Docker image or `docker-compose.yaml` file to any Cloud™ VM. -- [Turbo](https://github.com/ramitsurana/turbo) - Simple and Powerful utility for docker. By [@ramitsurana][ramitsurana]. +- [Turbo](https://github.com/ramitsurana/turbo) - Simple and Powerful utility for docker. By [ramitsurana][ramitsurana]. - [udocker](https://github.com/indigo-dc/udocker) - A tool to execute simple docker containers in batch or interactive systems without root privileges. - [Vagrant - Docker provider](https://developer.hashicorp.com/vagrant/docs/providers/docker/basics) - Good starting point is [vagrant-docker-example](https://github.com/bubenkoff/vagrant-docker-example). @@ -723,7 +670,7 @@ Services to securely store your Docker images. - [DockStat](https://github.com/its4nik/dockstat) - :construction: A full fletched (WIP) Docker management solution featuring plugin support and community integration by [its4nik](https://github.com/its4nik). - [Prometheus](https://prometheus.io/) - :heavy_dollar_sign: Open-source service monitoring system and time series database. - [Site24x7](https://www.site24x7.com/docker-monitoring.html) - :heavy_dollar_sign: Docker Monitoring for DevOps and IT is a SaaS Pay per Host model. -- [SPM for Docker](https://github.com/sematext/sematext-agent-docker) - :heavy_dollar_sign: Monitoring of host and container metrics, Docker events and logs. Automatic log parser. Anomaly Detection and alerting for metrics and logs. [@sematext](https://github.com/sematext). +- [SPM for Docker](https://github.com/sematext/sematext-agent-docker) - :heavy_dollar_sign: Monitoring of host and container metrics, Docker events and logs. Automatic log parser. Anomaly Detection and alerting for metrics and logs. [sematext](https://github.com/sematext). - [Sysdig Monitor](https://www.sysdig.com/products/monitor) - :heavy_dollar_sign: Sysdig Monitor can be used as either software or a SaaS service to monitor, alert, and troubleshoot containers using system calls. It has container-specific features for Docker and Kubernetes. # Useful Resources @@ -745,26 +692,26 @@ Services to securely store your Docker images. - [Awesome CI/CD](https://github.com/cicdops/awesome-ciandcd) - Not specific to docker but relevant. - [Awesome Compose](https://github.com/docker/awesome-compose) - Docker Compose samples. -- [Awesome Kubernetes](https://github.com/ramitsurana/awesome-kubernetes) by [@ramitsurana][ramitsurana] -- [Awesome Linux Container](https://github.com/Friz-zy/awesome-linux-containers) more general about container than this repo, by [@Friz-zy](https://github.com/Friz-zy). -- [Awesome Selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted) list of Free Software network services and web applications which can be hosted locally by running in a classical way (setup local web server and run applications from there) or in a Docker container. By [@Kickball](https://github.com/Kickball) -- [Awesome Sysadmin](https://github.com/n1trux/awesome-sysadmin) by [@n1trux](https://github.com/n1trux) -- [ToolsOfTheTrade](https://github.com/cjbarber/ToolsOfTheTrade) a list of SaaS and On premise applications by [@cjbarber](https://github.com/cjbarber) +- [Awesome Kubernetes](https://github.com/ramitsurana/awesome-kubernetes) by [ramitsurana][ramitsurana] +- [Awesome Linux Container](https://github.com/Friz-zy/awesome-linux-containers) more general about container than this repo, by [Friz-zy](https://github.com/Friz-zy). +- [Awesome Selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted) list of Free Software network services and web applications which can be hosted locally by running in a classical way (setup local web server and run applications from there) or in a Docker container. By [Kickball](https://github.com/Kickball) +- [Awesome Sysadmin](https://github.com/n1trux/awesome-sysadmin) by [n1trux](https://github.com/n1trux) +- [ToolsOfTheTrade](https://github.com/cjbarber/ToolsOfTheTrade) a list of SaaS and On premise applications by [cjbarber](https://github.com/cjbarber) ## Demos and Examples - [An Annotated Docker Config for Frontend Web Development](https://nystudio107.com/blog/an-annotated-docker-config-for-frontend-web-development) A local development environment with Docker allows you to shrink-wrap the devops your project needs as config, making onboarding frictionless. -- [Local Docker DB](https://github.com/alexmacarthur/local-docker-db) a list of docker-compose samples for a lot of databases by [@alexmacarthur](https://github.com/alexmacarthur) +- [Local Docker DB](https://github.com/alexmacarthur/local-docker-db) a list of docker-compose samples for a lot of databases by [alexmacarthur](https://github.com/alexmacarthur) - [Webstack-micro](https://github.com/ferbs/webstack-micro) Demo web app showing how Docker Compose might be used to set up an API Gateway, centralized authentication, background workers, and WebSockets as containerized services. ## Good Tips - [Docker Caveats](http://docker-saigon.github.io/post/Docker-Caveats/) What You Should Know About Running Docker In Production (written 11 APRIL 2016) **MUST SEE** -- [Docker Containers on the Desktop](https://blog.jessfraz.com/post/docker-containers-on-the-desktop/) - The **funniest way** to learn about docker by [@jessfraz][jessfraz] who also gave a [presentation](https://www.youtube.com/watch?v=1qlLUf7KtAw) about it @ DockerCon 2015. +- [Docker Containers on the Desktop](https://blog.jessfraz.com/post/docker-containers-on-the-desktop/) - The **funniest way** to learn about docker by [jessfraz][jessfraz] who also gave a [presentation](https://www.youtube.com/watch?v=1qlLUf7KtAw) about it @ DockerCon 2015. - [Docker vs. VMs? Combining Both for Cloud Portability Nirvana](https://www.flexera.com/blog/finops/) - [Dockerfile best practices](https://github.com/hexops/dockerfile) - This repository has best-practices for writing Dockerfiles. -- [Don't Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files](https://medium.com/@kinghuang/docker-compose-anchors-aliases-extensions-a1e4105d70bd) by [@King Chung Huang](https://github.com/kinghuang) -- [GUI Apps with Docker](http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/) by [@fgrehm][fgrehm] +- [Don't Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files](https://medium.com/@kinghuang/docker-compose-anchors-aliases-extensions-a1e4105d70bd) by [King Chung Huang](https://github.com/kinghuang) +- [GUI Apps with Docker](http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/) by [fgrehm][fgrehm] ## Raspberry Pi & ARM @@ -776,7 +723,7 @@ Services to securely store your Docker images. ## Security - [Bringing new security features to Docker](https://opensource.com/business/14/9/security-for-docker) -- [CVE Scanning Alpine images with Multi-stage builds in Docker 17.05](https://github.com/tomwillfixit/alpine-cvecheck) by [@tomwillfixit](https://twitter.com/tomwillfixit) +- [CVE Scanning Alpine images with Multi-stage builds in Docker 17.05](https://github.com/tomwillfixit/alpine-cvecheck) by [tomwillfixit](https://twitter.com/tomwillfixit) - [Docker Secure Deployment Guidelines](https://github.com/AonCyberLabs/Docker-Secure-Deployment-Guidelines) - [Docker Security - Quick Reference](https://binarymist.io/publication/docker-security/) - [Docker Security: Are Your Containers Tightly Secured to the Ship? SlideShare](https://www.slideshare.net/slideshow/docker-security-are-your-containers-tightly-secured-to-the-ship/43834790) @@ -792,20 +739,20 @@ Services to securely store your Docker images. ## Videos - [Contributing to Docker by Andrew "Tianon" Page (InfoSiftr)](https://www.youtube.com/watch?v=1jwo8-1HYYg) (34:31) -- [Deploying and scaling applications with Docker, Swarm, and a tiny bit of Python magic](https://www.youtube.com/watch?v=GpHMTR7P2Ms) (3:11:06) by [@jpetazzo][jpetazzo] +- [Deploying and scaling applications with Docker, Swarm, and a tiny bit of Python magic](https://www.youtube.com/watch?v=GpHMTR7P2Ms) (3:11:06) by [jpetazzo][jpetazzo] - [Docker and SELinux by Daniel Walsh from Red Hat](https://www.youtube.com/watch?v=zWGFqMuEHdw) (40:23) -- [Docker Course](https://www.youtube.com/watch?v=UZpyvK6UGFo) (Spanish) by [@pablokbs](https://github.com/pablokbs) -- [Docker for Developers](https://www.youtube.com/watch?v=FdkNAjjO5yQ) (54:26) by [@jpetazzo][jpetazzo] <== Good introduction, context, demo +- [Docker Course](https://www.youtube.com/watch?v=UZpyvK6UGFo) (Spanish) by [pablokbs](https://github.com/pablokbs) +- [Docker for Developers](https://www.youtube.com/watch?v=FdkNAjjO5yQ) (54:26) by [jpetazzo][jpetazzo] <== Good introduction, context, demo - [Docker from scratch](https://www.youtube.com/playlist?list=PLLhEJK7fQIxD-btrjrqdEfQHbkZnQrmqE) (1:22:01) on YouTube by Paris Nakita Kejser - [Docker: How to Use Your Own Private Registry](https://www.youtube.com/watch?v=CAewZCBT4PI) (15:01) -- [Docker in Production](https://www.youtube.com/watch?v=Glk5d5WP6MI) by [@jpetazzo][jpetazzo] (36:05) +- [Docker in Production](https://www.youtube.com/watch?v=Glk5d5WP6MI) by [jpetazzo][jpetazzo] (36:05) - [Docker Primer to Docker Compose](https://www.youtube.com/watch?v=G-s2GXGAjTk) (1:56:45) on YouTube by LoginRadius - [Docker Registry from scratch](https://www.youtube.com/playlist?list=PLLhEJK7fQIxAz3d4Fj3edq7UcxEhdTCBm) (44:40) on YouTube by Paris Nakita Kejser - [Docker Swarm from scratch](https://www.youtube.com/playlist?list=PLLhEJK7fQIxAY4gZd1Wl-GsLvg-e9Ap1e) (1:41:28) on YouTube by Paris Nakita Kejser - [Extending Docker with Plugins](https://vimeo.com/110835013) (15:21) -- [From Local Docker Development to Production Deployments](https://www.youtube.com/watch?v=7CZFpHUPqXw) by [@jpetazzo][jpetazzo] @ AWS re:Invent 2015 +- [From Local Docker Development to Production Deployments](https://www.youtube.com/watch?v=7CZFpHUPqXw) by [jpetazzo][jpetazzo] @ AWS re:Invent 2015 - [Immutable Infrastructure with Docker and EC2 by Michael Bryzek (Gilt)](https://www.youtube.com/watch?v=GaHzdqFithc) (42:04) -- [Introduction to Docker and containers](https://www.youtube.com/watch?v=ZVaRK10HBjo) (3:09:00) by [@jpetazzo][jpetazzo] +- [Introduction to Docker and containers](https://www.youtube.com/watch?v=ZVaRK10HBjo) (3:09:00) by [jpetazzo][jpetazzo] - [Logging on Docker: What You Need to Know](https://vimeo.com/123341629) (51:27) - [Performance Analysis of Docker - Jeremy Eder](https://www.youtube.com/watch?v=6f2E6PKYb0w) (1:36:58) - [Scalable Microservices with Kubernetes](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) Free Udacity course @@ -817,10 +764,6 @@ Services to securely store your Docker images. - [Docker BR on Telegram](https://telegram.me/dockerbr) -## Chinese - -- [DockerOne](http://dockone.io/) Docker Community (in Chinese) by [@LiYingJie](http://dockone.io/people/%E6%9D%8E%E9%A2%96%E6%9D%B0) - ## English - [Docker Community](https://www.docker.com/community/) @@ -882,7 +825,7 @@ Services to securely store your Docker images. [vegasbrianc]: https://github.com/vegasbrianc [weave]: https://github.com/weaveworks/weave [vmware]: https://github.com/vmware -[@byrnedo]: https://github.com/byrnedo -[@crazy-max]: https://github.com/crazy-max -[@grammarly]: https://github.com/grammarly -[@skanehira]: https://github.com/skanehira +[byrnedo]: https://github.com/byrnedo +[crazy-max]: https://github.com/crazy-max +[grammarly]: https://github.com/grammarly +[skanehira]: https://github.com/skanehira From dc01ff137e4017dcd1c625cb254da2ee9841489c Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:06:37 +0100 Subject: [PATCH 16/29] chore(github): align contributor docs and CI with Go workflow --- .github/CODEOWNERS | 2 +- .github/CONTRIBUTING.md | 116 +++++++------------ .github/ISSUE_TEMPLATE/add-a-project.md | 9 +- .github/MAINTENANCE.md | 146 +++++++++--------------- .github/PULL_REQUEST_TEMPLATE.md | 58 +++------- .github/workflows/broken_links.yml | 2 +- .github/workflows/deploy-pages.yml | 2 +- .github/workflows/health_report.yml | 2 +- .github/workflows/pull_request.yml | 2 +- 9 files changed, 120 insertions(+), 219 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 55d6bb2..ad6cfe7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -*.md @veggiemonk @agebhar1 @dmitrytokarev @gesellix @mashb1t @moshloop @vegasbrianc @noteed +* @veggiemonk @agebhar1 @dmitrytokarev @gesellix @mashb1t @moshloop @vegasbrianc @noteed diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e0fdbe2..92cfeab 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,94 +1,56 @@ # Contributing to awesome-docker -First: if you're unsure or afraid of anything, just ask or submit the issue or pull request anyways. You won't be yelled at for giving your best effort. The worst that can happen is that you'll be politely asked to change something. We appreciate any sort of contributions, and don't want a wall of rules to get in the way of that. +Thanks for taking the time to contribute. -However, for those individuals who want a bit more guidance on the best way to contribute to the project, read on. This document will cover what we're looking for. By addressing all the points we're looking for, it raises the chances we can quickly merge or address your contributions. +This repository is a curated list of Docker/container resources plus a Go-based maintenance CLI used by CI. Contributions are welcome for both content and tooling. -We appreciate and recognize [all contributors](https://github.com/veggiemonk/awesome-docker/graphs/contributors). +Please read and follow the [Code of Conduct](./CODE_OF_CONDUCT.md). -Please note that this project is released with a [Contributor Code of Conduct](https://github.com/veggiemonk/awesome-docker/blob/master/.github/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. +## What We Accept -# Table of Contents +- New high-quality Docker/container-related projects +- Fixes to descriptions, ordering, or categorization +- Removal of broken, archived, deprecated, or duplicate entries +- Improvements to the Go CLI and GitHub workflows -- [Mission Statement](#mission-statement) -- [Quality Standards](#quality-standards) -- [Contribution Guidelines](#contribution-guidelines) -- [New Collaborators](#new-collaborators) +## README Entry Rules -# Mission Statement +- Use one link per entry. +- Prefer GitHub project/repository URLs over marketing pages. +- Keep entries alphabetically sorted within their section. +- Keep descriptions concise and concrete. +- Use `:construction:` for WIP projects. +- Use `:heavy_dollar_sign:` for paid/commercial services. +- Do not use `:skull:`; archived/deprecated projects should be removed. +- Avoid duplicate links and redirect variants. -`awesome-docker` is a hand-crafted list for high-quality information about Docker and its resources. It should be related or compatible with Docker or containers. If it's just an image built on top of Docker, the project possibly belongs to other [awesome lists](https://github.com/sindresorhus/awesome). You can check the [awesome-selfhosted list](https://github.com/Kickball/awesome-selfhosted) or the [awesome-sysadmin list](https://github.com/n1trux/awesome-sysadmin) as well. -If it's a **tutorial or a blog post**, they get outdated really quickly so we don't really put them on the list but if it is on a very advanced and/or specific topic, we will consider it! -If something is awesome, share it (pull request or [issue](https://github.com/veggiemonk/awesome-docker/issues/new) or [chat](https://gitter.im/veggiemonk/awesome-docker)), let us know why and we will help you! +## Local Validation -# Quality Standards +```bash +# Build CLI +make build -Note that we can help you achieve those standards, just try your best and be brave. -We'll guide you to the best of our abilities. +# Validate README formatting and content +make lint -To be on the list, it would be **nice** if entries adhere to these quality standards: +# Run code tests (when touching Go code) +make test -- It should take less than 20 sec to find what is the project, how to install it and how to use it. -- Generally useful to the community. -- A project on GitHub with a well documented `README.md` file and plenty of examples is considered high quality. -- Clearly stating if an entry is related to (Linux) containers and not to Docker. There is an [awesome list](https://github.com/Friz-zy/awesome-linux-containers) for that. -- Clearly stating "what is it" i.e. which category it belongs to. -- Clearly stating "what is it for" i.e. mention a real problem it solves (even a small one). Make it clear for the next person. -- If it is a **WIP** (work in progress, not safe for production), please mention it. (Remember the time before Docker 1.0 ? ;-) ) -- Always put the link to the GitHub project instead of the website! +# Optional: full external checks (requires GITHUB_TOKEN) +./awesome-docker check +./awesome-docker validate +``` -To be on the list, the project **must** have: +## Pull Request Expectations -- How to setup/install the project -- How to use the project (examples) +- Keep the PR focused to one logical change. +- Explain what changed and why. +- If adding entries, include the target category. +- If removing entries, explain why (archived, broken, duplicate, etc.). +- Fill in the PR template checklist. -If your PR is not merged, we will tell you why so that you may be able to improve it. -But usually, we are pretty relaxed people, so just come and say hi, we'll figure something out together. +## Maintainer Notes -# Contribution Guidelines - -## I want to share a project, what should I do? - -- **Adding to the list:** Submit a pull request or open an [issue](https://github.com/veggiemonk/awesome-docker/issues/new) -- **Removing from the list:** Submit a pull request or open an [issue](https://github.com/veggiemonk/awesome-docker/issues/new) -- Changing something else: Submit a pull request or open an [issue](https://github.com/veggiemonk/awesome-docker/issues/new) -- Don't know what to do: Open an [issue](https://github.com/veggiemonk/awesome-docker/issues/new) or join our [chat](https://gitter.im/veggiemonk/awesome-docker), let us know what's going on. - -**join the chat:** - -[![Join the chat at https://gitter.im/veggiemonk/awesome-docker](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/veggiemonk/awesome-docker) - -or you can - -**ping us on Twitter:** - -* [veggiemonk](https://twitter.com/veggiemonk) -* [idomyowntricks](https://twitter.com/idomyowntricks) -* [gesellix](https://twitter.com/gesellix) -* [dmitrytokarev](https://twitter.com/dmitrytok) - -### Rules for Pull Request - -- Each item should be limited to one link, no duplicates, no redirection (careful with `http` vs `https`!) -- The link should be the name of the package or project or website -- Description should be clear and concise (read it out loud to be sure) -- Description should follow the link, on the same line -- Entries are listed alphabetically, please respect the order -- If you want to add more than one link, please don't do all PR on the exact same line, it usually results in conflicts and your PR cannot be automatically merged... - -Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries. - -#### Your commit message will be a [tweet](https://twitter.com/awesome_docker) so write a [good commit message](https://chris.beams.io/posts/git-commit/), keep that in mind :) - -# New Collaborators - -If you just joined the team of maintainers for this repo, first of all: WELCOME! - -If it is your first time maintaining an open source project, read the [best practice guides for maintainers](https://opensource.guide/best-practices/). - -Here are the few things you need to know: -* We don't push directly to the master branch. Every entry **MUST** be reviewed! -* Each entry should be in accordance to this quality standards and contribution guidelines. -* To ask a contributor to make a change, just copy paste this message [here](https://github.com/veggiemonk/awesome-docker/pull/289#issuecomment-285608004) and change few things like names and stuff. **The main idea is to help people making great projects.** -* If something seems weird, i.e. if you don't understand what a project does or the documentation is poor, don't hesitate to (nicely) ask for more explanation (see previous point). -* Say thank you to people who contribute to this project! It may not seems like much but respect and gratitude are important :D +- Changes should be reviewed before merge. +- Prefer helping contributors improve a PR over silently rejecting it. +- Keep `.github` documentation and workflows aligned with current tooling. diff --git a/.github/ISSUE_TEMPLATE/add-a-project.md b/.github/ISSUE_TEMPLATE/add-a-project.md index 6b0333e..3be305e 100644 --- a/.github/ISSUE_TEMPLATE/add-a-project.md +++ b/.github/ISSUE_TEMPLATE/add-a-project.md @@ -1,18 +1,21 @@ --- name: Add a project about: Add a new project to the list -title: add [PROJECT_NAME] +title: "add: [PROJECT_NAME]" labels: pending-evaluation assignees: '' --- +Category: Repository link: -Description: +Description (one sentence): Author: +Why this should be in the list: +Notes (`:construction:` or `:heavy_dollar_sign:` if relevant): Or directly write it: ```markdown -[REPO](https://github.com/AUTHOR/REPO) - DESCRIPTION. By [@AUTHOR](https://github.com/AUTHOR) +[REPO](https://github.com/AUTHOR/REPO) - DESCRIPTION. By [AUTHOR](https://github.com/AUTHOR) ``` diff --git a/.github/MAINTENANCE.md b/.github/MAINTENANCE.md index 2dfa90d..bf76ce1 100644 --- a/.github/MAINTENANCE.md +++ b/.github/MAINTENANCE.md @@ -1,125 +1,81 @@ -# 🔧 Maintenance Guide for Awesome Docker +# Maintenance Guide -This guide helps maintainers keep the awesome-docker list up-to-date and high-quality. +This guide describes how maintainers keep the list and automation healthy. -## 🤖 Automated Systems +## Automated Workflows -### Weekly Health Reports -- **What**: Checks all GitHub repositories for activity, archived status, and maintenance -- **When**: Every Monday at 9 AM UTC -- **Where**: Creates/updates a GitHub issue with label `health-report` -- **Action**: Review the report and mark abandoned projects with `:skull:` +### Pull Requests / Weekly QA (`pull_request.yml`) -### Broken Links Detection -- **What**: Tests all links in README.md for availability -- **When**: Every Saturday at 2 AM UTC + on every PR -- **Where**: Creates/updates a GitHub issue with label `broken-links` -- **Action**: Fix or remove broken links, or add to exclusion list +- Runs on pull requests and weekly on Saturday. +- Builds the Go CLI and runs `./awesome-docker validate`. -### PR Validation -- **What**: Checks for duplicate links and basic validation -- **When**: On every pull request -- **Action**: Automated - contributors see results immediately +### Broken Links Report (`broken_links.yml`) -## 📋 Manual Maintenance Tasks +- Runs weekly on Saturday and on manual trigger. +- Executes `./awesome-docker check`. +- Opens/updates a `broken-links` issue when problems are found. -### Monthly Review (First Monday of the month) -1. Check health report issue for archived/stale projects -2. Mark archived projects with `:skull:` in README.md -3. Review projects with 2+ years of inactivity -4. Remove projects that are truly abandoned/broken +### Weekly Health Report (`health_report.yml`) -### Quarterly Deep Dive (Every 3 months) -1. Run: `./awesome-docker health` then `./awesome-docker report` for detailed report -2. Review project categories - are they still relevant? -3. Check for popular new Docker tools to add -4. Update documentation links if newer versions exist +- Runs weekly on Monday and on manual trigger. +- Executes `./awesome-docker health` then `./awesome-docker report`. +- Opens/updates a `health-report` issue. -### Annual Cleanup (January) -1. Remove all `:skull:` projects older than 1 year -2. Review CONTRIBUTING.md guidelines -3. Update year references in documentation +### Deploy to GitHub Pages (`deploy-pages.yml`) -## 🛠️ Maintenance Commands +- Runs on pushes to `master` and manual trigger. +- Builds website with `./awesome-docker build` and publishes `website/`. + +## Day-to-Day Commands ```bash -# Build the CLI -go build -o awesome-docker ./cmd/awesome-docker +# Build CLI +make build -# Lint README formatting (add --fix to auto-fix) -./awesome-docker lint +# README lint/validation +make lint + +# Auto-fix formatting issues ./awesome-docker lint --fix -# Check all links (requires GITHUB_TOKEN for GitHub repos) -./awesome-docker check - -# PR validation (lint + external link check) -./awesome-docker validate - -# Score repository health (requires GITHUB_TOKEN) -./awesome-docker health - -# Generate health report from cache -./awesome-docker report - -# Build the website -./awesome-docker build - -# Run tests -go test ./... +# Link checks and health checks (requires GITHUB_TOKEN) +make check +make health +make report ``` -## 📊 Quality Standards +## Content Maintenance Policy -### Adding New Projects -- Must have clear documentation (README with install/usage) -- Should have activity within last 18 months -- GitHub project preferred over website links -- Must be Docker/container-related +- Remove archived/deprecated projects instead of tagging them. +- Remove broken links that cannot be fixed. +- Keep sections alphabetically sorted. +- Keep descriptions short and actionable. -### Marking Projects as Abandoned -Use `:skull:` emoji when: -- Repository is archived on GitHub -- No commits for 2+ years -- Project explicitly states it's deprecated -- Maintainer confirms abandonment +## Suggested Review Cadence -### Removing Projects -Only remove (don't just mark `:skull:`): -- Broken/404 links that can't be fixed -- Duplicate entries -- Spam or malicious projects -- Projects that never met quality standards +### Weekly -## 🚨 Emergency Procedures +- Triage open `broken-links` and `health-report` issues. +- Merge straightforward quality PRs. -### Critical Broken Links -If important resources are down: -1. Check if they moved (update URL) -2. Search for alternatives -3. Check Internet Archive for mirrors -4. Temporarily comment out until resolved +### Monthly -### Spam Pull Requests -1. Close immediately -2. Mark as spam -3. Block user if repeated offense -4. Don't engage in comments +- Review sections for stale/duplicate entries. +- Re-run `check` and `health` manually if needed. -## 📈 Metrics to Track +### Quarterly -- Total projects: ~731 GitHub repos -- Health status: aim for <5% archived -- Link availability: aim for >98% working -- PR merge time: aim for <7 days -- Weekly contributor engagement +- Review `.github` docs and templates for drift. +- Confirm workflows still match repository tooling and policies. -## 🤝 Getting Help +## Contributor Support -- Open a discussion in GitHub Discussions -- Check AGENTS.md for AI assistant guidelines -- Review CONTRIBUTING.md for contributor info +When requesting PR changes, be explicit and actionable: + +- point to section/order problems, +- explain why a link should be removed, +- suggest exact wording when description quality is the issue. --- -*Last updated: 2025-10-01* +Last updated: 2026-02-27 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2079360..292823a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,48 +1,28 @@ - +# Summary - +Describe what changed and why. -# TLDR - * all entries sorted alphabetically (from A to Z), - * If paying service add :heavy_dollar_sign: - * If WIP add :construction: - * clear and short description of the project - * project MUST have: How to setup/install - * project MUST have: How to use (examples) - * we can help you get there :) +## Scope -## Quality Standards +- [ ] README entries/content +- [ ] Go CLI/tooling +- [ ] GitHub workflows or `.github` docs -Note that we can help you achieve those standards, just try your best and be brave. -We'll guide you to the best of our abilities. +## If This PR Adds/Edits README Entries -To be on the list, it would be **nice** if entries adhere to these quality standards: +- Category/section touched: +- New or updated project links: -- It should take less than 20 sec to find what is the project, how to install it and how to use it. -- Generally useful to the community. -- A project on GitHub with a well documented `README.md` file and plenty of examples is considered high quality. -- Clearly stating if an entry is related to (Linux) containers and not to Docker. There is an [awesome list](https://github.com/Friz-zy/awesome-linux-containers) for that. -- Clearly stating "what is it" i.e. which category it belongs to. -- Clearly stating "what is it for" i.e. mention a real problem it solves (even a small one). Make it clear for the next person. -- If it is a **WIP** (work in progress, not safe for production), please mention it. (Remember the time before Docker 1.0 ? ;-) ) -- Always put the link to the GitHub project instead of the website! +## Validation -To be on the list, the project **must** have: +- [ ] `make lint` +- [ ] `make test` (if Go code changed) +- [ ] `./awesome-docker check` (if `GITHUB_TOKEN` available) -- How to setup/install the project -- How to use the project (examples) - -If your PR is not merged, we will tell you why so that you may be able to improve it. -But usually, we are pretty relaxed people, so just come and say hi, we'll figure something out together. - -# Rules for Pull Request - -- Each item should be limited to one link, no duplicates, no redirection (careful with `http` vs `https`!) -- The link should be the name of the package or project or website -- Description should be clear and concise (read it out loud to be sure) -- Description should follow the link, on the same line -- Entries are listed alphabetically, please respect the order -- If you want to add more than one link, please don't do all PR on the exact same line, it usually results in conflicts and your PR cannot be automatically merged... - -Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries. +## Contributor Checklist +- [ ] Entries are alphabetically ordered in their section +- [ ] Links point to project repositories (no duplicates or redirects) +- [ ] Descriptions are concise and specific +- [ ] Archived/deprecated projects were removed instead of tagged +- [ ] Used `:construction:` and `:heavy_dollar_sign:` only when applicable diff --git a/.github/workflows/broken_links.yml b/.github/workflows/broken_links.yml index 5cc6c77..835eed2 100644 --- a/.github/workflows/broken_links.yml +++ b/.github/workflows/broken_links.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 9d90e25..0316332 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Build CLI run: go build -o awesome-docker ./cmd/awesome-docker diff --git a/.github/workflows/health_report.yml b/.github/workflows/health_report.yml index 3a95606..8fc5141 100644 --- a/.github/workflows/health_report.yml +++ b/.github/workflows/health_report.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index bc613fc..edb1936 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker From 1151490ae837e9eaf74593ba2f05a68228dfa99f Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:12:38 +0100 Subject: [PATCH 17/29] chore(readme): remove entries still marked as under construction --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 801a47d..45e7277 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [Capitan](https://github.com/byrnedo/capitan) - Composable docker orchestration with added scripting support by [byrnedo]. - [Composerize](https://github.com/magicmark/composerize) - Convert docker run commands into docker-compose files. - [crowdr](https://github.com/polonskiy/crowdr) - Tool for managing multiple Docker containers (`docker-compose` alternative). -- [ctk](https://github.com/ctk-hq/ctk) - :construction: Visual composer for container based workloads. By [corpulent](https://github.com/corpulent). +- [ctk](https://github.com/ctk-hq/ctk) - Visual composer for container based workloads. By [corpulent](https://github.com/corpulent). - [docker-config-update](https://github.com/sudo-bmitch/docker-config-update) - Utility to update docker configs and secrets for deploying in a compose file. - [elsy](https://github.com/cisco/elsy) - An opinionated, multi-language, build tool based on Docker and Docker Compose. - [habitus](https://github.com/cloud66-oss/habitus) - A Build Flow Tool for Docker. @@ -201,7 +201,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [NexClipper](https://github.com/NexClipper/NexClipper) - NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes. - [Out-of-the-box Host/Container Monitoring/Logging/Alerting Stack](https://github.com/uschtwill/docker_monitoring_logging_alerting) - Docker host and container monitoring, logging and alerting out of the box using cAdvisor, Prometheus, Grafana for monitoring, Elasticsearch, Kibana and Logstash for logging and elastalert and Alertmanager for alerting. Set up in 5 Minutes. Secure mode for production use with built-in [Automated Nginx Reverse Proxy (jwilder's)][nginxproxy]. - [Sidekick](https://github.com/runsidekick/sidekick) - Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. -- [SuperVisor CPM](https://t0xic0der.medium.com/simply-accessible-container-performance-monitoring-with-supervisor-7fb47f925f3b) - :construction: A simple and accessible FOSS container performance monitoring service written in Python. - [SwarmAlert](https://github.com/gpulido/SwarmAlert) - Monitors a Docker Swarm and sends Pushover alerts when it finds a container with no healthy service task running. - [Zabbix Docker](https://github.com/gomex/docker-zabbix) - Monitor containers automatically using zabbix LLD feature. - [Zabbix Docker module](https://github.com/monitoringartist/Zabbix-Docker-Monitoring) - Zabbix module that provides discovery of running containers, CPU/memory/blk IO/net container metrics. Systemd Docker and LXC execution driver is also supported. It's a dynamically linked shared object library, so its performance is (~10x) better, than any script solution. @@ -403,7 +402,6 @@ Native desktop applications for managing and monitoring docker hosts and cluster - [Swirl](https://github.com/cuigh/swirl) - Swirl is a web management tool for Docker, focused on swarm cluster By [cuigh](https://github.com/cuigh/). - [Theia](https://github.com/eclipse-theia/theia) - Extensible platform to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technologies. - [usulnet](https://github.com/fr4nsys/usulnet) - A complete and modern Docker management platform designed for sysadmin, devops with enterprise grade tools, cve scanner, ssh, rdp on web and much more. By [fr4nsys](https://github.com/fr4nsys). -- [Yacht](https://github.com/SelfhostedPro/Yacht) - :construction: A Web UI for docker that focuses on templates and ease of use in order to make deployments as easy as possible. By [SelfhostedPro](https://github.com/SelfhostedPro). ## Docker Images @@ -486,7 +484,6 @@ Examples by: - [Dockadvisor](https://github.com/deckrun/dockadvisor) - Lightweight Dockerfile linter with 60+ rules, quality scoring, and security checks. - [docker-image-size-limit](https://github.com/wemake-services/docker-image-size-limit) - A tool to keep an eye on your docker images size. - [Dockerfile Linter action](https://github.com/buddy-works/dockerfile-linter) - The linter lets you verify Dockerfile syntax to make sure it follows the best practices for building efficient Docker images. -- [dockfmt](https://github.com/jessfraz/dockfmt) - :construction: Dockerfile formatter and parser. - [FROM:latest](https://github.com/replicatedhq/dockerfilelint) - An opinionated Dockerfile linter. - [Hadolint](https://github.com/hadolint/hadolint) - A Dockerfile linter that checks for best practices, common mistakes, and is also able to lint any bash written in `RUN` instructions;. @@ -542,7 +539,7 @@ Services to securely store your Docker images. - [DoMonit](https://github.com/eon01/DoMonit) - A simple Docker Monitoring wrapper For Docker API. - [go-dockerclient](https://github.com/fsouza/go-dockerclient/) - Go HTTP client for the Docker remote API. - [Gradle Docker plugin](https://github.com/gesellix/gradle-docker-plugin) - A Docker remote api plugin for Gradle. -- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - :construction: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [greenled](https://github.com/greenled). +- [Portainer stack utils](https://github.com/greenled/portainer-stack-utils) - Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [greenled](https://github.com/greenled). - [sbt-docker](https://github.com/marcuslonnberg/sbt-docker) - Create Docker images directly from sbt. ### CI/CD @@ -574,7 +571,7 @@ Services to securely store your Docker images. - [Binci](https://github.com/binci/binci) - Containerize your development workflow. (formerly DevLab by [TechnologyAdvice](https://github.com/TechnologyAdvice)). - [coder](https://github.com/coder/coder) - Remote development machines powered by Terraform or Docker. - [construi](https://github.com/lstephen/construi) - Run your builds inside a Docker defined environment. -- [dde](https://github.com/whatwedo/dde) - :construction: Local development environment toolset based on Docker. By [whatwedo](https://github.com/whatwedo). +- [dde](https://github.com/whatwedo/dde) - Local development environment toolset based on Docker. By [whatwedo](https://github.com/whatwedo). - [DIP](https://github.com/bibendi/dip) - CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [bibendi](https://github.com/bibendi). - [dobi](https://github.com/dnephin/dobi) - A build automation tool for Docker applications. By [dnephin](https://github.com/dnephin). - [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) - A set of bash commands to shortcut typical docker dev-ops. An alternative to creating typical helper scripts like "build.sh" and "deploy.sh" inside code repositories. By [NandoQuintana](https://github.com/nandoquintana). @@ -667,7 +664,6 @@ Services to securely store your Docker images. - [Broadcom Docker Monitoring](https://www.broadcom.com/info/aiops/docker-monitoring) - :heavy_dollar_sign: Agile Operations solutions from Broadcom deliver the modern Docker monitoring businesses need to accelerate and optimize the performance of microservices and the dynamic Docker environments running them. Monitor both the Docker environment and apps that run inside them. (former CA Technologies). - [Collecting docker logs and stats with Splunk](https://www.splunk.com/en_us/blog/tips-and-tricks/collecting-docker-logs-and-stats-with-splunk.html) - [Datadog](https://www.datadoghq.com/) - :heavy_dollar_sign: Datadog is a full-stack monitoring service for large-scale cloud environments that aggregates metrics/events from servers, databases, and applications. It includes support for Docker, Kubernetes, and Mesos. -- [DockStat](https://github.com/its4nik/dockstat) - :construction: A full fletched (WIP) Docker management solution featuring plugin support and community integration by [its4nik](https://github.com/its4nik). - [Prometheus](https://prometheus.io/) - :heavy_dollar_sign: Open-source service monitoring system and time series database. - [Site24x7](https://www.site24x7.com/docker-monitoring.html) - :heavy_dollar_sign: Docker Monitoring for DevOps and IT is a SaaS Pay per Host model. - [SPM for Docker](https://github.com/sematext/sematext-agent-docker) - :heavy_dollar_sign: Monitoring of host and container metrics, Docker events and logs. Automatic log parser. Anomaly Detection and alerting for metrics and logs. [sematext](https://github.com/sematext). From a5e2b831b50ee58f4930d6374dfd53a3fe551170 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:18:01 +0100 Subject: [PATCH 18/29] Remove construction tag guidance from docs and templates --- .github/CONTRIBUTING.md | 1 - .github/ISSUE_TEMPLATE/add-a-project.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- README.md | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 92cfeab..f0ea65b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -19,7 +19,6 @@ Please read and follow the [Code of Conduct](./CODE_OF_CONDUCT.md). - Prefer GitHub project/repository URLs over marketing pages. - Keep entries alphabetically sorted within their section. - Keep descriptions concise and concrete. -- Use `:construction:` for WIP projects. - Use `:heavy_dollar_sign:` for paid/commercial services. - Do not use `:skull:`; archived/deprecated projects should be removed. - Avoid duplicate links and redirect variants. diff --git a/.github/ISSUE_TEMPLATE/add-a-project.md b/.github/ISSUE_TEMPLATE/add-a-project.md index 3be305e..2bdd313 100644 --- a/.github/ISSUE_TEMPLATE/add-a-project.md +++ b/.github/ISSUE_TEMPLATE/add-a-project.md @@ -12,7 +12,7 @@ Repository link: Description (one sentence): Author: Why this should be in the list: -Notes (`:construction:` or `:heavy_dollar_sign:` if relevant): +Notes (`:heavy_dollar_sign:` if relevant): Or directly write it: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 292823a..db556e1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -25,4 +25,4 @@ Describe what changed and why. - [ ] Links point to project repositories (no duplicates or redirects) - [ ] Descriptions are concise and specific - [ ] Archived/deprecated projects were removed instead of tagged -- [ ] Used `:construction:` and `:heavy_dollar_sign:` only when applicable +- [ ] Used `:heavy_dollar_sign:` only when applicable diff --git a/README.md b/README.md index 45e7277..46a7a67 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,6 @@ All the links are monitored and tested with a home baked [Node.js script](https: # Legend -- Beta :construction: - Monetized :heavy_dollar_sign: # What is Docker From 67cc5caaa5e1a0e9b43dae9be99108756c0d1868 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:27:36 +0100 Subject: [PATCH 19/29] Update agent guide for Go tooling and refresh README links --- AGENTS.md | 67 +++++++++++++++++++++++++++++++++++++++---------------- README.md | 14 +++++------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c557da7..eb56acf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,28 +1,57 @@ # Agent Guidelines for awesome-docker ## Commands -- Build website: `npm run build` (converts README.md to website/index.html) -- Test all links: `npm test` (runs tests/test_all.mjs, requires GITHUB_TOKEN) -- Test PR changes: `npm run test-pr` (runs tests/pull_request.mjs, checks duplicates) -- Health check: `npm run health-check` (generates HEALTH_REPORT.md, requires GITHUB_TOKEN) +- Build CLI: `make build` (or `go build -o awesome-docker ./cmd/awesome-docker`) +- Run tests: `make test` (runs `go test ./internal/... -v`) +- Lint README rules: `make lint` (runs `./awesome-docker lint`) +- Auto-fix lint issues: `./awesome-docker lint --fix` +- Check links: `make check` (runs `./awesome-docker check`; `GITHUB_TOKEN` enables GitHub repo checks) +- PR validation: `./awesome-docker validate` (lint + external link checks in PR mode) +- Build website: `./awesome-docker build` (generates `website/index.html` from `README.md`) +- Health scoring: `make health` (requires `GITHUB_TOKEN`, updates `config/health_cache.yaml`) +- Generate health report: `make report` ## Architecture -- **Main content**: README.md - curated list of Docker resources (markdown format) -- **Build script**: build.js - converts README.md to HTML using showdown & cheerio -- **Tests**: tests/*.mjs - link validation, duplicate detection, URL checking -- **Website**: website/ - static site deployment folder +- **Main content**: `README.md` (curated Docker/container resources) +- **CLI entrypoint**: `cmd/awesome-docker/main.go` (Cobra commands) +- **Core packages**: + - `internal/parser` - parse README sections and entries + - `internal/linter` - alphabetical/order/format validation + autofix + - `internal/checker` - HTTP and GitHub link checks + - `internal/scorer` - repository health scoring and report generation + - `internal/cache` - exclude list and health cache read/write + - `internal/builder` - render README to website HTML from template +- **Config**: + - `config/exclude.yaml` - known link-check exclusions + - `config/website.tmpl.html` - HTML template for site generation + - `config/health_cache.yaml` - persisted health scoring cache +- **Website output**: `website/index.html` ## Code Style -- **Language**: Node.js with ES modules (.mjs) for tests, CommonJS for build.js -- **Imports**: Use ES6 imports in .mjs files, require() in .js files -- **Error handling**: Use try/catch with LOG.error() and process.exit(1) for failures -- **Logging**: Use LOG object with error/debug methods (see build.js for pattern) -- **Async**: Prefer async/await over callbacks +- **Language**: Go +- **Formatting**: Keep code `gofmt`-clean +- **Testing**: Add/adjust table-driven tests in `internal/*_test.go` for behavior changes +- **Error handling**: Return wrapped errors (`fmt.Errorf("context: %w", err)`) from command handlers +- **CLI conventions**: Keep command behavior consistent with existing Cobra commands (`lint`, `check`, `health`, `build`, `report`, `validate`) + +## CI/Automation +- **PR + weekly validation**: `.github/workflows/pull_request.yml` + - Triggers on pull requests to `master` and weekly schedule + - Builds Go CLI and runs `./awesome-docker validate` +- **Weekly broken links issue**: `.github/workflows/broken_links.yml` + - Runs `./awesome-docker check` + - Opens/updates `broken-links` issue when failures are found +- **Weekly health report issue**: `.github/workflows/health_report.yml` + - Runs `./awesome-docker health` then `./awesome-docker report` + - Opens/updates `health-report` issue +- **GitHub Pages deploy**: `.github/workflows/deploy-pages.yml` + - On push to `master`, builds CLI, runs `./awesome-docker build`, deploys `website/` ## Content Guidelines (from CONTRIBUTING.md) -- Link to GitHub projects, not websites -- Entries are listed alphabetically (from A to Z) -- Entries must be Docker/container-related with clear documentation -- Include project description, installation, and usage examples -- Mark WIP projects explicitly -- Avoid outdated tutorials/blog posts unless advanced/specific +- Use one link per entry +- Prefer project/repository URLs over marketing pages +- Keep entries alphabetically ordered within each section +- Keep descriptions concise and concrete +- Use `:heavy_dollar_sign:` only for paid/commercial services +- Remove archived/deprecated projects instead of tagging them +- Avoid duplicate links and redirect variants diff --git a/README.md b/README.md index 46a7a67..00818bd 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) ### Monitoring - [Autoheal](https://github.com/willfarrell/docker-autoheal) - Monitor and restart unhealthy docker containers automatically. -- [Axibase Collector](https://axibase.com/docs/axibase-collector/) - Axibase Collector streams performance counters, configuration changes and lifecycle events from the Docker engine(s) into Axibase Time Series Database for roll-up dashboards and integration with upstream monitoring systems. - [cAdvisor](https://github.com/google/cadvisor) - Analyzes resource usage and performance characteristics of running containers. - [Checkmate](https://github.com/bluewave-labs/checkmate) - Checkmate is an open-source, self-hosted tool designed to track and monitor server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. - [DLIA](https://github.com/zorak1103/dlia) - DLIA is an AI-powered Docker log monitoring agent that uses Large Language Models (LLMs) to intelligently analyze container logs, detect anomalies, and provide contextual insights over time. By [zorak1103](https://github.com/zorak1103). @@ -190,7 +189,7 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/) - [dockprom](https://github.com/stefanprodan/dockprom) - Docker hosts and containers monitoring with Prometheus, Grafana, cAdvisor, NodeExporter and AlertManager. - [Doku](https://github.com/amerkurev/doku) - Doku is a simple web-based application that allows you to monitor Docker disk usage. [amerkurev](https://github.com/amerkurev). - [Dozzle](dozzle) - Monitor container logs in real-time with a browser or mobile device. [amir20](https://github.com/amir20). -- [Dynatrace](https://www.dynatrace.com/solutions/container-monitoring/) - :heavy_dollar_sign: Monitor containerized applications without installing agents or modifying your Run commands. +- [Dynatrace](https://docs.dynatrace.com/docs/observe/infrastructure-observability/container-platform-monitoring) - :heavy_dollar_sign: Monitor containerized applications without installing agents or modifying your Run commands. - [Glances](https://github.com/nicolargo/glances) - A cross-platform curses-based system monitoring tool written in Python. - [Grafana Docker Dashboard Template](https://grafana.com/grafana/dashboards/179-docker-prometheus-monitoring/) - A template for your Docker, Grafana and Prometheus stack [vegasbrianc][vegasbrianc]. - [HertzBeat](https://github.com/dromara/hertzbeat) - An open-source real-time monitoring system with custom-monitor and agentless. @@ -488,7 +487,7 @@ Examples by: ### Metadata -- [opencontainer](https://github.com/opencontainers/image-spec/blob/master/annotations.md) - A convention and shared namespace for Docker labels defined by OCI Image Spec. +- [opencontainer](https://github.com/opencontainers/image-spec/blob/main/annotations.md) - A convention and shared namespace for Docker labels defined by OCI Image Spec. ### Registry @@ -609,7 +608,7 @@ Services to securely store your Docker images. ### Testing - [Container Structure Test](https://github.com/GoogleContainerTools/container-structure-test) - A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [GoogleContainerTools][googlecontainertools]. -- [dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. +- [dgoss](https://github.com/goss-org/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. - [DockerSpec](https://github.com/zuazo/dockerspec) - A small Ruby Gem to run RSpec and Serverspec, Infrataster and Capybara tests against Dockerfiles or Docker images easily. By [zuazo](https://github.com/zuazo). - [EZDC](https://github.com/lynchborg/ezdc) - Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [byrnedo]. - [InSpec][inspec] - InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements. By [chef](https://github.com/chef) @@ -619,7 +618,7 @@ Services to securely store your Docker images. ### Wrappers -- [Ansible](https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html) - Manage the life cycle of Docker containers. By RedHat. +- [Ansible](https://docs.ansible.com/projects/ansible/latest/collections/community/general/docker_container_module.html) - Manage the life cycle of Docker containers. By RedHat. - [dexec](https://github.com/docker-exec/dexec) - Command line interface written in Go for running code with Docker Exec images. - [dockerized](https://github.com/benzaita/dockerized-cli) - Seamlessly execute commands in a container. - [Dray](https://github.com/CenturyLinkLabs/dray) - An engine for managing the execution of container-based workflows. @@ -638,7 +637,7 @@ Services to securely store your Docker images. - [CircleCI](https://circleci.com/) - :heavy_dollar_sign: Push or pull Docker images from your build environment, or build and run containers right on CircleCI. - [CodeFresh](https://codefresh.io) - :heavy_dollar_sign: Everything you need to build, test, and share your Docker applications. Provides automated end to end testing. -- [CodeShip](https://www.cloudbees.com/products/codeship) - :heavy_dollar_sign: Work with your established Docker workflows while automating your testing and deployment tasks with our hosted platform dedicated to speed and security. +- [CodeShip](https://www.cloudbees.com/blog/how-to-run-codeship-parallel-test-pipelines-efficiently-for-optimal-ci-parallelization) - :heavy_dollar_sign: Work with your established Docker workflows while automating your testing and deployment tasks with our hosted platform dedicated to speed and security. - [ConcourseCI](https://concourse-ci.org) - :heavy_dollar_sign: A CI SaaS platform for developers and DevOps teams pipeline oriented. - [Semaphore CI](https://semaphore.io/) :heavy_dollar_sign: — A high-performance cloud solution that makes it easy to build, test and ship your containers to production. - [TravisCI](https://www.travis-ci.com/) - :heavy_dollar_sign: A Free github projects continuous integration Saas platform for developers and Devops. @@ -650,11 +649,10 @@ Services to securely store your Docker images. - [Azure AKS](https://azure.microsoft.com/en-us/products/kubernetes-service/) - :heavy_dollar_sign: Simplify Kubernetes management, deployment, and operations. Use a fully managed Kubernetes container orchestration service. - [Cloud 66](https://www.cloud66.com) - :heavy_dollar_sign: Full-stack hosted container management as a service. - [Giant Swarm](https://www.giantswarm.io/) - :heavy_dollar_sign: Simple microservice infrastructure. Deploy your containers in seconds. -- [Google Container Engine](https://cloud.google.com/kubernetes-engine/docs/) - :heavy_dollar_sign: Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes]. +- [Google Container Engine](https://docs.cloud.google.com/kubernetes-engine/docs) - :heavy_dollar_sign: Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes]. - [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) - :heavy_dollar_sign: Integrated platform for data and containers built on Apache Mesos. - [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) - :heavy_dollar_sign: Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud. - [Triton](https://www.joyent.com/) - :heavy_dollar_sign: Elastic container-native infrastructure by Joyent. -- [Virtuozzo Application Platform](https://www.virtuozzo.com/application-platform-partners/) - :heavy_dollar_sign: Deploy and manage your projects with turnkey PaaS across a wide network of reliable service providers. ### Monitoring Services From ca2246667c84c69eb972fb4d771edec39487ac30 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 00:46:59 +0100 Subject: [PATCH 20/29] Harden health checks and refresh GitHub health cache --- cmd/awesome-docker/main.go | 6 + config/health_cache.yaml | 2122 +++++++++++++++++++++++++++++++ internal/checker/github.go | 41 +- internal/checker/github_test.go | 24 + 4 files changed, 2186 insertions(+), 7 deletions(-) create mode 100644 config/health_cache.yaml diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 2a7b9eb..e9267ab 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -200,6 +200,12 @@ func healthCmd() *cobra.Command { for _, e := range errs { fmt.Printf(" error: %v\n", e) } + if len(infos) == 0 { + if len(errs) > 0 { + return fmt.Errorf("failed to fetch GitHub metadata for all repositories (%d errors); check network/DNS and GITHUB_TOKEN", len(errs)) + } + return fmt.Errorf("no GitHub repositories found in README") + } scored := scorer.ScoreAll(infos) cacheEntries := scorer.ToCacheEntries(scored) diff --git a/config/health_cache.yaml b/config/health_cache.yaml new file mode 100644 index 0000000..bc130fd --- /dev/null +++ b/config/health_cache.yaml @@ -0,0 +1,2122 @@ +entries: + - url: https://github.com/byrnedo/capitan + name: byrnedo/capitan + status: stale + stars: 31 + last_push: 2017-06-07T09:46:56Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/magicmark/composerize + name: magicmark/composerize + status: healthy + stars: 3701 + forks: 247 + last_push: 2026-01-17T12:14:28Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/polonskiy/crowdr + name: polonskiy/crowdr + status: stale + stars: 98 + forks: 9 + last_push: 2020-10-09T07:57:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ctk-hq/ctk + name: ctk-hq/ctk + status: healthy + stars: 298 + forks: 27 + last_push: 2026-02-15T22:53:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/sudo-bmitch/docker-config-update + name: sudo-bmitch/docker-config-update + status: stale + stars: 51 + forks: 8 + last_push: 2023-03-30T13:03:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cisco/elsy + name: cisco/elsy + status: stale + stars: 80 + forks: 22 + last_push: 2022-01-18T13:38:49Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cloud66-oss/habitus + name: cloud66-oss/habitus + status: stale + stars: 1390 + forks: 82 + last_push: 2020-02-05T17:10:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/kubernetes/kompose + name: kubernetes/kompose + status: healthy + stars: 10459 + forks: 793 + last_push: 2026-02-27T14:23:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/av/harbor + name: av/harbor + status: healthy + stars: 2470 + forks: 164 + last_push: 2026-02-15T00:04:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ihucos/plash + name: ihucos/plash + status: healthy + stars: 387 + forks: 15 + last_push: 2025-03-20T15:47:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/containers/podman-compose + name: containers/podman-compose + status: healthy + stars: 5973 + forks: 576 + last_push: 2026-02-26T23:05:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/alexaandrov/stitchocker + name: alexaandrov/stitchocker + status: inactive + stars: 30 + forks: 3 + last_push: 2024-03-14T13:50:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ethibox/awesome-stacks + name: ethibox/awesome-stacks + status: healthy + stars: 1245 + forks: 162 + last_push: 2026-02-25T16:10:25Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/newrelic/centurion + name: newrelic/centurion + status: archived + stars: 1757 + forks: 112 + last_push: 2025-09-11T20:47:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/brooklyncentral/clocker + name: brooklyncentral/clocker + status: stale + stars: 429 + forks: 65 + last_push: 2018-10-24T15:29:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ehazlett/conduit + name: ehazlett/conduit + status: stale + stars: 108 + forks: 11 + last_push: 2016-11-07T18:20:56Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ContainX/depcon + name: ContainX/depcon + status: stale + stars: 93 + forks: 15 + last_push: 2018-06-05T04:40:23Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/deploystackio/docker-to-iac + name: deploystackio/docker-to-iac + status: healthy + stars: 23 + last_push: 2026-02-25T22:52:42Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hasura/gitkube + name: hasura/gitkube + status: stale + stars: 3850 + forks: 203 + last_push: 2023-08-31T07:48:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/grafeas/grafeas + name: grafeas/grafeas + status: healthy + stars: 1564 + forks: 307 + last_push: 2026-02-13T21:53:15Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/LombardiDaniel/swarm-ansible + name: LombardiDaniel/swarm-ansible + status: healthy + stars: 58 + forks: 4 + last_push: 2026-01-24T22:01:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hansehe/SwarmManagement + name: hansehe/SwarmManagement + status: healthy + stars: 21 + forks: 1 + last_push: 2025-05-13T15:24:25Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/werf/werf + name: werf/werf + status: healthy + stars: 4659 + forks: 230 + last_push: 2026-02-27T21:26:34Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/willfarrell/docker-autoheal + name: willfarrell/docker-autoheal + status: healthy + stars: 1800 + forks: 253 + last_push: 2025-09-09T16:33:25Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/google/cadvisor + name: google/cadvisor + status: healthy + stars: 18913 + forks: 2460 + last_push: 2026-02-19T21:28:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bluewave-labs/checkmate + name: bluewave-labs/checkmate + status: healthy + stars: 9321 + forks: 674 + last_push: 2026-02-27T16:58:09Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/zorak1103/dlia + name: zorak1103/dlia + status: healthy + stars: 3 + last_push: 2026-02-27T11:12:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/deltaskelta/docker-alertd + name: deltaskelta/docker-alertd + status: stale + stars: 108 + forks: 12 + last_push: 2017-11-15T04:40:06Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker-flow/docker-flow-monitor + name: docker-flow/docker-flow-monitor + status: stale + stars: 88 + forks: 38 + last_push: 2021-03-17T14:33:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/stefanprodan/dockprom + name: stefanprodan/dockprom + status: healthy + stars: 6484 + forks: 1769 + last_push: 2025-07-04T04:18:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/amerkurev/doku + name: amerkurev/doku + status: healthy + stars: 408 + forks: 18 + last_push: 2025-12-26T09:13:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nicolargo/glances + name: nicolargo/glances + status: healthy + stars: 31804 + forks: 1688 + last_push: 2026-02-27T09:35:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dromara/hertzbeat + name: dromara/hertzbeat + status: healthy + stars: 7103 + forks: 1255 + last_push: 2026-02-27T16:10:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/vegasbrianc/docker-monitoring + name: vegasbrianc/docker-monitoring + status: stale + stars: 473 + forks: 129 + last_push: 2018-06-10T20:53:49Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gliderlabs/logspout + name: gliderlabs/logspout + status: stale + stars: 4700 + forks: 669 + last_push: 2023-07-11T20:36:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/decryptus/monit-docker + name: decryptus/monit-docker + status: stale + stars: 34 + forks: 5 + last_push: 2023-01-16T11:31:14Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/NexClipper/NexClipper + name: NexClipper/NexClipper + status: stale + stars: 566 + forks: 72 + last_push: 2023-05-05T02:21:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/uschtwill/docker_monitoring_logging_alerting + name: uschtwill/docker_monitoring_logging_alerting + status: stale + stars: 540 + forks: 119 + last_push: 2018-09-13T07:36:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/runsidekick/sidekick + name: runsidekick/sidekick + status: stale + stars: 1611 + forks: 67 + last_push: 2023-06-29T12:18:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gpulido/SwarmAlert + name: gpulido/SwarmAlert + status: stale + stars: 22 + forks: 2 + last_push: 2019-11-27T12:17:14Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gomex/docker-zabbix + name: gomex/docker-zabbix + status: stale + stars: 53 + forks: 12 + last_push: 2017-07-28T14:29:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/monitoringartist/Zabbix-Docker-Monitoring + name: monitoringartist/Zabbix-Docker-Monitoring + status: stale + stars: 1197 + forks: 265 + last_push: 2022-02-22T17:01:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/coreos/flannel + name: coreos/flannel + status: healthy + stars: 9406 + forks: 2898 + last_push: 2026-02-23T14:17:42Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Microsoft/Freeflow + name: Microsoft/Freeflow + status: stale + stars: 632 + forks: 96 + last_push: 2023-06-12T19:30:22Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jason5ng32/MyIP + name: jason5ng32/MyIP + status: healthy + stars: 9859 + forks: 1072 + last_push: 2026-02-10T07:38:47Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nicolaka/netshoot + name: nicolaka/netshoot + status: healthy + stars: 10421 + forks: 1085 + last_push: 2026-01-28T16:42:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jpetazzo/pipework + name: jpetazzo/pipework + status: inactive + stars: 4251 + forks: 727 + last_push: 2024-11-04T17:31:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Peco602/ansible-linux-docker + name: Peco602/ansible-linux-docker + status: stale + stars: 37 + forks: 4 + last_push: 2023-06-21T09:34:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/athena-oss/athena + name: athena-oss/athena + status: stale + stars: 96 + forks: 25 + last_push: 2017-07-06T08:26:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/CloudSlang/cloud-slang + name: CloudSlang/cloud-slang + status: healthy + stars: 240 + forks: 83 + last_push: 2026-02-18T13:38:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/clusterdock/clusterdock + name: clusterdock/clusterdock + status: stale + stars: 29 + forks: 8 + last_push: 2023-05-16T18:05:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Dataman-Cloud/crane + name: Dataman-Cloud/crane + status: stale + stars: 749 + forks: 164 + last_push: 2023-08-31T09:46:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker-flow/docker-flow-swarm-listener + name: docker-flow/docker-flow-swarm-listener + status: stale + stars: 69 + forks: 50 + last_push: 2019-05-20T19:40:37Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Wowu/docker-rollout + name: Wowu/docker-rollout + status: healthy + stars: 3104 + forks: 93 + last_push: 2025-07-25T17:57:48Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/codeabovelab/haven-platform + name: codeabovelab/haven-platform + status: stale + stars: 296 + forks: 41 + last_push: 2018-07-06T11:21:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/kubernetes/kubernetes + name: kubernetes/kubernetes + status: healthy + stars: 120812 + forks: 42554 + last_push: 2026-02-27T20:09:31Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ManageIQ/manageiq + name: ManageIQ/manageiq + status: healthy + stars: 1387 + forks: 923 + last_push: 2026-02-27T17:24:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/apache/mesos + name: apache/mesos + status: inactive + stars: 5365 + forks: 1669 + last_push: 2024-08-23T18:59:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hashicorp/nomad + name: hashicorp/nomad + status: healthy + stars: 16237 + forks: 2059 + last_push: 2026-02-27T21:40:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/rancher/rancher + name: rancher/rancher + status: healthy + stars: 25387 + forks: 3170 + last_push: 2026-02-27T21:04:04Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/redherd-project/redherd-framework + name: redherd-project/redherd-framework + status: stale + stars: 74 + forks: 17 + last_push: 2023-04-25T18:54:33Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/crazy-max/swarm-cronjob + name: crazy-max/swarm-cronjob + status: healthy + stars: 862 + forks: 74 + last_push: 2026-02-27T07:02:23Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/caprover/caprover + name: caprover/caprover + status: healthy + stars: 14878 + forks: 964 + last_push: 2026-01-31T15:42:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/convox/rack + name: convox/rack + status: healthy + stars: 1893 + forks: 177 + last_push: 2026-02-12T19:55:53Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/pbertera/dcw + name: pbertera/dcw + status: stale + stars: 17 + forks: 3 + last_push: 2017-03-29T07:55:37Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dokku/dokku + name: dokku/dokku + status: healthy + stars: 31878 + forks: 2021 + last_push: 2026-02-27T13:54:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/remind101/empire + name: remind101/empire + status: stale + stars: 2682 + forks: 156 + last_push: 2023-11-25T17:16:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/exoframejs/exoframe + name: exoframejs/exoframe + status: healthy + stars: 1147 + forks: 59 + last_push: 2026-02-22T16:24:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/teamhephy/workflow + name: teamhephy/workflow + status: stale + stars: 419 + forks: 36 + last_push: 2023-09-27T17:30:49Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/krane/krane + name: krane/krane + status: stale + stars: 80 + forks: 8 + last_push: 2023-05-11T20:39:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nanobox-io/nanobox + name: nanobox-io/nanobox + status: stale + stars: 1624 + forks: 90 + last_push: 2019-10-21T20:03:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tsuru/tsuru + name: tsuru/tsuru + status: healthy + stars: 5252 + forks: 550 + last_push: 2026-02-25T21:15:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bunkerity/bunkerweb + name: bunkerity/bunkerweb + status: healthy + stars: 10066 + forks: 565 + last_push: 2026-02-27T08:50:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lucaslorentz/caddy-docker-proxy + name: lucaslorentz/caddy-docker-proxy + status: healthy + stars: 4300 + forks: 210 + last_push: 2026-02-25T20:22:54Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/invzhi/caddy-docker-upstreams + name: invzhi/caddy-docker-upstreams + status: healthy + stars: 36 + forks: 8 + last_push: 2025-09-08T05:17:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/moonbuggy/docker-dnsmasq-updater + name: moonbuggy/docker-dnsmasq-updater + status: inactive + stars: 35 + forks: 2 + last_push: 2025-02-09T00:21:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker-flow/docker-flow-proxy + name: docker-flow/docker-flow-proxy + status: healthy + stars: 321 + forks: 189 + last_push: 2025-12-05T02:29:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/fabiolb/fabio + name: fabiolb/fabio + status: healthy + stars: 7332 + forks: 624 + last_push: 2026-02-23T02:48:11Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion + name: nginx-proxy/docker-letsencrypt-nginx-proxy-companion + status: healthy + stars: 7698 + forks: 835 + last_push: 2026-02-15T12:34:13Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Yundera/mesh-router + name: Yundera/mesh-router + status: healthy + stars: 8 + last_push: 2026-02-27T21:23:25Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jc21/nginx-proxy-manager + name: jc21/nginx-proxy-manager + status: healthy + stars: 31873 + forks: 3627 + last_push: 2026-02-27T00:35:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Safe3/openresty-manager + name: Safe3/openresty-manager + status: healthy + stars: 1317 + forks: 97 + last_push: 2026-01-25T10:38:42Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/flavioaiello/swarm-router + name: flavioaiello/swarm-router + status: healthy + stars: 73 + forks: 12 + last_push: 2025-09-15T06:12:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/containous/traefik + name: containous/traefik + status: healthy + stars: 61956 + forks: 5848 + last_push: 2026-02-27T15:30:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cri-o/cri-o + name: cri-o/cri-o + status: healthy + stars: 5579 + forks: 1147 + last_push: 2026-02-27T21:48:13Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lxc/lxc + name: lxc/lxc + status: healthy + stars: 5115 + forks: 1162 + last_push: 2026-02-26T19:40:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/containers/libpod + name: containers/libpod + status: healthy + stars: 30828 + forks: 2995 + last_push: 2026-02-26T02:13:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/brauner/rlxc + name: brauner/rlxc + status: stale + stars: 18 + forks: 3 + last_push: 2021-06-30T13:12:28Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/opencontainers/runtime-tools + name: opencontainers/runtime-tools + status: healthy + stars: 472 + forks: 159 + last_push: 2025-12-05T00:49:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/SongStitch/anchor + name: SongStitch/anchor + status: inactive + stars: 24 + last_push: 2025-01-15T23:09:06Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/genuinetools/bane + name: genuinetools/bane + status: stale + stars: 1225 + forks: 91 + last_push: 2020-09-17T20:10:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dash14/buildcage + name: dash14/buildcage + status: healthy + stars: 3 + last_push: 2026-02-23T08:57:48Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hectorm/cetusguard + name: hectorm/cetusguard + status: healthy + stars: 82 + forks: 2 + last_push: 2026-02-09T12:53:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bridgecrewio/checkov + name: bridgecrewio/checkov + status: healthy + stars: 8487 + forks: 1306 + last_push: 2026-02-24T10:20:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dev-sec/cis-docker-benchmark + name: dev-sec/cis-docker-benchmark + status: stale + stars: 524 + forks: 118 + last_push: 2023-05-02T12:59:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/quay/clair + name: quay/clair + status: healthy + stars: 10932 + forks: 1195 + last_push: 2026-02-25T21:52:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/wolffcatskyy/crowdsec-blocklist-import + name: wolffcatskyy/crowdsec-blocklist-import + status: healthy + stars: 175 + forks: 4 + last_push: 2026-02-26T20:00:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/eliasgranderubio/dagda + name: eliasgranderubio/dagda + status: stale + stars: 1219 + forks: 169 + last_push: 2023-05-23T02:03:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/deepfence/ThreatMapper + name: deepfence/ThreatMapper + status: healthy + stars: 5235 + forks: 640 + last_push: 2026-01-08T17:51:41Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker/docker-bench-security + name: docker/docker-bench-security + status: inactive + stars: 9599 + forks: 1036 + last_push: 2024-10-21T07:26:06Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/google/docker-explorer + name: google/docker-explorer + status: inactive + stars: 552 + forks: 45 + last_push: 2024-10-04T07:44:31Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Peco602/dvwassl + name: Peco602/dvwassl + status: stale + stars: 6 + forks: 4 + last_push: 2023-04-30T17:03:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/checkmarx/kics + name: checkmarx/kics + status: healthy + stars: 2575 + forks: 360 + last_push: 2026-02-27T12:39:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/theupdateframework/notary + name: theupdateframework/notary + status: archived + stars: 3288 + forks: 520 + last_push: 2024-08-07T19:02:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/OpenSCAP/openscap + name: OpenSCAP/openscap + status: healthy + stars: 1672 + forks: 421 + last_push: 2026-02-27T12:44:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dormstern/segspec + name: dormstern/segspec + status: healthy + stars: 15 + last_push: 2026-02-23T11:39:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/anchore/syft + name: anchore/syft + status: healthy + stars: 8429 + forks: 776 + last_push: 2026-02-27T19:38:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/falcosecurity/falco + name: falcosecurity/falco + status: healthy + stars: 8694 + forks: 989 + last_push: 2026-02-27T12:34:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/aquasecurity/trivy + name: aquasecurity/trivy + status: healthy + stars: 32289 + forks: 2977 + last_push: 2026-02-26T18:00:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bytesharky/docker-dns + name: bytesharky/docker-dns + status: healthy + stars: 3 + forks: 1 + last_push: 2025-12-26T02:44:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/etcd-io/etcd + name: etcd-io/etcd + status: healthy + stars: 51580 + forks: 10330 + last_push: 2026-02-27T21:04:29Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/istio/istio + name: istio/istio + status: healthy + stars: 38054 + forks: 8250 + last_push: 2026-02-27T22:16:29Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gliderlabs/registrator + name: gliderlabs/registrator + status: healthy + stars: 4677 + forks: 909 + last_push: 2025-05-22T04:16:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/minio/minio + name: minio/minio + status: archived + stars: 60392 + forks: 7138 + last_push: 2026-02-12T20:18:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Storidge/quick-start + name: Storidge/quick-start + status: stale + stars: 1 + forks: 1 + last_push: 2019-09-09T21:42:15Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/AbianS/docker-db-manager + name: AbianS/docker-db-manager + status: healthy + stars: 155 + forks: 5 + last_push: 2025-11-26T09:24:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/felixgborrego/simple-docker-ui + name: felixgborrego/simple-docker-ui + status: inactive + stars: 607 + forks: 96 + last_push: 2024-09-06T09:31:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/slonopotamus/stevedore + name: slonopotamus/stevedore + status: healthy + stars: 368 + forks: 13 + last_push: 2026-02-27T11:51:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jr-k/d4s + name: jr-k/d4s + status: healthy + stars: 51 + forks: 4 + last_push: 2026-02-24T00:58:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/wagoodman/dive + name: wagoodman/dive + status: healthy + stars: 53433 + forks: 1949 + last_push: 2025-12-15T17:20:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lirantal/dockly + name: lirantal/dockly + status: healthy + stars: 4011 + forks: 163 + last_push: 2026-02-01T19:31:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/shubh-io/dockmate + name: shubh-io/dockmate + status: healthy + stars: 276 + forks: 5 + last_push: 2026-01-14T06:52:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/GhostWriters/DockSTARTer + name: GhostWriters/DockSTARTer + status: healthy + stars: 2543 + forks: 291 + last_push: 2026-02-25T19:44:53Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/durableprogramming/dprs + name: durableprogramming/dprs + status: healthy + stars: 36 + forks: 1 + last_push: 2026-02-12T20:14:04Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/moncho/dry + name: moncho/dry + status: healthy + stars: 3222 + forks: 102 + last_push: 2026-02-27T23:13:28Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ajayd-san/gomanagedocker + name: ajayd-san/gomanagedocker + status: inactive + stars: 632 + forks: 26 + last_push: 2024-12-28T07:44:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jesseduffield/lazydocker + name: jesseduffield/lazydocker + status: healthy + stars: 49901 + forks: 1577 + last_push: 2026-01-17T06:16:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Lifailon/lazyjournal + name: Lifailon/lazyjournal + status: healthy + stars: 1132 + forks: 27 + last_push: 2026-02-25T09:43:40Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mrjackwills/oxker + name: mrjackwills/oxker + status: healthy + stars: 1536 + forks: 41 + last_push: 2026-02-23T15:18:34Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jenssegers/captain + name: jenssegers/captain + status: stale + stars: 244 + forks: 11 + last_push: 2022-12-08T07:39:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Falldog/dcinja + name: Falldog/dcinja + status: healthy + stars: 13 + forks: 3 + last_push: 2025-06-26T12:33:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/exdx/dcp + name: exdx/dcp + status: stale + stars: 114 + forks: 3 + last_push: 2023-07-24T01:09:54Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/FabienD/docker-stack + name: FabienD/docker-stack + status: healthy + stars: 22 + forks: 2 + last_push: 2026-02-04T08:56:30Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/s0rg/decompose + name: s0rg/decompose + status: healthy + stars: 123 + forks: 6 + last_push: 2025-12-19T20:03:44Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/christian-korneck/docker-pushrm + name: christian-korneck/docker-pushrm + status: inactive + stars: 148 + forks: 3 + last_push: 2024-06-10T21:42:09Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lucabello/docker-captain + name: lucabello/docker-captain + status: healthy + stars: 2 + last_push: 2026-02-21T00:13:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mayflower/docker-ls + name: mayflower/docker-ls + status: archived + stars: 456 + forks: 68 + last_push: 2023-08-31T06:44:18Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/howtowhale/dvm + name: howtowhale/dvm + status: stale + stars: 524 + forks: 50 + last_push: 2022-03-30T13:23:11Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/iamsoorena/goinside + name: iamsoorena/goinside + status: stale + stars: 30 + forks: 2 + last_push: 2020-10-17T20:31:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/g31s/Pdocker + name: g31s/Pdocker + status: stale + stars: 7 + forks: 2 + last_push: 2021-02-27T06:42:13Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/shiwaforce/poco + name: shiwaforce/poco + status: healthy + stars: 109 + forks: 6 + last_push: 2026-02-24T16:23:44Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/JonathonReinhart/scuba + name: JonathonReinhart/scuba + status: healthy + stars: 96 + forks: 17 + last_push: 2026-01-26T04:03:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/containers/skopeo + name: containers/skopeo + status: healthy + stars: 10502 + forks: 907 + last_push: 2026-02-27T15:31:34Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/segersniels/supdock + name: segersniels/supdock + status: healthy + stars: 86 + forks: 3 + last_push: 2026-02-23T13:29:54Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/qazbnm456/tsaotun + name: qazbnm456/tsaotun + status: stale + stars: 58 + forks: 3 + last_push: 2022-10-04T06:53:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/vutran/dext-docker-registry-plugin + name: vutran/dext-docker-registry-plugin + status: stale + stars: 4 + forks: 1 + last_push: 2017-01-10T03:04:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jeroenpeeters/docker-ssh + name: jeroenpeeters/docker-ssh + status: stale + stars: 660 + forks: 89 + last_push: 2018-04-11T20:24:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/marty90/multidocker + name: marty90/multidocker + status: stale + stars: 56 + forks: 9 + last_push: 2018-11-27T15:12:56Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/adrianmo/powerline-docker + name: adrianmo/powerline-docker + status: stale + stars: 61 + forks: 6 + last_push: 2017-06-30T09:11:44Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/knrdl/casa + name: knrdl/casa + status: healthy + stars: 84 + forks: 5 + last_push: 2026-02-26T16:33:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/wrfly/container-web-tty + name: wrfly/container-web-tty + status: healthy + stars: 258 + forks: 46 + last_push: 2026-02-07T06:18:34Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ProductiveOps/dokemon + name: ProductiveOps/dokemon + status: stale + stars: 758 + forks: 36 + last_push: 2024-02-21T10:51:14Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/klausmeyer/docker-registry-browser + name: klausmeyer/docker-registry-browser + status: healthy + stars: 675 + forks: 61 + last_push: 2026-02-21T09:06:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mkuchin/docker-registry-web + name: mkuchin/docker-registry-web + status: stale + stars: 548 + forks: 133 + last_push: 2022-02-08T08:42:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dockersamples/docker-swarm-visualizer + name: dockersamples/docker-swarm-visualizer + status: inactive + stars: 3348 + forks: 594 + last_push: 2024-10-26T07:12:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/louislam/dockge + name: louislam/dockge + status: healthy + stars: 22251 + forks: 705 + last_push: 2026-01-21T10:51:44Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mbecker20/komodo + name: mbecker20/komodo + status: healthy + stars: 10397 + forks: 276 + last_push: 2026-02-27T22:21:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/kubevious/kubevious + name: kubevious/kubevious + status: stale + stars: 1693 + forks: 95 + last_push: 2024-01-15T18:42:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hywax/mafl + name: hywax/mafl + status: healthy + stars: 671 + forks: 52 + last_push: 2025-10-26T02:26:26Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/netdata/netdata + name: netdata/netdata + status: healthy + stars: 77906 + forks: 6359 + last_push: 2026-02-27T21:54:35Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/OctoLinker/OctoLinker + name: OctoLinker/OctoLinker + status: stale + stars: 5351 + forks: 283 + last_push: 2023-10-02T12:33:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/portainer/portainer + name: portainer/portainer + status: healthy + stars: 36692 + forks: 2779 + last_push: 2026-02-27T13:23:22Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ozlerhakan/rapid + name: ozlerhakan/rapid + status: stale + stars: 147 + forks: 24 + last_push: 2021-09-21T08:44:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tobegit3hub/seagull + name: tobegit3hub/seagull + status: stale + stars: 1939 + forks: 268 + last_push: 2017-11-22T02:11:23Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/swarmpit/swarmpit + name: swarmpit/swarmpit + status: healthy + stars: 3407 + forks: 312 + last_push: 2026-01-25T16:08:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cuigh/swirl + name: cuigh/swirl + status: stale + stars: 667 + forks: 83 + last_push: 2023-05-16T02:47:48Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/eclipse-theia/theia + name: eclipse-theia/theia + status: healthy + stars: 21381 + forks: 2799 + last_push: 2026-02-27T22:10:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/fr4nsys/usulnet + name: fr4nsys/usulnet + status: healthy + stars: 71 + forks: 2 + last_push: 2026-02-23T23:00:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/genuinetools/amicontained + name: genuinetools/amicontained + status: stale + stars: 1072 + forks: 71 + last_push: 2020-12-09T04:37:59Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/garywiz/chaperone + name: garywiz/chaperone + status: stale + stars: 178 + forks: 31 + last_push: 2020-07-16T21:30:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nicomt/ckron + name: nicomt/ckron + status: healthy + stars: 56 + forks: 6 + last_push: 2026-02-15T17:58:14Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/GoogleContainerTools/distroless + name: GoogleContainerTools/distroless + status: healthy + stars: 22291 + forks: 1361 + last_push: 2026-02-27T21:06:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gliderlabs/docker-alpine + name: gliderlabs/docker-alpine + status: stale + stars: 5719 + forks: 530 + last_push: 2021-04-01T08:02:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jwilder/docker-gen + name: jwilder/docker-gen + status: healthy + stars: 4616 + forks: 615 + last_push: 2026-02-13T13:22:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/powerman/dockerize + name: powerman/dockerize + status: healthy + stars: 195 + forks: 17 + last_push: 2026-02-23T15:53:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tianon/gosu + name: tianon/gosu + status: healthy + stars: 4947 + forks: 356 + last_push: 2026-02-21T00:14:55Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/sindresorhus/is-docker + name: sindresorhus/is-docker + status: healthy + stars: 231 + forks: 16 + last_push: 2025-09-15T21:04:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ivanilves/lstags + name: ivanilves/lstags + status: stale + stars: 340 + forks: 26 + last_push: 2023-05-11T20:38:37Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tarampampam/microcheck + name: tarampampam/microcheck + status: healthy + stars: 127 + forks: 2 + last_push: 2026-02-24T19:11:41Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mcuadros/ofelia + name: mcuadros/ofelia + status: healthy + stars: 3731 + forks: 204 + last_push: 2026-02-27T07:34:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/beyondssl/sparkview-container + name: beyondssl/sparkview-container + status: healthy + stars: 20 + forks: 2 + last_push: 2025-09-22T06:59:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ncopa/su-exec + name: ncopa/su-exec + status: healthy + stars: 1017 + forks: 103 + last_push: 2025-10-07T13:49:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/theAkito/sue + name: theAkito/sue + status: stale + stars: 13 + forks: 1 + last_push: 2022-04-26T21:10:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/aptible/supercronic + name: aptible/supercronic + status: healthy + stars: 2383 + forks: 141 + last_push: 2026-02-11T20:22:54Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/vorakl/TrivialRC + name: vorakl/TrivialRC + status: stale + stars: 31 + forks: 5 + last_push: 2023-12-20T00:39:55Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ansible-community/ansible-bender + name: ansible-community/ansible-bender + status: healthy + stars: 692 + forks: 74 + last_push: 2026-01-07T23:21:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/containers/buildah + name: containers/buildah + status: healthy + stars: 8633 + forks: 879 + last_push: 2026-02-27T18:52:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/moby/buildkit + name: moby/buildkit + status: healthy + stars: 9795 + forks: 1373 + last_push: 2026-02-27T15:45:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cekit/cekit + name: cekit/cekit + status: healthy + stars: 113 + forks: 44 + last_push: 2026-01-30T15:06:33Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mutable/container-factory + name: mutable/container-factory + status: stale + stars: 64 + forks: 3 + last_push: 2015-05-06T16:07:53Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mdlavin/copy-docker-image + name: mdlavin/copy-docker-image + status: stale + stars: 38 + forks: 16 + last_push: 2018-08-29T08:27:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/alibaba/derrick + name: alibaba/derrick + status: stale + stars: 694 + forks: 109 + last_push: 2023-03-06T22:40:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/orisano/dlayer + name: orisano/dlayer + status: healthy + stars: 445 + forks: 12 + last_push: 2026-02-11T11:03:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mudler/docker-companion + name: mudler/docker-companion + status: healthy + stars: 47 + forks: 9 + last_push: 2025-05-28T08:17:46Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/CtripCloud/docker-make + name: CtripCloud/docker-make + status: stale + stars: 99 + forks: 20 + last_push: 2019-11-22T08:32:26Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/orf/docker-repack + name: orf/docker-repack + status: healthy + stars: 151 + forks: 3 + last_push: 2025-04-24T06:46:00Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bcicen/docker-replay + name: bcicen/docker-replay + status: stale + stars: 203 + forks: 13 + last_push: 2018-10-13T13:09:28Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/swipely/dockly + name: swipely/dockly + status: stale + stars: 228 + forks: 10 + last_push: 2023-02-15T15:26:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/utensils/essex + name: utensils/essex + status: healthy + stars: 38 + last_push: 2025-03-18T21:33:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/NVIDIA/hpc-container-maker + name: NVIDIA/hpc-container-maker + status: healthy + stars: 508 + forks: 100 + last_push: 2026-02-19T23:22:06Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/genuinetools/img + name: genuinetools/img + status: inactive + stars: 3990 + forks: 234 + last_push: 2024-05-19T22:07:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/duedil-ltd/portainer + name: duedil-ltd/portainer + status: stale + stars: 134 + forks: 16 + last_push: 2017-02-28T17:15:49Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cybersecsi/RAUDI + name: cybersecsi/RAUDI + status: healthy + stars: 560 + forks: 34 + last_push: 2026-02-26T09:33:46Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lavie/runlike + name: lavie/runlike + status: healthy + stars: 2916 + forks: 162 + last_push: 2025-12-04T12:36:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/theAkito/userdef + name: theAkito/userdef + status: stale + stars: 11 + last_push: 2023-10-14T20:34:12Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/P3GLEG/Whaler + name: P3GLEG/Whaler + status: healthy + stars: 1185 + forks: 101 + last_push: 2025-09-17T03:56:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Gueils/whales + name: Gueils/whales + status: stale + stars: 391 + forks: 20 + last_push: 2019-05-27T13:20:14Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/garywiz/chaperone-docker + name: garywiz/chaperone-docker + status: stale + stars: 66 + forks: 11 + last_push: 2018-10-05T07:48:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/patrickhoefler/dockerfilegraph + name: patrickhoefler/dockerfilegraph + status: healthy + stars: 255 + forks: 17 + last_push: 2026-02-26T05:40:58Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Dockershelf/dockershelf + name: Dockershelf/dockershelf + status: healthy + stars: 97 + forks: 13 + last_push: 2026-01-22T01:03:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/deckrun/dockadvisor + name: deckrun/dockadvisor + status: healthy + stars: 178 + forks: 6 + last_push: 2026-01-12T09:26:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/wemake-services/docker-image-size-limit + name: wemake-services/docker-image-size-limit + status: healthy + stars: 130 + forks: 5 + last_push: 2026-02-27T11:53:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/buddy-works/dockerfile-linter + name: buddy-works/dockerfile-linter + status: stale + stars: 46 + forks: 3 + last_push: 2023-03-04T05:06:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/replicatedhq/dockerfilelint + name: replicatedhq/dockerfilelint + status: stale + stars: 1031 + forks: 83 + last_push: 2023-09-27T20:58:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hadolint/hadolint + name: hadolint/hadolint + status: healthy + stars: 11966 + forks: 487 + last_push: 2026-01-27T13:27:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/RedCoolBeans/cargos-buildroot + name: RedCoolBeans/cargos-buildroot + status: stale + stars: 11 + forks: 2 + last_push: 2017-04-02T14:59:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hcguersoy/cleanreg + name: hcguersoy/cleanreg + status: stale + stars: 59 + forks: 18 + last_push: 2022-09-03T17:43:40Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/netvarun/docket + name: netvarun/docket + status: stale + stars: 709 + forks: 33 + last_push: 2020-09-02T02:35:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dragonflyoss/Dragonfly2 + name: dragonflyoss/Dragonfly2 + status: healthy + stars: 3049 + forks: 373 + last_push: 2026-02-25T02:37:31Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/uber/kraken + name: uber/kraken + status: healthy + stars: 6653 + forks: 468 + last_push: 2026-02-25T13:57:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jhstatewide/nscr + name: jhstatewide/nscr + status: healthy + stars: 1 + last_push: 2025-10-27T14:37:18Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/inmagik/registryo + name: inmagik/registryo + status: healthy + stars: 15 + last_push: 2025-12-17T10:20:47Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/noteed/rescoyl + name: noteed/rescoyl + status: stale + stars: 18 + forks: 4 + last_push: 2017-04-08T19:17:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/instacart/ahab + name: instacart/ahab + status: stale + stars: 137 + forks: 7 + last_push: 2018-11-16T21:54:44Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lispyclouds/contajners + name: lispyclouds/contajners + status: healthy + stars: 145 + forks: 8 + last_push: 2026-02-20T09:07:36Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gesellix/docker-client + name: gesellix/docker-client + status: healthy + stars: 119 + forks: 28 + last_push: 2026-02-27T16:52:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dgongut/docker-controller-bot + name: dgongut/docker-controller-bot + status: healthy + stars: 240 + forks: 31 + last_push: 2026-02-04T15:58:07Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/whisklabs/docker-it-scala + name: whisklabs/docker-it-scala + status: stale + stars: 433 + forks: 90 + last_push: 2024-02-14T12:56:54Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/amihaiemil/docker-java-api + name: amihaiemil/docker-java-api + status: stale + stars: 274 + forks: 55 + last_push: 2021-06-04T01:21:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/fabric8io/docker-maven-plugin + name: fabric8io/docker-maven-plugin + status: healthy + stars: 1928 + forks: 656 + last_push: 2026-02-24T15:30:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Microsoft/Docker.DotNet + name: Microsoft/Docker.DotNet + status: healthy + stars: 2403 + forks: 407 + last_push: 2025-08-28T14:08:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ChangemakerStudios/Docker.Registry.DotNet + name: ChangemakerStudios/Docker.Registry.DotNet + status: healthy + stars: 42 + forks: 21 + last_push: 2025-10-06T03:43:52Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/apocas/dockerode + name: apocas/dockerode + status: healthy + stars: 4827 + forks: 486 + last_push: 2026-01-09T08:49:53Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/eon01/DoMonit + name: eon01/DoMonit + status: stale + stars: 76 + forks: 15 + last_push: 2021-06-01T21:57:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/fsouza/go-dockerclient + name: fsouza/go-dockerclient + status: healthy + stars: 2236 + forks: 555 + last_push: 2026-02-26T03:52:11Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/gesellix/gradle-docker-plugin + name: gesellix/gradle-docker-plugin + status: healthy + stars: 81 + forks: 17 + last_push: 2026-02-27T14:32:37Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/greenled/portainer-stack-utils + name: greenled/portainer-stack-utils + status: healthy + stars: 74 + forks: 16 + last_push: 2025-12-05T02:34:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/marcuslonnberg/sbt-docker + name: marcuslonnberg/sbt-docker + status: inactive + stars: 733 + forks: 112 + last_push: 2024-12-12T15:18:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/harbur/captain + name: harbur/captain + status: healthy + stars: 776 + forks: 48 + last_push: 2025-05-25T00:09:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/caicloud/cyclone + name: caicloud/cyclone + status: stale + stars: 1074 + forks: 171 + last_push: 2023-10-24T12:08:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/DefangLabs/defang + name: DefangLabs/defang + status: healthy + stars: 146 + forks: 24 + last_push: 2026-02-27T19:16:01Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/crazy-max/diun + name: crazy-max/diun + status: healthy + stars: 4428 + forks: 144 + last_push: 2026-02-27T07:02:29Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/mag37/dockcheck + name: mag37/dockcheck + status: healthy + stars: 2221 + forks: 77 + last_push: 2026-02-06T17:07:58Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/jenkinsci/docker-plugin + name: jenkinsci/docker-plugin + status: healthy + stars: 498 + forks: 325 + last_push: 2026-01-16T13:00:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/drone/drone + name: drone/drone + status: healthy + stars: 33826 + forks: 2894 + last_push: 2026-02-27T08:17:22Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/CodesWhat/drydock + name: CodesWhat/drydock + status: healthy + stars: 93 + forks: 4 + last_push: 2026-02-24T04:20:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/shizunge/gantry + name: shizunge/gantry + status: healthy + stars: 86 + forks: 4 + last_push: 2026-02-24T05:29:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/theSage21/jaypore_ci + name: theSage21/jaypore_ci + status: stale + stars: 38 + forks: 4 + last_push: 2023-06-03T17:03:43Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Kraken-CI/kraken + name: Kraken-CI/kraken + status: healthy + stars: 160 + forks: 20 + last_push: 2026-01-15T13:00:32Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/francescou/docker-continuous-deployment + name: francescou/docker-continuous-deployment + status: stale + stars: 145 + forks: 38 + last_push: 2017-08-01T17:25:15Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/stelligent/mu + name: stelligent/mu + status: stale + stars: 965 + forks: 133 + last_push: 2020-06-18T14:09:29Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/systemslab/popper + name: systemslab/popper + status: stale + stars: 307 + forks: 62 + last_push: 2022-03-29T22:02:27Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Stratoscale/skipper + name: Stratoscale/skipper + status: healthy + stars: 50 + forks: 22 + last_push: 2025-05-13T13:33:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ghostsquad/swarmci + name: ghostsquad/swarmci + status: stale + stars: 58 + forks: 6 + last_push: 2017-02-24T02:14:18Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/binci/binci + name: binci/binci + status: stale + stars: 673 + forks: 24 + last_push: 2022-12-06T20:24:40Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/coder/coder + name: coder/coder + status: healthy + stars: 12338 + forks: 1177 + last_push: 2026-02-27T23:34:35Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lstephen/construi + name: lstephen/construi + status: stale + stars: 24 + forks: 5 + last_push: 2022-12-08T06:36:04Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/whatwedo/dde + name: whatwedo/dde + status: healthy + stars: 46 + forks: 9 + last_push: 2026-02-20T12:25:04Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bibendi/dip + name: bibendi/dip + status: inactive + stars: 1322 + forks: 50 + last_push: 2024-12-25T09:38:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/dnephin/dobi + name: dnephin/dobi + status: stale + stars: 315 + forks: 34 + last_push: 2023-11-10T06:32:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/nandoquintana/docker-missing-tools + name: nandoquintana/docker-missing-tools + status: stale + stars: 30 + forks: 6 + last_push: 2018-05-01T13:10:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Ph3nol/Docker-Arch + name: Ph3nol/Docker-Arch + status: stale + stars: 31 + forks: 2 + last_push: 2018-09-24T06:43:08Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/EugenMayer/docker-sync + name: EugenMayer/docker-sync + status: healthy + stars: 3565 + forks: 285 + last_push: 2025-11-30T20:06:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/shyiko/docker-vm + name: shyiko/docker-vm + status: stale + stars: 43 + forks: 8 + last_push: 2016-09-24T17:45:47Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/matifali/dockerdl + name: matifali/dockerdl + status: healthy + stars: 86 + forks: 11 + last_push: 2025-12-29T19:27:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/eclipse/che + name: eclipse/che + status: healthy + stars: 7128 + forks: 1199 + last_push: 2026-02-27T12:40:18Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/EnvCLI/EnvCLI + name: EnvCLI/EnvCLI + status: healthy + stars: 116 + forks: 4 + last_push: 2025-06-16T20:36:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hpsaturn/esp32s3-linux + name: hpsaturn/esp32s3-linux + status: healthy + stars: 78 + forks: 9 + last_push: 2025-04-05T08:38:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/moshebe/gebug + name: moshebe/gebug + status: healthy + stars: 634 + forks: 17 + last_push: 2026-02-27T21:45:21Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/senges/kitt + name: senges/kitt + status: stale + stars: 20 + forks: 1 + last_push: 2023-02-23T14:01:05Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lando/lando + name: lando/lando + status: healthy + stars: 4220 + forks: 530 + last_push: 2026-02-24T21:10:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Peco602/rust-universal-compiler + name: Peco602/rust-universal-compiler + status: stale + stars: 33 + forks: 2 + last_push: 2023-04-30T17:04:02Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/uniget-org/cli + name: uniget-org/cli + status: healthy + stars: 20 + last_push: 2026-02-12T08:35:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tailhook/vagga + name: tailhook/vagga + status: stale + stars: 1895 + forks: 96 + last_push: 2023-03-31T06:13:55Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/deluan/zsh-in-docker + name: deluan/zsh-in-docker + status: inactive + stars: 1094 + forks: 119 + last_push: 2024-09-30T19:07:49Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/tjamet/caduc + name: tjamet/caduc + status: stale + stars: 21 + forks: 1 + last_push: 2019-01-07T16:07:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ZZROTDesign/docker-clean + name: ZZROTDesign/docker-clean + status: stale + stars: 1304 + forks: 90 + last_push: 2018-01-16T16:29:41Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Yelp/docker-custodian + name: Yelp/docker-custodian + status: inactive + stars: 374 + forks: 49 + last_push: 2024-08-14T08:08:10Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/pdacity/docker_gc + name: pdacity/docker_gc + status: stale + stars: 127 + forks: 22 + last_push: 2024-02-09T17:50:47Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/stepchowfun/docuum + name: stepchowfun/docuum + status: healthy + stars: 683 + forks: 42 + last_push: 2025-12-12T02:03:33Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/apache/openwhisk + name: apache/openwhisk + status: healthy + stars: 6756 + forks: 1173 + last_push: 2026-01-24T05:17:06Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/bfirsh/funker-example-voting-app + name: bfirsh/funker-example-voting-app + status: stale + stars: 26 + forks: 8 + last_push: 2016-11-29T11:51:39Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/iron-io/functions + name: iron-io/functions + status: stale + stars: 3220 + forks: 224 + last_push: 2023-09-15T01:37:58Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/openfaas/faas + name: openfaas/faas + status: healthy + stars: 26102 + forks: 1970 + last_push: 2026-02-22T08:49:51Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/grycap/scar + name: grycap/scar + status: stale + stars: 600 + forks: 47 + last_push: 2023-05-22T11:01:11Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/GoogleContainerTools/container-structure-test + name: GoogleContainerTools/container-structure-test + status: healthy + stars: 2460 + forks: 207 + last_push: 2026-02-20T23:41:16Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/zuazo/dockerspec + name: zuazo/dockerspec + status: stale + stars: 181 + forks: 8 + last_push: 2017-08-30T20:40:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/lynchborg/ezdc + name: lynchborg/ezdc + status: stale + stars: 12 + last_push: 2024-02-12T08:42:24Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/kurtosis-tech/kurtosis + name: kurtosis-tech/kurtosis + status: healthy + stars: 523 + forks: 88 + last_push: 2026-02-27T07:48:41Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/alexei-led/pumba + name: alexei-led/pumba + status: healthy + stars: 2980 + forks: 201 + last_push: 2026-02-27T19:58:45Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker-exec/dexec + name: docker-exec/dexec + status: stale + stars: 332 + forks: 14 + last_push: 2021-05-13T06:04:19Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/benzaita/dockerized-cli + name: benzaita/dockerized-cli + status: stale + stars: 65 + forks: 5 + last_push: 2024-02-27T13:49:38Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/CenturyLinkLabs/dray + name: CenturyLinkLabs/dray + status: stale + stars: 386 + forks: 37 + last_push: 2020-01-24T17:34:58Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/artsy/hokusai + name: artsy/hokusai + status: healthy + stars: 98 + forks: 25 + last_push: 2026-02-06T19:41:17Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/livecycle/preevy + name: livecycle/preevy + status: healthy + stars: 2189 + forks: 87 + last_push: 2026-02-06T07:38:46Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ianmiell/shutit + name: ianmiell/shutit + status: stale + stars: 2145 + forks: 110 + last_push: 2022-08-14T14:43:18Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/subuser-security/subuser + name: subuser-security/subuser + status: inactive + stars: 894 + forks: 63 + last_push: 2025-02-23T11:31:31Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/christippett/terraform-cloudinit-container-server + name: christippett/terraform-cloudinit-container-server + status: stale + stars: 120 + forks: 30 + last_push: 2022-08-19T06:41:50Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/ramitsurana/turbo + name: ramitsurana/turbo + status: stale + stars: 27 + forks: 12 + last_push: 2021-12-22T19:03:53Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/indigo-dc/udocker + name: indigo-dc/udocker + status: healthy + stars: 1703 + forks: 164 + last_push: 2025-08-13T17:21:57Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/Appdynamics/docker-monitoring-extension + name: Appdynamics/docker-monitoring-extension + status: inactive + stars: 5 + forks: 6 + last_push: 2024-10-02T10:48:59Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/sematext/sematext-agent-docker + name: sematext/sematext-agent-docker + status: stale + stars: 208 + forks: 32 + last_push: 2023-12-09T18:07:20Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/cicdops/awesome-ciandcd + name: cicdops/awesome-ciandcd + status: inactive + stars: 1985 + forks: 224 + last_push: 2024-04-01T18:08:23Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/docker/awesome-compose + name: docker/awesome-compose + status: healthy + stars: 44126 + forks: 8054 + last_push: 2026-02-27T05:54:59Z + checked_at: 2026-02-27T23:43:36.588325Z + - url: https://github.com/hexops/dockerfile + name: hexops/dockerfile + status: stale + stars: 4092 + forks: 155 + last_push: 2021-08-08T04:42:37Z + checked_at: 2026-02-27T23:43:36.588325Z diff --git a/internal/checker/github.go b/internal/checker/github.go index 146240e..a141286 100644 --- a/internal/checker/github.go +++ b/internal/checker/github.go @@ -27,21 +27,35 @@ type RepoInfo struct { // ExtractGitHubRepo extracts owner/name from a GitHub URL. // Returns false for non-repo URLs (issues, wiki, apps, etc.). -func ExtractGitHubRepo(url string) (owner, name string, ok bool) { - if !strings.HasPrefix(url, "https://github.com/") { +func ExtractGitHubRepo(rawURL string) (owner, name string, ok bool) { + u, err := url.Parse(rawURL) + if err != nil { return "", "", false } - path := strings.TrimPrefix(url, "https://github.com/") - path = strings.TrimRight(path, "/") + + host := strings.ToLower(u.Hostname()) + if host != "github.com" && host != "www.github.com" { + return "", "", false + } + + path := strings.Trim(u.Path, "/") parts := strings.Split(path, "/") if len(parts) != 2 || parts[0] == "" || parts[1] == "" { return "", "", false } - // Skip non-repo paths - if parts[0] == "apps" || parts[0] == "features" || parts[0] == "topics" { + + // Skip known non-repository top-level routes. + switch parts[0] { + case "apps", "features", "topics": return "", "", false } - return parts[0], parts[1], true + + name = strings.TrimSuffix(parts[1], ".git") + if name == "" { + return "", "", false + } + + return parts[0], name, true } func isHTTPURL(raw string) bool { @@ -52,6 +66,16 @@ func isHTTPURL(raw string) bool { return u.Scheme == "http" || u.Scheme == "https" } +func isGitHubAuthError(err error) bool { + if err == nil { + return false + } + s := strings.ToLower(err.Error()) + return strings.Contains(s, "401 unauthorized") || + strings.Contains(s, "bad credentials") || + strings.Contains(s, "resource not accessible by integration") +} + // PartitionLinks separates URLs into GitHub repos and external HTTP(S) links. func PartitionLinks(urls []string) (github, external []string) { for _, url := range urls { @@ -134,6 +158,9 @@ func (gc *GitHubChecker) CheckRepos(ctx context.Context, urls []string, batchSiz info, err := gc.CheckRepo(ctx, owner, name) if err != nil { errs = append(errs, err) + if isGitHubAuthError(err) { + break + } continue } results = append(results, info) diff --git a/internal/checker/github_test.go b/internal/checker/github_test.go index 8e751d0..9ed6294 100644 --- a/internal/checker/github_test.go +++ b/internal/checker/github_test.go @@ -1,6 +1,7 @@ package checker import ( + "errors" "testing" ) @@ -14,6 +15,10 @@ func TestExtractGitHubRepo(t *testing.T) { {"https://github.com/docker/compose", "docker", "compose", true}, {"https://github.com/moby/moby", "moby", "moby", true}, {"https://github.com/user/repo/", "user", "repo", true}, + {"https://github.com/user/repo?tab=readme-ov-file", "user", "repo", true}, + {"https://github.com/user/repo#readme", "user", "repo", true}, + {"https://github.com/user/repo.git", "user", "repo", true}, + {"https://www.github.com/user/repo", "user", "repo", true}, {"https://github.com/user/repo/issues", "", "", false}, {"https://github.com/user/repo/wiki", "", "", false}, {"https://github.com/apps/dependabot", "", "", false}, @@ -52,3 +57,22 @@ func TestPartitionLinks(t *testing.T) { t.Errorf("external links = %d, want 2", len(ext)) } } + +func TestIsGitHubAuthError(t *testing.T) { + tests := []struct { + err error + want bool + }{ + {errors.New("non-200 OK status code: 401 Unauthorized body: \"Bad credentials\""), true}, + {errors.New("Resource not accessible by integration"), true}, + {errors.New("dial tcp: lookup api.github.com: no such host"), false}, + {errors.New("context deadline exceeded"), false}, + } + + for _, tt := range tests { + got := isGitHubAuthError(tt.err) + if got != tt.want { + t.Errorf("isGitHubAuthError(%q) = %v, want %v", tt.err, got, tt.want) + } + } +} From ae81c12fc5b8eb80c1e412825d2c1cf023fdacd0 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:00:35 +0100 Subject: [PATCH 21/29] Make report output complete by default and keep JSON mode --- cmd/awesome-docker/main.go | 15 +++++- go.mod | 2 +- internal/scorer/scorer.go | 84 ++++++++++++++++++++++++---------- internal/scorer/scorer_test.go | 64 ++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 25 deletions(-) diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index e9267ab..254028d 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -240,7 +240,8 @@ func buildCmd() *cobra.Command { } func reportCmd() *cobra.Command { - return &cobra.Command{ + var jsonOutput bool + cmd := &cobra.Command{ Use: "report", Short: "Generate health report from cache", RunE: func(cmd *cobra.Command, args []string) error { @@ -263,11 +264,23 @@ func reportCmd() *cobra.Command { }) } + if jsonOutput { + payload, err := scorer.GenerateJSONReport(scored) + if err != nil { + return fmt.Errorf("json report: %w", err) + } + fmt.Println(string(payload)) + return nil + } + report := scorer.GenerateReport(scored) fmt.Print(report) return nil }, } + + cmd.Flags().BoolVar(&jsonOutput, "json", false, "Output full health report as JSON") + return cmd } func validateCmd() *cobra.Command { diff --git a/go.mod b/go.mod index b72fbff..6a38142 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/veggiemonk/awesome-docker -go 1.25.0 +go 1.26.0 require github.com/spf13/cobra v1.10.2 diff --git a/internal/scorer/scorer.go b/internal/scorer/scorer.go index c91aaf1..f2f34d6 100644 --- a/internal/scorer/scorer.go +++ b/internal/scorer/scorer.go @@ -1,6 +1,7 @@ package scorer import ( + "encoding/json" "fmt" "strings" "time" @@ -30,6 +31,24 @@ type ScoredEntry struct { LastPush time.Time } +// ReportSummary contains grouped status counts. +type ReportSummary struct { + Healthy int `json:"healthy"` + Inactive int `json:"inactive"` + Stale int `json:"stale"` + Archived int `json:"archived"` + Dead int `json:"dead"` +} + +// ReportData is the full machine-readable report model. +type ReportData struct { + GeneratedAt time.Time `json:"generated_at"` + Total int `json:"total"` + Summary ReportSummary `json:"summary"` + Entries []ScoredEntry `json:"entries"` + ByStatus map[Status][]ScoredEntry `json:"by_status"` +} + // Score computes the health status of a GitHub repo. func Score(info checker.RepoInfo) Status { if info.IsDisabled { @@ -89,45 +108,64 @@ func ToCacheEntries(scored []ScoredEntry) []cache.HealthEntry { func GenerateReport(scored []ScoredEntry) string { var b strings.Builder - groups := map[Status][]ScoredEntry{} - for _, s := range scored { - groups[s.Status] = append(groups[s.Status], s) - } + data := BuildReportData(scored) + groups := data.ByStatus fmt.Fprintf(&b, "# Health Report\n\n") - fmt.Fprintf(&b, "**Generated:** %s\n\n", time.Now().UTC().Format(time.RFC3339)) - fmt.Fprintf(&b, "**Total:** %d repositories\n\n", len(scored)) + fmt.Fprintf(&b, "**Generated:** %s\n\n", data.GeneratedAt.Format(time.RFC3339)) + fmt.Fprintf(&b, "**Total:** %d repositories\n\n", data.Total) fmt.Fprintf(&b, "## Summary\n\n") - fmt.Fprintf(&b, "- Healthy: %d\n", len(groups[StatusHealthy])) - fmt.Fprintf(&b, "- Inactive (1-2 years): %d\n", len(groups[StatusInactive])) - fmt.Fprintf(&b, "- Stale (2+ years): %d\n", len(groups[StatusStale])) - fmt.Fprintf(&b, "- Archived: %d\n", len(groups[StatusArchived])) - fmt.Fprintf(&b, "- Dead: %d\n\n", len(groups[StatusDead])) + fmt.Fprintf(&b, "- Healthy: %d\n", data.Summary.Healthy) + fmt.Fprintf(&b, "- Inactive (1-2 years): %d\n", data.Summary.Inactive) + fmt.Fprintf(&b, "- Stale (2+ years): %d\n", data.Summary.Stale) + fmt.Fprintf(&b, "- Archived: %d\n", data.Summary.Archived) + fmt.Fprintf(&b, "- Dead: %d\n\n", data.Summary.Dead) - writeSection := func(title string, status Status, limit int) { + writeSection := func(title string, status Status) { entries := groups[status] if len(entries) == 0 { return } fmt.Fprintf(&b, "## %s\n\n", title) - count := len(entries) - if limit > 0 && count > limit { - count = limit - } - for _, e := range entries[:count] { + for _, e := range entries { fmt.Fprintf(&b, "- [%s](%s) - Stars: %d - Last push: %s\n", e.Name, e.URL, e.Stars, e.LastPush.Format("2006-01-02")) } - if len(entries) > count { - fmt.Fprintf(&b, "\n... and %d more\n", len(entries)-count) - } b.WriteString("\n") } - writeSection("Archived (should mark :skull:)", StatusArchived, 0) - writeSection("Stale (2+ years inactive)", StatusStale, 50) - writeSection("Inactive (1-2 years)", StatusInactive, 30) + writeSection("Archived (should mark :skull:)", StatusArchived) + writeSection("Stale (2+ years inactive)", StatusStale) + writeSection("Inactive (1-2 years)", StatusInactive) return b.String() } + +// BuildReportData returns full report data for machine-readable and markdown rendering. +func BuildReportData(scored []ScoredEntry) ReportData { + groups := map[Status][]ScoredEntry{} + for _, s := range scored { + groups[s.Status] = append(groups[s.Status], s) + } + + return ReportData{ + GeneratedAt: time.Now().UTC(), + Total: len(scored), + Summary: ReportSummary{ + Healthy: len(groups[StatusHealthy]), + Inactive: len(groups[StatusInactive]), + Stale: len(groups[StatusStale]), + Archived: len(groups[StatusArchived]), + Dead: len(groups[StatusDead]), + }, + Entries: scored, + ByStatus: groups, + } +} + +// GenerateJSONReport returns the full report as pretty-printed JSON. +func GenerateJSONReport(scored []ScoredEntry) ([]byte, error) { + data := BuildReportData(scored) + return json.MarshalIndent(data, "", " ") +} diff --git a/internal/scorer/scorer_test.go b/internal/scorer/scorer_test.go index 1aab44a..1d32515 100644 --- a/internal/scorer/scorer_test.go +++ b/internal/scorer/scorer_test.go @@ -1,6 +1,8 @@ package scorer import ( + "encoding/json" + "fmt" "strings" "testing" "time" @@ -82,6 +84,68 @@ func TestGenerateReport(t *testing.T) { } } +func TestGenerateReportShowsAllEntries(t *testing.T) { + var results []ScoredEntry + for i := 0; i < 55; i++ { + results = append(results, ScoredEntry{ + URL: fmt.Sprintf("https://github.com/stale/%d", i), + Name: fmt.Sprintf("stale/%d", i), + Status: StatusStale, + Stars: i, + LastPush: time.Now().AddDate(-3, 0, 0), + }) + } + + report := GenerateReport(results) + if strings.Contains(report, "... and") { + t.Fatal("report should not be truncated") + } + if !strings.Contains(report, "stale/54") { + t.Fatal("report should contain all entries") + } +} + +func TestGenerateJSONReport(t *testing.T) { + results := []ScoredEntry{ + { + URL: "https://github.com/a/a", + Name: "a/a", + Status: StatusHealthy, + Stars: 100, + LastPush: time.Now(), + }, + { + URL: "https://github.com/b/b", + Name: "b/b", + Status: StatusStale, + Stars: 50, + LastPush: time.Now().AddDate(-3, 0, 0), + }, + } + + data, err := GenerateJSONReport(results) + if err != nil { + t.Fatalf("GenerateJSONReport() error = %v", err) + } + + var report ReportData + if err := json.Unmarshal(data, &report); err != nil { + t.Fatalf("json.Unmarshal() error = %v", err) + } + if report.Total != 2 { + t.Fatalf("report.Total = %d, want 2", report.Total) + } + if report.Summary.Healthy != 1 || report.Summary.Stale != 1 { + t.Fatalf("summary = %+v, want healthy=1 stale=1", report.Summary) + } + if len(report.Entries) != 2 { + t.Fatalf("len(report.Entries) = %d, want 2", len(report.Entries)) + } + if len(report.ByStatus[StatusStale]) != 1 { + t.Fatalf("len(report.ByStatus[stale]) = %d, want 1", len(report.ByStatus[StatusStale])) + } +} + func TestScoreAll(t *testing.T) { infos := []checker.RepoInfo{ {Owner: "a", Name: "a", PushedAt: time.Now(), Stars: 10}, From 0089da7ecb870aaeb279ddf13d45bed40c622dba Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:07:53 +0100 Subject: [PATCH 22/29] Expand Makefile workflow dependencies and sync parser formatting --- Makefile | 135 ++++++++++++++++++++++++++++++++++---- internal/parser/parser.go | 4 +- internal/parser/types.go | 2 +- 3 files changed, 126 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 9101c7e..47e67a8 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,134 @@ -BINARY := awesome-docker -.PHONY: build test lint check health report clean +SHELL := /bin/bash -build: - go build -o $(BINARY) ./cmd/awesome-docker +BINARY ?= awesome-docker +GO ?= go +CMD_PACKAGE := ./cmd/awesome-docker +INTERNAL_PACKAGES := ./internal/... +WEBSITE_OUTPUT := website/index.html +HEALTH_CACHE := config/health_cache.yaml +HEALTH_REPORT_MD := HEALTH_REPORT.md +HEALTH_REPORT_JSON := HEALTH_REPORT.json -test: - go test ./internal/... -v +GO_SOURCES := $(shell find cmd internal -type f -name '*.go') +BUILD_INPUTS := $(GO_SOURCES) go.mod go.sum +WEBSITE_INPUTS := README.md config/website.tmpl.html +HEALTH_INPUTS := README.md config/exclude.yaml -lint: build +.DEFAULT_GOAL := help + +.PHONY: help \ + build rebuild clean \ + fmt test test-race \ + lint lint-fix check check-pr validate website \ + guard-github-token health health-cache \ + report report-json report-file report-json-file health-report \ + workflow-dev workflow-pr workflow-maint workflow-ci + +help: ## Show the full local workflow and available targets + @echo "awesome-docker Makefile" + @echo + @echo "Workflows:" + @echo " make workflow-dev # local iteration (fmt + test + lint + check-pr + website)" + @echo " make workflow-pr # recommended before opening/updating a PR" + @echo " make workflow-maint # repository maintenance (health + JSON report)" + @echo " make workflow-ci # CI-equivalent checks" + @echo + @echo "Core targets:" + @echo " make build # build CLI binary" + @echo " make test # run internal Go tests" + @echo " make lint # validate README formatting/content rules" + @echo " make check # check links (uses GITHUB_TOKEN when set)" + @echo " make validate # run PR validation (lint + check --pr)" + @echo " make website # generate website/index.html" + @echo " make report-file # generate HEALTH_REPORT.md" + @echo " make report-json-file# generate HEALTH_REPORT.json" + @echo " make health # refresh health cache (requires GITHUB_TOKEN)" + @echo " make report # print markdown health report" + @echo " make report-json # print full JSON health report" + @echo + @echo "Generated artifacts:" + @echo " $(BINARY)" + @echo " $(WEBSITE_OUTPUT)" + @echo " $(HEALTH_CACHE)" + @echo " $(HEALTH_REPORT_MD)" + @echo " $(HEALTH_REPORT_JSON)" + +$(BINARY): $(BUILD_INPUTS) + $(GO) build -o $(BINARY) $(CMD_PACKAGE) + +build: $(BINARY) ## Build CLI binary + +rebuild: clean build ## Rebuild from scratch + +clean: ## Remove generated binary + rm -f $(BINARY) $(HEALTH_REPORT_MD) $(HEALTH_REPORT_JSON) + +fmt: ## Format Go code + $(GO) fmt ./... + +test: ## Run internal unit tests + $(GO) test $(INTERNAL_PACKAGES) -v + +test-race: ## Run internal tests with race detector + $(GO) test $(INTERNAL_PACKAGES) -race + +lint: build ## Validate README formatting/content rules ./$(BINARY) lint -check: build +lint-fix: build ## Auto-fix lint issues when possible + ./$(BINARY) lint --fix + +check: build ## Check links (GitHub checks enabled when GITHUB_TOKEN is set) ./$(BINARY) check -health: build +check-pr: build ## Check links in PR mode (external links only) + ./$(BINARY) check --pr + +validate: build ## Run PR validation (lint + check --pr) + ./$(BINARY) validate + +$(WEBSITE_OUTPUT): $(BINARY) $(WEBSITE_INPUTS) + ./$(BINARY) build + +website: $(WEBSITE_OUTPUT) ## Generate website from README + +guard-github-token: + @if [ -z "$$GITHUB_TOKEN" ]; then \ + echo "GITHUB_TOKEN is required for this target."; \ + echo "Set it with: export GITHUB_TOKEN="; \ + exit 1; \ + fi + +$(HEALTH_CACHE): guard-github-token $(BINARY) $(HEALTH_INPUTS) ./$(BINARY) health -report: build +health-cache: $(HEALTH_CACHE) ## Update config/health_cache.yaml + +health: ## Refresh health cache from GitHub metadata + @$(MAKE) --no-print-directory -B health-cache + +report: build ## Print markdown health report from cache ./$(BINARY) report -clean: - rm -f $(BINARY) +report-json: build ## Print full health report as JSON + ./$(BINARY) report --json + +$(HEALTH_REPORT_MD): $(BINARY) $(HEALTH_CACHE) + ./$(BINARY) report > $(HEALTH_REPORT_MD) + +report-file: $(HEALTH_REPORT_MD) ## Generate HEALTH_REPORT.md from cache + +$(HEALTH_REPORT_JSON): $(BINARY) $(HEALTH_CACHE) + ./$(BINARY) report --json > $(HEALTH_REPORT_JSON) + +report-json-file: $(HEALTH_REPORT_JSON) ## Generate HEALTH_REPORT.json from cache + +health-report: health report-file ## Refresh health cache then generate HEALTH_REPORT.md + +workflow-dev: fmt test lint check-pr website ## Full local development workflow + +workflow-pr: fmt test validate ## Recommended workflow before opening a PR + +workflow-maint: health report-json-file ## Weekly maintenance workflow + +workflow-ci: test validate ## CI-equivalent validation workflow diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 7fbb093..a571cf2 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -11,8 +11,8 @@ import ( // entryRe matches: - [Name](URL) - Description // Also handles optional markers/text between URL and " - " separator, e.g.: // -// - [Name](URL) :skull: - Description -// - [Name](URL) (2) :skull: - Description +// - [Name](URL) :skull: - Description +// - [Name](URL) (2) :skull: - Description var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)(.*?)\s+-\s+(.+)$`) // headingRe matches markdown headings: # Title, ## Title, etc. diff --git a/internal/parser/types.go b/internal/parser/types.go index 43a1ccf..2c58bd5 100644 --- a/internal/parser/types.go +++ b/internal/parser/types.go @@ -30,6 +30,6 @@ type Section struct { // Document is the parsed representation of the full README. type Document struct { - Preamble []string // lines before the first section + Preamble []string // lines before the first section Sections []Section } From 8dc187abc3883440700bfbf65f6d28f0e31103c5 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:09:04 +0100 Subject: [PATCH 23/29] gofumpt --- internal/builder/builder.go | 2 +- internal/builder/builder_test.go | 8 ++++---- internal/cache/cache.go | 2 +- internal/cache/cache_test.go | 4 ++-- internal/parser/parser.go | 3 ++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/internal/builder/builder.go b/internal/builder/builder.go index 872072e..ac85f31 100644 --- a/internal/builder/builder.go +++ b/internal/builder/builder.go @@ -44,7 +44,7 @@ func Build(markdownPath, templatePath, outputPath string) error { output = strings.Replace(output, r.old, r.new, 1) } - if err := os.WriteFile(outputPath, []byte(output), 0644); err != nil { + if err := os.WriteFile(outputPath, []byte(output), 0o644); err != nil { return fmt.Errorf("write output: %w", err) } return nil diff --git a/internal/builder/builder_test.go b/internal/builder/builder_test.go index cdf992d..7fd631e 100644 --- a/internal/builder/builder_test.go +++ b/internal/builder/builder_test.go @@ -12,7 +12,7 @@ func TestBuild(t *testing.T) { md := "# Test List\n\n- [Example](https://example.com) - A test entry.\n" mdPath := filepath.Join(dir, "README.md") - if err := os.WriteFile(mdPath, []byte(md), 0644); err != nil { + if err := os.WriteFile(mdPath, []byte(md), 0o644); err != nil { t.Fatal(err) } @@ -23,7 +23,7 @@ func TestBuild(t *testing.T) { ` tmplPath := filepath.Join(dir, "template.html") - if err := os.WriteFile(tmplPath, []byte(tmpl), 0644); err != nil { + if err := os.WriteFile(tmplPath, []byte(tmpl), 0o644); err != nil { t.Fatal(err) } @@ -51,7 +51,7 @@ func TestBuildWithSectionPlaceholder(t *testing.T) { md := "# Hello\n\nWorld.\n" mdPath := filepath.Join(dir, "README.md") - if err := os.WriteFile(mdPath, []byte(md), 0644); err != nil { + if err := os.WriteFile(mdPath, []byte(md), 0o644); err != nil { t.Fatal(err) } @@ -63,7 +63,7 @@ func TestBuildWithSectionPlaceholder(t *testing.T) { ` tmplPath := filepath.Join(dir, "template.html") - if err := os.WriteFile(tmplPath, []byte(tmpl), 0644); err != nil { + if err := os.WriteFile(tmplPath, []byte(tmpl), 0o644); err != nil { t.Fatal(err) } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index a19089d..ce9c672 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -76,7 +76,7 @@ func SaveHealthCache(path string, hc *HealthCache) error { if err != nil { return err } - return os.WriteFile(path, data, 0644) + return os.WriteFile(path, data, 0o644) } // Merge updates the cache with new entries, replacing existing ones by URL. diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index a868743..71d1293 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -14,7 +14,7 @@ func TestLoadExcludeList(t *testing.T) { - https://example.com - https://test.org ` - if err := os.WriteFile(path, []byte(content), 0644); err != nil { + if err := os.WriteFile(path, []byte(content), 0o644); err != nil { t.Fatal(err) } @@ -81,7 +81,7 @@ func TestLoadHealthCacheMissing(t *testing.T) { func TestLoadHealthCacheInvalidYAML(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "health.yaml") - if err := os.WriteFile(path, []byte("entries:\n - url: [not yaml"), 0644); err != nil { + if err := os.WriteFile(path, []byte("entries:\n - url: [not yaml"), 0o644); err != nil { t.Fatal(err) } diff --git a/internal/parser/parser.go b/internal/parser/parser.go index a571cf2..3b428f1 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -110,7 +110,8 @@ func Parse(r io.Reader) (Document, error) { func buildTree(flat []struct { section Section level int -}) []Section { +}, +) []Section { if len(flat) == 0 { return nil } From 927c3124b8c7c78e34a60fa388857defa28b2d9d Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:11:19 +0100 Subject: [PATCH 24/29] Update AGENTS guide for Makefile workflows and generated artifacts --- AGENTS.md | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index eb56acf..a7b11e7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,14 +2,22 @@ ## Commands - Build CLI: `make build` (or `go build -o awesome-docker ./cmd/awesome-docker`) +- Rebuild from scratch: `make rebuild` +- Show local workflows: `make help` +- Format Go code: `make fmt` - Run tests: `make test` (runs `go test ./internal/... -v`) +- Race tests: `make test-race` - Lint README rules: `make lint` (runs `./awesome-docker lint`) -- Auto-fix lint issues: `./awesome-docker lint --fix` +- Auto-fix lint issues: `make lint-fix` - Check links: `make check` (runs `./awesome-docker check`; `GITHUB_TOKEN` enables GitHub repo checks) -- PR validation: `./awesome-docker validate` (lint + external link checks in PR mode) -- Build website: `./awesome-docker build` (generates `website/index.html` from `README.md`) -- Health scoring: `make health` (requires `GITHUB_TOKEN`, updates `config/health_cache.yaml`) -- Generate health report: `make report` +- PR-safe link checks: `make check-pr` +- PR validation: `make validate` (lint + external link checks in PR mode) +- Build website: `make website` (generates `website/index.html` from `README.md`) +- Health scoring: `make health` (requires `GITHUB_TOKEN`, refreshes `config/health_cache.yaml`) +- Print health report (Markdown): `make report` +- Print health report (JSON): `make report-json` or `./awesome-docker report --json` +- Generate report files: `make report-file` (`HEALTH_REPORT.md`) and `make report-json-file` (`HEALTH_REPORT.json`) +- Maintenance shortcut: `make workflow-maint` (health + JSON report file) ## Architecture - **Main content**: `README.md` (curated Docker/container resources) @@ -25,7 +33,11 @@ - `config/exclude.yaml` - known link-check exclusions - `config/website.tmpl.html` - HTML template for site generation - `config/health_cache.yaml` - persisted health scoring cache -- **Website output**: `website/index.html` +- **Generated outputs**: + - `awesome-docker` - compiled CLI binary + - `website/index.html` - generated website + - `HEALTH_REPORT.md` - generated markdown report + - `HEALTH_REPORT.json` - generated JSON report ## Code Style - **Language**: Go @@ -47,6 +59,15 @@ - **GitHub Pages deploy**: `.github/workflows/deploy-pages.yml` - On push to `master`, builds CLI, runs `./awesome-docker build`, deploys `website/` +## Makefile Workflow +- The `Makefile` models file dependencies for generated artifacts (`awesome-docker`, `website/index.html`, `config/health_cache.yaml`, `HEALTH_REPORT.md`, `HEALTH_REPORT.json`). +- Prefer `make` targets over ad-hoc command sequences so dependency and regeneration behavior stays consistent. +- Use: + - `make workflow-dev` for local iteration + - `make workflow-pr` before opening/updating a PR + - `make workflow-maint` for health/report maintenance + - `make workflow-ci` for CI-equivalent local checks + ## Content Guidelines (from CONTRIBUTING.md) - Use one link per entry - Prefer project/repository URLs over marketing pages From 89d625229b308cb8f257a223c79ea658250ba4fd Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:13:31 +0100 Subject: [PATCH 25/29] Update github actions --- .github/workflows/broken_links.yml | 8 ++++---- .github/workflows/deploy-pages.yml | 8 ++++---- .github/workflows/health_report.yml | 6 +++--- .github/workflows/pull_request.yml | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/broken_links.yml b/.github/workflows/broken_links.yml index 835eed2..cab7e2f 100644 --- a/.github/workflows/broken_links.yml +++ b/.github/workflows/broken_links.yml @@ -13,9 +13,9 @@ jobs: issues: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod @@ -45,7 +45,7 @@ jobs: - name: Create/Update Issue for Broken Links if: steps.link_check.outputs.has_errors == 'true' - uses: actions/github-script@v7 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const fs = require('fs'); @@ -81,7 +81,7 @@ jobs: - name: Close Issue if No Errors if: steps.link_check.outputs.has_errors == 'false' - uses: actions/github-script@v7 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const issues = await github.rest.issues.listForRepo({ diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 0316332..54db0dd 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -20,9 +20,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod @@ -33,7 +33,7 @@ jobs: run: ./awesome-docker build - name: Upload artifact - uses: actions/upload-pages-artifact@v4 + uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # ratchet:actions/upload-pages-artifact@v4 with: path: ./website @@ -46,4 +46,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # ratchet:actions/deploy-pages@v4 diff --git a/.github/workflows/health_report.yml b/.github/workflows/health_report.yml index 8fc5141..14e091a 100644 --- a/.github/workflows/health_report.yml +++ b/.github/workflows/health_report.yml @@ -13,9 +13,9 @@ jobs: issues: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod @@ -40,7 +40,7 @@ jobs: - name: Create/Update Issue with Health Report if: steps.report.outputs.has_report == 'true' - uses: actions/github-script@v7 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const fs = require('fs'); diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index edb1936..f72cd98 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -11,9 +11,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod From 682cffc308bf604d9875d516ae91d57c990e64cd Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:15:15 +0100 Subject: [PATCH 26/29] update dependencies --- Makefile | 8 ++++++++ go.mod | 14 ++++++++------ go.sum | 4 +++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 47e67a8..68523a2 100644 --- a/Makefile +++ b/Makefile @@ -132,3 +132,11 @@ workflow-pr: fmt test validate ## Recommended workflow before opening a PR workflow-maint: health report-json-file ## Weekly maintenance workflow workflow-ci: test validate ## CI-equivalent validation workflow + +update-ga: + ratchet upgrade .github/workflows/* + +update-go: + go get -u go@latest + go get -u ./... + go mod tidy diff --git a/go.mod b/go.mod index 6a38142..57ec302 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,16 @@ module github.com/veggiemonk/awesome-docker go 1.26.0 -require github.com/spf13/cobra v1.10.2 +require ( + github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed + github.com/spf13/cobra v1.10.2 + github.com/yuin/goldmark v1.7.16 + golang.org/x/oauth2 v0.35.0 + gopkg.in/yaml.v3 v3.0.1 +) require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed // indirect github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/yuin/goldmark v1.7.16 // indirect - golang.org/x/oauth2 v0.35.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect ) diff --git a/go.sum b/go.sum index 0c38e50..cc4a312 100644 --- a/go.sum +++ b/go.sum @@ -8,13 +8,15 @@ github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf h1:o1uxfymjZ7jZ4M github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From e6e23bf1cff7e93a7a855799defda37c5dc69bff Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:20:15 +0100 Subject: [PATCH 27/29] remove netlify status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00818bd..f7efbd5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Awesome Docker [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)][sindresorhus] [![Netlify Status](https://api.netlify.com/api/v1/badges/8ca86717-11ba-46d4-9d0a-700d8527f13b/deploy-status)](https://app.netlify.com/sites/awesome-docker/deploys)[![Track Awesome List](https://www.trackawesomelist.com/badge.svg)](https://www.trackawesomelist.com/veggiemonk/awesome-docker/)[![Last Commit](https://img.shields.io/github/last-commit/veggiemonk/awesome-docker)](https://github.com/veggiemonk/awesome-docker/commits/main) +# Awesome Docker [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)][sindresorhus] [![Track Awesome List](https://www.trackawesomelist.com/badge.svg)](https://www.trackawesomelist.com/veggiemonk/awesome-docker/)[![Last Commit](https://img.shields.io/github/last-commit/veggiemonk/awesome-docker)](https://github.com/veggiemonk/awesome-docker/commits/main) > A curated list of Docker resources and projects From c14a071c8d7ebd0f9b665e327fdf33d630ccf0a2 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:31:37 +0100 Subject: [PATCH 28/29] Improve checker/fixer cohesion and harden workflows --- cmd/awesome-docker/main.go | 33 +++++++++++++---- internal/builder/builder.go | 26 +++++++++++-- internal/builder/builder_test.go | 20 ++++++++++ internal/cache/cache.go | 1 + internal/cache/cache_test.go | 16 ++++++++ internal/checker/http.go | 38 ++++++++++++------- internal/checker/http_test.go | 38 +++++++++++++++++++ internal/linter/fixer.go | 63 ++++++++++++++++---------------- internal/linter/fixer_test.go | 53 +++++++++++++++++++++++++++ internal/parser/parser.go | 21 ++++++----- internal/parser/parser_test.go | 14 +++++++ internal/scorer/scorer.go | 41 +++++++++++---------- 12 files changed, 279 insertions(+), 85 deletions(-) diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 254028d..9c336fe 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -121,7 +121,10 @@ func checkCmd() *cobra.Command { var urls []string collectURLs(doc.Sections, &urls) - exclude, _ := cache.LoadExcludeList(excludePath) + exclude, err := cache.LoadExcludeList(excludePath) + if err != nil { + return fmt.Errorf("load exclude list: %w", err) + } ghURLs, extURLs := checker.PartitionLinks(urls) @@ -138,13 +141,15 @@ func checkCmd() *cobra.Command { } } + var ghErrs []error if !prMode { token := os.Getenv("GITHUB_TOKEN") if token != "" { fmt.Printf("Checking %d GitHub repositories...\n", len(ghURLs)) gc := checker.NewGitHubChecker(token) _, errs := gc.CheckRepos(context.Background(), ghURLs, 50) - for _, e := range errs { + ghErrs = errs + for _, e := range ghErrs { fmt.Printf(" GitHub error: %v\n", e) } } else { @@ -164,8 +169,16 @@ func checkCmd() *cobra.Command { for _, r := range broken { fmt.Printf(" %s -> %d %s\n", r.URL, r.StatusCode, r.Error) } + } + if len(broken) > 0 && len(ghErrs) > 0 { + return fmt.Errorf("found %d broken links and %d GitHub API errors", len(broken), len(ghErrs)) + } + if len(broken) > 0 { return fmt.Errorf("found %d broken links", len(broken)) } + if len(ghErrs) > 0 { + return fmt.Errorf("github checks failed with %d errors", len(ghErrs)) + } fmt.Println("All links OK") return nil @@ -256,11 +269,12 @@ func reportCmd() *cobra.Command { var scored []scorer.ScoredEntry for _, e := range hc.Entries { scored = append(scored, scorer.ScoredEntry{ - URL: e.URL, - Name: e.Name, - Status: scorer.Status(e.Status), - Stars: e.Stars, - LastPush: e.LastPush, + URL: e.URL, + Name: e.Name, + Status: scorer.Status(e.Status), + Stars: e.Stars, + HasLicense: e.HasLicense, + LastPush: e.LastPush, }) } @@ -307,7 +321,10 @@ func validateCmd() *cobra.Command { fmt.Println("\n=== Checking links (PR mode) ===") var urls []string collectURLs(doc.Sections, &urls) - exclude, _ := cache.LoadExcludeList(excludePath) + exclude, err := cache.LoadExcludeList(excludePath) + if err != nil { + return fmt.Errorf("load exclude list: %w", err) + } _, extURLs := checker.PartitionLinks(urls) fmt.Printf("Checking %d external links...\n", len(extURLs)) diff --git a/internal/builder/builder.go b/internal/builder/builder.go index ac85f31..6b2cd20 100644 --- a/internal/builder/builder.go +++ b/internal/builder/builder.go @@ -36,12 +36,30 @@ func Build(markdownPath, templatePath, outputPath string) error { // Inject into template — support both placeholder formats output := string(tmpl) - replacements := []struct{ old, new string }{ - {`
`, `
` + buf.String() + `
`}, - {`
`, `
` + buf.String() + `
`}, + replacements := []struct { + old string + new string + }{ + { + old: `
`, + new: `
` + buf.String() + `
`, + }, + { + old: `
`, + new: `
` + buf.String() + `
`, + }, } + + replaced := false for _, r := range replacements { - output = strings.Replace(output, r.old, r.new, 1) + if strings.Contains(output, r.old) { + output = strings.Replace(output, r.old, r.new, 1) + replaced = true + break + } + } + if !replaced { + return fmt.Errorf("template missing supported markdown placeholder") } if err := os.WriteFile(outputPath, []byte(output), 0o644); err != nil { diff --git a/internal/builder/builder_test.go b/internal/builder/builder_test.go index 7fd631e..5cf98c3 100644 --- a/internal/builder/builder_test.go +++ b/internal/builder/builder_test.go @@ -111,3 +111,23 @@ func TestBuildRealREADME(t *testing.T) { } t.Logf("Generated %d bytes", info.Size()) } + +func TestBuildFailsWithoutPlaceholder(t *testing.T) { + dir := t.TempDir() + + mdPath := filepath.Join(dir, "README.md") + if err := os.WriteFile(mdPath, []byte("# Title\n"), 0o644); err != nil { + t.Fatal(err) + } + + tmplPath := filepath.Join(dir, "template.html") + if err := os.WriteFile(tmplPath, []byte("
"), 0o644); err != nil { + t.Fatal(err) + } + + outPath := filepath.Join(dir, "index.html") + err := Build(mdPath, tmplPath, outPath) + if err == nil { + t.Fatal("expected Build to fail when template has no supported placeholder") + } +} diff --git a/internal/cache/cache.go b/internal/cache/cache.go index ce9c672..0c481ba 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -89,6 +89,7 @@ func (hc *HealthCache) Merge(entries []HealthEntry) { if i, exists := index[e.URL]; exists { hc.Entries[i] = e } else { + index[e.URL] = len(hc.Entries) hc.Entries = append(hc.Entries, e) } } diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 71d1293..52a161d 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -119,3 +119,19 @@ func TestMerge(t *testing.T) { t.Errorf("last entry = %q, want C", hc.Entries[2].Name) } } + +func TestMergeDeduplicatesIncomingBatch(t *testing.T) { + hc := &HealthCache{} + + hc.Merge([]HealthEntry{ + {URL: "https://github.com/c/c", Name: "C", Stars: 1}, + {URL: "https://github.com/c/c", Name: "C", Stars: 2}, + }) + + if len(hc.Entries) != 1 { + t.Fatalf("entries = %d, want 1", len(hc.Entries)) + } + if hc.Entries[0].Stars != 2 { + t.Fatalf("stars = %d, want last value 2", hc.Entries[0].Stars) + } +} diff --git a/internal/checker/http.go b/internal/checker/http.go index 3e17929..7aa0a82 100644 --- a/internal/checker/http.go +++ b/internal/checker/http.go @@ -25,6 +25,15 @@ type LinkResult struct { Error string } +func shouldFallbackToGET(statusCode int) bool { + switch statusCode { + case http.StatusBadRequest, http.StatusForbidden, http.StatusMethodNotAllowed, http.StatusNotImplemented: + return true + default: + return false + } +} + // CheckLink checks a single URL. Uses HEAD first, falls back to GET. func CheckLink(url string, client *http.Client) LinkResult { result := LinkResult{URL: url} @@ -32,14 +41,6 @@ func CheckLink(url string, client *http.Client) LinkResult { ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() - // Try HEAD first - req, err := http.NewRequestWithContext(ctx, http.MethodHead, url, nil) - if err != nil { - result.Error = err.Error() - return result - } - req.Header.Set("User-Agent", userAgent) - // Track redirects var finalURL string origCheckRedirect := client.CheckRedirect @@ -52,16 +53,25 @@ func CheckLink(url string, client *http.Client) LinkResult { } defer func() { client.CheckRedirect = origCheckRedirect }() - resp, err := client.Do(req) + doRequest := func(method string) (*http.Response, error) { + req, err := http.NewRequestWithContext(ctx, method, url, nil) + if err != nil { + return nil, err + } + req.Header.Set("User-Agent", userAgent) + return client.Do(req) + } + + resp, err := doRequest(http.MethodHead) if err != nil { - // Fallback to GET - req, err2 := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) - if err2 != nil { + resp, err = doRequest(http.MethodGet) + if err != nil { result.Error = err.Error() return result } - req.Header.Set("User-Agent", userAgent) - resp, err = client.Do(req) + } else if shouldFallbackToGET(resp.StatusCode) { + resp.Body.Close() + resp, err = doRequest(http.MethodGet) if err != nil { result.Error = err.Error() return result diff --git a/internal/checker/http_test.go b/internal/checker/http_test.go index b8eef45..e51188d 100644 --- a/internal/checker/http_test.go +++ b/internal/checker/http_test.go @@ -78,3 +78,41 @@ func TestCheckLinks(t *testing.T) { } } } + +func TestCheckLinkFallbackToGETOnMethodNotAllowed(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodHead { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + result := CheckLink(server.URL, &http.Client{}) + if !result.OK { + t.Errorf("expected OK after GET fallback, got status %d, error: %s", result.StatusCode, result.Error) + } + if result.StatusCode != http.StatusOK { + t.Errorf("status = %d, want 200", result.StatusCode) + } +} + +func TestCheckLinkFallbackToGETOnForbiddenHead(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodHead { + w.WriteHeader(http.StatusForbidden) + return + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + result := CheckLink(server.URL, &http.Client{}) + if !result.OK { + t.Errorf("expected OK after GET fallback, got status %d, error: %s", result.StatusCode, result.Error) + } + if result.StatusCode != http.StatusOK { + t.Errorf("status = %d, want 200", result.StatusCode) + } +} diff --git a/internal/linter/fixer.go b/internal/linter/fixer.go index edb22e0..4d8eac7 100644 --- a/internal/linter/fixer.go +++ b/internal/linter/fixer.go @@ -20,6 +20,9 @@ var attributionRe = regexp.MustCompile(`\s+(?:(?:[Cc]reated|[Mm]aintained|[Bb]ui // bareAttributionRe matches: by @author at end of line (no link). var bareAttributionRe = regexp.MustCompile(`\s+by\s+@\w+\.?$`) +// sectionHeadingRe matches markdown headings. +var sectionHeadingRe = regexp.MustCompile(`^(#{1,6})\s+(.+?)(?:\s*)?$`) + // RemoveAttribution strips author attribution from a description string. func RemoveAttribution(desc string) string { desc = attributionRe.ReplaceAllString(desc, "") @@ -47,12 +50,6 @@ func FormatEntry(e parser.Entry) string { return fmt.Sprintf("- [%s](%s) - %s", e.Name, e.URL, desc) } -// entryGroup tracks a consecutive run of entry lines. -type entryGroup struct { - startIdx int // index in lines slice - entries []parser.Entry -} - // FixFile reads the README, fixes entries (capitalize, period, remove attribution, // sort), and writes the result back. func FixFile(path string) (int, error) { @@ -71,34 +68,39 @@ func FixFile(path string) (int, error) { return 0, err } - // Identify entry groups (consecutive parsed entry lines) - var groups []entryGroup - var current *entryGroup fixCount := 0 + var headingLines []int for i, line := range lines { - entry, err := parser.ParseEntry(line, i+1) - if err != nil { - // Not an entry — close any active group - if current != nil { - groups = append(groups, *current) - current = nil - } - continue + if sectionHeadingRe.MatchString(line) { + headingLines = append(headingLines, i) } - if current == nil { - current = &entryGroup{startIdx: i} - } - current.entries = append(current.entries, entry) - } - if current != nil { - groups = append(groups, *current) } - // Process each group: fix entries, sort, replace lines - for _, g := range groups { + // Process each heading block independently to match linter sort scope. + for i, headingIdx := range headingLines { + start := headingIdx + 1 + end := len(lines) + if i+1 < len(headingLines) { + end = headingLines[i+1] + } + + var entryPositions []int + var entries []parser.Entry + for lineIdx := start; lineIdx < end; lineIdx++ { + entry, err := parser.ParseEntry(lines[lineIdx], lineIdx+1) + if err != nil { + continue + } + entryPositions = append(entryPositions, lineIdx) + entries = append(entries, entry) + } + if len(entries) == 0 { + continue + } + var fixed []parser.Entry - for _, e := range g.entries { + for _, e := range entries { f := FixEntry(e) f.Description = RemoveAttribution(f.Description) // Re-apply period after removing attribution (it may have been stripped) @@ -109,13 +111,12 @@ func FixFile(path string) (int, error) { } sorted := SortEntries(fixed) - for j, e := range sorted { newLine := FormatEntry(e) - idx := g.startIdx + j - if lines[idx] != newLine { + lineIdx := entryPositions[j] + if lines[lineIdx] != newLine { fixCount++ - lines[idx] = newLine + lines[lineIdx] = newLine } } } diff --git a/internal/linter/fixer_test.go b/internal/linter/fixer_test.go index ae37ef0..6872ce7 100644 --- a/internal/linter/fixer_test.go +++ b/internal/linter/fixer_test.go @@ -138,3 +138,56 @@ Some text here. t.Errorf("expected period added, got:\n%s", result) } } + +func TestFixFileSortsAcrossBlankLinesAndIsIdempotent(t *testing.T) { + content := `# Awesome Docker + +## Tools + +- [Zulu](https://example.com/zulu) - z tool + +- [Alpha](https://example.com/alpha) - a tool +` + + tmp, err := os.CreateTemp("", "readme-*.md") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + if _, err := tmp.WriteString(content); err != nil { + t.Fatal(err) + } + tmp.Close() + + firstCount, err := FixFile(tmp.Name()) + if err != nil { + t.Fatal(err) + } + if firstCount == 0 { + t.Fatal("expected first run to apply fixes") + } + + firstData, err := os.ReadFile(tmp.Name()) + if err != nil { + t.Fatal(err) + } + firstResult := string(firstData) + + alphaIdx := strings.Index(firstResult, "[Alpha]") + zuluIdx := strings.Index(firstResult, "[Zulu]") + if alphaIdx == -1 || zuluIdx == -1 { + t.Fatalf("expected both Alpha and Zulu in result:\n%s", firstResult) + } + if alphaIdx > zuluIdx { + t.Fatalf("expected Alpha before Zulu after fix:\n%s", firstResult) + } + + secondCount, err := FixFile(tmp.Name()) + if err != nil { + t.Fatal(err) + } + if secondCount != 0 { + t.Fatalf("expected second run to be idempotent, got %d changes", secondCount) + } +} diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 3b428f1..5eb0d93 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -18,10 +18,13 @@ var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)(.*?)\s+-\s+(.+ // headingRe matches markdown headings: # Title, ## Title, etc. var headingRe = regexp.MustCompile(`^(#{1,6})\s+(.+?)(?:\s*)?$`) -var markerMap = map[string]Marker{ - ":skull:": MarkerAbandoned, - ":heavy_dollar_sign:": MarkerPaid, - ":construction:": MarkerWIP, +var markerDefs = []struct { + text string + marker Marker +}{ + {text: ":skull:", marker: MarkerAbandoned}, + {text: ":heavy_dollar_sign:", marker: MarkerPaid}, + {text: ":construction:", marker: MarkerWIP}, } // ParseEntry parses a single markdown list line into an Entry. @@ -36,11 +39,11 @@ func ParseEntry(line string, lineNum int) (Entry, error) { var markers []Marker // Extract markers from both the middle section and the description - for text, marker := range markerMap { - if strings.Contains(middle, text) || strings.Contains(desc, text) { - markers = append(markers, marker) - middle = strings.ReplaceAll(middle, text, "") - desc = strings.ReplaceAll(desc, text, "") + for _, def := range markerDefs { + if strings.Contains(middle, def.text) || strings.Contains(desc, def.text) { + markers = append(markers, def.marker) + middle = strings.ReplaceAll(middle, def.text, "") + desc = strings.ReplaceAll(desc, def.text, "") } } desc = strings.TrimSpace(desc) diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go index d414747..9f86b6f 100644 --- a/internal/parser/parser_test.go +++ b/internal/parser/parser_test.go @@ -54,6 +54,20 @@ func TestParseEntryMultipleMarkers(t *testing.T) { } } +func TestParseEntryMarkersCanonicalOrder(t *testing.T) { + line := `- [SomeProject](https://example.com) - :construction: A project. :skull:` + entry, err := ParseEntry(line, 1) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(entry.Markers) != 2 { + t.Fatalf("markers count = %d, want 2", len(entry.Markers)) + } + if entry.Markers[0] != MarkerAbandoned || entry.Markers[1] != MarkerWIP { + t.Fatalf("marker order = %v, want [MarkerAbandoned MarkerWIP]", entry.Markers) + } +} + func TestParseDocument(t *testing.T) { input := `# Awesome Docker diff --git a/internal/scorer/scorer.go b/internal/scorer/scorer.go index f2f34d6..1920e0c 100644 --- a/internal/scorer/scorer.go +++ b/internal/scorer/scorer.go @@ -23,12 +23,13 @@ const ( // ScoredEntry is a repo with its computed health status. type ScoredEntry struct { - URL string - Name string - Status Status - Stars int - Forks int - LastPush time.Time + URL string + Name string + Status Status + Stars int + Forks int + HasLicense bool + LastPush time.Time } // ReportSummary contains grouped status counts. @@ -75,12 +76,13 @@ func ScoreAll(infos []checker.RepoInfo) []ScoredEntry { results := make([]ScoredEntry, len(infos)) for i, info := range infos { results[i] = ScoredEntry{ - URL: info.URL, - Name: fmt.Sprintf("%s/%s", info.Owner, info.Name), - Status: Score(info), - Stars: info.Stars, - Forks: info.Forks, - LastPush: info.PushedAt, + URL: info.URL, + Name: fmt.Sprintf("%s/%s", info.Owner, info.Name), + Status: Score(info), + Stars: info.Stars, + Forks: info.Forks, + HasLicense: info.HasLicense, + LastPush: info.PushedAt, } } return results @@ -92,13 +94,14 @@ func ToCacheEntries(scored []ScoredEntry) []cache.HealthEntry { now := time.Now().UTC() for i, s := range scored { entries[i] = cache.HealthEntry{ - URL: s.URL, - Name: s.Name, - Status: string(s.Status), - Stars: s.Stars, - Forks: s.Forks, - LastPush: s.LastPush, - CheckedAt: now, + URL: s.URL, + Name: s.Name, + Status: string(s.Status), + Stars: s.Stars, + Forks: s.Forks, + HasLicense: s.HasLicense, + LastPush: s.LastPush, + CheckedAt: now, } } return entries From 9a5331398d4d618ab59ec10453b441e8d55f5550 Mon Sep 17 00:00:00 2001 From: Julien Bisconti Date: Sat, 28 Feb 2026 01:44:56 +0100 Subject: [PATCH 29/29] Add ci subcommands and simplify scheduled workflows --- .github/workflows/broken_links.yml | 27 +- .github/workflows/health_report.yml | 24 +- cmd/awesome-docker/main.go | 528 +++++++++++++++++++++------- 3 files changed, 420 insertions(+), 159 deletions(-) diff --git a/.github/workflows/broken_links.yml b/.github/workflows/broken_links.yml index cab7e2f..d300688 100644 --- a/.github/workflows/broken_links.yml +++ b/.github/workflows/broken_links.yml @@ -5,9 +5,14 @@ on: - cron: "0 2 * * 6" workflow_dispatch: +concurrency: + group: broken-links-${{ github.ref }} + cancel-in-progress: false + jobs: check-links: runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: read issues: write @@ -24,22 +29,7 @@ jobs: - name: Run Link Check id: link_check - run: | - set +e - ./awesome-docker check > link_check_output.txt 2>&1 - exit_code=$? - set -e - - has_errors=false - if [ "$exit_code" -ne 0 ]; then - has_errors=true - fi - if grep -qi "broken links" link_check_output.txt; then - has_errors=true - fi - - echo "has_errors=$has_errors" >> "$GITHUB_OUTPUT" - echo "check_exit_code=$exit_code" >> "$GITHUB_OUTPUT" + run: ./awesome-docker ci broken-links --issue-file broken_links_issue.md --github-output "$GITHUB_OUTPUT" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -49,10 +39,7 @@ jobs: with: script: | const fs = require('fs'); - const output = fs.readFileSync('link_check_output.txt', 'utf8'); - const exitCode = '${{ steps.link_check.outputs.check_exit_code }}'; - - const issueBody = `# Broken Links Detected\n\nThe weekly link check found broken links or the checker failed to execute cleanly.\n\nChecker exit code: ${exitCode}\n\n\`\`\`\n${output}\n\`\`\`\n\n## Action Required\n\n- Update the URL if the resource moved\n- Remove the entry if permanently unavailable\n- Add to \`config/exclude.yaml\` if a known false positive\n- Investigate checker failures when exit code is non-zero\n\n---\n*Auto-generated by broken_links.yml*`; + const issueBody = fs.readFileSync('broken_links_issue.md', 'utf8'); const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, diff --git a/.github/workflows/health_report.yml b/.github/workflows/health_report.yml index 14e091a..0945182 100644 --- a/.github/workflows/health_report.yml +++ b/.github/workflows/health_report.yml @@ -5,9 +5,14 @@ on: - cron: "0 9 * * 1" workflow_dispatch: +concurrency: + group: health-report-${{ github.ref }} + cancel-in-progress: false + jobs: health-check: runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: read issues: write @@ -22,22 +27,12 @@ jobs: - name: Build run: go build -o awesome-docker ./cmd/awesome-docker - - name: Run Health Scoring - run: ./awesome-docker health - continue-on-error: true + - name: Run Health + Report + id: report + run: ./awesome-docker ci health-report --issue-file health_report.txt --github-output "$GITHUB_OUTPUT" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Generate Report - id: report - run: | - ./awesome-docker report > health_report.txt 2>&1 || true - if [ -s health_report.txt ]; then - echo "has_report=true" >> "$GITHUB_OUTPUT" - else - echo "has_report=false" >> "$GITHUB_OUTPUT" - fi - - name: Create/Update Issue with Health Report if: steps.report.outputs.has_report == 'true' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 @@ -45,8 +40,7 @@ jobs: script: | const fs = require('fs'); const report = fs.readFileSync('health_report.txt', 'utf8'); - - const issueBody = report + '\n\n---\n*Auto-generated weekly by health_report.yml*'; + const issueBody = report; const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, diff --git a/cmd/awesome-docker/main.go b/cmd/awesome-docker/main.go index 9c336fe..5ad2518 100644 --- a/cmd/awesome-docker/main.go +++ b/cmd/awesome-docker/main.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "os" + "strconv" + "strings" "github.com/spf13/cobra" "github.com/veggiemonk/awesome-docker/internal/builder" @@ -23,6 +25,15 @@ const ( version = "0.1.0" ) +type checkSummary struct { + ExternalTotal int + GitHubTotal int + Broken []checker.LinkResult + Redirected []checker.LinkResult + GitHubErrors []error + GitHubSkipped bool +} + func main() { root := &cobra.Command{ Use: "awesome-docker", @@ -37,6 +48,7 @@ func main() { buildCmd(), reportCmd(), validateCmd(), + ciCmd(), ) if err := root.Execute(); err != nil { @@ -70,6 +82,205 @@ func collectURLs(sections []parser.Section, urls *[]string) { } } +func runLinkChecks(prMode bool) (checkSummary, error) { + doc, err := parseReadme() + if err != nil { + return checkSummary{}, fmt.Errorf("parse: %w", err) + } + + var urls []string + collectURLs(doc.Sections, &urls) + + exclude, err := cache.LoadExcludeList(excludePath) + if err != nil { + return checkSummary{}, fmt.Errorf("load exclude list: %w", err) + } + + ghURLs, extURLs := checker.PartitionLinks(urls) + + summary := checkSummary{ + ExternalTotal: len(extURLs), + GitHubTotal: len(ghURLs), + } + + results := checker.CheckLinks(extURLs, 10, exclude) + for _, r := range results { + if !r.OK { + summary.Broken = append(summary.Broken, r) + } + if r.Redirected { + summary.Redirected = append(summary.Redirected, r) + } + } + + if prMode { + summary.GitHubSkipped = true + return summary, nil + } + + token := os.Getenv("GITHUB_TOKEN") + if token == "" { + summary.GitHubSkipped = true + return summary, nil + } + + gc := checker.NewGitHubChecker(token) + _, errs := gc.CheckRepos(context.Background(), ghURLs, 50) + summary.GitHubErrors = errs + return summary, nil +} + +func runHealth(ctx context.Context) error { + token := os.Getenv("GITHUB_TOKEN") + if token == "" { + return fmt.Errorf("GITHUB_TOKEN environment variable is required") + } + + doc, err := parseReadme() + if err != nil { + return fmt.Errorf("parse: %w", err) + } + + var urls []string + collectURLs(doc.Sections, &urls) + ghURLs, _ := checker.PartitionLinks(urls) + + fmt.Printf("Scoring %d GitHub repositories...\n", len(ghURLs)) + gc := checker.NewGitHubChecker(token) + infos, errs := gc.CheckRepos(ctx, ghURLs, 50) + for _, e := range errs { + fmt.Printf(" error: %v\n", e) + } + if len(infos) == 0 { + if len(errs) > 0 { + return fmt.Errorf("failed to fetch GitHub metadata for all repositories (%d errors); check network/DNS and GITHUB_TOKEN", len(errs)) + } + return fmt.Errorf("no GitHub repositories found in README") + } + + scored := scorer.ScoreAll(infos) + cacheEntries := scorer.ToCacheEntries(scored) + + hc, err := cache.LoadHealthCache(healthCachePath) + if err != nil { + return fmt.Errorf("load cache: %w", err) + } + hc.Merge(cacheEntries) + if err := cache.SaveHealthCache(healthCachePath, hc); err != nil { + return fmt.Errorf("save cache: %w", err) + } + + fmt.Printf("Cache updated: %d entries in %s\n", len(hc.Entries), healthCachePath) + return nil +} + +func scoredFromCache() ([]scorer.ScoredEntry, error) { + hc, err := cache.LoadHealthCache(healthCachePath) + if err != nil { + return nil, fmt.Errorf("load cache: %w", err) + } + if len(hc.Entries) == 0 { + return nil, fmt.Errorf("no cache data, run 'health' first") + } + + scored := make([]scorer.ScoredEntry, 0, len(hc.Entries)) + for _, e := range hc.Entries { + scored = append(scored, scorer.ScoredEntry{ + URL: e.URL, + Name: e.Name, + Status: scorer.Status(e.Status), + Stars: e.Stars, + HasLicense: e.HasLicense, + LastPush: e.LastPush, + }) + } + return scored, nil +} + +func markdownReportFromCache() (string, error) { + scored, err := scoredFromCache() + if err != nil { + return "", err + } + return scorer.GenerateReport(scored), nil +} + +func writeGitHubOutput(path, key, value string) error { + if path == "" { + return nil + } + f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) + if err != nil { + return fmt.Errorf("open github output file: %w", err) + } + defer f.Close() + if _, err := fmt.Fprintf(f, "%s=%s\n", key, value); err != nil { + return fmt.Errorf("write github output: %w", err) + } + return nil +} + +func sanitizeOutputValue(v string) string { + v = strings.ReplaceAll(v, "\n", " ") + v = strings.ReplaceAll(v, "\r", " ") + return strings.TrimSpace(v) +} + +func buildBrokenLinksIssueBody(summary checkSummary, runErr error) string { + var b strings.Builder + b.WriteString("# Broken Links Detected\n\n") + + if runErr != nil { + b.WriteString("The link checker failed to execute cleanly.\n\n") + b.WriteString("## Failure\n\n") + fmt.Fprintf(&b, "- %s\n\n", runErr) + } else { + fmt.Fprintf(&b, "- Broken links: %d\n", len(summary.Broken)) + fmt.Fprintf(&b, "- Redirected links: %d\n", len(summary.Redirected)) + fmt.Fprintf(&b, "- GitHub API errors: %d\n\n", len(summary.GitHubErrors)) + + if len(summary.Broken) > 0 { + b.WriteString("## Broken Links\n\n") + for _, r := range summary.Broken { + fmt.Fprintf(&b, "- `%s` -> `%d %s`\n", r.URL, r.StatusCode, strings.TrimSpace(r.Error)) + } + b.WriteString("\n") + } + + if len(summary.GitHubErrors) > 0 { + b.WriteString("## GitHub API Errors\n\n") + for _, e := range summary.GitHubErrors { + fmt.Fprintf(&b, "- `%s`\n", e) + } + b.WriteString("\n") + } + } + + b.WriteString("## Action Required\n\n") + b.WriteString("- Update the URL if the resource moved\n") + b.WriteString("- Remove the entry if permanently unavailable\n") + b.WriteString("- Add to `config/exclude.yaml` if a known false positive\n") + b.WriteString("- Investigate GitHub API/auth failures when present\n\n") + b.WriteString("---\n") + b.WriteString("*Auto-generated by awesome-docker ci broken-links*\n") + return b.String() +} + +func buildHealthReportIssueBody(report string, healthErr error) string { + var b strings.Builder + if healthErr != nil { + b.WriteString("WARNING: health refresh failed in this run; showing latest cached report.\n\n") + fmt.Fprintf(&b, "Error: `%s`\n\n", healthErr) + } + b.WriteString(report) + if !strings.HasSuffix(report, "\n") { + b.WriteString("\n") + } + b.WriteString("\n---\n") + b.WriteString("*Auto-generated weekly by awesome-docker ci health-report*\n") + return b.String() +} + func lintCmd() *cobra.Command { var fix bool cmd := &cobra.Command{ @@ -113,71 +324,45 @@ func checkCmd() *cobra.Command { Use: "check", Short: "Check links for reachability", RunE: func(cmd *cobra.Command, args []string) error { - doc, err := parseReadme() + summary, err := runLinkChecks(prMode) if err != nil { - return fmt.Errorf("parse: %w", err) + return err } - var urls []string - collectURLs(doc.Sections, &urls) - - exclude, err := cache.LoadExcludeList(excludePath) - if err != nil { - return fmt.Errorf("load exclude list: %w", err) - } - - ghURLs, extURLs := checker.PartitionLinks(urls) - - fmt.Printf("Checking %d external links...\n", len(extURLs)) - results := checker.CheckLinks(extURLs, 10, exclude) - var broken []checker.LinkResult - var redirected []checker.LinkResult - for _, r := range results { - if !r.OK { - broken = append(broken, r) - } - if r.Redirected { - redirected = append(redirected, r) - } - } - - var ghErrs []error + fmt.Printf("Checking %d external links...\n", summary.ExternalTotal) if !prMode { - token := os.Getenv("GITHUB_TOKEN") - if token != "" { - fmt.Printf("Checking %d GitHub repositories...\n", len(ghURLs)) - gc := checker.NewGitHubChecker(token) - _, errs := gc.CheckRepos(context.Background(), ghURLs, 50) - ghErrs = errs - for _, e := range ghErrs { - fmt.Printf(" GitHub error: %v\n", e) - } - } else { + if summary.GitHubSkipped { fmt.Println("GITHUB_TOKEN not set, skipping GitHub repo checks") + } else { + fmt.Printf("Checking %d GitHub repositories...\n", summary.GitHubTotal) } } - if len(redirected) > 0 { - fmt.Printf("\n%d redirected links (consider updating):\n", len(redirected)) - for _, r := range redirected { + for _, e := range summary.GitHubErrors { + fmt.Printf(" GitHub error: %v\n", e) + } + + if len(summary.Redirected) > 0 { + fmt.Printf("\n%d redirected links (consider updating):\n", len(summary.Redirected)) + for _, r := range summary.Redirected { fmt.Printf(" %s -> %s\n", r.URL, r.RedirectURL) } } - if len(broken) > 0 { - fmt.Printf("\n%d broken links:\n", len(broken)) - for _, r := range broken { + if len(summary.Broken) > 0 { + fmt.Printf("\n%d broken links:\n", len(summary.Broken)) + for _, r := range summary.Broken { fmt.Printf(" %s -> %d %s\n", r.URL, r.StatusCode, r.Error) } } - if len(broken) > 0 && len(ghErrs) > 0 { - return fmt.Errorf("found %d broken links and %d GitHub API errors", len(broken), len(ghErrs)) + if len(summary.Broken) > 0 && len(summary.GitHubErrors) > 0 { + return fmt.Errorf("found %d broken links and %d GitHub API errors", len(summary.Broken), len(summary.GitHubErrors)) } - if len(broken) > 0 { - return fmt.Errorf("found %d broken links", len(broken)) + if len(summary.Broken) > 0 { + return fmt.Errorf("found %d broken links", len(summary.Broken)) } - if len(ghErrs) > 0 { - return fmt.Errorf("github checks failed with %d errors", len(ghErrs)) + if len(summary.GitHubErrors) > 0 { + return fmt.Errorf("github checks failed with %d errors", len(summary.GitHubErrors)) } fmt.Println("All links OK") @@ -193,47 +378,7 @@ func healthCmd() *cobra.Command { Use: "health", Short: "Score repository health and update cache", RunE: func(cmd *cobra.Command, args []string) error { - token := os.Getenv("GITHUB_TOKEN") - if token == "" { - return fmt.Errorf("GITHUB_TOKEN environment variable is required") - } - - doc, err := parseReadme() - if err != nil { - return fmt.Errorf("parse: %w", err) - } - - var urls []string - collectURLs(doc.Sections, &urls) - ghURLs, _ := checker.PartitionLinks(urls) - - fmt.Printf("Scoring %d GitHub repositories...\n", len(ghURLs)) - gc := checker.NewGitHubChecker(token) - infos, errs := gc.CheckRepos(context.Background(), ghURLs, 50) - for _, e := range errs { - fmt.Printf(" error: %v\n", e) - } - if len(infos) == 0 { - if len(errs) > 0 { - return fmt.Errorf("failed to fetch GitHub metadata for all repositories (%d errors); check network/DNS and GITHUB_TOKEN", len(errs)) - } - return fmt.Errorf("no GitHub repositories found in README") - } - - scored := scorer.ScoreAll(infos) - cacheEntries := scorer.ToCacheEntries(scored) - - hc, err := cache.LoadHealthCache(healthCachePath) - if err != nil { - return fmt.Errorf("load cache: %w", err) - } - hc.Merge(cacheEntries) - if err := cache.SaveHealthCache(healthCachePath, hc); err != nil { - return fmt.Errorf("save cache: %w", err) - } - - fmt.Printf("Cache updated: %d entries in %s\n", len(hc.Entries), healthCachePath) - return nil + return runHealth(context.Background()) }, } } @@ -258,24 +403,9 @@ func reportCmd() *cobra.Command { Use: "report", Short: "Generate health report from cache", RunE: func(cmd *cobra.Command, args []string) error { - hc, err := cache.LoadHealthCache(healthCachePath) + scored, err := scoredFromCache() if err != nil { - return fmt.Errorf("load cache: %w", err) - } - if len(hc.Entries) == 0 { - return fmt.Errorf("no cache data, run 'health' first") - } - - var scored []scorer.ScoredEntry - for _, e := range hc.Entries { - scored = append(scored, scorer.ScoredEntry{ - URL: e.URL, - Name: e.Name, - Status: scorer.Status(e.Status), - Stars: e.Stars, - HasLicense: e.HasLicense, - LastPush: e.LastPush, - }) + return err } if jsonOutput { @@ -319,28 +449,17 @@ func validateCmd() *cobra.Command { fmt.Printf("Lint OK: %d warnings\n", result.Warnings) fmt.Println("\n=== Checking links (PR mode) ===") - var urls []string - collectURLs(doc.Sections, &urls) - exclude, err := cache.LoadExcludeList(excludePath) + summary, err := runLinkChecks(true) if err != nil { - return fmt.Errorf("load exclude list: %w", err) + return err } - _, extURLs := checker.PartitionLinks(urls) - - fmt.Printf("Checking %d external links...\n", len(extURLs)) - results := checker.CheckLinks(extURLs, 10, exclude) - var broken []checker.LinkResult - for _, r := range results { - if !r.OK { - broken = append(broken, r) - } - } - if len(broken) > 0 { - fmt.Printf("\n%d broken links:\n", len(broken)) - for _, r := range broken { + fmt.Printf("Checking %d external links...\n", summary.ExternalTotal) + if len(summary.Broken) > 0 { + fmt.Printf("\n%d broken links:\n", len(summary.Broken)) + for _, r := range summary.Broken { fmt.Printf(" %s -> %d %s\n", r.URL, r.StatusCode, r.Error) } - return fmt.Errorf("found %d broken links", len(broken)) + return fmt.Errorf("found %d broken links", len(summary.Broken)) } fmt.Println("\nValidation passed") @@ -348,3 +467,164 @@ func validateCmd() *cobra.Command { }, } } + +func ciCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "ci", + Short: "CI-oriented helper commands", + } + cmd.AddCommand( + ciBrokenLinksCmd(), + ciHealthReportCmd(), + ) + return cmd +} + +func ciBrokenLinksCmd() *cobra.Command { + var issueFile string + var githubOutput string + var strict bool + + cmd := &cobra.Command{ + Use: "broken-links", + Short: "Run link checks and emit CI outputs/artifacts", + RunE: func(cmd *cobra.Command, args []string) error { + summary, runErr := runLinkChecks(false) + + hasErrors := runErr != nil || len(summary.Broken) > 0 || len(summary.GitHubErrors) > 0 + exitCode := 0 + if hasErrors { + exitCode = 1 + } + if runErr != nil { + exitCode = 2 + } + + if issueFile != "" && hasErrors { + body := buildBrokenLinksIssueBody(summary, runErr) + if err := os.WriteFile(issueFile, []byte(body), 0o644); err != nil { + return fmt.Errorf("write issue file: %w", err) + } + } + + if err := writeGitHubOutput(githubOutput, "has_errors", strconv.FormatBool(hasErrors)); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "check_exit_code", strconv.Itoa(exitCode)); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "broken_count", strconv.Itoa(len(summary.Broken))); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "github_error_count", strconv.Itoa(len(summary.GitHubErrors))); err != nil { + return err + } + if runErr != nil { + if err := writeGitHubOutput(githubOutput, "run_error", sanitizeOutputValue(runErr.Error())); err != nil { + return err + } + } + + if runErr != nil { + fmt.Printf("CI broken-links run error: %v\n", runErr) + } + if hasErrors { + fmt.Printf("CI broken-links found %d broken links and %d GitHub errors\n", len(summary.Broken), len(summary.GitHubErrors)) + } else { + fmt.Println("CI broken-links found no errors") + } + + if strict { + if runErr != nil { + return runErr + } + if hasErrors { + return fmt.Errorf("found %d broken links and %d GitHub API errors", len(summary.Broken), len(summary.GitHubErrors)) + } + } + return nil + }, + } + + cmd.Flags().StringVar(&issueFile, "issue-file", "broken_links_issue.md", "Path to write issue markdown body") + cmd.Flags().StringVar(&githubOutput, "github-output", "", "Path to GitHub output file (typically $GITHUB_OUTPUT)") + cmd.Flags().BoolVar(&strict, "strict", false, "Return non-zero when errors are found") + return cmd +} + +func ciHealthReportCmd() *cobra.Command { + var issueFile string + var githubOutput string + var strict bool + + cmd := &cobra.Command{ + Use: "health-report", + Short: "Refresh health cache, render report, and emit CI outputs/artifacts", + RunE: func(cmd *cobra.Command, args []string) error { + healthErr := runHealth(context.Background()) + report, reportErr := markdownReportFromCache() + + healthOK := healthErr == nil + reportOK := reportErr == nil + hasReport := reportOK && strings.TrimSpace(report) != "" + hasErrors := !healthOK || !reportOK + + if hasReport && issueFile != "" { + body := buildHealthReportIssueBody(report, healthErr) + if err := os.WriteFile(issueFile, []byte(body), 0o644); err != nil { + return fmt.Errorf("write issue file: %w", err) + } + } + + if err := writeGitHubOutput(githubOutput, "has_report", strconv.FormatBool(hasReport)); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "health_ok", strconv.FormatBool(healthOK)); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "report_ok", strconv.FormatBool(reportOK)); err != nil { + return err + } + if err := writeGitHubOutput(githubOutput, "has_errors", strconv.FormatBool(hasErrors)); err != nil { + return err + } + if healthErr != nil { + if err := writeGitHubOutput(githubOutput, "health_error", sanitizeOutputValue(healthErr.Error())); err != nil { + return err + } + } + if reportErr != nil { + if err := writeGitHubOutput(githubOutput, "report_error", sanitizeOutputValue(reportErr.Error())); err != nil { + return err + } + } + + if healthErr != nil { + fmt.Printf("CI health-report health error: %v\n", healthErr) + } + if reportErr != nil { + fmt.Printf("CI health-report report error: %v\n", reportErr) + } + if hasReport { + fmt.Println("CI health-report generated report artifact") + } else { + fmt.Println("CI health-report has no report artifact") + } + + if strict { + if healthErr != nil { + return healthErr + } + if reportErr != nil { + return reportErr + } + } + return nil + }, + } + + cmd.Flags().StringVar(&issueFile, "issue-file", "health_report.txt", "Path to write health issue markdown body") + cmd.Flags().StringVar(&githubOutput, "github-output", "", "Path to GitHub output file (typically $GITHUB_OUTPUT)") + cmd.Flags().BoolVar(&strict, "strict", false, "Return non-zero when health/report fails") + return cmd +}