Repository: veggiemonk/awesome-docker Branch: master Commit: bba85d05492b Files: 48 Total size: 380.4 KB Directory structure: gitextract_uu2bikk7/ ├── .claude/ │ └── settings.local.json ├── .gitattributes ├── .github/ │ ├── CODEOWNERS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE/ │ │ └── add-a-project.md │ ├── MAINTENANCE.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── dependabot.yml │ └── workflows/ │ ├── broken_links.yml │ ├── deploy-pages.yml │ ├── health_report.yml │ └── pull_request.yml ├── .gitignore ├── AGENTS.md ├── LICENSE ├── Makefile ├── README.md ├── cmd/ │ └── awesome-docker/ │ └── main.go ├── config/ │ ├── exclude.yaml │ ├── health_cache.yaml │ └── website.tmpl.html ├── go.mod ├── go.sum ├── index.html └── internal/ ├── builder/ │ ├── builder.go │ └── builder_test.go ├── cache/ │ ├── cache.go │ └── cache_test.go ├── checker/ │ ├── github.go │ ├── github_test.go │ ├── http.go │ └── http_test.go ├── linter/ │ ├── fixer.go │ ├── fixer_test.go │ ├── linter.go │ ├── linter_test.go │ └── rules.go ├── parser/ │ ├── parser.go │ ├── parser_test.go │ └── types.go ├── scorer/ │ ├── scorer.go │ └── scorer_test.go └── tui/ ├── model.go ├── styles.go ├── tree.go ├── tree_test.go └── tui.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .claude/settings.local.json ================================================ { "permissions": { "allow": [ "mcp__plugin_context-mode_context-mode__ctx_batch_execute", "mcp__plugin_context7_context7__resolve-library-id", "mcp__plugin_context7_context7__query-docs", "Bash(go:*)", "Bash(./awesome-docker:*)", "Bash(tmux send-keys:*)", "Bash(tmux capture-pane:*)", "Bash(tmux:*)" ] } } ================================================ FILE: .gitattributes ================================================ *.css linguist-vendored *.* linguist-language=Markdown ================================================ FILE: .github/CODEOWNERS ================================================ * @veggiemonk @agebhar1 @dmitrytokarev @gesellix @mashb1t @moshloop @vegasbrianc @noteed ================================================ FILE: .github/CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at julien.bisconti (at) hotmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing to awesome-docker Thanks for taking the time to contribute. 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. Please read and follow the [Code of Conduct](./CODE_OF_CONDUCT.md). ## What We Accept - 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 ## README Entry Rules - 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 `:yen:` for paid/commercial services. - Use `:ice_cube:` for stale projects (2+ years inactive). - Do not use `:skull:`; archived/deprecated projects should be removed. - Avoid duplicate links and redirect variants. ## Local Validation ```bash # Build CLI make build # Validate README formatting and content make lint # Run code tests (when touching Go code) make test # Optional: full external checks (requires GITHUB_TOKEN) ./awesome-docker check ./awesome-docker validate ``` ## Pull Request Expectations - 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. ## Maintainer Notes - 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. ================================================ FILE: .github/ISSUE_TEMPLATE/add-a-project.md ================================================ --- name: Add a project about: Add a new project to the list title: "add: [PROJECT_NAME] in [SECTION_NAME]" labels: pending-evaluation assignees: '' --- Category: Repository link: Description (one sentence): Author: Why this should be in the list: Notes (`:yen:` if relevant): Or directly write it: ```markdown [REPO](https://github.com/AUTHOR/REPO) - DESCRIPTION. ``` ================================================ FILE: .github/MAINTENANCE.md ================================================ # Maintenance Guide This guide describes how maintainers keep the list and automation healthy. ## Automated Workflows ### Pull Requests / Weekly QA (`pull_request.yml`) - Runs on pull requests and weekly on Saturday. - Builds the Go CLI and runs `./awesome-docker validate`. ### Broken Links Report (`broken_links.yml`) - Runs weekly on Saturday and on manual trigger. - Executes `./awesome-docker check`. - Opens/updates a `broken-links` issue when problems are found. ### Weekly Health Report (`health_report.yml`) - Runs weekly on Monday and on manual trigger. - Executes `./awesome-docker health` then `./awesome-docker report`. - Opens/updates a `health-report` issue. ### Deploy to GitHub Pages (`deploy-pages.yml`) - Runs on pushes to `master` and manual trigger. - Builds website with `./awesome-docker build` and publishes `website/`. ## Day-to-Day Commands ```bash # Build CLI make build # README lint/validation make lint # Auto-fix formatting issues ./awesome-docker lint --fix # Link checks and health checks (requires GITHUB_TOKEN) make check make health make report ``` ## Content Maintenance Policy - Remove archived/deprecated projects instead of tagging them. - Remove broken links that cannot be fixed. - Keep sections alphabetically sorted. - Keep descriptions short and actionable. ## Suggested Review Cadence ### Weekly - Triage open `broken-links` and `health-report` issues. - Merge straightforward quality PRs. ### Monthly - Review sections for stale/duplicate entries. - Re-run `check` and `health` manually if needed. ### Quarterly - Review `.github` docs and templates for drift. - Confirm workflows still match repository tooling and policies. ## Contributor Support 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: 2026-02-27 ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ # Summary Describe what changed and why. ## Scope - [ ] README entries/content - [ ] Go CLI/tooling - [ ] GitHub workflows or `.github` docs ## If This PR Adds/Edits README Entries - Category/section touched: - New or updated project links: ## Validation - [ ] `make lint` - [ ] `make test` (if Go code changed) - [ ] `./awesome-docker check` (if `GITHUB_TOKEN` available) ## 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 `:yen:` only when applicable ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: # Enable version updates for Go modules - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" # Enable version updates for GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" ================================================ FILE: .github/workflows/broken_links.yml ================================================ name: Broken Links Report on: schedule: - 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 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker - name: Run Link Check id: link_check run: ./awesome-docker ci broken-links --issue-file broken_links_issue.md --github-output "$GITHUB_OUTPUT" 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 with: script: | const fs = require('fs'); const issueBody = fs.readFileSync('broken_links_issue.md', 'utf8'); const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', labels: 'broken-links', per_page: 1 }); if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, body: issueBody }); } else { await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: 'Broken Links Detected', body: issueBody, labels: ['broken-links', 'bug'] }); } - name: Close Issue if No Errors if: steps.link_check.outputs.has_errors == 'false' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', labels: 'broken-links', per_page: 1 }); if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, state: 'closed', state_reason: 'completed' }); } ================================================ FILE: .github/workflows/deploy-pages.yml ================================================ name: Deploy to GitHub Pages on: push: branches: - master workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: false jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod - name: Build CLI run: go build -o awesome-docker ./cmd/awesome-docker - name: Build website run: make website - name: Upload artifact uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # ratchet:actions/upload-pages-artifact@v4 with: path: ./website deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # ratchet:actions/deploy-pages@v4 ================================================ FILE: .github/workflows/health_report.yml ================================================ name: Weekly Health Report on: schedule: - 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 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker - 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: Create/Update Issue with Health Report if: steps.report.outputs.has_report == 'true' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const fs = require('fs'); const report = fs.readFileSync('health_report.txt', 'utf8'); const issueBody = report; const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', labels: 'health-report', per_page: 1 }); if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, body: issueBody }); } else { await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: 'Weekly Health Report - Repository Maintenance Needed', body: issueBody, labels: ['health-report', 'maintenance'] }); } ================================================ FILE: .github/workflows/pull_request.yml ================================================ name: Pull Requests / Weekly QA on: pull_request: branches: - master schedule: - cron: "0 0 * * 6" jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6 - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # ratchet:actions/setup-go@v6 with: go-version-file: go.mod - name: Build run: go build -o awesome-docker ./cmd/awesome-docker - name: Build website run: ./awesome-docker build - name: Validate run: ./awesome-docker validate env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ logs *.log npm-debug.log* build node_modules .cache dist website/index.html website/table.html .idea **/.DS_Store .worktrees # Go /awesome-docker ================================================ FILE: AGENTS.md ================================================ # Agent Guidelines for awesome-docker ## 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: `make lint-fix` - Check links: `make check` (runs `./awesome-docker check`; `GITHUB_TOKEN` enables GitHub repo checks) - 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) - **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 - **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 - **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/` ## 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 - Keep entries alphabetically ordered within each section - Keep descriptions concise and concrete - Use `:yen:` only for paid/commercial services - Use `:ice_cube:` for stale projects (2+ years inactive) - Remove archived/deprecated projects instead of tagging them - Avoid duplicate links and redirect variants ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: Makefile ================================================ SHELL := /bin/bash 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 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 .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 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 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 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 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 browse: build ## Launch interactive TUI browser ./$(BINARY) browse 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 update-ga: ratchet upgrade .github/workflows/* update-go: go get -u go@latest go get -u ./... go mod tidy ================================================ FILE: README.md ================================================ # 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 If you would like to contribute, please read [CONTRIBUTING.md][contributing] first. It contains a lot of tips and guidelines to help keep things organized. Just click [README.md][editreadme] to submit a [pull request][editreadme]. If this list is not complete, you can [contribute][editreadme] to make it so. Here is a great video tutorial to learn how to [contribute on Github](https://egghead.io/lessons/javascript-identifying-how-to-contribute-to-an-open-source-project-on-github). > **Please**, help organize these resources so that they are _easy to find_ and _understand_ for newcomers. See how to **[Contribute][contributing]** for tips! **_If you see a link here that is not (any longer) a good fit, you can fix it by submitting a [pull request][editreadme] to improve this file. Thank you!_** The creators and maintainers of this list do not receive any form of payment to accept a change made by any contributor. This page is not an official Docker product in any way. It is a list of links to projects and is maintained by volunteers. Everybody is welcome to contribute. The goal of this repo is to index open-source projects, not to advertise for profit. # Contents - [Legend](#legend) - [What is Docker](#what-is-docker) - [Where to start](#where-to-start) - [Where to start (Windows)](#where-to-start-windows) - [Projects](#projects) - [Container Operations](#container-operations) - [Container Composition](#container-composition) - [Deployment and Infrastructure](#deployment-and-infrastructure) - [Monitoring](#monitoring) - [Networking](#networking) - [Orchestration](#orchestration) - [PaaS](#paas) - [Reverse Proxy](#reverse-proxy) - [Runtime](#runtime) - [Security](#security) - [Service Discovery](#service-discovery) - [Volume Management / Data](#volume-management--data) - [User Interface](#user-interface) - [IDE integrations](#ide-integrations) - [Desktop](#desktop) - [Terminal](#terminal) - [Terminal UI](#terminal-ui) - [CLI tools](#cli-tools) - [Other](#other) - [Web](#web) - [Docker Images](#docker-images) - [Base Tools](#base-tools) - [Builder](#builder) - [Dockerfile](#dockerfile) - [Linter](#linter) - [Metadata](#metadata) - [Registry](#registry) - [Development with Docker](#development-with-docker) - [API Client](#api-client) - [CI/CD](#cicd) - [Development Environment](#development-environment) - [Garbage Collection](#garbage-collection) - [Serverless](#serverless) - [Testing](#testing) - [Wrappers](#wrappers) - [Services based on Docker (mostly :yen:)](#services-based-on-docker-mostly-yen) - [CI Services](#ci-services) - [CaaS](#caas) - [Monitoring Services](#monitoring-services) - [Useful Resources](#useful-resources) - [Awesome Lists](#awesome-lists) - [Demos and Examples](#demos-and-examples) - [Good Tips](#good-tips) - [Raspberry Pi \& ARM](#raspberry-pi--arm) - [Security](#security-1) - [Videos](#videos) - [Communities and Meetups](#communities-and-meetups) - [Brazilian](#brazilian) - [English](#english) - [Russian](#russian) - [Spanish](#spanish) - [Stargazers over time](#stargazers-over-time) # Legend - Monetized :yen: - Stale (2+ years inactive) :ice_cube: # What is Docker > Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications. Consisting of Docker Engine, a portable, lightweight runtime and packaging tool, and Docker Hub, a cloud service for sharing applications and automating workflows, Docker enables apps to be quickly assembled from components and eliminates the friction between development, QA, and production environments. As a result, IT can ship faster and run the same app, unchanged, on laptops, data center VMs, and any cloud. _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) - 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. - [Docker for novices](https://www.youtube.com/watch?v=xsjSadjKXns) An introduction to Docker for developers and testers who have never used it. (Video 1h40, recorded linux.conf.au 2019 — Christchurch, New Zealand) by Alex Clews. - [Docker katas](https://github.com/eficode-academy/docker-katas) A series of labs that will take you from "Hello Docker" to deploying a containerized web application to a server. - [Docker simplified in 55 seconds](https://www.youtube.com/watch?v=vP_4DlOH1G4): An animated high-level introduction to Docker. Think of it as a visual tl;dr that makes it easier to dive into more complex learning materials. - [Docker Training](https://training.mirantis.com) :yen: - [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 (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) # 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 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) - 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 --- # Projects - Moby = open source development - Docker CE = free product release based on Moby - Docker EE = commercial product release based on Docker CE. > Docker EE is on the same code base as Docker CE, so also built from Moby, with commercial components added, such as "docker data center / universal control plane" - [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 Registry][distribution] (The Docker toolset to pack, ship, store, and deliver content) ## Container Operations ### Container Composition - [Capitan](https://github.com/byrnedo/capitan) :ice_cube: - 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) :ice_cube: - Tool for managing multiple Docker containers (`docker-compose` alternative). - [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) :ice_cube: - Utility to update docker configs and secrets for deploying in a compose file. - [elsy](https://github.com/cisco/elsy) :ice_cube: - An opinionated, multi-language, build tool based on Docker and Docker Compose. - [habitus](https://github.com/cloud66-oss/habitus) :ice_cube: - 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). - [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. - [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. - [Clocker](https://github.com/brooklyncentral/clocker) :ice_cube: - 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) :ice_cube: - Experimental deployment system for Docker. - [depcon](https://github.com/ContainX/depcon) :ice_cube: - 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. - [gitkube](https://github.com/hasura/gitkube) :ice_cube: - 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). - [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 - [ADRG](https://github.com/jaldertech/adrg) - Dynamic Docker resource governor using cgroups v2 to manage system load. - [Autoheal](https://github.com/willfarrell/docker-autoheal) - Monitor and restart unhealthy docker containers automatically. - [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) :ice_cube: - Monitor and send alerts based on docker container resource usage/statistics. - [Docker-Flow-Monitor](https://github.com/docker-flow/docker-flow-monitor) :ice_cube: - Reconfigures Prometheus when a new service is updated or deployed automatically. - [DockProbe](https://github.com/deep-on/dockprobe) - Lightweight Docker monitoring dashboard in a single container. Real-time metrics, 6 anomaly detection rules, Telegram alerts, and 16 automated security scans. Zero config, ~50MB RAM. By [DeepOn](https://github.com/deep-on). - [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). - [Drydock](https://github.com/CodesWhat/drydock) - Container update monitoring with web dashboard, 23 registry providers, 20 notification triggers, and distributed agent architecture. By [CodesWhat](https://github.com/CodesWhat). - [Dynatrace](https://docs.dynatrace.com/docs/observe/infrastructure-observability/container-platform-monitoring) - :yen: 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) :ice_cube: - InfluxDB Time series DB in combination with Grafana and cAdvisor. - [Logspout](https://github.com/gliderlabs/logspout) :ice_cube: - Log routing for Docker container logs. - [Maintenant](https://github.com/kolapsis/maintenant) - Self-discovering infrastructure monitoring for Docker and Kubernetes. Auto-detects containers via labels, with endpoint monitoring, heartbeats, TLS certificates, resource metrics, update intelligence, and a built-in status page. Single binary with embedded SPA. By [kolapsis](https://github.com/kolapsis). - [monit-docker](https://github.com/decryptus/monit-docker) :ice_cube: - Monitor docker containers resources usage or status and execute docker commands or inside containers. [decryptus][decryptus]. - [NexClipper](https://github.com/NexClipper/NexClipper) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. - [SwarmAlert](https://github.com/gpulido/SwarmAlert) :ice_cube: - 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) :ice_cube: - Monitor containers automatically using zabbix LLD feature. - [Zabbix Docker module](https://github.com/monitoringartist/Zabbix-Docker-Monitoring) :ice_cube: - 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) :ice_cube: - 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]. ### Orchestration - [Ansible Linux Docker](https://github.com/Peco602/ansible-linux-docker) :ice_cube: - Run Ansible from a Linux container. By [Peco602][peco602]. - [athena](https://github.com/athena-oss/athena) :ice_cube: - An automation platform with a plugin architecture that allows you to easily create and share services. - [CloudSlang](https://github.com/CloudSlang/cloud-slang) - CloudSlang is a workflow engine to create Docker process automation. - [clusterdock](https://github.com/clusterdock/clusterdock) :ice_cube: - Docker container orchestration to enable the testing of long-running cluster deployments. - [Crane](https://github.com/Dataman-Cloud/crane) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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/). - [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. - [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) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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. - [Hephy Workflow](https://github.com/teamhephy/workflow) :ice_cube: - 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) :ice_cube: - Toolset for managing container workloads on remote servers. - [Nanobox](https://github.com/nanobox-io/nanobox) :ice_cube: - :yen: 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. ### 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]. - [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). - [idle-less](https://github.com/tvup/idle-less) - Reverse proxy with automatic Wake-on-LAN — wakes sleeping backend servers when traffic arrives, shows a waiting screen, and redirects when ready. By [tvup](https://github.com/tvup). - [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 - [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) :ice_cube: - 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/) - :yen: Analyze images for CVE vulnerabilities and against custom security policies. - [Aqua Security](https://www.aquasec.com) - :yen: Securing container-based applications from Dev to Production on any platform. - [bane](https://github.com/genuinetools/bane) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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) - :yen: 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. - [dvwassl](https://github.com/Peco602/dvwassl) :ice_cube: - 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). - [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) - :yen: (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) - :yen: 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) - :yen: 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. - [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. - [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) :yen:- 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) - [duplicacy-cli-cron](https://github.com/GeiserX/duplicacy-cli-cron) - Docker-based encrypted dual-storage backup automation using Duplicacy CLI with cross-site redundancy and Telegram notifications. By [GeiserX](https://github.com/GeiserX). - [Netshare](https://github.com/ContainX/docker-volume-netshare) Docker NFS, AWS EFS, Ceph & Samba/CIFS Volume Plugin. By [ContainX][containx] - [portworx](https://portworx.com) - :yen: Decentralized storage solution for persistent, shared and replicated volumes. - [quobyte](https://www.quobyte.com/) - :yen: 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) :ice_cube: - :yen: Software-defined Persistent Storage for Kubernetes and Docker Swarm. ### User Interface #### IDE integrations - 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) - [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 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). #### Terminal ##### Terminal UI - [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] - [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). - [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),. ##### CLI tools - [captain](https://github.com/jenssegers/captain) :ice_cube: - 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) :ice_cube: - 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. - [DVM](https://github.com/howtowhale/dvm) :ice_cube: - Docker version manager. - [goinside](https://github.com/iamsoorena/goinside) :ice_cube: - Get inside a running docker container easily. - [Pdocker](https://github.com/g31s/Pdocker) :ice_cube: - 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. - [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) :ice_cube: - Python based Assistance for Docker. ##### Other - [dext-docker-registry-plugin](https://github.com/vutran/dext-docker-registry-plugin) :ice_cube: - Search the Docker Registry with the Dext smart launcher. By [vutran](https://github.com/vutran). - [docker-ssh](https://github.com/jeroenpeeters/docker-ssh) :ice_cube: - 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) :ice_cube: - Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. - [Powerline-Docker](https://github.com/adrianmo/powerline-docker) :ice_cube: - A Powerline segment for showing the status of Docker containers. #### Web - [Arcane](https://github.com/getarcaneapp/arcane) - An easy and modern Docker management platform, built with everybody in mind. By [getarcaneapp](https://github.com/getarcaneapp). - [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) :ice_cube: - 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-web](https://github.com/mkuchin/docker-registry-web) :ice_cube: - 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). - [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) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - A simple query dashboard to use Docker Remote API. - [Seagull](https://github.com/tobegit3hub/seagull) :ice_cube: - 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) :ice_cube: - 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). ## Docker Images ### Base Tools 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) :ice_cube: - Container introspection tool. Find out what container runtime is being used as well as features available. - [Chaperone](https://github.com/garywiz/chaperone) :ice_cube: - 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,. - [docker-alpine](https://github.com/gliderlabs/docker-alpine) :ice_cube: - 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) :ice_cube: - 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. - [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) :ice_cube: - 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) :ice_cube: - 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`. - [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-factory](https://github.com/mutable/container-factory) :ice_cube: - Produces Docker images from tarballs of application source code. - [copy-docker-image](https://github.com/mdlavin/copy-docker-image) :ice_cube: - Copy a Docker image between registries without a full Docker installation. - [Derrick](https://github.com/alibaba/derrick) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - Dockly is a gem made to ease the pain of packaging an application in Docker. - [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) :ice_cube: - Apache Mesos framework for building Docker images. - [Production-Ready Python Containers :yen:](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. - [userdef](https://github.com/theAkito/userdef) :ice_cube: - 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) :ice_cube: - A tool to automatically dockerize your applications. ### Dockerfile - [chaperone-docker](https://github.com/garywiz/chaperone-docker) :ice_cube: - 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. - [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) ### Linter - [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) :ice_cube: - The linter lets you verify Dockerfile syntax to make sure it follows the best practices for building efficient Docker images. - [FROM:latest](https://github.com/replicatedhq/dockerfilelint) :ice_cube: - 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;. ### Metadata - [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 Services to securely store your Docker images. - [Amazon Elastic Container Registry :yen:](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 :yen:](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) :ice_cube: - 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) :ice_cube: - A small tool to delete image manifests from a Docker Registry implementing the API v2, dereferencing them for the GC. - [Cloudsmith :yen:](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 :yen:](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 :yen:](https://cycle.io/) - Bare-metal container hosting. - [DigitalOcean :yen:](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) :ice_cube: - 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 :yen:](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. - [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 :yen:](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 :yen:](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) :ice_cube: - 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) :ice_cube: - 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]. - [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-it-scala](https://github.com/whisklabs/docker-it-scala) :ice_cube: - Docker integration testing kit with Scala. - [docker-java-api](https://github.com/amihaiemil/docker-java-api) :ice_cube: - 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). - [dockerode](https://github.com/apocas/dockerode) - Docker Remote API node.js module. - [DoMonit](https://github.com/eon01/DoMonit) :ice_cube: - 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) - 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 - [Buddy :yen:](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) :ice_cube: - 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 :yen:](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. - [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) :ice_cube: - Continuous deployment of a microservices application. - [mu](https://github.com/stelligent/mu) :ice_cube: - 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) :ice_cube: - Github actions workflow (HCL syntax) execution engine. - [Screwdriver :yen:](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) :ice_cube: - Create a distributed, isolated task pipeline in your Docker Swarm. - [Tekton CD](https://tekton.dev/) - A cloud-native pipeline resource. ### Development Environment - [Binci](https://github.com/binci/binci) :ice_cube: - 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) :ice_cube: - Run your builds inside a Docker defined environment. - [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) :ice_cube: - A build automation tool for Docker applications. By [dnephin](https://github.com/dnephin). - [Docker Missing Tools](https://github.com/nandoquintana/docker-missing-tools) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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). - [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) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - 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) :ice_cube: - A docker garbage collector cleaning stuff you did not use recently. - [Docker Clean](https://github.com/ZZROTDesign/docker-clean) :ice_cube: - 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_gc](https://github.com/pdacity/docker_gc) :ice_cube: - 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 - [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) :ice_cube: - Functions as Docker containers example voting app. By [bfirsh](https://github.com/bfirsh). - [IronFunctions](https://github.com/iron-io/functions) :ice_cube: - 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/) - :yen: 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) :ice_cube: - 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/goss-org/goss/tree/master/extras/dgoss) - A fast YAML based tool for validating docker containers. - [DockerSpec](https://github.com/zuazo/dockerspec) :ice_cube: - 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) :ice_cube: - 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). ### Wrappers - [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) :ice_cube: - Command line interface written in Go for running code with Docker Exec images. - [dockerized](https://github.com/benzaita/dockerized-cli) :ice_cube: - Seamlessly execute commands in a container. - [Dray](https://github.com/CenturyLinkLabs/dray) :ice_cube: - An engine for managing the execution of container-based workflows. - [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) :ice_cube: - 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. - [Terraform cloud-init config](https://github.com/christippett/terraform-cloudinit-container-server) :ice_cube: - Terraform module for deploying a single Docker image or `docker-compose.yaml` file to any Cloud™ VM. - [Turbo](https://github.com/ramitsurana/turbo) :ice_cube: - 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 :yen:) ### CI Services - [CircleCI](https://circleci.com/) - :yen: Push or pull Docker images from your build environment, or build and run containers right on CircleCI. - [CodeFresh](https://codefresh.io) - :yen: Everything you need to build, test, and share your Docker applications. Provides automated end to end testing. - [CodeShip](https://www.cloudbees.com/blog/how-to-run-codeship-parallel-test-pipelines-efficiently-for-optimal-ci-parallelization) - :yen: 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) - :yen: A CI SaaS platform for developers and DevOps teams pipeline oriented. - [Semaphore CI](https://semaphore.io/) :yen: — A high-performance cloud solution that makes it easy to build, test and ship your containers to production. - [TravisCI](https://www.travis-ci.com/) - :yen: A Free github projects continuous integration Saas platform for developers and Devops. ### CaaS - [Amazon ECS](https://aws.amazon.com/ecs/) - :yen: A management service on EC2 that supports Docker containers. - [Appfleet](https://appfleet.com/) - :yen: 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/) - :yen: Simplify Kubernetes management, deployment, and operations. Use a fully managed Kubernetes container orchestration service. - [Cloud 66](https://www.cloud66.com) - :yen: Full-stack hosted container management as a service. - [Giant Swarm](https://www.giantswarm.io/) - :yen: Simple microservice infrastructure. Deploy your containers in seconds. - [Google Container Engine](https://docs.cloud.google.com/kubernetes-engine/docs) - :yen: Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes]. - [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) - :yen: Integrated platform for data and containers built on Apache Mesos. - [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) - :yen: Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud. - [Triton](https://www.joyent.com/) - :yen: Elastic container-native infrastructure by Joyent. ### 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/) - :yen: 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) - :yen: 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/) - :yen: 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. - [Prometheus](https://prometheus.io/) - :yen: Open-source service monitoring system and time series database. - [Site24x7](https://www.site24x7.com/docker-monitoring.html) - :yen: Docker Monitoring for DevOps and IT is a SaaS Pay per Host model. - [SPM for Docker](https://github.com/sematext/sematext-agent-docker) :ice_cube: - :yen: 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) - :yen: 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 Certification](https://intellipaat.com/docker-training-course/?US) :yen: 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 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. - [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. - [Programming Community Curated Resources for learning Docker](https://hackr.io/tutorials/learn-docker) ## Awesome Lists - [Awesome CI/CD](https://github.com/cicdops/awesome-ciandcd) :ice_cube: - 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) ## 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) - [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 vs. VMs? Combining Both for Cloud Portability Nirvana](https://www.flexera.com/blog/finops/) - [Dockerfile best practices](https://github.com/hexops/dockerfile) :ice_cube: - 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] ## Raspberry Pi & ARM - [Docker Pirates ARMed with explosive stuff](https://blog.hypriot.com/) Huge resource on clustering, swarm, docker, pre-installed image for SD card on Raspberry Pi - [Get Docker up and running on the RaspberryPi in three steps](https://github.com/umiddelb/armhf/wiki/Get-Docker-up-and-running-on-the-RaspberryPi-%28ARMv6%29-in-three-steps) - [git push docker containers to linux devices](https://www.balena.io) Modern DevOps for IoT, leveraging git and Docker. - [Installing, running, using Docker on armhf (ARMv7) devices](https://github.com/umiddelb/armhf/wiki/Installing,-running,-using-docker-on-armhf-%28ARMv7%29-devices) ## 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) - [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) - [How CVE's are handled on Offical Docker Images](https://github.com/docker-library/official-images/issues/1448) - [Lynis is an open source security auditing tool including Docker auditing](https://cisofy.com/lynis/) - [Security Best Practices for Building Docker Images](https://linux-audit.com/tags/docker/) - [Software Engineering Radio interview of Docker Security Team Lead (Diogo Mónica)](https://www.se-radio.net/2017/05/se-radio-episode-290-diogo-monica-on-docker-security/) - [Ten Docker Image Security Best Practices Cheat Sheet](https://snyk.io/blog/10-docker-image-security-best-practices/) - [Top ten most popular docker images each contain at least 30 vulnerabilities](https://snyk.io/blog/top-ten-most-popular-docker-images-each-contain-at-least-30-vulnerabilities/) - [Tuning Docker with the newest security enhancements](https://opensource.com/business/15/3/docker-security-tuning) - [10 best practices to containerize Node.js web applications with Docker](https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/) ## 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] - [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 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 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 - [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] - [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 - [State of containers: a debate with CoreOS, VMware and Google](https://www.youtube.com/watch?v=IiITP3yIRd8) (27:38) # Communities and Meetups ## Brazilian - [Docker BR on Telegram](https://telegram.me/dockerbr) ## English - [Docker Community](https://www.docker.com/community/) - [Docker Events](https://www.docker.com/events/) - [Docker Online Meetup](https://www.meetup.com/en-AU/Docker-Online-Meetup/) - [Docker Reddit Community](https://www.reddit.com/r/docker/) ## Russian - [Docker Russian-speaking Community](https://t.me/docker_ru) ## Spanish - [Docker Tips](https://dockertips.com/) ## Stargazers over time [![Stargazers over time](https://starchart.cc/veggiemonk/awesome-docker.svg?variant=adaptive)](https://starchart.cc/veggiemonk/awesome-docker) [contributing]: https://github.com/veggiemonk/awesome-docker/blob/master/.github/CONTRIBUTING.md [calico]: https://github.com/projectcalico/calico [containx]: https://github.com/ContainX [coreos]: https://github.com/coreos [deepfence]: https://github.com/deepfence [distribution]: https://github.com/docker/distribution [docker-flow]: https://github.com/docker-flow [docker-for-windows]: https://docs.docker.com/desktop/setup/install/windows-install/ [docker]: https://github.com/docker [dozzle]: https://github.com/amir20/dozzle [editreadme]: https://github.com/veggiemonk/awesome-docker/edit/master/README.md [fgrehm]: https://github.com/fgrehm [gliderlabs]: https://github.com/gliderlabs [googlecontainertools]: https://github.com/GoogleContainerTools [inspec]: https://github.com/inspec/inspec [jessfraz]: https://github.com/jessfraz [jpetazzo]: https://github.com/jpetazzo [jwilder]: https://github.com/jwilder [kubernetes]: https://kubernetes.io [lispyclouds]: https://github.com/lispyclouds [nginxproxy]: https://github.com/nginx-proxy/nginx-proxy [openshift]: https://okd.io/ [powerman]: https://github.com/powerman [progrium]: https://github.com/progrium [ramitsurana]: https://github.com/ramitsurana [sindresorhus]: https://github.com/sindresorhus/awesome [spotify]: https://github.com/spotify [vegasbrianc]: https://github.com/vegasbrianc [vmware]: https://github.com/vmware [byrnedo]: https://github.com/byrnedo [crazy-max]: https://github.com/crazy-max [skanehira]: https://github.com/skanehira [akito]: https://github.com/theAkito [peco602]: https://github.com/Peco602 [weave]: https://github.com/weaveworks/weave ================================================ FILE: cmd/awesome-docker/main.go ================================================ package main import ( "context" "fmt" "os" "strconv" "strings" "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" "github.com/veggiemonk/awesome-docker/internal/tui" ) 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" ) 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", Short: "Quality tooling for the awesome-docker curated list", } root.AddCommand( versionCmd(), lintCmd(), checkCmd(), healthCmd(), buildCmd(), reportCmd(), validateCmd(), ciCmd(), browseCmd(), ) 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) } } type entryMeta struct { Category string Description string } func collectEntriesWithCategory(sections []parser.Section, parentPath string, out map[string]entryMeta) { for _, s := range sections { path := s.Title if parentPath != "" { path = parentPath + " > " + s.Title } for _, e := range s.Entries { out[e.URL] = entryMeta{Category: path, Description: e.Description} } collectEntriesWithCategory(s.Children, path, out) } } 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) meta := make(map[string]entryMeta) collectEntriesWithCategory(doc.Sections, "", meta) for i := range scored { if m, ok := meta[scored[i].URL]; ok { scored[i].Category = m.Category scored[i].Description = m.Description } } 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, Forks: e.Forks, HasLicense: e.HasLicense, LastPush: e.LastPush, Category: e.Category, Description: e.Description, }) } 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{ 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) } 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) } 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 { summary, err := runLinkChecks(prMode) if err != nil { return err } fmt.Printf("Checking %d external links...\n", summary.ExternalTotal) if !prMode { if summary.GitHubSkipped { fmt.Println("GITHUB_TOKEN not set, skipping GitHub repo checks") } else { fmt.Printf("Checking %d GitHub repositories...\n", summary.GitHubTotal) } } 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(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(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(summary.Broken) > 0 { return fmt.Errorf("found %d broken links", len(summary.Broken)) } if len(summary.GitHubErrors) > 0 { return fmt.Errorf("github checks failed with %d errors", len(summary.GitHubErrors)) } 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 { return runHealth(context.Background()) }, } } 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 { var jsonOutput bool cmd := &cobra.Command{ Use: "report", Short: "Generate health report from cache", RunE: func(cmd *cobra.Command, args []string) error { scored, err := scoredFromCache() if err != nil { return err } 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 { 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) ===") summary, err := runLinkChecks(true) if err != nil { return err } 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(summary.Broken)) } fmt.Println("\nValidation passed") return nil }, } } 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 } func browseCmd() *cobra.Command { var cachePath string cmd := &cobra.Command{ Use: "browse", Short: "Interactive TUI browser for awesome-docker resources", RunE: func(cmd *cobra.Command, args []string) error { hc, err := cache.LoadHealthCache(cachePath) if err != nil { return fmt.Errorf("load cache: %w", err) } if len(hc.Entries) == 0 { return fmt.Errorf("no cache data; run 'awesome-docker health' first") } return tui.Run(hc.Entries) }, } cmd.Flags().StringVar(&cachePath, "cache", healthCachePath, "Path to health cache YAML") return cmd } ================================================ FILE: config/exclude.yaml ================================================ # 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 ================================================ FILE: config/health_cache.yaml ================================================ entries: - url: https://github.com/byrnedo/capitan name: byrnedo/capitan status: stale stars: 31 last_push: 2017-06-07T09:46:56Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Composable docker orchestration with added scripting support by [byrnedo]. - url: https://github.com/magicmark/composerize name: magicmark/composerize status: healthy stars: 3703 forks: 247 last_push: 2026-01-17T12:14:28Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Convert docker run commands into docker-compose files. - url: https://github.com/polonskiy/crowdr name: polonskiy/crowdr status: stale stars: 98 forks: 9 last_push: 2020-10-09T07:57:52Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Tool for managing multiple Docker containers (`docker-compose` alternative). - url: https://github.com/ctk-hq/ctk name: ctk-hq/ctk status: healthy stars: 298 forks: 27 last_push: 2026-02-15T22:53:00Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Visual composer for container based workloads. By [corpulent](https://github.com/corpulent). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Utility to update docker configs and secrets for deploying in a compose file. - url: https://github.com/cisco/elsy name: cisco/elsy status: stale stars: 80 forks: 22 last_push: 2022-01-18T13:38:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: An opinionated, multi-language, build tool based on Docker and Docker Compose. - url: https://github.com/cloud66-oss/habitus name: cloud66-oss/habitus status: stale stars: 1392 forks: 81 last_push: 2020-02-05T17:10:30Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: A Build Flow Tool for Docker. - url: https://github.com/kubernetes/kompose name: kubernetes/kompose status: healthy stars: 10464 forks: 794 last_push: 2026-02-27T14:23:27Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: Go from Docker Compose to Kubernetes. - url: https://github.com/av/harbor name: av/harbor status: healthy stars: 2485 forks: 166 last_push: 2026-03-08T14:30:46Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: A CLI and companion app to effortlessly run LLM backends, APIs, frontends, and services with one command. By [av](https://github.com/av). - url: https://github.com/ihucos/plash name: ihucos/plash status: healthy stars: 387 forks: 15 last_push: 2025-03-20T15:47:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: A container run and build engine - runs inside docker. - url: https://github.com/containers/podman-compose name: containers/podman-compose status: healthy stars: 5990 forks: 577 last_push: 2026-03-05T16:25:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: A script to run docker-compose.yml using podman. - url: https://github.com/alexaandrov/stitchocker name: alexaandrov/stitchocker status: inactive stars: 30 forks: 2 last_push: 2024-03-14T13:50:30Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Container Composition description: A lightweight and fast command line utility for conveniently grouping your docker-compose multiple container services. By [alexaandrov](https://github.com/alexaandrov). - url: https://github.com/ethibox/awesome-stacks name: ethibox/awesome-stacks status: healthy stars: 1250 forks: 162 last_push: 2026-03-08T14:40:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Deploy 150+ open-source web apps with one Docker command. - url: https://github.com/newrelic/centurion name: newrelic/centurion status: archived stars: 1757 forks: 112 last_push: 2025-09-11T20:47:50Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: 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). - url: https://github.com/brooklyncentral/clocker name: brooklyncentral/clocker status: stale stars: 429 forks: 64 last_push: 2018-10-24T15:29:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: 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). - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Experimental deployment system for Docker. - url: https://github.com/ContainX/depcon name: ContainX/depcon status: stale stars: 93 forks: 15 last_push: 2018-06-05T04:40:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Depcon is written in Go and allows you to easily deploy Docker containers to Apache Mesos/Marathon, Amazon ECS and Kubernetes. By [ContainX][containx]. - url: https://github.com/deploystackio/docker-to-iac name: deploystackio/docker-to-iac status: healthy stars: 23 last_push: 2026-03-02T06:11:33Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Translate docker run and commit into Infrastructure as Code templates for AWS, Render.com and DigitalOcean. - url: https://github.com/hasura/gitkube name: hasura/gitkube status: stale stars: 3850 forks: 203 last_push: 2023-08-31T07:48:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Gitkube is a tool for building and deploying docker images on Kubernetes using `git push`. By [Hasura](https://github.com/hasura/). - url: https://github.com/grafeas/grafeas name: grafeas/grafeas status: healthy stars: 1564 forks: 307 last_push: 2026-02-13T21:53:15Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: A common API for metadata about containers, from image and build details to security vulnerabilities. By [grafeas](https://github.com/grafeas). - url: https://github.com/LombardiDaniel/swarm-ansible name: LombardiDaniel/swarm-ansible status: healthy stars: 59 forks: 4 last_push: 2026-01-24T22:01:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - url: https://github.com/hansehe/SwarmManagement name: hansehe/SwarmManagement status: healthy stars: 21 forks: 1 last_push: 2025-05-13T15:24:25Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: 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. - url: https://github.com/werf/werf name: werf/werf status: healthy stars: 4661 forks: 230 last_push: 2026-03-06T15:47:09Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Deployment and Infrastructure description: Werf is a CI/CD tool for building Docker images efficiently and deploying them to Kubernetes using GitOps. - url: https://github.com/willfarrell/docker-autoheal name: willfarrell/docker-autoheal status: healthy stars: 1801 forks: 254 last_push: 2025-09-09T16:33:25Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Monitor and restart unhealthy docker containers automatically. - url: https://github.com/google/cadvisor name: google/cadvisor status: healthy stars: 18952 forks: 2461 last_push: 2026-03-02T18:35:32Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Analyzes resource usage and performance characteristics of running containers. - url: https://github.com/bluewave-labs/checkmate name: bluewave-labs/checkmate status: healthy stars: 9372 forks: 680 last_push: 2026-03-07T01:22:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: 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. - url: https://github.com/zorak1103/dlia name: zorak1103/dlia status: healthy stars: 3 last_push: 2026-03-07T04:03:52Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: 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). - url: https://github.com/deltaskelta/docker-alertd name: deltaskelta/docker-alertd status: stale stars: 108 forks: 12 last_push: 2017-11-15T04:40:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Monitor and send alerts based on docker container resource usage/statistics. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Reconfigures Prometheus when a new service is updated or deployed automatically. - url: https://github.com/stefanprodan/dockprom name: stefanprodan/dockprom status: healthy stars: 6488 forks: 1768 last_push: 2026-03-06T05:28:07Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Docker hosts and containers monitoring with Prometheus, Grafana, cAdvisor, NodeExporter and AlertManager. - url: https://github.com/amerkurev/doku name: amerkurev/doku status: healthy stars: 410 forks: 18 last_push: 2025-12-26T09:13:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Doku is a simple web-based application that allows you to monitor Docker disk usage. [amerkurev](https://github.com/amerkurev). - url: https://github.com/nicolargo/glances name: nicolargo/glances status: healthy stars: 31995 forks: 1695 last_push: 2026-03-07T15:24:35Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: A cross-platform curses-based system monitoring tool written in Python. - url: https://github.com/dromara/hertzbeat name: dromara/hertzbeat status: healthy stars: 7114 forks: 1255 last_push: 2026-03-08T12:09:09Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: An open-source real-time monitoring system with custom-monitor and agentless. - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: InfluxDB Time series DB in combination with Grafana and cAdvisor. - url: https://github.com/gliderlabs/logspout name: gliderlabs/logspout status: stale stars: 4701 forks: 668 last_push: 2023-07-11T20:36:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Log routing for Docker container logs. - url: https://github.com/decryptus/monit-docker name: decryptus/monit-docker status: stale stars: 34 forks: 5 last_push: 2023-01-16T11:31:14Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Monitor docker containers resources usage or status and execute docker commands or inside containers. [decryptus][decryptus]. - url: https://github.com/NexClipper/NexClipper name: NexClipper/NexClipper status: stale stars: 565 forks: 72 last_push: 2023-05-05T02:21:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: NexClipper is the container monitoring and performance management solution specialized in Docker, Apache Mesos, Marathon, DC/OS, Mesosphere, Kubernetes. - url: https://github.com/uschtwill/docker_monitoring_logging_alerting name: uschtwill/docker_monitoring_logging_alerting status: stale stars: 539 forks: 119 last_push: 2018-09-13T07:36:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: 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]. - url: https://github.com/runsidekick/sidekick name: runsidekick/sidekick status: stale stars: 1611 forks: 67 last_push: 2023-06-29T12:18:38Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Open source live application debugger like Chrome DevTools for your backend. Collect traces and generate logs on-demand without stopping & redeploying your applications. - url: https://github.com/gpulido/SwarmAlert name: gpulido/SwarmAlert status: stale stars: 22 forks: 2 last_push: 2019-11-27T12:17:14Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Monitors a Docker Swarm and sends Pushover alerts when it finds a container with no healthy service task running. - url: https://github.com/gomex/docker-zabbix name: gomex/docker-zabbix status: stale stars: 53 forks: 12 last_push: 2017-07-28T14:29:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: Monitor containers automatically using zabbix LLD feature. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Monitoring description: 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. - url: https://github.com/coreos/flannel name: coreos/flannel status: healthy stars: 9410 forks: 2902 last_push: 2026-03-06T12:10:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - url: https://github.com/Microsoft/Freeflow name: Microsoft/Freeflow status: stale stars: 632 forks: 96 last_push: 2023-06-12T19:30:22Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Networking description: 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). - url: https://github.com/jason5ng32/MyIP name: jason5ng32/MyIP status: healthy stars: 9895 forks: 1072 last_push: 2026-02-10T07:38:47Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Networking description: 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). - url: https://github.com/nicolaka/netshoot name: nicolaka/netshoot status: healthy stars: 10445 forks: 1085 last_push: 2026-03-05T17:23:33Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Networking description: The netshoot container has a powerful set of networking tools to help troubleshoot Docker networking issues. - url: https://github.com/jpetazzo/pipework name: jpetazzo/pipework status: inactive stars: 4252 forks: 727 last_push: 2024-11-04T17:31:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Networking description: Software-Defined Networking for Linux Containers, Pipework works with "plain" LXC containers, and with the awesome Docker. By [jpetazzo][jpetazzo]. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Run Ansible from a Linux container. By [Peco602][peco602]. - url: https://github.com/athena-oss/athena name: athena-oss/athena status: stale stars: 96 forks: 25 last_push: 2017-07-06T08:26:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: An automation platform with a plugin architecture that allows you to easily create and share services. - url: https://github.com/CloudSlang/cloud-slang name: CloudSlang/cloud-slang status: healthy stars: 240 forks: 83 last_push: 2026-03-04T10:56:48Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: CloudSlang is a workflow engine to create Docker process automation. - url: https://github.com/clusterdock/clusterdock name: clusterdock/clusterdock status: stale stars: 29 forks: 8 last_push: 2023-05-16T18:05:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Docker container orchestration to enable the testing of long-running cluster deployments. - url: https://github.com/Dataman-Cloud/crane name: Dataman-Cloud/crane status: stale stars: 748 forks: 164 last_push: 2023-08-31T09:46:38Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Control plane based on docker built-in swarm [Dataman-Cloud](https://github.com/Dataman-Cloud). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Docker Flow Swarm Listener project is to listen to Docker Swarm events and send requests when a change occurs. By [docker-flow][docker-flow]. - url: https://github.com/Wowu/docker-rollout name: Wowu/docker-rollout status: healthy stars: 3111 forks: 93 last_push: 2025-07-25T17:57:48Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Zero downtime deployment for Docker Compose services. - url: https://github.com/codeabovelab/haven-platform name: codeabovelab/haven-platform status: stale stars: 297 forks: 41 last_push: 2018-07-06T11:21:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Haven is a simplified container management platform that integrates container, application, cluster, image, and registry managements. By [codeabovelab](https://github.com/codeabovelab). - url: https://github.com/kubernetes/kubernetes name: kubernetes/kubernetes status: healthy stars: 120996 forks: 42620 last_push: 2026-03-07T08:41:59Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Open source orchestration system for Docker containers by Google. - url: https://github.com/ManageIQ/manageiq name: ManageIQ/manageiq status: healthy stars: 1392 forks: 922 last_push: 2026-03-05T20:13:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Discover, optimize and control your hybrid IT. By [ManageIQ](https://github.com/ManageIQ). - url: https://github.com/apache/mesos name: apache/mesos status: inactive stars: 5364 forks: 1669 last_push: 2024-08-23T18:59:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Resource/Job scheduler for containers, VM's and physical hosts [apache](https://mesos.apache.org/). - url: https://github.com/hashicorp/nomad name: hashicorp/nomad status: healthy stars: 16262 forks: 2059 last_push: 2026-03-08T09:06:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Easily deploy applications at any scale. A Distributed, Highly Available, Datacenter-Aware Scheduler. - url: https://github.com/rancher/rancher name: rancher/rancher status: healthy stars: 25400 forks: 3173 last_push: 2026-03-06T22:49:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: An open source project that provides a complete platform for operating Docker in production. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: 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). - url: https://github.com/crazy-max/swarm-cronjob name: crazy-max/swarm-cronjob status: healthy stars: 861 forks: 74 last_push: 2026-03-06T07:02:33Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Orchestration description: Create jobs on a time-based schedule on Swarm by [crazy-max]. - url: https://github.com/caprover/caprover name: caprover/caprover status: healthy stars: 14892 forks: 966 last_push: 2026-01-31T15:42:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: '[Previously known as CaptainDuckDuck] Automated Scalable Webserver Package (automated Docker+nginx) - Heroku on Steroids.' - url: https://github.com/convox/rack name: convox/rack status: healthy stars: 1892 forks: 177 last_push: 2026-02-12T19:55:53Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: Convox Rack is open source PaaS built on top of expert infrastructure automation and devops best practices. - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: 'Docker-compose SSH wrapper: a very poor man PaaS, exposing the docker-compose and custom-container commands defined in container labels.' - url: https://github.com/dokku/dokku name: dokku/dokku status: healthy stars: 31896 forks: 2022 last_push: 2026-03-07T18:31:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: Docker powered mini-Heroku that helps you build and manage the lifecycle of applications (originally by [progrium][progrium]). - url: https://github.com/remind101/empire name: remind101/empire status: stale stars: 2681 forks: 156 last_push: 2023-11-25T17:16:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: A PaaS built on top of Amazon EC2 Container Service (ECS). - url: https://github.com/exoframejs/exoframe name: exoframejs/exoframe status: healthy stars: 1146 forks: 59 last_push: 2026-02-22T16:24:52Z checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: A self-hosted tool that allows simple one-command deployments using Docker. - url: https://github.com/teamhephy/workflow name: teamhephy/workflow status: stale stars: 419 forks: 36 last_push: 2023-09-27T17:30:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: 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). - url: https://github.com/krane/krane name: krane/krane status: stale stars: 80 forks: 8 last_push: 2023-05-11T20:39:00Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: Toolset for managing container workloads on remote servers. - url: https://github.com/nanobox-io/nanobox name: nanobox-io/nanobox status: stale stars: 1625 forks: 90 last_push: 2019-10-21T20:03:10Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: An application development platform that creates local environments that can then be deployed and scaled in the cloud. - url: https://github.com/tsuru/tsuru name: tsuru/tsuru status: healthy stars: 5259 forks: 550 last_push: 2026-03-05T03:11:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > PaaS description: Tsuru is an extensible and open source Platform as a Service software. - url: https://github.com/bunkerity/bunkerweb name: bunkerity/bunkerweb status: healthy stars: 10112 forks: 568 last_push: 2026-03-06T17:15:47Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Open-source and next-gen Web Application Firewall (WAF). By [Bunkerity](https://www.bunkerity.com). - url: https://github.com/lucaslorentz/caddy-docker-proxy name: lucaslorentz/caddy-docker-proxy status: healthy stars: 4315 forks: 211 last_push: 2026-03-08T07:04:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Caddy-based reverse proxy, configured with service or container labels. By [lucaslorentz](https://github.com/lucaslorentz). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Docker upstreams module for Caddy, configured with container labels. By [invzhi](https://github.com/invzhi). - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Update a remote dnsmasq server with Docker container hostnames. - url: https://github.com/docker-flow/docker-flow-proxy name: docker-flow/docker-flow-proxy status: healthy stars: 320 forks: 189 last_push: 2025-12-05T02:29:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Reconfigures proxy every time a new service is deployed, or when a service is scaled. By [docker-flow][docker-flow]. - url: https://github.com/fabiolb/fabio name: fabiolb/fabio status: healthy stars: 7333 forks: 624 last_push: 2026-02-23T02:48:11Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: A fast, modern, zero-conf load balancing HTTP(S) router for deploying microservices managed by consul. By [magiconair](https://github.com/magiconair) (Frank Schroeder). - url: https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion name: nginx-proxy/docker-letsencrypt-nginx-proxy-companion status: healthy stars: 7698 forks: 834 last_push: 2026-03-02T17:04:31Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: 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). - url: https://github.com/Yundera/mesh-router name: Yundera/mesh-router status: healthy stars: 8 last_push: 2026-03-02T15:37:53Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: 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). - url: https://github.com/jc21/nginx-proxy-manager name: jc21/nginx-proxy-manager status: healthy stars: 32001 forks: 3639 last_push: 2026-03-06T14:15:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: A beautiful web interface for proxying web based services with SSL. By [jc21](https://github.com/jc21). - url: https://github.com/Safe3/openresty-manager name: Safe3/openresty-manager status: healthy stars: 1322 forks: 98 last_push: 2026-01-25T10:38:42Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: The easiest using, powerful and beautiful OpenResty Manager(Nginx Enhanced Version), open source alternative to OpenResty Edge. By [Safe3](https://github.com/Safe3/). - url: https://github.com/flavioaiello/swarm-router name: flavioaiello/swarm-router status: healthy stars: 73 forks: 12 last_push: 2025-09-15T06:12:30Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: A «zero config» service name based router for docker swarm mode with a fresh and more secure approach. By [flavioaiello](https://github.com/flavioaiello). - url: https://github.com/containous/traefik name: containous/traefik status: healthy stars: 62086 forks: 5865 last_push: 2026-03-06T16:16:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Reverse Proxy description: Automated reverse proxy and load-balancer for Docker, Mesos, Consul, Etcd... By [EmileVauge](https://github.com/emilevauge). - url: https://github.com/cri-o/cri-o name: cri-o/cri-o status: healthy stars: 5588 forks: 1151 last_push: 2026-03-08T00:16:02Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Runtime description: Open Container Initiative-based implementation of Kubernetes Container Runtime Interface by [cri-o](https://github.com/cri-o). - url: https://github.com/lxc/lxc name: lxc/lxc status: healthy stars: 5126 forks: 1162 last_push: 2026-03-02T14:26:30Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Runtime description: LXC - Linux Containers. - url: https://github.com/containers/libpod name: containers/libpod status: healthy stars: 30937 forks: 3006 last_push: 2026-03-06T15:57:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Runtime description: Libpod is a library used to create container pods. Home of Podman. - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > Runtime description: LXC binary written in Rust. - url: https://github.com/opencontainers/runtime-tools name: opencontainers/runtime-tools status: healthy stars: 473 forks: 159 last_push: 2025-12-05T00:49:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Runtime description: Oci-runtime-tool is a collection of tools for working with the OCI runtime specification. - url: https://github.com/SongStitch/anchor name: SongStitch/anchor status: inactive stars: 24 last_push: 2025-01-15T23:09:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - url: https://github.com/genuinetools/bane name: genuinetools/bane status: stale stars: 1224 forks: 91 last_push: 2020-09-17T20:10:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: AppArmor profile generator for Docker containers. - url: https://github.com/dash14/buildcage name: dash14/buildcage status: healthy stars: 4 last_push: 2026-03-08T16:59:17Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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. - url: https://github.com/hectorm/cetusguard name: hectorm/cetusguard status: healthy stars: 82 forks: 2 last_push: 2026-03-01T11:42:56Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: CetusGuard is a tool that protects the Docker daemon socket by filtering calls to its API endpoints. - url: https://github.com/bridgecrewio/checkov name: bridgecrewio/checkov status: healthy stars: 8510 forks: 1307 last_push: 2026-03-08T07:40:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - url: https://github.com/quay/clair name: quay/clair status: healthy stars: 10940 forks: 1195 last_push: 2026-03-06T23:17:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers. By [coreos][coreos]. - url: https://github.com/wolffcatskyy/crowdsec-blocklist-import name: wolffcatskyy/crowdsec-blocklist-import status: healthy stars: 179 forks: 4 last_push: 2026-03-07T18:44:39Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - url: https://github.com/eliasgranderubio/dagda name: eliasgranderubio/dagda status: stale stars: 1220 forks: 169 last_push: 2023-05-23T02:03:43Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - url: https://github.com/deepfence/ThreatMapper name: deepfence/ThreatMapper status: healthy stars: 5235 forks: 640 last_push: 2026-03-08T03:35:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: Powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless. By [deepfence][deepfence]. - url: https://github.com/docker/docker-bench-security name: docker/docker-bench-security status: inactive stars: 9600 forks: 1038 last_push: 2024-10-21T07:26:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: Script that checks for dozens of common best-practices around deploying Docker containers in production. By [docker][docker]. - url: https://github.com/google/docker-explorer name: google/docker-explorer status: inactive stars: 553 forks: 45 last_push: 2024-10-04T07:44:31Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: A tool to help forensicate offline docker acquisitions. - url: https://github.com/Peco602/dvwassl name: Peco602/dvwassl status: stale stars: 6 forks: 4 last_push: 2023-04-30T17:03:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: SSL-enabled Damn Vulnerable Web App to test Web Application Firewalls. By [Peco602][peco602]. - url: https://github.com/checkmarx/kics name: checkmarx/kics status: healthy stars: 2581 forks: 361 last_push: 2026-03-06T15:34:55Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - url: https://github.com/theupdateframework/notary name: theupdateframework/notary status: archived stars: 3287 forks: 520 last_push: 2024-08-07T19:02:32Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: A server and a client for running and interacting with trusted collections. By [TUF](https://github.com/theupdateframework). - url: https://github.com/OpenSCAP/openscap name: OpenSCAP/openscap status: healthy stars: 1676 forks: 424 last_push: 2026-02-27T12:44:50Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: OpenSCAP provides oscap-docker tool which is used to scan Docker containers and images. By [OpenSCAP](https://github.com/OpenSCAP). - url: https://github.com/dormstern/segspec name: dormstern/segspec status: healthy stars: 15 last_push: 2026-02-23T11:39:00Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: 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). - url: https://github.com/anchore/syft name: anchore/syft status: healthy stars: 8454 forks: 779 last_push: 2026-03-08T08:12:44Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: CLI tool and library for generating a Software Bill of Materials (SBOM) from container images and filesystems. - url: https://github.com/falcosecurity/falco name: falcosecurity/falco status: healthy stars: 8712 forks: 990 last_push: 2026-03-02T17:54:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: Sysdig Falco is an open source container security monitor. It can monitor application, container, host, and network activity and alert on unauthorized activity. - url: https://github.com/aquasecurity/trivy name: aquasecurity/trivy status: healthy stars: 33020 forks: 76 last_push: 2026-03-06T06:42:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Security description: Aqua Security's open source simple and comprehensive vulnerability scanner for containers (suitable for CI). - url: https://github.com/bytesharky/docker-dns name: bytesharky/docker-dns status: healthy stars: 3 forks: 1 last_push: 2025-12-26T02:44:43Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Service Discovery description: Lightweight DNS forwarder for Docker containers, resolves container names with custom suffixes (e.g. `.docker`) on the host to simplify service discovery. - url: https://github.com/etcd-io/etcd name: etcd-io/etcd status: healthy stars: 51631 forks: 10336 last_push: 2026-03-06T20:11:02Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Service Discovery description: 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). - url: https://github.com/istio/istio name: istio/istio status: healthy stars: 38089 forks: 8260 last_push: 2026-03-08T16:55:04Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Service Discovery description: An open platform to connect, manage, and secure microservices. - url: https://github.com/gliderlabs/registrator name: gliderlabs/registrator status: healthy stars: 4675 forks: 909 last_push: 2025-05-22T04:16:52Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Service Discovery description: Service registry bridge for Docker by [gliderlabs][gliderlabs] and [progrium][progrium]. - url: https://github.com/minio/minio name: minio/minio status: archived stars: 60448 forks: 7197 last_push: 2026-02-12T20:18:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > Volume Management / Data description: S3 compatible object storage server in Docker containers. - 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-03-08T18:26:00.233336Z category: Projects > Container Operations > Volume Management / Data description: Software-defined Persistent Storage for Kubernetes and Docker Swarm. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Desktop description: Desktop app for managing Docker database containers with visual interface and one-click operations. - url: https://github.com/felixgborrego/simple-docker-ui name: felixgborrego/simple-docker-ui status: inactive stars: 606 forks: 96 last_push: 2024-09-06T09:31:07Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Desktop description: Built on Electron. By [felixgborrego](https://github.com/felixgborrego/). - url: https://github.com/slonopotamus/stevedore name: slonopotamus/stevedore status: healthy stars: 369 forks: 13 last_push: 2026-02-27T11:51:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Desktop description: Good Docker Desktop replacement for Windows. Both Linux and Windows Containers are supported. [slonopotamus](https://github.com/slonopotamus). - url: https://github.com/jr-k/d4s name: jr-k/d4s status: healthy stars: 55 forks: 4 last_push: 2026-03-04T21:15:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: A fast, keyboard-driven terminal UI to manage Docker containers, Compose stacks, and Swarm services with the ergonomics of K9s. - url: https://github.com/wagoodman/dive name: wagoodman/dive status: healthy stars: 53505 forks: 1953 last_push: 2025-12-15T17:20:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: A tool for exploring each layer in a docker image. By [wagoodman](https://github.com/wagoodman). - url: https://github.com/lirantal/dockly name: lirantal/dockly status: healthy stars: 4014 forks: 164 last_push: 2026-02-01T19:31:17Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: An interactive shell UI for managing Docker containers. - url: https://github.com/shubh-io/dockmate name: shubh-io/dockmate status: healthy stars: 278 forks: 5 last_push: 2026-01-14T06:52:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: Lightweight terminal-based Docker and Podman manager with a text-based user interface,. - url: https://github.com/GhostWriters/DockSTARTer name: GhostWriters/DockSTARTer status: healthy stars: 2545 forks: 291 last_push: 2026-03-01T14:12:50Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: DockSTARTer helps you get started with home server apps running in Docker by [GhostWriters](https://github.com/GhostWriters). - url: https://github.com/durableprogramming/dprs name: durableprogramming/dprs status: healthy stars: 36 forks: 1 last_push: 2026-03-05T15:59:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: 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). - url: https://github.com/moncho/dry name: moncho/dry status: healthy stars: 3227 forks: 103 last_push: 2026-03-08T10:25:15Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: An interactive CLI for Docker containers. - url: https://github.com/ajayd-san/gomanagedocker name: ajayd-san/gomanagedocker status: inactive stars: 632 forks: 26 last_push: 2024-12-28T07:44:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box. - url: https://github.com/jesseduffield/lazydocker name: jesseduffield/lazydocker status: healthy stars: 50030 forks: 1578 last_push: 2026-01-17T06:16:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: 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). - url: https://github.com/Lifailon/lazyjournal name: Lifailon/lazyjournal status: healthy stars: 1175 forks: 28 last_push: 2026-03-06T14:14:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: 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. - url: https://github.com/mrjackwills/oxker name: mrjackwills/oxker status: healthy stars: 1552 forks: 43 last_push: 2026-02-23T15:18:34Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Terminal UI description: 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),. - url: https://github.com/jenssegers/captain name: jenssegers/captain status: stale stars: 244 forks: 10 last_push: 2022-12-08T07:39:21Z checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Easily start and stop docker compose projects from any directory. By [jenssegers](https://github.com/jenssegers). - url: https://github.com/Falldog/dcinja name: Falldog/dcinja status: healthy stars: 13 forks: 3 last_push: 2025-06-26T12:33:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: The powerful and smallest binary size of template engine for docker command line environment. By [Falldog](https://github.com/Falldog). - url: https://github.com/exdx/dcp name: exdx/dcp status: stale stars: 114 forks: 3 last_push: 2023-07-24T01:09:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: A simple tool for copying files from container filesystems. By [exdx](https://github.com/exdx). - url: https://github.com/FabienD/docker-stack name: FabienD/docker-stack status: healthy stars: 22 forks: 2 last_push: 2026-03-01T10:58:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: 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). - url: https://github.com/s0rg/decompose name: s0rg/decompose status: healthy stars: 126 forks: 6 last_push: 2025-12-19T20:03:44Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Reverse-engineering tool for docker environments. By [s0rg](https://github.com/s0rg). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: 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). - url: https://github.com/lucabello/docker-captain name: lucabello/docker-captain status: healthy stars: 2 last_push: 2026-03-07T00:13:26Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: A friendly CLI to manage multiple Docker Compose deployments with style — powered by Typer, Rich, questionary, and sh. - url: https://github.com/mayflower/docker-ls name: mayflower/docker-ls status: archived stars: 456 forks: 68 last_push: 2023-08-31T06:44:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: CLI tools for browsing and manipulating docker registries. - url: https://github.com/howtowhale/dvm name: howtowhale/dvm status: stale stars: 525 forks: 50 last_push: 2022-03-30T13:23:11Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Docker version manager. - url: https://github.com/iamsoorena/goinside name: iamsoorena/goinside status: stale stars: 30 forks: 2 last_push: 2020-10-17T20:31:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Get inside a running docker container easily. - url: https://github.com/g31s/Pdocker name: g31s/Pdocker status: stale stars: 7 forks: 2 last_push: 2021-02-27T06:42:13Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: A simple tool to manage and maintain Docker for personal projects. - url: https://github.com/shiwaforce/poco name: shiwaforce/poco status: healthy stars: 111 forks: 6 last_push: 2026-02-28T12:31:09Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: 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. - url: https://github.com/JonathonReinhart/scuba name: JonathonReinhart/scuba status: healthy stars: 96 forks: 17 last_push: 2026-01-26T04:03:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Transparently use Docker containers to encapsulate software build environments,. - url: https://github.com/containers/skopeo name: containers/skopeo status: healthy stars: 10538 forks: 908 last_push: 2026-03-08T00:58:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Work with remote images registries - retrieving information, images, signing content. - url: https://github.com/segersniels/supdock name: segersniels/supdock status: healthy stars: 86 forks: 3 last_push: 2026-02-23T13:29:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Allows for slightly more visual usage of Docker with an interactive prompt. By [segersniels](https://github.com/segersniels). - url: https://github.com/qazbnm456/tsaotun name: qazbnm456/tsaotun status: stale stars: 59 forks: 3 last_push: 2022-10-04T06:53:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > CLI tools description: Python based Assistance for Docker. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Other description: Search the Docker Registry with the Dext smart launcher. By [vutran](https://github.com/vutran). - url: https://github.com/jeroenpeeters/docker-ssh name: jeroenpeeters/docker-ssh status: stale stars: 659 forks: 89 last_push: 2018-04-11T20:24:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Other description: SSH Server for Docker containers ~ Because every container should be accessible. By [jeroenpeeters](https://github.com/jeroenpeeters). - url: https://github.com/marty90/multidocker name: marty90/multidocker status: stale stars: 56 forks: 9 last_push: 2018-11-27T15:12:56Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Other description: Create a secure multi-user Docker machine, where each user is segregated into an indepentent container. - url: https://github.com/adrianmo/powerline-docker name: adrianmo/powerline-docker status: stale stars: 61 forks: 6 last_push: 2017-06-30T09:11:44Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Terminal > Other description: A Powerline segment for showing the status of Docker containers. - url: https://github.com/knrdl/casa name: knrdl/casa status: healthy stars: 84 forks: 5 last_push: 2026-03-02T14:26:48Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Outsource the administration of a handful of containers to your co-workers,. - url: https://github.com/wrfly/container-web-tty name: wrfly/container-web-tty status: healthy stars: 258 forks: 46 last_push: 2026-03-02T16:34:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Connect your containers via a web-tty [wrfly](https://github.com/wrfly). - url: https://github.com/ProductiveOps/dokemon name: ProductiveOps/dokemon status: stale stars: 759 forks: 36 last_push: 2024-02-21T10:51:14Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Docker Container Management GUI. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Web Interface for the Docker Registry HTTP API v2. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Web UI, authentication service and event recorder for private docker registry v2. - url: https://github.com/dockersamples/docker-swarm-visualizer name: dockersamples/docker-swarm-visualizer status: inactive stars: 3348 forks: 596 last_push: 2024-10-26T07:12:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Visualizes Docker services on a Docker Swarm (for running demos). - url: https://github.com/louislam/dockge name: louislam/dockge status: healthy stars: 22365 forks: 707 last_push: 2026-01-21T10:51:44Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager. - url: https://github.com/mbecker20/komodo name: mbecker20/komodo status: healthy stars: 10494 forks: 277 last_push: 2026-03-08T14:48:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: A tool to build and deploy software on many servers. - url: https://github.com/kubevious/kubevious name: kubevious/kubevious status: stale stars: 1692 forks: 95 last_push: 2024-01-15T18:42:38Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: A highly visual web UI for Kubernetes which renders configuration and state in an application centric way. - url: https://github.com/hywax/mafl name: hywax/mafl status: healthy stars: 675 forks: 52 last_push: 2025-10-26T02:26:26Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Minimalistic flexible homepage. - url: https://github.com/netdata/netdata name: netdata/netdata status: healthy stars: 77993 forks: 6360 last_push: 2026-03-08T10:17:43Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Real-time performance monitoring. - url: https://github.com/OctoLinker/OctoLinker name: OctoLinker/OctoLinker status: stale stars: 5352 forks: 283 last_push: 2023-10-02T12:33:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: A browser extension for GitHub that makes the image name in a `Dockerfile` clickable and redirect you to the related Docker Hub page. - url: https://github.com/portainer/portainer name: portainer/portainer status: healthy stars: 36781 forks: 2787 last_push: 2026-03-07T13:14:38Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: A lightweight management UI for managing your Docker hosts or Docker Swarm clusters. - url: https://github.com/ozlerhakan/rapid name: ozlerhakan/rapid status: stale stars: 147 forks: 24 last_push: 2021-09-21T08:44:39Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: A simple query dashboard to use Docker Remote API. - url: https://github.com/tobegit3hub/seagull name: tobegit3hub/seagull status: stale stars: 1939 forks: 268 last_push: 2017-11-22T02:11:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Friendly Web UI to monitor docker daemon. - url: https://github.com/swarmpit/swarmpit name: swarmpit/swarmpit status: healthy stars: 3410 forks: 312 last_push: 2026-03-04T00:04:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Swarmpit provides simple and easy to use interface for your Docker Swarm cluster. You can manage your stacks, services, secrets, volumes, networks etc. - url: https://github.com/cuigh/swirl name: cuigh/swirl status: stale stars: 668 forks: 83 last_push: 2023-05-16T02:47:48Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Swirl is a web management tool for Docker, focused on swarm cluster By [cuigh](https://github.com/cuigh/). - url: https://github.com/eclipse-theia/theia name: eclipse-theia/theia status: healthy stars: 21393 forks: 2801 last_push: 2026-03-07T09:12:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: Extensible platform to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technologies. - url: https://github.com/fr4nsys/usulnet name: fr4nsys/usulnet status: healthy stars: 77 forks: 3 last_push: 2026-02-23T23:00:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Container Operations > User Interface > Web description: 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). - url: https://github.com/genuinetools/amicontained name: genuinetools/amicontained status: stale stars: 1073 forks: 71 last_push: 2020-12-09T04:37:59Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Container introspection tool. Find out what container runtime is being used as well as features available. - url: https://github.com/garywiz/chaperone name: garywiz/chaperone status: stale stars: 179 forks: 31 last_push: 2020-07-16T21:30:27Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: A single PID1 process designed for docker containers. Does user management, log management, startup, zombie reaping, all in one small package. - url: https://github.com/nicomt/ckron name: nicomt/ckron status: healthy stars: 56 forks: 6 last_push: 2026-02-15T17:58:14Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: A cron-style job scheduler for docker,. - url: https://github.com/GoogleContainerTools/distroless name: GoogleContainerTools/distroless status: healthy stars: 22329 forks: 1360 last_push: 2026-03-06T14:09:42Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Language focused docker images, minus the operating system,. - url: https://github.com/gliderlabs/docker-alpine name: gliderlabs/docker-alpine status: stale stars: 5720 forks: 530 last_push: 2021-04-01T08:02:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: A super small Docker base image _(5MB)_ using Alpine Linux. - url: https://github.com/jwilder/docker-gen name: jwilder/docker-gen status: healthy stars: 4620 forks: 615 last_push: 2026-03-07T14:15:15Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Generate files from docker container meta-data. - url: https://github.com/powerman/dockerize name: powerman/dockerize status: healthy stars: 195 forks: 17 last_push: 2026-03-05T18:12:32Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Utility to simplify running applications in docker containers by [jwilder][jwilder], [powerman][powerman]. - url: https://github.com/tianon/gosu name: tianon/gosu status: healthy stars: 4952 forks: 356 last_push: 2026-03-04T18:27:37Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Run this specific application as this specific user and get out of the pipeline (entrypoint script tool). - url: https://github.com/sindresorhus/is-docker name: sindresorhus/is-docker status: healthy stars: 233 forks: 16 last_push: 2025-09-15T21:04:10Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Check if the process is running inside a Docker container. - url: https://github.com/ivanilves/lstags name: ivanilves/lstags status: stale stars: 340 forks: 26 last_push: 2023-05-11T20:38:37Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Sync Docker images across registries. - url: https://github.com/tarampampam/microcheck name: tarampampam/microcheck status: healthy stars: 130 forks: 2 last_push: 2026-02-24T19:11:41Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: 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. - url: https://github.com/mcuadros/ofelia name: mcuadros/ofelia status: healthy stars: 3742 forks: 204 last_push: 2026-03-08T01:55:37Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - 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-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Access VMs, desktops, servers or applications anytime and from anywhere, without complex and costly client roll-outs or user management. - url: https://github.com/ncopa/su-exec name: ncopa/su-exec status: healthy stars: 1019 forks: 103 last_push: 2025-10-07T13:49:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: 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). - url: https://github.com/theAkito/sue name: theAkito/sue status: stale stars: 13 forks: 1 last_push: 2022-04-26T21:10:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: 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]. - url: https://github.com/aptible/supercronic name: aptible/supercronic status: healthy stars: 2391 forks: 141 last_push: 2026-03-06T13:28:13Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: Crontab-compatible job runner, designed specifically to run in containers. - url: https://github.com/vorakl/TrivialRC name: vorakl/TrivialRC status: stale stars: 32 forks: 5 last_push: 2023-12-20T00:39:55Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Base Tools description: A minimalistic Runtime Configuration system and process manager for containers [vorakl](https://github.com/vorakl). - url: https://github.com/ansible-community/ansible-bender name: ansible-community/ansible-bender status: healthy stars: 694 forks: 74 last_push: 2026-01-07T23:21:32Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A tool utilising `ansible` and `buildah`. - url: https://github.com/containers/buildah name: containers/buildah status: healthy stars: 8662 forks: 882 last_push: 2026-03-08T17:53:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A tool that facilitates building OCI images. - url: https://github.com/moby/buildkit name: moby/buildkit status: healthy stars: 9817 forks: 1379 last_push: 2026-03-06T22:37:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit. - url: https://github.com/cekit/cekit name: cekit/cekit status: healthy stars: 113 forks: 44 last_push: 2026-01-30T15:06:33Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A tool used by openshift to build base images using different build engines. - url: https://github.com/mutable/container-factory name: mutable/container-factory status: stale stars: 64 forks: 3 last_push: 2015-05-06T16:07:53Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Produces Docker images from tarballs of application source code. - 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-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Copy a Docker image between registries without a full Docker installation. - url: https://github.com/alibaba/derrick name: alibaba/derrick status: stale stars: 693 forks: 109 last_push: 2023-03-06T22:40:17Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A tool help you to automate the generation of Dockerfile and dockerize application by scanning the code. By [alibaba](https://github.com/alibaba). - url: https://github.com/orisano/dlayer name: orisano/dlayer status: healthy stars: 445 forks: 12 last_push: 2026-03-02T09:11:34Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Docker layer analyzer. - url: https://github.com/mudler/docker-companion name: mudler/docker-companion status: healthy stars: 47 forks: 9 last_push: 2025-05-28T08:17:46Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A command line tool written in Golang to squash and unpack docker images. - url: https://github.com/CtripCloud/docker-make name: CtripCloud/docker-make status: stale stars: 99 forks: 20 last_push: 2019-11-22T08:32:26Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Build, tag,and push a bunch of related docker images via a single command. - 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-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Repacks a Docker image into a smaller, more efficient version that makes it significantly faster to pull. By [orf](https://github.com/orf). - url: https://github.com/bcicen/docker-replay name: bcicen/docker-replay status: stale stars: 203 forks: 13 last_push: 2018-10-13T13:09:28Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Generate `docker run`command and options from running containers. By [bcicen](https://github.com/bcicen). - url: https://github.com/swipely/dockly name: swipely/dockly status: stale stars: 228 forks: 10 last_push: 2023-02-15T15:26:17Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Dockly is a gem made to ease the pain of packaging an application in Docker. - url: https://github.com/utensils/essex name: utensils/essex status: healthy stars: 38 last_push: 2025-03-18T21:33:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: '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).' - url: https://github.com/NVIDIA/hpc-container-maker name: NVIDIA/hpc-container-maker status: healthy stars: 510 forks: 100 last_push: 2026-02-19T23:22:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Generates Dockerfiles from a high level Python recipe, including building blocks for High-Performance Computing components. - url: https://github.com/genuinetools/img name: genuinetools/img status: inactive stars: 3990 forks: 234 last_push: 2024-05-19T22:07:07Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder. - url: https://github.com/duedil-ltd/portainer name: duedil-ltd/portainer status: stale stars: 134 forks: 16 last_push: 2017-02-28T17:15:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Apache Mesos framework for building Docker images. - url: https://github.com/cybersecsi/RAUDI name: cybersecsi/RAUDI status: healthy stars: 560 forks: 34 last_push: 2026-03-05T01:57:28Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: 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). - url: https://github.com/lavie/runlike name: lavie/runlike status: healthy stars: 2919 forks: 163 last_push: 2025-12-04T12:36:39Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Generate `docker run`command and options from running containers. - url: https://github.com/theAkito/userdef name: theAkito/userdef status: stale stars: 11 last_push: 2023-10-14T20:34:12Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: An advanced `adduser` for your Alpine based Docker images. Made by [Akito][akito]. - url: https://github.com/P3GLEG/Whaler name: P3GLEG/Whaler status: healthy stars: 1185 forks: 101 last_push: 2025-09-17T03:56:52Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: Program to reverse Docker images into Dockerfiles. - url: https://github.com/Gueils/whales name: Gueils/whales status: stale stars: 391 forks: 20 last_push: 2019-05-27T13:20:14Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Builder description: A tool to automatically dockerize your applications. - url: https://github.com/garywiz/chaperone-docker name: garywiz/chaperone-docker status: stale stars: 66 forks: 11 last_push: 2018-10-05T07:48:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Dockerfile description: A set of images using the Chaperone process manager, including a lean Alpine image, LAMP, LEMP, and bare-bones base kits. - url: https://github.com/patrickhoefler/dockerfilegraph name: patrickhoefler/dockerfilegraph status: healthy stars: 255 forks: 17 last_push: 2026-03-08T00:49:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Dockerfile description: Visualize your multi-stage Dockerfiles. By [PatrickHoefler](https://github.com/patrickhoefler). - url: https://github.com/Dockershelf/dockershelf name: Dockershelf/dockershelf status: healthy stars: 97 forks: 13 last_push: 2026-03-05T01:03:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Dockerfile description: 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. - url: https://github.com/deckrun/dockadvisor name: deckrun/dockadvisor status: healthy stars: 186 forks: 6 last_push: 2026-01-12T09:26:02Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Linter description: Lightweight Dockerfile linter with 60+ rules, quality scoring, and security checks. - 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-03-06T23:18:34Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Linter description: A tool to keep an eye on your docker images size. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Linter description: The linter lets you verify Dockerfile syntax to make sure it follows the best practices for building efficient Docker images. - url: https://github.com/replicatedhq/dockerfilelint name: replicatedhq/dockerfilelint status: stale stars: 1029 forks: 83 last_push: 2023-09-27T20:58:01Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Linter description: An opinionated Dockerfile linter. - url: https://github.com/hadolint/hadolint name: hadolint/hadolint status: healthy stars: 11985 forks: 487 last_push: 2026-03-02T08:58:07Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Linter description: A Dockerfile linter that checks for best practices, common mistakes, and is also able to lint any bash written in `RUN` instructions;. - url: https://github.com/RedCoolBeans/cargos-buildroot name: RedCoolBeans/cargos-buildroot status: stale stars: 11 forks: 2 last_push: 2017-04-02T14:59:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: A bare essential OS for running the Docker Engine on bare metal or Cloud. By [RedCoolBeans](https://github.com/RedCoolBeans). - url: https://github.com/hcguersoy/cleanreg name: hcguersoy/cleanreg status: stale stars: 59 forks: 18 last_push: 2022-09-03T17:43:40Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: A small tool to delete image manifests from a Docker Registry implementing the API v2, dereferencing them for the GC. - url: https://github.com/netvarun/docket name: netvarun/docket status: stale stars: 709 forks: 33 last_push: 2020-09-02T02:35:17Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: Custom docker registry that allows for lightning fast deploys through bittorrent. - url: https://github.com/dragonflyoss/Dragonfly2 name: dragonflyoss/Dragonfly2 status: healthy stars: 3070 forks: 377 last_push: 2026-03-05T12:44:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: Provide efficient, stable and secure file distribution and image acceleration based on p2p technology. - url: https://github.com/uber/kraken name: uber/kraken status: healthy stars: 6659 forks: 468 last_push: 2026-03-05T13:24:04Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: Uber's Highly scalable P2P docker registry, capable of distributing TBs of data in seconds. - url: https://github.com/jhstatewide/nscr name: jhstatewide/nscr status: healthy stars: 1 last_push: 2025-10-27T14:37:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: A light-weight, self-contained container registry that's easy to run and maintain. - url: https://github.com/inmagik/registryo name: inmagik/registryo status: healthy stars: 15 last_push: 2025-12-17T10:20:47Z checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: UI and token based authentication server for onpremise docker registry. - url: https://github.com/noteed/rescoyl name: noteed/rescoyl status: stale stars: 18 forks: 4 last_push: 2017-04-08T19:17:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Docker Images > Registry description: Private Docker registry (free and open source). - url: https://github.com/instacart/ahab name: instacart/ahab status: stale stars: 137 forks: 7 last_push: 2018-11-16T21:54:44Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Docker event handling with Python. - url: https://github.com/lispyclouds/contajners name: lispyclouds/contajners status: healthy stars: 145 forks: 8 last_push: 2026-02-20T09:07:36Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: An idiomatic, data-driven, REPL friendly Clojure client for OCI container engines. By [lispyclouds][lispyclouds]. - url: https://github.com/gesellix/docker-client name: gesellix/docker-client status: healthy stars: 119 forks: 28 last_push: 2026-03-08T12:34:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: A Docker remote api client library for the JVM, written in Groovy. - url: https://github.com/dgongut/docker-controller-bot name: dgongut/docker-controller-bot status: healthy stars: 241 forks: 31 last_push: 2026-02-04T15:58:07Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Telegram bot to control docker containers. By [dgongut](https://github.com/dgongut/). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Docker integration testing kit with Scala. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Lightweight, truly object-oriented, Java client for Docker's API. By [amihaiemil](https://github.com/amihaiemil). - url: https://github.com/fabric8io/docker-maven-plugin name: fabric8io/docker-maven-plugin status: healthy stars: 1929 forks: 656 last_push: 2026-02-24T15:30:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: A Maven plugin for running and creating Docker images. - url: https://github.com/Microsoft/Docker.DotNet name: Microsoft/Docker.DotNet status: healthy stars: 2405 forks: 409 last_push: 2025-08-28T14:08:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: C#/.NET HTTP client for the Docker remote API. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: .NET (C#) Client Library for interacting with a Docker Registry API (v2) [rquackenbush](https://github.com/rquackenbush). - url: https://github.com/apocas/dockerode name: apocas/dockerode status: healthy stars: 4834 forks: 486 last_push: 2026-02-28T03:51:43Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Docker Remote API node.js module. - url: https://github.com/eon01/DoMonit name: eon01/DoMonit status: stale stars: 76 forks: 15 last_push: 2021-06-01T21:57:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: A simple Docker Monitoring wrapper For Docker API. - url: https://github.com/fsouza/go-dockerclient name: fsouza/go-dockerclient status: healthy stars: 2236 forks: 556 last_push: 2026-03-06T04:10:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - url: https://github.com/gesellix/gradle-docker-plugin name: gesellix/gradle-docker-plugin status: healthy stars: 81 forks: 17 last_push: 2026-03-08T12:36:04Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: A Docker remote api plugin for Gradle. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Bash script to deploy/update/undeploy Docker stacks in a Portainer instance from a docker-compose yaml file. By [greenled](https://github.com/greenled). - url: https://github.com/marcuslonnberg/sbt-docker name: marcuslonnberg/sbt-docker status: inactive stars: 733 forks: 112 last_push: 2024-12-12T15:18:45Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > API Client description: Create Docker images directly from sbt. - url: https://github.com/harbur/captain name: harbur/captain status: healthy stars: 776 forks: 48 last_push: 2025-05-25T00:09:20Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Convert your Git workflow to Docker containers ready for Continuous Delivery. - url: https://github.com/caicloud/cyclone name: caicloud/cyclone status: stale stars: 1073 forks: 171 last_push: 2023-10-24T12:08:27Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Powerful workflow engine and end-to-end pipeline solutions implemented with native Kubernetes resources. - url: https://github.com/DefangLabs/defang name: DefangLabs/defang status: healthy stars: 146 forks: 24 last_push: 2026-03-08T06:20:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Deploy Docker Compose to your favorite cloud in minutes. - url: https://github.com/crazy-max/diun name: crazy-max/diun status: healthy stars: 4457 forks: 143 last_push: 2026-03-08T17:42:13Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Receive notifications when an image or repository is updated on a Docker registry by [crazy-max]. - url: https://github.com/mag37/dockcheck name: mag37/dockcheck status: healthy stars: 2237 forks: 80 last_push: 2026-03-05T18:27:54Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: A script checking updates for docker images without pulling then auto-update selected/all containers. With notifications, pruning and more. - url: https://github.com/jenkinsci/docker-plugin name: jenkinsci/docker-plugin status: healthy stars: 499 forks: 325 last_push: 2026-02-28T10:00:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z - url: https://github.com/drone/drone name: drone/drone status: healthy stars: 33861 forks: 2896 last_push: 2026-03-07T12:23:43Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Continuous integration server built on Docker and configured using YAML files. - url: https://github.com/CodesWhat/drydock name: CodesWhat/drydock status: healthy stars: 111 forks: 5 last_push: 2026-03-08T18:03:39Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: 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). - url: https://github.com/shizunge/gantry name: shizunge/gantry status: healthy stars: 84 forks: 4 last_push: 2026-03-06T03:39:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Automatically update selected Docker swarm services. - url: https://github.com/theSage21/jaypore_ci name: theSage21/jaypore_ci status: healthy stars: 38 forks: 4 last_push: 2026-03-07T17:18:09Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Simple, very flexible, powerful CI / CD / automation system configured in Python. Offline and local first. - url: https://github.com/Kraken-CI/kraken name: Kraken-CI/kraken status: healthy stars: 160 forks: 20 last_push: 2026-01-15T13:00:32Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Modern CI/CD, open-source, on-premise system that is highly scalable and focused on testing. One of its executors is Docker. Developed. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Continuous deployment of a microservices application. - url: https://github.com/stelligent/mu name: stelligent/mu status: stale stars: 965 forks: 133 last_push: 2020-06-18T14:09:29Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Tool to configure CI/CD of your container applications via AWS CodePipeline, CodeBuild and ECS [Stelligent](https://github.com/stelligent). - url: https://github.com/systemslab/popper name: systemslab/popper status: stale stars: 307 forks: 62 last_push: 2022-03-29T22:02:27Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Github actions workflow (HCL syntax) execution engine. - url: https://github.com/Stratoscale/skipper name: Stratoscale/skipper status: healthy stars: 50 forks: 22 last_push: 2025-05-13T13:33:39Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Easily dockerize your Git repository. - url: https://github.com/ghostsquad/swarmci name: ghostsquad/swarmci status: stale stars: 58 forks: 6 last_push: 2017-02-24T02:14:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > CI/CD description: Create a distributed, isolated task pipeline in your Docker Swarm. - url: https://github.com/binci/binci name: binci/binci status: stale stars: 673 forks: 24 last_push: 2022-12-06T20:24:40Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Containerize your development workflow. (formerly DevLab by [TechnologyAdvice](https://github.com/TechnologyAdvice)). - url: https://github.com/coder/coder name: coder/coder status: healthy stars: 12417 forks: 1194 last_push: 2026-03-08T17:58:52Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Remote development machines powered by Terraform or Docker. - url: https://github.com/lstephen/construi name: lstephen/construi status: stale stars: 24 forks: 5 last_push: 2022-12-08T06:36:04Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Run your builds inside a Docker defined environment. - url: https://github.com/whatwedo/dde name: whatwedo/dde status: healthy stars: 46 forks: 9 last_push: 2026-02-20T12:25:04Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Local development environment toolset based on Docker. By [whatwedo](https://github.com/whatwedo). - url: https://github.com/bibendi/dip name: bibendi/dip status: inactive stars: 1324 forks: 50 last_push: 2024-12-25T09:38:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: CLI utility for straightforward provisioning and interacting with an application configured by docker-compose. By [bibendi](https://github.com/bibendi). - url: https://github.com/dnephin/dobi name: dnephin/dobi status: stale stars: 315 forks: 34 last_push: 2023-11-10T06:32:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: A build automation tool for Docker applications. By [dnephin](https://github.com/dnephin). - 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-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: 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). - url: https://github.com/Ph3nol/Docker-Arch name: Ph3nol/Docker-Arch status: stale stars: 31 forks: 2 last_push: 2018-09-24T06:43:08Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Generate Web/CLI projects Dockerized development environments, from 1 simple YAML file. By [Ph3nol](https://github.com/ph3nol). - url: https://github.com/EugenMayer/docker-sync name: EugenMayer/docker-sync status: healthy stars: 3564 forks: 285 last_push: 2025-11-30T20:06:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: 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). - 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-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Simple and transparent alternative to boot2docker (backed by Vagrant). - url: https://github.com/matifali/dockerdl name: matifali/dockerdl status: healthy stars: 86 forks: 11 last_push: 2025-12-29T19:27:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: 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. - url: https://github.com/eclipse/che name: eclipse/che status: healthy stars: 7129 forks: 1200 last_push: 2026-03-06T15:10:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Developer workspace server with Docker runtimes, cloud IDE, next-generation Eclipse IDE. - url: https://github.com/EnvCLI/EnvCLI name: EnvCLI/EnvCLI status: healthy stars: 116 forks: 4 last_push: 2025-06-16T20:36:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Replace your local installation of Node, Go, ... with project-specific docker containers. By [EnvCLI](https://github.com/EnvCLI). - 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-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Container solution to compile Linux and develop it for ESP32 microcontrollers - By [Hpsaturn](https://github.com/hpsaturn). - url: https://github.com/moshebe/gebug name: moshebe/gebug status: healthy stars: 634 forks: 17 last_push: 2026-03-06T21:42:46Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. - url: https://github.com/senges/kitt name: senges/kitt status: stale stars: 20 forks: 1 last_push: 2023-02-23T14:01:05Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: A portable and disposable Shell environment, based on Docker and Nix. By [senges](https://github.com/senges). - url: https://github.com/lando/lando name: lando/lando status: healthy stars: 4222 forks: 527 last_push: 2026-02-24T21:10:02Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: 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/). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Container solution to compile Rust projects for Linux, macOS and Windows. By [Peco602][peco602]. - url: https://github.com/uniget-org/cli name: uniget-org/cli status: healthy stars: 20 last_push: 2026-02-12T08:35:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Uni(versal)get, the installer and updater for container tools and beyond (formerly docker-setup). By [nicholasdille](https://github.com/nicholasdille). - url: https://github.com/tailhook/vagga name: tailhook/vagga status: stale stars: 1896 forks: 96 last_push: 2023-03-31T06:13:55Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Vagga is a containerisation tool without daemons. It is a fully-userspace container engine inspired by Vagrant and Docker, specialized for development environments. - url: https://github.com/deluan/zsh-in-docker name: deluan/zsh-in-docker status: inactive stars: 1096 forks: 119 last_push: 2024-09-30T19:07:49Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Development Environment description: Install Zsh, Oh-My-Zsh and plugins inside a Docker container with one line! By [Deluan](https://www.deluan.com). - url: https://github.com/tjamet/caduc name: tjamet/caduc status: stale stars: 21 forks: 1 last_push: 2019-01-07T16:07:50Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Garbage Collection description: A docker garbage collector cleaning stuff you did not use recently. - url: https://github.com/ZZROTDesign/docker-clean name: ZZROTDesign/docker-clean status: stale stars: 1304 forks: 90 last_push: 2018-01-16T16:29:41Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Garbage Collection description: A script that cleans Docker containers, images and volumes. - url: https://github.com/Yelp/docker-custodian name: Yelp/docker-custodian status: inactive stars: 374 forks: 49 last_push: 2024-08-14T08:08:10Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Garbage Collection description: Keep docker hosts tidy. By [Yelp](https://github.com/Yelp). - url: https://github.com/pdacity/docker_gc name: pdacity/docker_gc status: stale stars: 128 forks: 22 last_push: 2024-02-09T17:50:47Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Garbage Collection description: Image for automatic removing unused Docker Swarm objects. Also works just as Docker Service. - url: https://github.com/stepchowfun/docuum name: stepchowfun/docuum status: healthy stars: 684 forks: 43 last_push: 2026-03-07T22:59:03Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Garbage Collection description: Least recently used (LRU) eviction of Docker images. - url: https://github.com/apache/openwhisk name: apache/openwhisk status: healthy stars: 6757 forks: 1174 last_push: 2026-01-24T05:17:06Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Serverless description: A serverless, open source cloud platform that executes functions in response to events at any scale. By [apache](https://github.com/apache). - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Serverless description: Functions as Docker containers example voting app. By [bfirsh](https://github.com/bfirsh). - url: https://github.com/iron-io/functions name: iron-io/functions status: stale stars: 3220 forks: 224 last_push: 2023-09-15T01:37:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Serverless description: The serverless microservices platform FaaS (Functions as a Service) which uses Docker containers to run Any language or AWS Lambda functions. - url: https://github.com/openfaas/faas name: openfaas/faas status: healthy stars: 26105 forks: 1970 last_push: 2026-02-22T08:49:51Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Serverless description: A complete serverless functions framework for Docker and Kubernetes. By [OpenFaaS](https://github.com/openfaas). - url: https://github.com/grycap/scar name: grycap/scar status: stale stars: 599 forks: 47 last_push: 2023-05-22T11:01:11Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Serverless description: 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). - url: https://github.com/GoogleContainerTools/container-structure-test name: GoogleContainerTools/container-structure-test status: healthy stars: 2462 forks: 207 last_push: 2026-02-20T23:41:16Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Testing description: A framework to validate the structure of an image by checking the outputs of commands or the contents of the filesystem. By [GoogleContainerTools][googlecontainertools]. - url: https://github.com/zuazo/dockerspec name: zuazo/dockerspec status: stale stars: 181 forks: 8 last_push: 2017-08-30T20:40:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Testing description: 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). - url: https://github.com/lynchborg/ezdc name: lynchborg/ezdc status: stale stars: 12 last_push: 2024-02-12T08:42:24Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Testing description: Golang test harness for easily setting up tests that rely on services in a docker-compose.yml. By [byrnedo]. - url: https://github.com/kurtosis-tech/kurtosis name: kurtosis-tech/kurtosis status: healthy stars: 526 forks: 90 last_push: 2026-03-06T11:06:13Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Testing description: '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/).' - url: https://github.com/alexei-led/pumba name: alexei-led/pumba status: healthy stars: 3000 forks: 201 last_push: 2026-03-01T21:26:21Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Testing description: Chaos testing tool for Docker. Can be deployed on kubernetes and CoreOS cluster. By [alexei-led](https://github.com/alexei-led). - url: https://github.com/docker-exec/dexec name: docker-exec/dexec status: stale stars: 332 forks: 14 last_push: 2021-05-13T06:04:19Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Command line interface written in Go for running code with Docker Exec images. - url: https://github.com/benzaita/dockerized-cli name: benzaita/dockerized-cli status: stale stars: 65 forks: 5 last_push: 2024-02-27T13:49:38Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Seamlessly execute commands in a container. - url: https://github.com/CenturyLinkLabs/dray name: CenturyLinkLabs/dray status: stale stars: 386 forks: 37 last_push: 2020-01-24T17:34:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: An engine for managing the execution of container-based workflows. - url: https://github.com/artsy/hokusai name: artsy/hokusai status: healthy stars: 98 forks: 25 last_push: 2026-03-06T10:57:58Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: 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). - url: https://github.com/livecycle/preevy name: livecycle/preevy status: healthy stars: 2191 forks: 87 last_push: 2026-02-06T07:38:46Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: 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. - url: https://github.com/ianmiell/shutit name: ianmiell/shutit status: stale stars: 2144 forks: 110 last_push: 2022-08-14T14:43:18Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Tool for building and maintaining complex Docker deployments. - url: https://github.com/subuser-security/subuser name: subuser-security/subuser status: inactive stars: 894 forks: 63 last_push: 2025-02-23T11:31:31Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Makes it easy to securely and portably run graphical desktop applications in Docker. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Terraform module for deploying a single Docker image or `docker-compose.yaml` file to any Cloud™ VM. - url: https://github.com/ramitsurana/turbo name: ramitsurana/turbo status: stale stars: 27 forks: 12 last_push: 2021-12-22T19:03:53Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: Simple and Powerful utility for docker. By [ramitsurana][ramitsurana]. - url: https://github.com/indigo-dc/udocker name: indigo-dc/udocker status: healthy stars: 1709 forks: 164 last_push: 2025-08-13T17:21:57Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Development with Docker > Wrappers description: A tool to execute simple docker containers in batch or interactive systems without root privileges. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Services based on Docker (mostly :heavy_dollar_sign:) > Monitoring Services description: Docker Monitoring extension gathers metrics from the Docker Remote API, either using Unix Socket or TCP. - 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 has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Projects > Services based on Docker (mostly :heavy_dollar_sign:) > Monitoring Services description: 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). - url: https://github.com/cicdops/awesome-ciandcd name: cicdops/awesome-ciandcd status: inactive stars: 1987 forks: 225 last_push: 2024-04-01T18:08:23Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Useful Resources > Awesome Lists description: Not specific to docker but relevant. - url: https://github.com/docker/awesome-compose name: docker/awesome-compose status: healthy stars: 44283 forks: 8070 last_push: 2026-03-05T09:59:09Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Useful Resources > Awesome Lists description: Docker Compose samples. - url: https://github.com/hexops/dockerfile name: hexops/dockerfile status: stale stars: 4091 forks: 155 last_push: 2021-08-08T04:42:37Z has_license: true checked_at: 2026-03-08T18:26:00.233336Z category: Useful Resources > Good Tips description: This repository has best-practices for writing Dockerfiles. ================================================ FILE: config/website.tmpl.html ================================================ Awesome-docker
================================================ FILE: go.mod ================================================ module github.com/veggiemonk/awesome-docker go 1.26.0 require ( charm.land/bubbletea/v2 v2.0.2 charm.land/lipgloss/v2 v2.0.2 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.36.0 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20260309091805-903bfd0cf188 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-runewidth v0.0.21 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.42.0 // indirect ) ================================================ FILE: go.sum ================================================ charm.land/bubbletea/v2 v2.0.1 h1:B8e9zzK7x9JJ+XvHGF4xnYu9Xa0E0y0MyggY6dbaCfQ= charm.land/bubbletea/v2 v2.0.1/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0= charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo= charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14= charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM= github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM= github.com/aymanbagabas/go-udiff v0.4.0/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA= github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98= github.com/charmbracelet/ultraviolet v0.0.0-20260309091805-903bfd0cf188 h1:J8v4kWJYCaxv1SLhLunN74S+jMteZ1f7Dae99ioq4Bo= github.com/charmbracelet/ultraviolet v0.0.0-20260309091805-903bfd0cf188/go.mod h1:FzWNAbe1jEmI+GZljSnlaSA8wJjnNIZhWBLkTsAl6eg= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA= github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM= github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k= github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= 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/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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/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/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 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/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= 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= ================================================ FILE: index.html ================================================ Awesome-docker

Redirecting to the generated site.

================================================ FILE: internal/builder/builder.go ================================================ package builder import ( "bytes" "fmt" "os" "strings" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "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.WithParserOptions(parser.WithAutoHeadingID()), 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 string new string }{ { old: `
`, new: `
` + buf.String() + `
`, }, { old: `
`, new: `
` + buf.String() + `
`, }, } replaced := false for _, r := range replacements { 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 { return fmt.Errorf("write output: %w", err) } return nil } ================================================ FILE: internal/builder/builder_test.go ================================================ 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), 0o644); err != nil { t.Fatal(err) } tmpl := `
` tmplPath := filepath.Join(dir, "template.html") if err := os.WriteFile(tmplPath, []byte(tmpl), 0o644); 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), 0o644); 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), 0o644); 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()) } 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") } } func TestBuildAddsHeadingIDs(t *testing.T) { dir := t.TempDir() md := "# Getting Started\n\n## Next Step\n" mdPath := filepath.Join(dir, "README.md") if err := os.WriteFile(mdPath, []byte(md), 0o644); err != nil { t.Fatal(err) } tmpl := `
` tmplPath := filepath.Join(dir, "template.html") if err := os.WriteFile(tmplPath, []byte(tmpl), 0o644); 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, `id="getting-started"`) { t.Error("expected auto-generated heading id for h1") } if !strings.Contains(html, `id="next-step"`) { t.Error("expected auto-generated heading id for h2") } } ================================================ FILE: internal/cache/cache.go ================================================ 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"` Category string `yaml:"category,omitempty"` Description string `yaml:"description,omitempty"` } // 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, 0o644) } // 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 { index[e.URL] = len(hc.Entries) hc.Entries = append(hc.Entries, e) } } } ================================================ FILE: internal/cache/cache_test.go ================================================ 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), 0o644); 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 TestLoadHealthCacheInvalidYAML(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "health.yaml") if err := os.WriteFile(path, []byte("entries:\n - url: [not yaml"), 0o644); 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{ {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) } } 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) } } ================================================ FILE: internal/checker/github.go ================================================ package checker import ( "context" "fmt" "net/url" "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(rawURL string) (owner, name string, ok bool) { u, err := url.Parse(rawURL) if err != nil { return "", "", false } 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 known non-repository top-level routes. switch parts[0] { case "apps", "features", "topics": return "", "", false } name = strings.TrimSuffix(parts[1], ".git") if name == "" { return "", "", false } return parts[0], name, true } func isHTTPURL(raw string) bool { u, err := url.Parse(raw) if err != nil { return false } 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 { if _, _, ok := ExtractGitHubRepo(url); ok { github = append(github, url) } else if isHTTPURL(url) { 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) if isGitHubAuthError(err) { break } continue } results = append(results, info) if (i+1)%batchSize == 0 { time.Sleep(1 * time.Second) } } return results, errs } ================================================ FILE: internal/checker/github_test.go ================================================ package checker import ( "errors" "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?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}, {"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", "dozzle", "#projects", } 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)) } } 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) } } } ================================================ FILE: internal/checker/http.go ================================================ 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 } 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} ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() // 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 }() 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 { resp, err = doRequest(http.MethodGet) if err != nil { result.Error = err.Error() return result } } else if shouldFallbackToGET(resp.StatusCode) { resp.Body.Close() resp, err = doRequest(http.MethodGet) 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 } ================================================ FILE: internal/checker/http_test.go ================================================ 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") } } } 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) } } ================================================ FILE: internal/linter/fixer.go ================================================ 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+\.?$`) // 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, "") 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, ":yen:") case parser.MarkerWIP: markers = append(markers, ":construction:") case parser.MarkerStale: markers = append(markers, ":ice_cube:") } } if len(markers) > 0 { desc = strings.Join(markers, " ") + " " + desc } return fmt.Sprintf("- [%s](%s) - %s", e.Name, e.URL, desc) } // 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 } fixCount := 0 var headingLines []int for i, line := range lines { if sectionHeadingRe.MatchString(line) { headingLines = append(headingLines, i) } } // 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 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) lineIdx := entryPositions[j] if lines[lineIdx] != newLine { fixCount++ lines[lineIdx] = 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() } ================================================ FILE: internal/linter/fixer_test.go ================================================ 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) } } 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) } } ================================================ FILE: internal/linter/linter.go ================================================ 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++ } } ================================================ FILE: internal/linter/linter_test.go ================================================ 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)") } } ================================================ FILE: internal/linter/rules.go ================================================ 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 first, ok := firstLetter(e.Description); ok && !unicode.IsUpper(first) { 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 } // 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 (find it, may not be at index 0) runes := []rune(fixed.Description) for i, r := range runes { if unicode.IsLetter(r) { runes[i] = unicode.ToUpper(r) break } } 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 } ================================================ FILE: internal/parser/parser.go ================================================ package parser import ( "bufio" "fmt" "io" "regexp" "strings" ) // 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 var entryRe = regexp.MustCompile(`^[-*]\s+\[([^\]]+)\]\(([^)]+)\)(.*?)\s+-\s+(.+)$`) // headingRe matches markdown headings: # Title, ## Title, etc. var headingRe = regexp.MustCompile(`^(#{1,6})\s+(.+?)(?:\s*)?$`) var markerDefs = []struct { text string marker Marker }{ {text: ":skull:", marker: MarkerAbandoned}, {text: ":yen:", marker: MarkerPaid}, {text: ":construction:", marker: MarkerWIP}, {text: ":ice_cube:", marker: MarkerStale}, } // 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) } 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 _, 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) 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 } ================================================ FILE: internal/parser/parser_test.go ================================================ 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. :yen: :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 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 > 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. :yen: ` 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 } ================================================ FILE: internal/parser/types.go ================================================ package parser // Marker represents a status emoji on an entry. type Marker int const ( MarkerAbandoned Marker = iota // :skull: MarkerPaid // :yen: MarkerWIP // :construction: MarkerStale // :ice_cube: ) // 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 } ================================================ FILE: internal/scorer/scorer.go ================================================ package scorer import ( "encoding/json" "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 HasLicense bool LastPush time.Time Category string Description string } // 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 { 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, HasLicense: info.HasLicense, 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, HasLicense: s.HasLicense, LastPush: s.LastPush, CheckedAt: now, Category: s.Category, Description: s.Description, } } return entries } // GenerateReport produces a Markdown health report. func GenerateReport(scored []ScoredEntry) string { var b strings.Builder data := BuildReportData(scored) groups := data.ByStatus fmt.Fprintf(&b, "# Health Report\n\n") 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", 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) { entries := groups[status] if len(entries) == 0 { return } fmt.Fprintf(&b, "## %s\n\n", title) 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")) } b.WriteString("\n") } 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, "", " ") } ================================================ FILE: internal/scorer/scorer_test.go ================================================ package scorer import ( "encoding/json" "fmt" "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 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}, {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) } } ================================================ FILE: internal/tui/model.go ================================================ package tui import ( "fmt" "os/exec" "runtime" "strings" "unicode/utf8" tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" "github.com/veggiemonk/awesome-docker/internal/cache" ) type panel int const ( panelTree panel = iota panelList ) const entryHeight = 5 // lines rendered per entry in the list panel const scrollOff = 4 // minimum lines/entries kept visible above and below cursor // Model is the top-level Bubbletea model. type Model struct { roots []*TreeNode flatTree []FlatNode activePanel panel treeCursor int treeOffset int listCursor int listOffset int currentEntries []cache.HealthEntry filtering bool filterText string width, height int } // New creates a new Model from health cache entries. func New(entries []cache.HealthEntry) Model { roots := BuildTree(entries) // Expand first root by default if len(roots) > 0 { roots[0].Expanded = true } flat := FlattenVisible(roots) m := Model{ roots: roots, flatTree: flat, } m.updateCurrentEntries() return m } // Init returns an initial command. func (m Model) Init() tea.Cmd { return nil } // Update handles messages. func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: m.width = msg.Width m.height = msg.Height return m, nil case openURLMsg: return m, nil case tea.KeyPressMsg: // Filter mode input if m.filtering { return m.handleFilterKey(msg) } switch msg.String() { case "q", "ctrl+c": return m, tea.Quit case "tab": if m.activePanel == panelTree { m.activePanel = panelList } else { m.activePanel = panelTree } case "/": m.filtering = true m.filterText = "" default: if m.activePanel == panelTree { return m.handleTreeKey(msg) } return m.handleListKey(msg) } } return m, nil } func (m Model) handleFilterKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { switch msg.String() { case "esc": m.filtering = false m.filterText = "" m.flatTree = FlattenVisible(m.roots) m.updateCurrentEntries() case "enter": m.filtering = false case "backspace": if len(m.filterText) > 0 { m.filterText = m.filterText[:len(m.filterText)-1] m.applyFilter() } default: r := msg.String() if utf8.RuneCountInString(r) == 1 { m.filterText += r m.applyFilter() } } return m, nil } func (m *Model) applyFilter() { if m.filterText == "" { m.flatTree = FlattenVisible(m.roots) m.updateCurrentEntries() return } query := strings.ToLower(m.filterText) var filtered []cache.HealthEntry for _, root := range m.roots { for _, e := range root.AllEntries() { if strings.Contains(strings.ToLower(e.Name), query) || strings.Contains(strings.ToLower(e.Description), query) || strings.Contains(strings.ToLower(e.Category), query) { filtered = append(filtered, e) } } } m.currentEntries = filtered m.listCursor = 0 m.listOffset = 0 } func (m Model) handleTreeKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { switch msg.String() { case "up", "k": if m.treeCursor > 0 { m.treeCursor-- m.adjustTreeScroll() m.updateCurrentEntries() } case "down", "j": if m.treeCursor < len(m.flatTree)-1 { m.treeCursor++ m.adjustTreeScroll() m.updateCurrentEntries() } case "enter", " ": if m.treeCursor < len(m.flatTree) { node := m.flatTree[m.treeCursor].Node if node.HasChildren() { node.Expanded = !node.Expanded m.flatTree = FlattenVisible(m.roots) if m.treeCursor >= len(m.flatTree) { m.treeCursor = len(m.flatTree) - 1 } } m.adjustTreeScroll() m.updateCurrentEntries() } case "ctrl+d", "pgdown": half := m.treePanelHeight() / 2 if half < 1 { half = 1 } m.treeCursor += half if m.treeCursor >= len(m.flatTree) { m.treeCursor = len(m.flatTree) - 1 } m.adjustTreeScroll() m.updateCurrentEntries() case "ctrl+u", "pgup": half := m.treePanelHeight() / 2 if half < 1 { half = 1 } m.treeCursor -= half if m.treeCursor < 0 { m.treeCursor = 0 } m.adjustTreeScroll() m.updateCurrentEntries() case "g", "home": m.treeCursor = 0 m.adjustTreeScroll() m.updateCurrentEntries() case "G", "end": m.treeCursor = len(m.flatTree) - 1 m.adjustTreeScroll() m.updateCurrentEntries() case "right", "l": if m.treeCursor < len(m.flatTree) { node := m.flatTree[m.treeCursor].Node if node.HasChildren() && !node.Expanded { node.Expanded = true m.flatTree = FlattenVisible(m.roots) m.adjustTreeScroll() m.updateCurrentEntries() } else { m.activePanel = panelList } } case "left", "h": if m.treeCursor < len(m.flatTree) { node := m.flatTree[m.treeCursor].Node if node.HasChildren() && node.Expanded { node.Expanded = false m.flatTree = FlattenVisible(m.roots) m.adjustTreeScroll() m.updateCurrentEntries() } } } return m, nil } func (m *Model) adjustTreeScroll() { visible := m.treePanelHeight() off := scrollOff if off > visible/2 { off = visible / 2 } if m.treeCursor < m.treeOffset+off { m.treeOffset = m.treeCursor - off } if m.treeCursor >= m.treeOffset+visible-off { m.treeOffset = m.treeCursor - visible + off + 1 } if m.treeOffset < 0 { m.treeOffset = 0 } } func (m Model) treePanelHeight() int { h := m.height - 6 // header, footer, borders, title if h < 1 { h = 1 } return h } func (m Model) handleListKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { switch msg.String() { case "up", "k": if m.listCursor > 0 { m.listCursor-- m.adjustListScroll() } case "down", "j": if m.listCursor < len(m.currentEntries)-1 { m.listCursor++ m.adjustListScroll() } case "ctrl+d", "pgdown": half := m.visibleListEntries() / 2 if half < 1 { half = 1 } m.listCursor += half if m.listCursor >= len(m.currentEntries) { m.listCursor = len(m.currentEntries) - 1 } m.adjustListScroll() case "ctrl+u", "pgup": half := m.visibleListEntries() / 2 if half < 1 { half = 1 } m.listCursor -= half if m.listCursor < 0 { m.listCursor = 0 } m.adjustListScroll() case "g", "home": m.listCursor = 0 m.adjustListScroll() case "G", "end": m.listCursor = len(m.currentEntries) - 1 m.adjustListScroll() case "enter": if m.listCursor < len(m.currentEntries) { return m, openURL(m.currentEntries[m.listCursor].URL) } case "left", "h": m.activePanel = panelTree } return m, nil } func (m *Model) updateCurrentEntries() { if len(m.flatTree) == 0 { m.currentEntries = nil return } if m.treeCursor >= len(m.flatTree) { m.treeCursor = len(m.flatTree) - 1 } node := m.flatTree[m.treeCursor].Node m.currentEntries = node.AllEntries() m.listCursor = 0 m.listOffset = 0 } func (m Model) visibleListEntries() int { v := m.listPanelHeight() / entryHeight if v < 1 { return 1 } return v } func (m *Model) adjustListScroll() { visible := m.visibleListEntries() off := scrollOff if off > visible/2 { off = visible / 2 } if m.listCursor < m.listOffset+off { m.listOffset = m.listCursor - off } if m.listCursor >= m.listOffset+visible-off { m.listOffset = m.listCursor - visible + off + 1 } if m.listOffset < 0 { m.listOffset = 0 } } func (m Model) listPanelHeight() int { // height minus header, footer, borders h := m.height - 4 if h < 1 { h = 1 } return h } // View renders the UI. func (m Model) View() tea.View { if m.width == 0 || m.height == 0 { return tea.NewView("Loading...") } treeWidth := m.width*3/10 - 2 // 30% minus borders listWidth := m.width - treeWidth - 6 // remaining minus borders/gaps contentHeight := m.height - 3 // minus footer if treeWidth < 10 { treeWidth = 10 } if listWidth < 20 { listWidth = 20 } if contentHeight < 3 { contentHeight = 3 } tree := m.renderTree(treeWidth, contentHeight) list := m.renderList(listWidth, contentHeight) // Apply border styles treeBorder := inactiveBorderStyle listBorder := inactiveBorderStyle if m.activePanel == panelTree { treeBorder = activeBorderStyle } else { listBorder = activeBorderStyle } treePanel := treeBorder.Width(treeWidth).Height(contentHeight).Render(tree) listPanel := listBorder.Width(listWidth).Height(contentHeight).Render(list) body := lipgloss.JoinHorizontal(lipgloss.Top, treePanel, listPanel) footer := m.renderFooter() content := lipgloss.JoinVertical(lipgloss.Left, body, footer) v := tea.NewView(content) v.AltScreen = true return v } func (m Model) renderTree(width, height int) string { var b strings.Builder title := headerStyle.Render("Categories") b.WriteString(title) b.WriteString("\n\n") linesUsed := 2 end := m.treeOffset + height - 2 if end > len(m.flatTree) { end = len(m.flatTree) } for i := m.treeOffset; i < end; i++ { fn := m.flatTree[i] if linesUsed >= height { break } indent := strings.Repeat(" ", fn.Depth) icon := " " if fn.Node.HasChildren() { if fn.Node.Expanded { icon = "▼ " } else { icon = "▶ " } } count := fn.Node.TotalEntries() label := fmt.Sprintf("%s%s%s (%d)", indent, icon, fn.Node.Name, count) // Truncate to width if len(label) > width { label = label[:width-1] + "…" } if i == m.treeCursor { label = treeSelectedStyle.Render(label) } else { label = treeNormalStyle.Render(label) } b.WriteString(label) b.WriteString("\n") linesUsed++ } return b.String() } func (m Model) renderList(width, height int) string { var b strings.Builder // Title title := "Resources" if m.filtering && m.filterText != "" { title = fmt.Sprintf("Resources (filter: %s)", m.filterText) } b.WriteString(headerStyle.Render(title)) b.WriteString("\n\n") if len(m.currentEntries) == 0 { b.WriteString(entryDescStyle.Render(" No entries")) return b.String() } linesUsed := 2 visible := (height - 2) / entryHeight if visible < 1 { visible = 1 } start := m.listOffset end := start + visible if end > len(m.currentEntries) { end = len(m.currentEntries) } for idx := start; idx < end; idx++ { if linesUsed+entryHeight > height { break } e := m.currentEntries[idx] selected := idx == m.listCursor // Use a safe width that accounts for Unicode characters (★, ⑂) // that some terminals render as 2 columns but lipgloss counts as 1. safeWidth := width - 2 // Line 1: name + stars + forks stats := fmt.Sprintf("★ %d", e.Stars) if e.Forks > 0 { stats += fmt.Sprintf(" ⑂ %d", e.Forks) } name := e.Name statsW := lipgloss.Width(stats) maxName := safeWidth - statsW - 2 // 2 for minimum gap if maxName < 4 { maxName = 4 } if lipgloss.Width(name) > maxName { name = truncateToWidth(name, maxName-1) + "…" } nameStr := entryNameStyle.Render(name) statsStr := entryDescStyle.Render(stats) padding := safeWidth - lipgloss.Width(nameStr) - lipgloss.Width(statsStr) if padding < 1 { padding = 1 } line1 := nameStr + strings.Repeat(" ", padding) + statsStr // Line 2: URL url := e.URL if lipgloss.Width(url) > safeWidth { url = truncateToWidth(url, safeWidth-1) + "…" } line2 := entryURLStyle.Render(url) // Line 3: description desc := e.Description if lipgloss.Width(desc) > safeWidth { desc = truncateToWidth(desc, safeWidth-3) + "..." } line3 := entryDescStyle.Render(desc) // Line 4: status + last push statusStr := statusStyle(e.Status).Render(e.Status) lastPush := "" if !e.LastPush.IsZero() { lastPush = fmt.Sprintf(" Last push: %s", e.LastPush.Format("2006-01-02")) } line4 := statusStr + entryDescStyle.Render(lastPush) // Line 5: separator sepWidth := safeWidth if sepWidth < 1 { sepWidth = 1 } line5 := entryDescStyle.Render(strings.Repeat("─", sepWidth)) entry := fmt.Sprintf("%s\n%s\n%s\n%s\n%s", line1, line2, line3, line4, line5) if selected && m.activePanel == panelList { entry = entrySelectedStyle.Render(entry) } b.WriteString(entry) b.WriteString("\n") linesUsed += entryHeight } // Scroll indicator if len(m.currentEntries) > visible { indicator := fmt.Sprintf(" %d-%d of %d", start+1, end, len(m.currentEntries)) b.WriteString(footerStyle.Render(indicator)) } return b.String() } func (m Model) renderFooter() string { if m.filtering { return filterPromptStyle.Render("/") + entryDescStyle.Render(m.filterText+"█") } help := " Tab:switch j/k:nav PgDn/PgUp:page g/G:top/bottom Enter:expand/open /:filter q:quit" return footerStyle.Render(help) } // openURLMsg is sent after attempting to open a URL. type openURLMsg struct{ err error } func openURL(url string) tea.Cmd { return func() tea.Msg { var cmd *exec.Cmd switch runtime.GOOS { case "darwin": cmd = exec.Command("open", url) case "windows": cmd = exec.Command("cmd", "/c", "start", url) default: cmd = exec.Command("xdg-open", url) } return openURLMsg{err: cmd.Run()} } } // truncateToWidth truncates s to at most maxWidth visible columns. func truncateToWidth(s string, maxWidth int) string { if maxWidth <= 0 { return "" } w := 0 for i, r := range s { rw := lipgloss.Width(string(r)) if w+rw > maxWidth { return s[:i] } w += rw } return s } ================================================ FILE: internal/tui/styles.go ================================================ package tui import "charm.land/lipgloss/v2" var ( // Panel borders activeBorderStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("#7D56F4")) inactiveBorderStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("#555555")) // Tree styles treeSelectedStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#FF79C6")).Background(lipgloss.Color("#3B2D50")) treeNormalStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#CCCCCC")) // Entry styles entryNameStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#50FA7B")) entryURLStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#888888")).Italic(true) entryDescStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#CCCCCC")) // Status badge styles statusHealthyStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#50FA7B")).Bold(true) statusInactiveStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFB86C")) statusStaleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#F1FA8C")) statusArchivedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF5555")).Bold(true) statusDeadStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#666666")).Strikethrough(true) // Selected entry entrySelectedStyle = lipgloss.NewStyle().Background(lipgloss.Color("#44475A")) // Header headerStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#BD93F9")).Padding(0, 1) // Footer footerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#666666")) // Filter filterPromptStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF79C6")).Bold(true) ) func statusStyle(status string) lipgloss.Style { switch status { case "healthy": return statusHealthyStyle case "inactive": return statusInactiveStyle case "stale": return statusStaleStyle case "archived": return statusArchivedStyle case "dead": return statusDeadStyle default: return lipgloss.NewStyle() } } ================================================ FILE: internal/tui/tree.go ================================================ package tui import ( "sort" "strings" "github.com/veggiemonk/awesome-docker/internal/cache" ) // TreeNode represents a node in the category tree. type TreeNode struct { Name string // display name (leaf segment, e.g. "Networking") Path string // full path (e.g. "Container Operations > Networking") Children []*TreeNode Expanded bool Entries []cache.HealthEntry } // FlatNode is a visible tree node with its indentation depth. type FlatNode struct { Node *TreeNode Depth int } // HasChildren returns true if this node has child categories. func (n *TreeNode) HasChildren() bool { return len(n.Children) > 0 } // TotalEntries returns the count of entries in this node and all descendants. func (n *TreeNode) TotalEntries() int { count := len(n.Entries) for _, c := range n.Children { count += c.TotalEntries() } return count } // AllEntries returns entries from this node and all descendants. func (n *TreeNode) AllEntries() []cache.HealthEntry { result := make([]cache.HealthEntry, 0, n.TotalEntries()) result = append(result, n.Entries...) for _, c := range n.Children { result = append(result, c.AllEntries()...) } return result } // BuildTree constructs a tree from flat HealthEntry slice, grouping by Category. func BuildTree(entries []cache.HealthEntry) []*TreeNode { root := &TreeNode{Name: "root"} nodeMap := map[string]*TreeNode{} for _, e := range entries { cat := e.Category if cat == "" { cat = "Uncategorized" } node := ensureNode(root, nodeMap, cat) node.Entries = append(node.Entries, e) } // Sort children at every level sortTree(root) return root.Children } func ensureNode(root *TreeNode, nodeMap map[string]*TreeNode, path string) *TreeNode { if n, ok := nodeMap[path]; ok { return n } parts := strings.Split(path, " > ") current := root for i, part := range parts { subpath := strings.Join(parts[:i+1], " > ") if n, ok := nodeMap[subpath]; ok { current = n continue } child := &TreeNode{ Name: part, Path: subpath, } current.Children = append(current.Children, child) nodeMap[subpath] = child current = child } return current } func sortTree(node *TreeNode) { sort.Slice(node.Children, func(i, j int) bool { return node.Children[i].Name < node.Children[j].Name }) for _, c := range node.Children { sortTree(c) } } // FlattenVisible returns visible nodes in depth-first order for rendering. func FlattenVisible(roots []*TreeNode) []FlatNode { var result []FlatNode for _, r := range roots { flattenNode(r, 0, &result) } return result } func flattenNode(node *TreeNode, depth int, result *[]FlatNode) { *result = append(*result, FlatNode{Node: node, Depth: depth}) if node.Expanded { for _, c := range node.Children { flattenNode(c, depth+1, result) } } } ================================================ FILE: internal/tui/tree_test.go ================================================ package tui import ( "testing" "github.com/veggiemonk/awesome-docker/internal/cache" ) func TestBuildTree(t *testing.T) { entries := []cache.HealthEntry{ {URL: "https://github.com/a/b", Name: "a/b", Category: "Projects > Networking", Description: "desc1"}, {URL: "https://github.com/c/d", Name: "c/d", Category: "Projects > Networking", Description: "desc2"}, {URL: "https://github.com/e/f", Name: "e/f", Category: "Projects > Security", Description: "desc3"}, {URL: "https://github.com/g/h", Name: "g/h", Category: "Docker Images > Base Tools", Description: "desc4"}, {URL: "https://github.com/i/j", Name: "i/j", Category: "", Description: "no category"}, } roots := BuildTree(entries) // Should have 3 roots: Docker Images, Projects, Uncategorized (sorted) if len(roots) != 3 { t.Fatalf("expected 3 roots, got %d", len(roots)) } if roots[0].Name != "Docker Images" { t.Errorf("expected first root 'Docker Images', got %q", roots[0].Name) } if roots[1].Name != "Projects" { t.Errorf("expected second root 'Projects', got %q", roots[1].Name) } if roots[2].Name != "Uncategorized" { t.Errorf("expected third root 'Uncategorized', got %q", roots[2].Name) } // Projects > Networking should have 2 entries projects := roots[1] if len(projects.Children) != 2 { t.Fatalf("expected 2 children under Projects, got %d", len(projects.Children)) } networking := projects.Children[0] // Networking < Security alphabetically if networking.Name != "Networking" { t.Errorf("expected 'Networking', got %q", networking.Name) } if len(networking.Entries) != 2 { t.Errorf("expected 2 entries in Networking, got %d", len(networking.Entries)) } } func TestBuildTreeEmpty(t *testing.T) { roots := BuildTree(nil) if len(roots) != 0 { t.Errorf("expected 0 roots for nil input, got %d", len(roots)) } } func TestTotalEntries(t *testing.T) { entries := []cache.HealthEntry{ {URL: "https://a", Category: "A > B"}, {URL: "https://b", Category: "A > B"}, {URL: "https://c", Category: "A > C"}, {URL: "https://d", Category: "A"}, } roots := BuildTree(entries) if len(roots) != 1 { t.Fatalf("expected 1 root, got %d", len(roots)) } if roots[0].TotalEntries() != 4 { t.Errorf("expected 4 total entries, got %d", roots[0].TotalEntries()) } } func TestFlattenVisible(t *testing.T) { entries := []cache.HealthEntry{ {URL: "https://a", Category: "A > B"}, {URL: "https://b", Category: "A > C"}, } roots := BuildTree(entries) // Initially not expanded, should see just root flat := FlattenVisible(roots) if len(flat) != 1 { t.Fatalf("expected 1 visible node (collapsed), got %d", len(flat)) } if flat[0].Depth != 0 { t.Errorf("expected depth 0, got %d", flat[0].Depth) } // Expand root roots[0].Expanded = true flat = FlattenVisible(roots) if len(flat) != 3 { t.Fatalf("expected 3 visible nodes (expanded), got %d", len(flat)) } if flat[1].Depth != 1 { t.Errorf("expected depth 1 for child, got %d", flat[1].Depth) } } func TestAllEntries(t *testing.T) { entries := []cache.HealthEntry{ {URL: "https://a", Category: "A > B"}, {URL: "https://b", Category: "A"}, } roots := BuildTree(entries) all := roots[0].AllEntries() if len(all) != 2 { t.Errorf("expected 2 entries from AllEntries, got %d", len(all)) } } ================================================ FILE: internal/tui/tui.go ================================================ package tui import ( tea "charm.land/bubbletea/v2" "github.com/veggiemonk/awesome-docker/internal/cache" ) // Run launches the TUI browser. It blocks until the user quits. func Run(entries []cache.HealthEntry) error { m := New(entries) p := tea.NewProgram(m) _, err := p.Run() return err }