diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 733348d..a88400c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version-file: go.mod - name: Verify dependencies run: go mod verify diff --git a/.gitignore b/.gitignore index f40e964..d17700a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ go.work.sum # env file .env +paper/*.pdf +paper/*.log +paper/*.aux diff --git a/.goreleaser.yaml b/.goreleaser.yaml index a32f486..29d81f4 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,5 +1,5 @@ version: 2 -project_name: container-doctor +project_name: container-preflight before: hooks: - go mod tidy @@ -16,6 +16,8 @@ builds: ignore: - goos: windows goarch: arm64 + ldflags: + - -s -w -X github.com/raphgm/container-preflight/cmd.Version={{.Version}} archives: - format: tar.gz # this name template makes the OS and Arch compatible with the results of uname. diff --git a/.zenodo.json b/.zenodo.json new file mode 100644 index 0000000..6d349a6 --- /dev/null +++ b/.zenodo.json @@ -0,0 +1,8 @@ +{ + "title": "Container Preflight: predicting container deployment failures before execution (software and evaluation data)", + "upload_type": "software", + "description": "Container Preflight predicts Docker and Docker Compose build and start-up failures before execution by jointly analyzing project artifacts, the host environment and registry metadata. This archive contains the tool, its rules, the GitHub failure-mining scripts and data, the labeled development and held-out test samples, and the field-validation notes used in the accompanying paper.", + "creators": [{"name": "Gab-Momoh, Raphael", "affiliation": "Paynautik Limited"}], + "license": "MIT", + "keywords": ["containers", "Docker", "Docker Compose", "configuration errors", "failure prediction", "root cause analysis"] +} diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..1bcd171 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,11 @@ +cff-version: 1.2.0 +message: "If you use this software or its data, please cite it as below." +title: "Container Preflight: predicting container deployment failures before execution" +type: software +authors: + - family-names: Gab-Momoh + given-names: Raphael + affiliation: Paynautik Limited +repository-code: "https://github.com/raphgm/container-preflight" +license: MIT +keywords: [containers, Docker, Docker Compose, configuration errors, failure prediction, root cause analysis] diff --git a/README.md b/README.md index 2dcc8b8..a896c72 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,109 @@ -# Container Doctor 🩺 +# Container Preflight ✈️ -`container-doctor` is a fast, extensible CLI tool designed to diagnose your system's readiness for running Docker and container workloads. It performs health checks across your system, Docker daemon, and Compose installation, alerting you to critical issues like low memory, insufficient disk space, or missing dependencies. +**Predict container failures before you run, and diagnose them at the root cause when they happen.** -## Features +`container-preflight` predicts whether a container project will build and run on a machine **before you run it**, and explains each predicted failure once, at its root cause. + +Linters look only at your Dockerfile. `docker info` looks only at your machine. Most "works on my machine" failures come from the mismatch between the two: an amd64-only image on an Apple silicon laptop, a Compose file that needs more memory than Docker Desktop's VM has, a `COPY` of a file your `.dockerignore` excludes, a port something else already holds. `container-preflight check` checks the project and the host together. + +## Check a project + +```bash +container-preflight check . +``` + +Preflight builds three views and joins them: + +1. **What the project needs.** The Compose file and every Dockerfile are parsed with Docker's own parsers (`compose-go`, BuildKit's Dockerfile frontend). This covers platforms, memory limits and replicas, published ports, bind mounts, `COPY` sources (only in stages BuildKit will actually build), BuildKit-only syntax, Compose features and interpolated variables. +2. **What the host offers.** The daemon's platform and memory (on macOS and Windows these are the VM's, not the laptop's), emulation, Compose/buildx versions, kernel settings, local images, credential helpers and live port usage. +3. **What registries publish.** Each image's platforms and download size, read from the registry without pulling. + +Each finding quotes its evidence from both sides and the error Docker would print: + +``` +✗ [web] COPY source ".env.production" is excluded by .dockerignore Dockerfile:11 + web/.dockerignore: pattern ".env*" + would fail with: "failed to compute cache key: \"/.env.production\": not found" + fix: Remove or negate the pattern ".env*" in web/.dockerignore. +``` + +### Root causes, not symptom lists + +Checks depend on facts: the Docker CLI → the daemon → its platform and memory, and so on. When a fact cannot be established, every check that needs it is grouped under that single root cause instead of failing separately. Checks that do not depend on it keep running. + +``` +ROOT CAUSES + ✗ Docker daemon is not reachable + fix: Start Docker Desktop (or `colima start`, `sudo systemctl start docker`) … + blocks 5 check(s): image.platform, resources.memory, resources.gpu, … +``` + +### Predict for another machine + +```bash +# on the target machine (a teammate's laptop, a CI runner, a server) +container-preflight snapshot -o ci-runner.json + +# anywhere +container-preflight check . --host ci-runner.json +``` + +`examples/` contains a deliberately broken project and two example host snapshots. The same project gets different predictions on each: + +```bash +container-preflight check examples/broken-shop --host examples/hosts/macbook-m2-desktop.json +container-preflight check examples/broken-shop --host examples/hosts/ubuntu-legacy-server.json +``` + +### Learning from real failures + +Built-in rules cover common failures. `learn` turns the failures your project actually hits into new rules: + +```bash +container-preflight learn -- docker compose up db +``` + +It runs the command and extracts the decisive error line from the output. It turns that line into a signature, with addresses, IDs, paths and numbers generalized. It then records the conditions at the time: image, platform, emulation (QEMU/Rosetta), memory, builder, and which environment variables were set (never their values). The rule goes to `.container-preflight/learned.yaml`; commit it, and preflight predicts the failure for everyone on the team. + +Rules improve with evidence: + +- **Another failure with the same error** drops the conditions the two runs disagree on, which makes the rule more general. +- **A working run** (`learn --success -- docker compose up -d`) that satisfies a rule adds the condition that tells it apart from the failures, which makes the rule more specific. If no such condition exists, the rule is marked unreliable and no longer reported. +- **A failure a built-in rule already predicted** is reported as such and is not learned twice. + +Example from a real run: Postgres started without a password failed. `learn` created a rule for `image=postgres`. After a password was added, the successful run refined the rule to `env.POSTGRES_PASSWORD=unset`, and preflight now flags any Compose file that uses Postgres without one. + +### Rules + +| Rule | Predicts | +|---|---| +| `image.exists` | tag or repository missing from the registry | +| `image.platform` | no variant for the host's platform, emulation needed or unavailable (`exec format error`) | +| `registry.credentials` | configured credential helper not installed (`error getting credentials`) | +| `build.context` | `COPY`/`ADD` sources missing, excluded by `.dockerignore`, or outside the context; bad target or ARG | +| `build.buildkit` | `RUN --mount`, heredocs, `COPY --chmod/--link` without BuildKit | +| `compose.version` | Compose features newer than the installed Compose (`include`, `name`, `develop`, hooks, `gpus`, `models`) | +| `compose.env` | unset variables, required `${VAR:?}` without a value | +| `resources.memory` | known image minimums and total limits vs Docker's memory | +| `resources.disk` | image download size ×2.5 vs free disk (the smaller of the VM disk and the host volume it lives on) | +| `host.disk` | too little space on this machine for Docker Desktop/Colima/OrbStack to start or grow their VM | +| `resources.gpu` | GPU requests without the NVIDIA runtime, or on macOS | +| `kernel.sysctl` | `vm.max_map_count` for Elasticsearch/OpenSearch/SonarQube | +| `ports.conflict` | two services, or several replicas, on one host port | +| `ports.host` | host port already held by another process or container; privileged ports under rootless Docker | +| `mounts.bind` | missing bind sources that Docker will turn into directories, stale empty directories | +| `mounts.permissions` | non-root containers writing to bind mounts Docker creates as root or that another uid owns; SELinux without `:z`; Postgres data folders bind-mounted from Windows | +| `mounts.sharing` | paths outside Docker Desktop's shared folders (read from the running VM on macOS; home only on Linux) | + +Containers started without Compose are checked the same way: + +```bash +container-preflight check --run "docker run -p 8080:80 -v ./site:/usr/share/nginx/html nginx:1.27" +``` + +Use `--format json` for machine-readable output and `--offline` to skip registry lookups. The exit code is 1 when a blocking problem is predicted. + +## Other commands - **System Diagnostics**: Checks your operating system, CPU architecture, memory (RAM), and disk space to ensure you meet minimum requirements. - **Docker Health**: Validates that Docker is installed, the daemon is running, the socket is accessible, and client/server versions are compatible. @@ -17,46 +118,46 @@ ### Using Go If you have Go installed, you can install the CLI directly: ```bash -go install github.com/raphgm/container-doctor@latest +go install github.com/raphgm/container-preflight@latest ``` ### From Releases Pre-compiled binaries for **macOS**, **Linux**, and **Windows** are automatically generated for every release. -Head over to the [Releases page](https://github.com/raphgm/container-doctor/releases) to download the binary for your operating system. +Head over to the [Releases page](https://github.com/raphgm/container-preflight/releases) to download the binary for your operating system. --- ## Usage -### 1. Run Health Checks +### Host health checks Run the diagnostic engine to check your environment: ```bash -container-doctor check +container-preflight host ``` You can export the results to different formats using the `--format` flag: ```bash # JSON Output -container-doctor check --format json > report.json +container-preflight host --format json > report.json # Markdown Output -container-doctor check --format markdown > report.md +container-preflight host --format markdown > report.md # HTML Output (Standalone Webpage) -container-doctor check --format html > report.html +container-preflight host --format html > report.html ``` -### 2. Inspect a Project +### Inspect a project Statically analyze the configuration files in your current directory (or any specified path): ```bash -container-doctor inspect . +container-preflight inspect . ``` --- ## Architecture & Extensibility -`container-doctor` is built with a highly decoupled, plugin-based architecture. +`container-preflight` is built with a highly decoupled, plugin-based architecture. - **Engine**: The core `internal/engine` runs the execution loop and aggregates results. - **Providers**: Checks are grouped by Providers (e.g., `system`, `docker`, `compose`). diff --git a/bench/__pycache__/mine.cpython-314.pyc b/bench/__pycache__/mine.cpython-314.pyc new file mode 100644 index 0000000..4904097 Binary files /dev/null and b/bench/__pycache__/mine.cpython-314.pyc differ diff --git a/bench/__pycache__/precision.cpython-314.pyc b/bench/__pycache__/precision.cpython-314.pyc new file mode 100644 index 0000000..4f9f772 Binary files /dev/null and b/bench/__pycache__/precision.cpython-314.pyc differ diff --git a/bench/__pycache__/sample.cpython-314.pyc b/bench/__pycache__/sample.cpython-314.pyc new file mode 100644 index 0000000..f2d4931 Binary files /dev/null and b/bench/__pycache__/sample.cpython-314.pyc differ diff --git a/bench/data/address-already-in-use.json b/bench/data/address-already-in-use.json new file mode 100644 index 0000000..272ab49 --- /dev/null +++ b/bench/data/address-already-in-use.json @@ -0,0 +1,280 @@ +{ + "category": "address already in use", + "rule": "ports.host", + "query": "\"address already in use\" docker is:issue created:>=2021-01-01", + "total": 3792, + "sample": [ + { + "url": "https://github.com/NginxProxyManager/nginx-proxy-manager/issues/5852", + "title": "Address already in use", + "repo": "NginxProxyManager/nginx-proxy-manager", + "created": "2026-09-11T17:46:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/overcast-sh/overcast/issues/2005", + "title": "test flake: TestRunTask_withDocker_debuggerInspectorAnswersThroughTheProxy fails with 'address already in use' when Docker publishes the debug port", + "repo": "overcast-sh/overcast", + "created": "2026-09-20T04:29:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tiliondev/fortress/issues/38", + "title": "Container self-exits with \"socat ... bind :9222: Address already in use\" after 1-2 requests", + "repo": "tiliondev/fortress", + "created": "2026-09-17T15:14:06Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/microsoft/aspire/issues/19014", + "title": "[CI Failure] Flaky: AzureSqlPrincipalReconciliationTests fail because SqlServerContainerFixture cannot bind port 1433 (address already in use)", + "repo": "microsoft/aspire", + "created": "2026-08-05T16:15:39Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kavix/why/issues/8", + "title": "[Adapter] Docker Diagnostic Adapter: why docker compose up", + "repo": "kavix/why", + "created": "2026-09-20T03:39:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/microsoft/aspire/issues/12247", + "title": "`dotnet run` fails with \"address already in use\" for fixed external ports via `.WithEndpoint`", + "repo": "microsoft/aspire", + "created": "2025-10-21T12:59:06Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/tobychui/zoraxy/issues/1117", + "title": "[BUG] Cannot generate certificate from ZeroSSL. listen tcp :56563: bind: address already in use", + "repo": "tobychui/zoraxy", + "created": "2026-04-14T08:28:51Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/moby/moby/issues/47944", + "title": "False address already in use", + "repo": "moby/moby", + "created": "2024-06-10T18:21:41Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/moby/moby/issues/53153", + "title": "28->29 Regression: RootlessKit PortManager.AddPort(): listen tcp4 0.0.0.0:32769: bind: address already in use", + "repo": "moby/moby", + "created": "2026-07-23T15:14:09Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/ostis-apps/nika/issues/192", + "title": "Error. Address already in use.", + "repo": "ostis-apps/nika", + "created": "2023-01-04T13:39:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/aiordache/demos/issues/2", + "title": "address already in use", + "repo": "aiordache/demos", + "created": "2021-06-17T09:20:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/stilliard/docker-pure-ftpd/issues/159", + "title": "bind: Address already in use", + "repo": "stilliard/docker-pure-ftpd", + "created": "2021-04-26T19:03:01Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/EtherealEngine/Digital-Beings/issues/592", + "title": "address already in use", + "repo": "EtherealEngine/Digital-Beings", + "created": "2023-10-14T12:24:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/aschmelyun/subvert/issues/38", + "title": "Docker Install Error: bind: address already in use.", + "repo": "aschmelyun/subvert", + "created": "2024-06-25T19:14:26Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/JunYupK/CDC-PipeLine-With-Kafka/issues/12", + "title": "[Docker] docker oserror: [errno 98] address already in use", + "repo": "JunYupK/CDC-PipeLine-With-Kafka", + "created": "2025-01-23T00:59:24Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/getumbrel/umbrel/issues/2213", + "title": "tailscale serve claims ports with no coordination against app_proxy's Docker port-publish \u2014 causes app containers to fail with \"address already in use\"", + "repo": "getumbrel/umbrel", + "created": "2026-08-28T18:28:01Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/localagi/gpt-code-ui-docker/issues/1", + "title": "Address already in use, Connection refused ", + "repo": "localagi/gpt-code-ui-docker", + "created": "2023-07-12T08:32:42Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/jasonacox/Powerwall-Dashboard/issues/605", + "title": " failed to bind port - address already in use", + "repo": "jasonacox/Powerwall-Dashboard", + "created": "2025-04-02T23:00:31Z", + "state": "open", + "comments": 19, + "verified": true + }, + { + "url": "https://github.com/aden-hive/hive/issues/6968", + "title": "[Bug]:error while attempting to bind on address ('127.0.0.1', 8787): address already in use", + "repo": "aden-hive/hive", + "created": "2026-04-07T05:19:20Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/microsoft/WSL/issues/40984", + "title": "[WSL 2.9.3] Docker fails to bind ports with \"address already in use\" when networkingMode=mirrored is enabled", + "repo": "microsoft/WSL", + "created": "2026-07-02T17:10:09Z", + "state": "open", + "comments": 28, + "verified": true + }, + { + "url": "https://github.com/hashicorp/vagrant-vmware-desktop/issues/96", + "title": "VMWare Utility address already in use", + "repo": "hashicorp/vagrant-vmware-desktop", + "created": "2021-11-11T07:59:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/dmohanja/GT7Monitor/issues/5", + "title": "Error Address already in use", + "repo": "dmohanja/GT7Monitor", + "created": "2025-03-04T03:24:57Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Banh-Canh/docker-FMD2/issues/13", + "title": "[errno 98] Address already in use", + "repo": "Banh-Canh/docker-FMD2", + "created": "2023-11-04T20:50:35Z", + "state": "open", + "comments": 42, + "verified": true + }, + { + "url": "https://github.com/canonical/edgex-snap-testing/issues/118", + "title": "Bind address already in use", + "repo": "canonical/edgex-snap-testing", + "created": "2022-08-15T06:58:14Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/bigcommerce/stencil-cli/issues/1366", + "title": "Docker: will not start, Error: listen EADDRINUSE: address already in use :::3001", + "repo": "bigcommerce/stencil-cli", + "created": "2026-04-11T18:23:23Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/qdm12/port-checker/issues/13", + "title": "Fatal error: starting http server: listen tcp :: bind: address already in use", + "repo": "qdm12/port-checker", + "created": "2026-01-16T09:04:10Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/lgsvl/lanefollowing/issues/17", + "title": " what(): bind: Address already in use", + "repo": "lgsvl/lanefollowing", + "created": "2022-03-03T09:55:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/lgsvl/simulator/issues/2009", + "title": " what(): bind: Address already in use", + "repo": "lgsvl/simulator", + "created": "2022-03-03T09:55:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/kata-containers/kata-containers/issues/6427", + "title": "error=\"listen unix /run/kata/test/shim-monitor.sock: bind: address already in use", + "repo": "kata-containers/kata-containers", + "created": "2023-03-08T12:51:40Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/KurtzL/nestjs-temporal/issues/54", + "title": "Worker restarts: address already in use", + "repo": "KurtzL/nestjs-temporal", + "created": "2024-06-10T08:17:37Z", + "state": "open", + "comments": 2, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 3792 +} \ No newline at end of file diff --git a/bench/data/app-config-env-missing-at-runtime.json b/bench/data/app-config-env-missing-at-runtime.json new file mode 100644 index 0000000..8228c50 --- /dev/null +++ b/bench/data/app-config-env-missing-at-runtime.json @@ -0,0 +1,280 @@ +{ + "category": "app config/env missing at runtime", + "rule": "(learned)", + "query": "\"Database is uninitialized and superuser password is not specified\" is:issue created:>=2021-01-01", + "total": 118, + "sample": [ + { + "url": "https://github.com/attevon-llc/OpenTranscribe/issues/961", + "title": "fix(docker): a --fresh stack started from a git worktree fails twice \u2014 no .env, and the second Vite dev server hits EMFILE", + "repo": "attevon-llc/OpenTranscribe", + "created": "2026-09-20T20:01:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/open-horizon-services/service-postgresql/issues/5", + "title": "ERROR: Error message being thrown in docker logs", + "repo": "open-horizon-services/service-postgresql", + "created": "2025-04-08T15:18:34Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Crivaledaz/Mattermost-LDAP/issues/82", + "title": "Database not being created in container?", + "repo": "Crivaledaz/Mattermost-LDAP", + "created": "2021-11-02T16:00:52Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/qdrtech/self-hosted-ai/issues/3", + "title": "Postgress database is uninitilized", + "repo": "qdrtech/self-hosted-ai", + "created": "2024-12-22T22:48:22Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/mattermost/docker/issues/163", + "title": "Any support with podman-compose?", + "repo": "mattermost/docker", + "created": "2025-03-06T06:39:06Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/asc-lab/dotnetcore-microservices-poc/issues/58", + "title": "Unable to start Postgres from infra-run.sh file ", + "repo": "asc-lab/dotnetcore-microservices-poc", + "created": "2023-08-29T13:20:03Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/divio/divio-cli/issues/243", + "title": "Database configuration in `divio app setup` not working correctly", + "repo": "divio/divio-cli", + "created": "2021-10-28T14:01:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker-library/postgres/issues/1339", + "title": "Container in Ubuntu aarch64 machine cannot use Docker Secrets feature", + "repo": "docker-library/postgres", + "created": "2025-05-08T07:36:31Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/satoshipay/docker-stellar-core/issues/33", + "title": "Issues with initializing db", + "repo": "satoshipay/docker-stellar-core", + "created": "2021-06-26T22:39:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/delner/docker-training/issues/1", + "title": "Postgres needs POSTGRES_PASSWORD at startup", + "repo": "delner/docker-training", + "created": "2021-01-12T07:58:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/akornatskyy/scheduler/issues/815", + "title": "Docker Compose instructions are not instructions", + "repo": "akornatskyy/scheduler", + "created": "2022-12-13T07:45:21Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/hashicorp/waypoint/issues/2975", + "title": "environment variables in waypoint.hcl not getting passed to the docker deployed container ", + "repo": "hashicorp/waypoint", + "created": "2022-02-03T04:48:11Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/haswanth13901/Zenoscribe/issues/50", + "title": "Document the Dependabot secret store in docs/github-repo-settings.md \u00a72", + "repo": "haswanth13901/Zenoscribe", + "created": "2026-08-27T07:13:13Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/shamedgh/confine/issues/14", + "title": "Options in image input file (`images.json`) are not parsed correctly", + "repo": "shamedgh/confine", + "created": "2023-05-05T19:43:33Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/wtfloris/hestia/issues/80", + "title": "Generate reaction message that can be easily copied", + "repo": "wtfloris/hestia", + "created": "2025-05-06T17:53:11Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/dotnet/tye/issues/1255", + "title": "Tye on Podman with Postgres couldn't inject environment variables", + "repo": "dotnet/tye", + "created": "2021-12-30T08:04:02Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/taimg1/shipkit/issues/19", + "title": "Only KAMAL_REGISTRY_PASSWORD reaches Kamal: every other declared secret silently resolves to empty", + "repo": "taimg1/shipkit", + "created": "2026-09-16T17:58:15Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dyne/reflow-os/issues/25", + "title": "Initialization fails on MACOS with readme instructions", + "repo": "dyne/reflow-os", + "created": "2022-01-14T11:54:21Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/metanull/appsec-scout-2/issues/508", + "title": "Park the postgres service behind the local-db profile in docker-compose.ghcr.yml", + "repo": "metanull/appsec-scout-2", + "created": "2026-09-14T15:50:14Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/testcontainers/testcontainers-native/issues/69", + "title": "Failed container starts aren't always reported", + "repo": "testcontainers/testcontainers-native", + "created": "2026-02-02T21:02:34Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/6760", + "title": "Unable to bind to address other than 127.0.0.1 or 0.0.0.0", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2024-04-23T22:09:35Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/oikawa-d/task_management/issues/481", + "title": "[task] CD\u5ec3\u6b62\u65b9\u91dd\u3078\u306e\u5207\u308a\u66ff\u3048\u3068\u5c06\u6765\u306erunner\u624b\u9806\u6574\u7406", + "repo": "oikawa-d/task_management", + "created": "2026-09-15T06:25:15Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/trydirect/stacker/issues/240", + "title": "stacker deploy --target server writes every project to the same remote path, causing real cross-project deployment damage", + "repo": "trydirect/stacker", + "created": "2026-08-21T11:34:59Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/EnterpriseDB/docs/issues/6920", + "title": "Regarding \"Installing PostgreSQL in a Docker container on your local machine\"", + "repo": "EnterpriseDB/docs", + "created": "2025-07-25T04:49:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/clertonraf/satzwerk/issues/315", + "title": "Production 'satzwerk' Portainer stack has no DB_PASSWORD/JWT_SECRET configured - backend+postgres have never actually run on 192.168.0.110", + "repo": "clertonraf/satzwerk", + "created": "2026-09-15T10:09:25Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/coollabsio/coolify/issues/9029", + "title": "[Bug]: PR Preview: POSTGRES_PASSWORD interpolation fails because DB_PASSWORD is not injected into .env", + "repo": "coollabsio/coolify", + "created": "2026-03-18T13:37:19Z", + "state": "closed", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/projectcaluma/alexandria/issues/421", + "title": "Quick start not working", + "repo": "projectcaluma/alexandria", + "created": "2024-01-18T12:14:33Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/alchemy-run/alchemy/issues/1117", + "title": "Docker.Container passes environment names without values", + "repo": "alchemy-run/alchemy", + "created": "2026-08-06T06:56:24Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/rajnathsah/smartflow-engine/issues/8", + "title": "Error in starting application using docker compose", + "repo": "rajnathsah/smartflow-engine", + "created": "2026-06-03T03:17:23Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/s3rius/FastAPI-template/issues/174", + "title": "Project starts with Docker error.", + "repo": "s3rius/FastAPI-template", + "created": "2023-06-22T09:04:10Z", + "state": "open", + "comments": 23, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 118 +} \ No newline at end of file diff --git a/bench/data/bind--dir-onto-file.json b/bench/data/bind--dir-onto-file.json new file mode 100644 index 0000000..7a9f5ae --- /dev/null +++ b/bench/data/bind--dir-onto-file.json @@ -0,0 +1,280 @@ +{ + "category": "bind: dir onto file", + "rule": "mounts.bind", + "query": "\"Are you trying to mount a directory onto a file\" is:issue created:>=2021-01-01", + "total": 707, + "sample": [ + { + "url": "https://github.com/nothingmn/echonotes/issues/2", + "title": "summarize-notes.md: not a directory: unknown: Are you trying to mount a directory onto a file", + "repo": "nothingmn/echonotes", + "created": "2025-07-27T21:18:27Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/portainer/portainer/issues/11023", + "title": "Git Compose Deploy Issue - flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file", + "repo": "portainer/portainer", + "created": "2024-01-27T03:13:20Z", + "state": "open", + "comments": 13, + "verified": true + }, + { + "url": "https://github.com/open-webui/oikb/issues/116", + "title": "Docker and .oikb.yaml", + "repo": "open-webui/oikb", + "created": "2026-09-03T06:51:28Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/bassmaster187/TeslaLogger/issues/999", + "title": "Error after starting docker-compose - Are you trying to mount a directory onto a file (or vice-versa)?", + "repo": "bassmaster187/TeslaLogger", + "created": "2023-04-29T17:48:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/pneumaticapp/pneumaticworkflow/issues/336", + "title": "Docker fails to run: seaweedfs-filer fails to mount filer.toml", + "repo": "pneumaticapp/pneumaticworkflow", + "created": "2026-08-11T15:08:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/GispoCoding/geoviz-notebooks/issues/48", + "title": "Restarting server with docker-compose may crash with \"Are you trying to mount a directory onto a file (or vice-versa)?\"", + "repo": "GispoCoding/geoviz-notebooks", + "created": "2022-01-24T10:49:47Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/moesnow/March7thAssistant/issues/1187", + "title": "[Bug]:\u4f7f\u7528\u9884\u7f16\u8bd1\u955c\u50cf\u65f6\u5c06config\u6587\u4ef6\u521b\u5efa\u6210\u6587\u4ef6\u5939", + "repo": "moesnow/March7thAssistant", + "created": "2026-08-19T11:39:52Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/NeonGeckoCom/neon-hub-installer/issues/31", + "title": "[BUG] Issues in Cloud Deployment docs", + "repo": "NeonGeckoCom/neon-hub-installer", + "created": "2026-08-19T00:52:21Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/bililive-go/bililive-go/issues/811", + "title": "\u4f7f\u7528docker-compose\u90e8\u7f72\u65f6\uff0c\u7a0b\u5e8f\u628aconfig.docker.yml\u6587\u4ef6\u521b\u5efa\u6210\u4e86\u540d\u4e3a\u6587\u4ef6\u5939\uff0c\u5bfc\u81f4\u7a0b\u5e8f\u62a5\u9519", + "repo": "bililive-go/bililive-go", + "created": "2024-11-28T13:56:34Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/RyuKosei/PACEbench/issues/1", + "title": "[CORAZA-WAF] Benchmark cannot launch", + "repo": "RyuKosei/PACEbench", + "created": "2026-09-03T00:10:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/souvikg10/rasa_multi_bot/issues/3", + "title": "ERROR: for rasa_multi_bot-master_rasa_fr_1", + "repo": "souvikg10/rasa_multi_bot", + "created": "2021-01-26T05:11:11Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/qcgzxw/ebook-sender-bot/issues/63", + "title": "ERROR: Encountered errors while bringing up the project.", + "repo": "qcgzxw/ebook-sender-bot", + "created": "2023-01-28T09:07:03Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/robincher/docker-compose-ghost-quickstart/issues/1", + "title": "Starting ghost ... error", + "repo": "robincher/docker-compose-ghost-quickstart", + "created": "2021-07-03T12:36:26Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/linagora/linshare/issues/280", + "title": "Some docker container not running during installation ", + "repo": "linagora/linshare", + "created": "2023-08-18T07:08:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/shamhi/HamsterKombatBot/issues/1567", + "title": "ERROR: for HamsterKombatBot Cannot start service bot: failed", + "repo": "shamhi/HamsterKombatBot", + "created": "2024-07-14T11:53:37Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/angristan/feedbin-docker/issues/73", + "title": "Can't start Caddy container", + "repo": "angristan/feedbin-docker", + "created": "2021-06-09T02:14:19Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/setiseta/docker-librenms/issues/44", + "title": "Failed to mount volume of maridb", + "repo": "setiseta/docker-librenms", + "created": "2022-01-14T03:25:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/canyanio/janus-gateway-docker/issues/29", + "title": "Error running docker compose", + "repo": "canyanio/janus-gateway-docker", + "created": "2022-03-18T12:04:30Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Open-Location-Stack/open-location-hub/issues/59", + "title": "local-hub want to create clickhouse but config files appear as directories", + "repo": "Open-Location-Stack/open-location-hub", + "created": "2026-06-26T09:10:08Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/winboat-org/winboat/issues/354", + "title": "Command failed: docker container start WinBoat -> ventoy (\"Winboat Guest Api offline - Container exiting\")", + "repo": "winboat-org/winboat", + "created": "2025-10-16T14:13:49Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/mariomare22/docker-pihole-unbound/issues/17", + "title": "Cannot start service pihole: OCI runtime create failed: (Happening on Pi4)", + "repo": "mariomare22/docker-pihole-unbound", + "created": "2023-04-28T01:39:07Z", + "state": "open", + "comments": 15, + "verified": true + }, + { + "url": "https://github.com/denverdino/lxcfs-admission-webhook/issues/17", + "title": "pod \u51fa\u73b0CrashLoopBackOff", + "repo": "denverdino/lxcfs-admission-webhook", + "created": "2021-04-01T11:35:16Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/exment-git/docker-exment/issues/3", + "title": "Docker toolbox \u3067\u306f\u52d5\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002", + "repo": "exment-git/docker-exment", + "created": "2021-12-23T16:08:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/paschmann/changd/issues/3", + "title": "Problem starting ui_server", + "repo": "paschmann/changd", + "created": "2022-01-19T12:35:29Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/4286", + "title": "Failure to start container with file mounts after windows reboot or wsl restart", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2023-03-27T11:34:01Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/BillyOutlast/rocm-automated/issues/2", + "title": "Error while deploying in portainer", + "repo": "BillyOutlast/rocm-automated", + "created": "2026-02-07T06:03:30Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dwaaan/HRConvert2-Docker/issues/11", + "title": "Error: The command failed, on Unraid server, please help!", + "repo": "dwaaan/HRConvert2-Docker", + "created": "2022-09-20T02:22:00Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/stonier/groot_rocker_extensions/issues/27", + "title": "Ssh temporary agents don't persist (conflicts with --persistant)", + "repo": "stonier/groot_rocker_extensions", + "created": "2021-04-02T16:31:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/anse-app/chatgpt-demo/issues/110", + "title": "docker: Error response from daemon: failed to create shim task", + "repo": "anse-app/chatgpt-demo", + "created": "2023-03-05T15:11:35Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/Cloud-RF/tak-server/issues/85", + "title": "Error during setup", + "repo": "Cloud-RF/tak-server", + "created": "2026-05-06T14:24:22Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 707 +} \ No newline at end of file diff --git a/bench/data/bind--source-does-not-exist.json b/bench/data/bind--source-does-not-exist.json new file mode 100644 index 0000000..8edccb7 --- /dev/null +++ b/bench/data/bind--source-does-not-exist.json @@ -0,0 +1,280 @@ +{ + "category": "bind: source does not exist", + "rule": "mounts.bind", + "query": "\"bind source path does not exist\" is:issue created:>=2021-01-01", + "total": 544, + "sample": [ + { + "url": "https://github.com/BenjaminBenetti/fleet-man/issues/241", + "title": "macOS: intermittent 'bind source path does not exist' for freshly recreated workspace dirs (Docker Desktop VirtioFS race)", + "repo": "BenjaminBenetti/fleet-man", + "created": "2026-07-21T18:36:48Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tribut/homeassistant-docker-venv/issues/35", + "title": "--mount: \"bind source path does not exist\", but it does", + "repo": "tribut/homeassistant-docker-venv", + "created": "2024-08-03T07:45:27Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/coder/coder/issues/19708", + "title": "bug: `coder_devcontainer` fails with \"bind source path does not exist\" for existing directories in Kubernetes deployment", + "repo": "coder/coder", + "created": "2025-09-04T22:08:23Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/LucienShui/PasteMe/issues/127", + "title": "invalid mount config for type \"bind\": bind source path does not exist", + "repo": "LucienShui/PasteMe", + "created": "2021-10-27T01:45:13Z", + "state": "open", + "comments": 17, + "verified": true + }, + { + "url": "https://github.com/common-workflow-language/cwltool/issues/1887", + "title": "bind source path does not exist - cwltool keeps waiting / running does not stop", + "repo": "common-workflow-language/cwltool", + "created": "2023-08-17T13:47:58Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/XedinUnknown/red-acre-test-a-1/issues/4", + "title": "invalid mount config for type \"bind\": bind source path does not exist", + "repo": "XedinUnknown/red-acre-test-a-1", + "created": "2023-07-13T17:13:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/derio-net/super-fr/issues/578", + "title": "fr isolation up: a failed postCreate leaves worktree + container with no state record", + "repo": "derio-net/super-fr", + "created": "2026-09-22T23:05:52Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/devcontainers/features/issues/952", + "title": "invalid mount config for type \"bind\": bind source path does not exist: /var/run/docker.sock", + "repo": "devcontainers/features", + "created": "2024-04-17T18:00:03Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/MCSManager/MCSManager/issues/2230", + "title": "[Bug Report] Docker\u90e8\u7f72MCSM\uff0c\u65e0\u6cd5\u7528\u5bb9\u5668\u5316\u8fd0\u884c\u5e7b\u517d\u5e15\u9c81", + "repo": "MCSManager/MCSManager", + "created": "2026-07-10T15:21:39Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/devcontainers/cli/issues/613", + "title": "Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist", + "repo": "devcontainers/cli", + "created": "2023-08-08T21:40:32Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/common-workflow-language/cwltool/issues/1433", + "title": "docker: Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist", + "repo": "common-workflow-language/cwltool", + "created": "2021-04-08T13:50:05Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/IMAP-Science-Operations-Center/imap_L3_processing/issues/191", + "title": "BUG - GLOWS integration tests fail in CI", + "repo": "IMAP-Science-Operations-Center/imap_L3_processing", + "created": "2026-09-04T13:22:42Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/ResearchDataCom/actions/issues/10", + "title": "Testing fails when run via Act due to nested volume mounts", + "repo": "ResearchDataCom/actions", + "created": "2026-07-30T15:44:39Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/zdeneksvarc/postal-tls/issues/3", + "title": "Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt", + "repo": "zdeneksvarc/postal-tls", + "created": "2023-04-27T13:29:27Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/docker/awesome-compose/issues/412", + "title": "[fix] Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /home/traefik/dockerWork/workpress/wordpress", + "repo": "docker/awesome-compose", + "created": "2024-01-15T02:38:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/harbor-framework/harbor/issues/2097", + "title": "\u3010Bug\u3011Docker fails to identiry the local directory", + "repo": "harbor-framework/harbor", + "created": "2026-06-25T14:36:48Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/ospaarmann/exdgraph/issues/30", + "title": "Cannot create container for service", + "repo": "ospaarmann/exdgraph", + "created": "2022-04-20T07:56:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DefuzeX-AI/AgentBehaviorBench/issues/116", + "title": "[runtime] Docker interceptor temp paths are not mountable from Colima on macOS", + "repo": "DefuzeX-AI/AgentBehaviorBench", + "created": "2026-09-20T16:48:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/cli/issues/7176", + "title": "Truncating log lines at 75 characters makes them useless.", + "repo": "docker/cli", + "created": "2026-08-11T16:53:51Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/arifulhb/laravel-docker-app/issues/2", + "title": "Error on Docker-compose up...can't find directory for Volume Mount", + "repo": "arifulhb/laravel-docker-app", + "created": "2021-12-17T19:31:28Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/circlefin/arc-node/issues/51", + "title": "Main issue with prometheus metrics endpoint ports", + "repo": "circlefin/arc-node", + "created": "2026-05-01T03:37:33Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/fadhilkurnia/xdn/issues/82", + "title": "primary-backup service launch livelocks: duplicate pb-init threads race the recorder's bind-mount wipe", + "repo": "fadhilkurnia/xdn", + "created": "2026-08-20T06:31:28Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/eclipse-enclave/enclave/issues/41", + "title": "Deleting disposable cache data can break Enclave sessions", + "repo": "eclipse-enclave/enclave", + "created": "2026-08-10T23:47:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/enclaver-io/enclaver/issues/241", + "title": "Docker bind error: : invalid mount config for type \"bind\"", + "repo": "enclaver-io/enclaver", + "created": "2025-11-08T00:17:48Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/bytedance/deer-flow/issues/2207", + "title": "\u5728win\u7cfb\u7edfwsl\u4e2d\u4f7f\u7528make docker-start\u542f\u52a8\uff0c\u6c99\u7bb1\u5bb9\u5668\u65e0\u6cd5\u6b63\u5e38\u6302\u8f7d\uff0c\u5bfc\u81f4\u6280\u80fd\u65e0\u6cd5\u4f7f\u7528", + "repo": "bytedance/deer-flow", + "created": "2026-04-14T02:54:22Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/shonansurvivors/laravel-fargate-app/issues/27", + "title": "4.23\u3000\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u306e\u5b9f\u884c", + "repo": "shonansurvivors/laravel-fargate-app", + "created": "2022-11-08T07:25:23Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/hubblo-org/publications/issues/1", + "title": "Erreur ", + "repo": "hubblo-org/publications", + "created": "2021-11-04T14:27:07Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/devcontainers/spec/issues/335", + "title": "Proposal: Predefined variables for user's home directory", + "repo": "devcontainers/spec", + "created": "2023-11-07T23:53:58Z", + "state": "open", + "comments": 21, + "verified": true + }, + { + "url": "https://github.com/MCSManager/MCSManager/issues/2198", + "title": "[Bug Report] \u5728 daemon \u5bb9\u5668\u4e2d\u4ee5\u975e root \u6743\u9650\u8fd0\u884c daemon \uff0c\u542f\u52a8 docker \u5b9e\u4f8b\u65f6\uff0c\u6302\u8f7d\u66f4\u591a\u76ee\u5f55\u4f1a\u51fa\u73b0\u521b\u5efa\u6587\u4ef6\u5939\u5931\u8d25\u7684\u95ee\u9898", + "repo": "MCSManager/MCSManager", + "created": "2026-06-05T01:37:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tabaresjc/HeadUP/issues/25", + "title": "Cannot run the docker...", + "repo": "tabaresjc/HeadUP", + "created": "2021-01-05T11:19:26Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 544 +} \ No newline at end of file diff --git a/bench/data/build--buildkit-required.json b/bench/data/build--buildkit-required.json new file mode 100644 index 0000000..40573b1 --- /dev/null +++ b/bench/data/build--buildkit-required.json @@ -0,0 +1,280 @@ +{ + "category": "build: BuildKit required", + "rule": "build.buildkit", + "query": "\"requires BuildKit\" is:issue created:>=2021-01-01", + "total": 443, + "sample": [ + { + "url": "https://github.com/gonuit/heroku-docker-deploy/issues/16", + "title": "Docker requires BuildKit", + "repo": "gonuit/heroku-docker-deploy", + "created": "2021-10-03T05:55:30Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/crazy-goat/go-mesi/issues/442", + "title": "[tests] servers/test-server image unbuildable without the buildx component \u2014 COPY --chmod requires BuildKit (docker build, DOCKER_BUILDKIT=1 and docker compose all fail locally)", + "repo": "crazy-goat/go-mesi", + "created": "2026-09-22T11:49:33Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/compose/issues/13695", + "title": "[BUG] Confusing error messages when Bake mode requires BuildKit but it's not enabled", + "repo": "docker/compose", + "created": "2026-04-01T07:18:21Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/devspace-sh/devspace/issues/3293", + "title": "Support buildkit backend for local builds", + "repo": "devspace-sh/devspace", + "created": "2026-08-10T09:09:03Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/airvzxf/ftp-deployment-action/issues/210", + "title": "[EPIC] Dockerfile/Makefile hardening audit (F2 round)", + "repo": "airvzxf/ftp-deployment-action", + "created": "2026-09-03T20:31:37Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/NVIDIA/NemoClaw/issues/9921", + "title": "Hermes Portable image build uses a BuildKit-only COPY option", + "repo": "NVIDIA/NemoClaw", + "created": "2026-08-21T20:02:18Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/airvzxf/ftp-deployment-action/issues/222", + "title": "[EPIC] workflows hardening audit (F2 round)", + "repo": "airvzxf/ftp-deployment-action", + "created": "2026-09-03T20:32:55Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ScottRBK/eval-harness/issues/5", + "title": "Build eval-owned Docker images with BuildKit", + "repo": "ScottRBK/eval-harness", + "created": "2026-08-09T09:13:23Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dromara/Jpom/issues/49", + "title": "\u4fee\u6539docker demon\u914d\u7f6e\u540e\uff0cdocker\u6784\u5efa\u6ca1\u6709\u4f7f\u7528\u65b0\u914d\u7f6e", + "repo": "dromara/Jpom", + "created": "2023-06-14T12:53:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/NVIDIA/workbench-example-onboarding-project/issues/21", + "title": "Building JupyterLab failed", + "repo": "NVIDIA/workbench-example-onboarding-project", + "created": "2025-10-15T12:24:49Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/portainer/portainer/issues/10482", + "title": "Build Image throws BuildKit error for --chmod", + "repo": "portainer/portainer", + "created": "2023-10-16T11:31:27Z", + "state": "open", + "comments": 12, + "verified": true + }, + { + "url": "https://github.com/NVIDIA/NemoClaw/issues/10007", + "title": "Hermes Portable Dockerfile requires BuildKit-only features on Podman", + "repo": "NVIDIA/NemoClaw", + "created": "2026-08-23T15:18:33Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/airvzxf/ftp-deployment-action/issues/156", + "title": "test(integration): Dockerfile.test-server requires BuildKit but Makefile uses plain 'docker build'", + "repo": "airvzxf/ftp-deployment-action", + "created": "2026-09-03T16:42:32Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/nuriel77/goshimmer-playbook/issues/29", + "title": "Playbook failed while installing Docker image", + "repo": "nuriel77/goshimmer-playbook", + "created": "2021-10-01T12:49:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Mollomm1/NovetusDocker/issues/2", + "title": "container fails to build at step 7/13", + "repo": "Mollomm1/NovetusDocker", + "created": "2025-07-01T18:26:16Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/bmuschko/gradle-docker-plugin/issues/1226", + "title": "RUN --mount=type=bind doesn't work", + "repo": "bmuschko/gradle-docker-plugin", + "created": "2024-11-04T16:38:40Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/night1008/night1008.github.io/issues/71", + "title": "mac + colima + docker-cli \u4e0b --mount build \u5931\u8d25", + "repo": "night1008/night1008.github.io", + "created": "2026-04-21T02:54:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Radiergummi/cetacean/issues/89", + "title": "Add windows nanoserver container image", + "repo": "Radiergummi/cetacean", + "created": "2026-07-01T16:30:51Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/shakacode/react-on-rails-demo-marketplace-rsc/issues/201", + "title": "Follow-up: .controlplane/.dockerignore is never read by docker build", + "repo": "shakacode/react-on-rails-demo-marketplace-rsc", + "created": "2026-09-02T09:52:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/caretdev/iris-python-faker/issues/1", + "title": "Installation error in WSL2", + "repo": "caretdev/iris-python-faker", + "created": "2022-01-08T15:42:17Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Azure/acr/issues/721", + "title": "Allow `buildkit` build in `az acr build`", + "repo": "Azure/acr", + "created": "2023-09-11T07:28:48Z", + "state": "open", + "comments": 14, + "verified": true + }, + { + "url": "https://github.com/jojo243/seafile-docker-arm64/issues/19", + "title": "Buildkit Error", + "repo": "jojo243/seafile-docker-arm64", + "created": "2022-01-05T15:57:36Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ptone/scion/issues/1453", + "title": "fix(build): enable BuildKit in cloudbuild-omni.yaml for --mount support", + "repo": "ptone/scion", + "created": "2026-09-07T12:00:19Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dotnet/dotnet-docker/issues/5654", + "title": "Consider using Docker custom build outputs (`--output`) for generated Dockerfiles and Readmes", + "repo": "dotnet/dotnet-docker", + "created": "2024-07-05T19:00:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/o1-labs/submission-updater/issues/6", + "title": "Restructure the dual-binary Dockerfile: variant stages + directory COPY", + "repo": "o1-labs/submission-updater", + "created": "2026-08-31T15:35:12Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/moby/moby/issues/46727", + "title": "`ADD --checksum` doesn't work with windows builds", + "repo": "moby/moby", + "created": "2023-10-26T08:06:35Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/paulkokos/project-management-dashboard/issues/93", + "title": "Keyboard shortcuts system", + "repo": "paulkokos/project-management-dashboard", + "created": "2025-11-05T03:49:58Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/dotnet/Docker.DotNet/issues/635", + "title": "Docket.DotNet Build Image has undocumented limitations", + "repo": "dotnet/Docker.DotNet", + "created": "2023-05-13T21:13:22Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/fabric8io/docker-maven-plugin/issues/1711", + "title": "Failed to build the docker image on using \"chmod\" option", + "repo": "fabric8io/docker-maven-plugin", + "created": "2023-10-05T18:14:50Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/calpaterson/csvbase/issues/126", + "title": "Will this run on an ARM64 Raspberry Pi?", + "repo": "calpaterson/csvbase", + "created": "2024-06-02T15:20:23Z", + "state": "open", + "comments": 4, + "verified": true + } + ], + "precision": 0.9666666666666667, + "adjusted": 428 +} \ No newline at end of file diff --git a/bench/data/build--copy-failed-legacy.json b/bench/data/build--copy-failed-legacy.json new file mode 100644 index 0000000..7ecf8a3 --- /dev/null +++ b/bench/data/build--copy-failed-legacy.json @@ -0,0 +1,280 @@ +{ + "category": "build: COPY failed legacy", + "rule": "build.context", + "query": "\"COPY failed: file not found in build context\" is:issue created:>=2021-01-01", + "total": 417, + "sample": [ + { + "url": "https://github.com/NekomyaDev/nudge/issues/38", + "title": "Dockerfile build fails: COPY references non-existent runtime/ directory", + "repo": "NekomyaDev/nudge", + "created": "2026-09-23T00:31:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kubespace/kubespace/issues/1", + "title": "COPY failed: file not found in build context or excluded by .dockerignore: stat kubespace: file does not exist", + "repo": "kubespace/kubespace", + "created": "2022-06-14T11:28:08Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/vsoch/cdb/issues/6", + "title": "COPY failed: file not found in build context or excluded by .dockerignore: stat data: file does not exist", + "repo": "vsoch/cdb", + "created": "2021-01-16T16:48:21Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/swarmpit/swarmpit/issues/651", + "title": "COPY failed: file not found in build context or excluded by .dockerignore: stat target/swarmpit.jar: file does not exist", + "repo": "swarmpit/swarmpit", + "created": "2023-01-18T14:34:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tfeldmann/organize/issues/409", + "title": "Dockerfile Image Creation Error : COPY failed: file not found in build context or excluded by .dockerignore: stat organize: file does not exist", + "repo": "tfeldmann/organize", + "created": "2024-08-23T10:32:02Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/rancher/rancher/issues/51500", + "title": "[BUG]COPY failed: file not found in build context or excluded by .dockerignore: stat root/vv/rancher/hack/airgap/go.mod: file does not exist exit status 1", + "repo": "rancher/rancher", + "created": "2025-08-15T03:29:34Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/strandborg/AlsavoCtrl/issues/22", + "title": "Error during docker build - COPY failed: file not found in build context or excluded by .dockerignore: stat alsavo.py: file does not exist", + "repo": "strandborg/AlsavoCtrl", + "created": "2024-01-04T00:45:40Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/eth0izzle/shhgit/issues/101", + "title": "Error docker install \"docker-compose up\"", + "repo": "eth0izzle/shhgit", + "created": "2022-04-30T00:11:47Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/microsoft-foundry/foundry-samples/issues/626", + "title": "Bug: Docker build fails due to missing read_cosmos_data.py in migration directory", + "repo": "microsoft-foundry/foundry-samples", + "created": "2026-03-26T07:09:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/rohitbakoliya/sieve.ai/issues/11", + "title": "\"uploads\" package is missing", + "repo": "rohitbakoliya/sieve.ai", + "created": "2024-01-22T13:30:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/aertslab/scenicplus/issues/604", + "title": "Dockerfile does not build", + "repo": "aertslab/scenicplus", + "created": "2025-09-09T18:51:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/aertslab/scenicplus/issues/213", + "title": "Dockerfile does not build ", + "repo": "aertslab/scenicplus", + "created": "2023-08-24T16:56:12Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/wpdiaries/wordpress-xdebug/issues/2", + "title": "COPY command keeps failing", + "repo": "wpdiaries/wordpress-xdebug", + "created": "2023-11-17T16:32:12Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/IfCodingWereNatural/minimal-nvim/issues/1", + "title": ".cache directory not exist", + "repo": "IfCodingWereNatural/minimal-nvim", + "created": "2023-08-19T13:56:07Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/ChristopherSweeney/RGBD_SIM/issues/1", + "title": "Dockerfile fails because drake_install does not exist", + "repo": "ChristopherSweeney/RGBD_SIM", + "created": "2021-11-15T23:57:48Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/NeodomoEwe/hassio-hotspot/issues/4", + "title": "Cannot install: stat run.sh: file does not exist", + "repo": "NeodomoEwe/hassio-hotspot", + "created": "2023-01-25T21:01:17Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/BeardedTek-com/rtsp2mjpg/issues/2", + "title": "COPY failed (COPY etc to /etc)", + "repo": "BeardedTek-com/rtsp2mjpg", + "created": "2026-02-09T20:22:57Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/CycloneDX/cyclonedx-cli/issues/259", + "title": "Dockerfile Problem", + "repo": "CycloneDX/cyclonedx-cli", + "created": "2022-08-17T03:27:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/accreleus/quasar-images/issues/31", + "title": "benchapp template build fails under the control-plane's dir-scoped context: COPY images/quasar-benchapp/quasar-benchapp expects repo-root context", + "repo": "accreleus/quasar-images", + "created": "2026-08-27T13:03:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RickStrahl/AlbumViewerVNext/issues/17", + "title": "docker-compose fails", + "repo": "RickStrahl/AlbumViewerVNext", + "created": "2023-07-05T09:40:54Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/sberk42/fritzbox_exporter/issues/23", + "title": "Create from Dockerfile - metrics.json / metrics-lua.json cannot be copied", + "repo": "sberk42/fritzbox_exporter", + "created": "2023-01-15T13:02:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/bigornoo/pcloud_docker/issues/1", + "title": "copy failed", + "repo": "bigornoo/pcloud_docker", + "created": "2023-01-12T12:26:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/microsoft/navcontainerhelper/issues/4210", + "title": "[Bug]: Flush-ContainerHelperCache deletes the empty \"my\" folder out of a concurrent New-BcImage build context, breaking parallel builds on a shared host", + "repo": "microsoft/navcontainerhelper", + "created": "2026-09-18T05:19:13Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/NeodomoEwe/hassio-hotspot/issues/5", + "title": "Dockerfile problem on upgrading", + "repo": "NeodomoEwe/hassio-hotspot", + "created": "2023-02-06T01:44:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/IntelSmartEdge/open-developer-experience-kits/issues/1", + "title": "New Release setup failed due to file does not exist", + "repo": "IntelSmartEdge/open-developer-experience-kits", + "created": "2021-10-13T02:59:30Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/ProyectoPAIS/VICOS/issues/2", + "title": "Error building docker image", + "repo": "ProyectoPAIS/VICOS", + "created": "2023-02-09T11:42:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/guojiaxing1995/easy-test/issues/51", + "title": "docker\u6784\u5efa\u62a5\u9519", + "repo": "guojiaxing1995/easy-test", + "created": "2024-05-10T12:12:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/google/ax/issues/364", + "title": "`make build-task-runner` fails: `.dockerignore` excludes `bin/`, which `Dockerfile.task-runner` COPYs from", + "repo": "google/ax", + "created": "2026-09-22T08:40:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/mSorok/SugarRemovalWeb/issues/1", + "title": "docker-compose build fails atm, dependency issue?", + "repo": "mSorok/SugarRemovalWeb", + "created": "2022-08-11T20:19:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/linera-io/linera-protocol/issues/2873", + "title": "issue while docker build", + "repo": "linera-io/linera-protocol", + "created": "2024-11-12T18:29:23Z", + "state": "open", + "comments": 3, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 417 +} \ No newline at end of file diff --git a/bench/data/build--copy-source-not-found.json b/bench/data/build--copy-source-not-found.json new file mode 100644 index 0000000..a0de08e --- /dev/null +++ b/bench/data/build--copy-source-not-found.json @@ -0,0 +1,280 @@ +{ + "category": "build: COPY source not found", + "rule": "build.context", + "query": "\"failed to compute cache key\" \"not found\" is:issue created:>=2021-01-01", + "total": 1421, + "sample": [ + { + "url": "https://github.com/earthly/earthly/issues/1614", + "title": " failed to compute cache key", + "repo": "earthly/earthly", + "created": "2022-01-26T20:51:07Z", + "state": "open", + "comments": 15, + "verified": true + }, + { + "url": "https://github.com/InterviewReady/joy-of-system-design/issues/5", + "title": "failed to solve: failed to compute cache key: \"/yarn.lock\" not found: not found", + "repo": "InterviewReady/joy-of-system-design", + "created": "2023-01-19T08:54:32Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/allofphysicsgraph/ui_v8_website_flask_neo4j/issues/204", + "title": "github action to build container fails due to files needed by Dockerfile but not in git repo", + "repo": "allofphysicsgraph/ui_v8_website_flask_neo4j", + "created": "2026-09-12T17:31:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/loblab/noip-renew/issues/79", + "title": "failed to compute cache key: \"/noip-renew.py\" not found: not found", + "repo": "loblab/noip-renew", + "created": "2021-08-10T20:42:01Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/spliit-app/spliit/issues/235", + "title": "ERROR: failed to solve: failed to compute cache key: \"/next.config.js\": not found", + "repo": "spliit-app/spliit", + "created": "2024-10-03T05:47:08Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/sagostin/gofaxserver/issues/3", + "title": "Dockerfile can't build: COPY go.mod go.sum fails, repo has no go.sum (vendored deps)", + "repo": "sagostin/gofaxserver", + "created": "2026-08-31T22:39:26Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/edusense/edusense/issues/42", + "title": "failed to compute cache key: \"/app/build/examples/edusense/edusense.bin\" not found: not found", + "repo": "edusense/edusense", + "created": "2023-02-03T02:40:02Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/moby/buildkit/issues/4128", + "title": "failed to solve: failed to compute cache key: failed to calculate checksum of ref", + "repo": "moby/buildkit", + "created": "2023-08-09T08:06:59Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/guge199205-byte/QuantMind-oss/issues/3", + "title": "docker compose up \u542f\u52a8\u5931\u8d25", + "repo": "guge199205-byte/QuantMind-oss", + "created": "2026-08-05T10:06:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/weka/export/issues/53", + "title": "Docker build fails with the following: failed to compute cache key: \"/tarball/export/export\" not found: not found", + "repo": "weka/export", + "created": "2023-06-07T19:33:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/analogdevicesinc/microcontroller-hackathon/issues/1", + "title": "Docker container build fail", + "repo": "analogdevicesinc/microcontroller-hackathon", + "created": "2026-08-07T09:13:34Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/PlaiPin/rosclaw/issues/3", + "title": "Packages not found", + "repo": "PlaiPin/rosclaw", + "created": "2026-03-03T06:55:22Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/vuongnguyenbinh/ZaloCRM/issues/4", + "title": "\"/app/backend/prisma.config.ts\": not found", + "repo": "vuongnguyenbinh/ZaloCRM", + "created": "2026-03-28T15:45:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/openremote/openremote/issues/3025", + "title": "Manager Docker build sometimes fails to compute cache key", + "repo": "openremote/openremote", + "created": "2026-07-14T14:47:22Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/fyrlove/r0re/issues/1", + "title": "The Docker build fails because container-android/AGENTS.md is missing", + "repo": "fyrlove/r0re", + "created": "2026-08-11T10:42:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Vynx-Velvet/Flyx-main/issues/20", + "title": "/app/pow_wasm.js missing", + "repo": "Vynx-Velvet/Flyx-main", + "created": "2026-07-19T18:33:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/crossplane-contrib/provider-palette/issues/115", + "title": "Docker image build fails: terraform-provider-spectrocloud zip not found in build context (linux_arm64)", + "repo": "crossplane-contrib/provider-palette", + "created": "2026-09-01T07:22:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/coleschaffer/Gabagool/issues/3", + "title": "failed to solve: failed to compute cache key: failed to calculate checksum of ref 686290d4-7997-43f4-8fd3-a67552da50d3::78wd65fbco1b74i7qffzq6jhr: \"/app/public\": not found", + "repo": "coleschaffer/Gabagool", + "created": "2025-12-26T06:25:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/pyflink/playgrounds/issues/22", + "title": "failed to compute cache key: \"/flink-sql-connector-kafka_2.11-1.13.0.jar\" not found: not found", + "repo": "pyflink/playgrounds", + "created": "2022-06-16T07:03:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/anmonteiro/aws-lambda-ocaml-runtime/issues/70", + "title": "How to resolve failed to compute cache key: \"/esy.lock\" not found: not found error when running build.sh", + "repo": "anmonteiro/aws-lambda-ocaml-runtime", + "created": "2023-04-23T22:55:44Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Hochfrequenz/ahb-tabellen/issues/395", + "title": "docs are oudated?: cannot start local server: failed to compute cache key / azure-mock not found", + "repo": "Hochfrequenz/ahb-tabellen", + "created": "2025-01-25T09:31:31Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/ClawixAI/clawix/issues/58", + "title": "**Bug: `egress-firewall.sh` path mismatch in python-runner Dockerfile**", + "repo": "ClawixAI/clawix", + "created": "2026-08-08T06:42:08Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/onyx-dot-app/onyx/issues/14177", + "title": "backend/Dockerfile: chown -R onyx:onyx /app runs before /app exists (introduced in #6390), fails every fresh build", + "repo": "onyx-dot-app/onyx", + "created": "2026-08-23T08:37:36Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/kieranroneill/q-rewrite/issues/9", + "title": "Feedback Julian", + "repo": "kieranroneill/q-rewrite", + "created": "2026-08-21T09:38:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/paolorechia/open-code-gen-api/issues/1", + "title": "Models not found", + "repo": "paolorechia/open-code-gen-api", + "created": "2023-01-09T10:48:04Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Aaronhrndz/antigravity-cli-addon/issues/2", + "title": "Build fails for version 1.8.8 on aarch64: \"/run_agy.sh\": not found", + "repo": "Aaronhrndz/antigravity-cli-addon", + "created": "2026-06-19T10:03:09Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/VisionRush/DeepFakeDefenders/issues/4", + "title": "ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 338532d9-772c-451b-ba3d-c9fd060590f3::bivmsdw8vm9wgmzzrffunihup: \"/pre_model\": not found", + "repo": "VisionRush/DeepFakeDefenders", + "created": "2024-09-04T02:05:33Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/GitDakky/mitsubishi-ae200-hass/issues/2", + "title": "Installation Failure issue: \"/pymelans\": not found on Home Assistant OS and kills integration", + "repo": "GitDakky/mitsubishi-ae200-hass", + "created": "2026-07-17T01:34:20Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Goblin-Airdrops/allora-coin-prediction-node-goblin/issues/1", + "title": ".pth model ERROR not found", + "repo": "Goblin-Airdrops/allora-coin-prediction-node-goblin", + "created": "2024-09-22T18:32:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/biobricks-ai/toxtransformer/issues/3", + "title": "selfies_property_val_tokenizer not found", + "repo": "biobricks-ai/toxtransformer", + "created": "2025-10-14T07:52:40Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 1421 +} \ No newline at end of file diff --git a/bench/data/build--outside-build-context.json b/bench/data/build--outside-build-context.json new file mode 100644 index 0000000..04c230a --- /dev/null +++ b/bench/data/build--outside-build-context.json @@ -0,0 +1,280 @@ +{ + "category": "build: outside build context", + "rule": "build.context", + "query": "\"forbidden path outside the build context\" is:issue created:>=2021-01-01", + "total": 65, + "sample": [ + { + "url": "https://github.com/jtfrey/xdmod-container/issues/3", + "title": "COPY failed: forbidden path outside the build context: XDMoD-start", + "repo": "jtfrey/xdmod-container", + "created": "2021-09-22T11:30:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/aws-samples/iot-network-traffic-control-and-load-testing-simulator/issues/6", + "title": "npx cdk deploy IoTFaultInjectionSimulatorStack", + "repo": "aws-samples/iot-network-traffic-control-and-load-testing-simulator", + "created": "2023-06-27T11:29:13Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/PacktPublishing/Event-Driven-Architecture-in-Golang/issues/9", + "title": "Docker build fails", + "repo": "PacktPublishing/Event-Driven-Architecture-in-Golang", + "created": "2023-08-23T05:01:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/myfjdthink/doris-docker-compose/issues/1", + "title": "which version of docker-compose and docker used?", + "repo": "myfjdthink/doris-docker-compose", + "created": "2022-08-15T13:41:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/intuinno/conceptvector/issues/25", + "title": "docker-compose up throws Error", + "repo": "intuinno/conceptvector", + "created": "2021-09-27T12:25:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Algorithmic-Battle/algobattle/issues/168", + "title": "Allow for shared implementations", + "repo": "Algorithmic-Battle/algobattle", + "created": "2024-10-19T21:21:49Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/davglass/bambu-farm/issues/4", + "title": "Cannot even start it", + "repo": "davglass/bambu-farm", + "created": "2024-03-27T15:11:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/GoogleContainerTools/skaffold/issues/7504", + "title": "build can not use dockerfiles out of the docker context", + "repo": "GoogleContainerTools/skaffold", + "created": "2022-06-05T01:35:46Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/AxonIQ/axon-observability-demo/issues/1", + "title": "docker-compose build FAILED", + "repo": "AxonIQ/axon-observability-demo", + "created": "2022-11-09T13:59:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/david-svitov/HAHA/issues/2", + "title": "Edits needed to the Dockerfile", + "repo": "david-svitov/HAHA", + "created": "2024-04-05T00:14:46Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/hashicorp/waypoint/issues/2711", + "title": "Docker build: Fails if both 'dockerfile' and 'context' point outside of current dir tree", + "repo": "hashicorp/waypoint", + "created": "2021-11-10T21:20:28Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/moby/buildkit/issues/2130", + "title": "BuildKit should provide clear error if files are referenced outside build context", + "repo": "moby/buildkit", + "created": "2021-05-21T15:50:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/moby/buildkit/issues/2131", + "title": "BuildKit uses wrong path when referencing files outside of build context", + "repo": "moby/buildkit", + "created": "2021-05-21T15:52:16Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/tjmlabs/AgentRun/issues/20", + "title": "not executing the python code ; resulting in internal server error", + "repo": "tjmlabs/AgentRun", + "created": "2025-02-05T02:35:27Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/OktopUSP/oktopus/issues/379", + "title": "Build of containers fails due to 'forbidden path outside the build context'", + "repo": "OktopUSP/oktopus", + "created": "2025-10-28T08:59:21Z", + "state": "closed", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/openkruise/agents/issues/269", + "title": "[BUG] Deploying and building images on the ARM environment failed.", + "repo": "openkruise/agents", + "created": "2026-04-13T07:06:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/constructorfabric/gears-rust/issues/4798", + "title": "Docker: every build-from-source image is broken and make e2e-docker cannot run (no CI job builds images)", + "repo": "constructorfabric/gears-rust", + "created": "2026-09-14T10:57:58Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/typefly/TypeFly/issues/8", + "title": "COPY failed: forbidden path outside the build context: ../.. ()", + "repo": "typefly/TypeFly", + "created": "2025-03-20T11:58:03Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/SchneiderDaniel/cheasee-pi/issues/1246", + "title": "[Bug] Init extractor writes compose files to workdir root, not docker/ \u2014 inconsistent with docker/.env and run-pi.sh", + "repo": "SchneiderDaniel/cheasee-pi", + "created": "2026-07-14T15:15:03Z", + "state": "closed", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/MassonNN/masson-aiogram-template/issues/18", + "title": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (forbidden path outside the build context: ../poetry.lock ())", + "repo": "MassonNN/masson-aiogram-template", + "created": "2024-01-22T13:31:51Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/APTRS/APTRS/issues/55", + "title": "Docker compose fails at Step 9 in Dockerfile_API ", + "repo": "APTRS/APTRS", + "created": "2024-12-24T19:22:28Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/docs/issues/21827", + "title": "ADD/COPY do not strip paths outside of the build context", + "repo": "docker/docs", + "created": "2025-01-15T19:42:51Z", + "state": "closed", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/spider-rs/headless-browser/issues/7", + "title": "Docker build", + "repo": "spider-rs/headless-browser", + "created": "2025-05-21T13:32:35Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/colanode/colanode/issues/32", + "title": "Error running docker-compose", + "repo": "colanode/colanode", + "created": "2025-05-07T06:38:39Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/immich-app/immich/issues/90", + "title": "Build does not work", + "repo": "immich-app/immich", + "created": "2022-03-29T21:50:34Z", + "state": "closed", + "comments": 27, + "verified": true + }, + { + "url": "https://github.com/jupyterlab/jupyterlab/issues/15709", + "title": "Docker run fails to build image", + "repo": "jupyterlab/jupyterlab", + "created": "2024-01-29T00:24:44Z", + "state": "closed", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/The-Alpha-Project/alpha-core/issues/1460", + "title": "COPY failed: forbidden path outside the build context: ../../../../requirements.txt ()", + "repo": "The-Alpha-Project/alpha-core", + "created": "2024-11-13T02:56:10Z", + "state": "closed", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/opea-project/GenAIExamples/issues/153", + "title": "ChatQnA Megaservice container build issue", + "repo": "opea-project/GenAIExamples", + "created": "2024-05-17T14:15:57Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/go-nunu/nunu/issues/60", + "title": "\u8bf7\u95eemac\u7535\u8111\uff0c\u8fd0\u884c/projectName/deploy/build/Dockerfile\u7684\u811a\u672c\u6253\u955c\u50cf\uff0c\u8001\u662f\u62a5 COPY failed: forbidden path outside the build context: .. ()", + "repo": "go-nunu/nunu", + "created": "2024-06-03T13:58:10Z", + "state": "closed", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/SWE-agent/SWE-agent/issues/68", + "title": "Building eval docker failed: COPY failed: forbidden path outside the build context: ../evaluation/evaluation.py ()", + "repo": "SWE-agent/SWE-agent", + "created": "2024-04-05T09:08:23Z", + "state": "closed", + "comments": 3, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 65 +} \ No newline at end of file diff --git a/bench/data/compose--required-variable.json b/bench/data/compose--required-variable.json new file mode 100644 index 0000000..ed67241 --- /dev/null +++ b/bench/data/compose--required-variable.json @@ -0,0 +1,280 @@ +{ + "category": "compose: required variable", + "rule": "compose.env", + "query": "\"required variable\" \"is missing a value\" is:issue created:>=2021-01-01", + "total": 475, + "sample": [ + { + "url": "https://github.com/rubentalstra/FerroCHART/issues/213", + "title": "README quick start fails: the compose file requires FERROCHART_CDR_URL and FERROCHART_TERM_URL even with --profile demo", + "repo": "rubentalstra/FerroCHART", + "created": "2026-09-12T19:34:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Kralizek/octosmith/issues/49", + "title": "Validate required variables and secrets in the active execution context", + "repo": "Kralizek/octosmith", + "created": "2026-09-23T14:48:45Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/geekau/mediastack/issues/49", + "title": ".restart.sh: variable VPN_USERNAME is missing a value: err", + "repo": "geekau/mediastack", + "created": "2025-07-23T16:09:08Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/compose-spec/compose-go/issues/934", + "title": "`ExtractVariables` does not report a variable used inside a `${VAR:?\u2026}` message", + "repo": "compose-spec/compose-go", + "created": "2026-09-23T11:50:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/42ae/moodle-docker/issues/12", + "title": "`compose.yml` is not compatible with `_FILE` environment variables", + "repo": "42ae/moodle-docker", + "created": "2026-09-16T15:44:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/KeniBeck/MinecraftBedrock/issues/5", + "title": "La docuemntacion de la instalacion es incorecta", + "repo": "KeniBeck/MinecraftBedrock", + "created": "2026-08-20T04:29:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/optimizr-tech/optimizr-actions/issues/265", + "title": ":wrench: feat(ci): let _docker-compose-validate accept compose env for required vars", + "repo": "optimizr-tech/optimizr-actions", + "created": "2026-09-20T05:47:27Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/TAIPANBOX/stack-single/issues/62", + "title": "install.sh gives .env no backup path, and a re-run with .env gone regenerates a Postgres password pgdata does not know", + "repo": "TAIPANBOX/stack-single", + "created": "2026-09-18T13:44:54Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Osmantic/ODS/issues/5633", + "title": "test-bootstrap-mode.sh reports 'Invalid compose configuration' on any clean checkout", + "repo": "Osmantic/ODS", + "created": "2026-09-17T10:59:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/frappe/crm/issues/2230", + "title": "SITES_RULE Missing on Production install", + "repo": "frappe/crm", + "created": "2026-05-28T01:22:37Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/menna-nageh/retroloop-/issues/6", + "title": "Configure environment variables", + "repo": "menna-nageh/retroloop-", + "created": "2026-09-06T13:43:01Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/MrEyratnz/software-factory/issues/344", + "title": "[tech-debt][medium] docs/observability.md:94 \u2014 operator docker compose logs/down commands omit --env-file and fail", + "repo": "MrEyratnz/software-factory", + "created": "2026-07-28T10:21:06Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/stellXpress/backend/issues/39", + "title": "Service starts successfully even with missing required environment variables", + "repo": "stellXpress/backend", + "created": "2026-09-03T17:56:07Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/NuimanLP/srisurart-pos-flutter/issues/2", + "title": "Backend phase 1 \u2014 program brief (NestJS multi-tenant server, Architecture A + T1)", + "repo": "NuimanLP/srisurart-pos-flutter", + "created": "2026-09-04T12:16:52Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/StellarExpress/backend/issues/33", + "title": "Service starts successfully even with missing required environment variables", + "repo": "StellarExpress/backend", + "created": "2026-09-03T18:02:37Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/t59688/arboris-novel/issues/30", + "title": "\u660e\u660e\u8bbe\u7f6e\u4e86\u7684\u5b57\u6bb5\uff0c\u5374\u663e\u793a\u6ca1\u6709\u8bbe\u7f6e", + "repo": "t59688/arboris-novel", + "created": "2025-12-28T13:49:51Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/Antropophag/ic/issues/249", + "title": "podman-compose 1.6.0 \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 --env-file \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 deployment contracts", + "repo": "Antropophag/ic", + "created": "2026-08-11T18:30:47Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/sakibsadmanshajib/hive/issues/1610", + "title": "post-deploy-verify is failing against the demo box", + "repo": "sakibsadmanshajib/hive", + "created": "2026-08-31T10:05:18Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/kreigan/adm-composectl/issues/2", + "title": "Having a common \".env\" file ignores stack's \".env\" file", + "repo": "kreigan/adm-composectl", + "created": "2026-01-04T20:17:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/matrixorigin/memoria/issues/18", + "title": "[Bug]: docker compose up -d error", + "repo": "matrixorigin/memoria", + "created": "2026-03-13T19:24:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/frappe/helpdesk/issues/3067", + "title": "Getting \"Generating Compose File failed\" error", + "repo": "frappe/helpdesk", + "created": "2026-02-26T06:38:13Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/nathanpond/Auton8/issues/519", + "title": "Guard hardening, round 6: the round-8 guards, including one #513 item closed unfixed", + "repo": "nathanpond/Auton8", + "created": "2026-09-17T15:52:37Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/cubrid-lab/cubrid-mcp-server/issues/177", + "title": "fix(config): reject empty required connection environment variables", + "repo": "cubrid-lab/cubrid-mcp-server", + "created": "2026-09-18T12:41:49Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/avnox-com/papermark-self-host/issues/1", + "title": ".env values not being picked up", + "repo": "avnox-com/papermark-self-host", + "created": "2025-11-06T13:51:37Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/project-chip/certification-tool/issues/986", + "title": "[Bug] Auto Install Error", + "repo": "project-chip/certification-tool", + "created": "2026-05-08T22:12:14Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/frappe/lms/issues/2130", + "title": "Docker images on ghcr.io are outdated (December 2025) \u2014 critical bug fixes not available in production deployments + easy-install.py bug", + "repo": "frappe/lms", + "created": "2026-02-25T09:56:49Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/docker/cli/issues/7313", + "title": "`docker stack` subcommands: the `:?` interpolation operator and hyphens do not mix", + "repo": "docker/cli", + "created": "2026-09-17T17:31:09Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/the-deep/deeper/issues/1004", + "title": "docker-compose failing", + "repo": "the-deep/deeper", + "created": "2024-10-21T14:57:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/BioMicroCenter/NExtSEEK/issues/112", + "title": "A $ in NEO4J_PASSWORD silently breaks compose, and the error blames .env for it", + "repo": "BioMicroCenter/NExtSEEK", + "created": "2026-08-20T20:41:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nathanpond/Auton8/issues/518", + "title": "Requiring AUTONATE_MOUNTS_ROOT broke preflight.sh run by hand and three skill docs", + "repo": "nathanpond/Auton8", + "created": "2026-09-17T15:52:10Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 0.8333333333333334, + "adjusted": 396 +} \ No newline at end of file diff --git a/bench/data/compose--unsupported-property.json b/bench/data/compose--unsupported-property.json new file mode 100644 index 0000000..1051047 --- /dev/null +++ b/bench/data/compose--unsupported-property.json @@ -0,0 +1,280 @@ +{ + "category": "compose: unsupported property", + "rule": "compose.version", + "query": "\"additional property\" \"is not allowed\" compose is:issue created:>=2021-01-01", + "total": 486, + "sample": [ + { + "url": "https://github.com/xebialabs-community/community-release-llm-integration/issues/10", + "title": "docker compose Additional property models is not allowed", + "repo": "xebialabs-community/community-release-llm-integration", + "created": "2026-03-10T08:39:29Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/langchain-ai/langchain-extract/issues/16", + "title": "Additional property name is not allowed", + "repo": "langchain-ai/langchain-extract", + "created": "2024-03-07T13:34:16Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/shahinism/docker-stealth-openvpn/issues/4", + "title": "Additional property openvpn is not allowed", + "repo": "shahinism/docker-stealth-openvpn", + "created": "2023-05-03T12:28:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tombstoneghost/TIWAP/issues/4", + "title": "Additional property app is not allowed", + "repo": "tombstoneghost/TIWAP", + "created": "2022-09-14T06:04:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/multica-ai/multica/issues/1401", + "title": "[Bug]: Installation fails with message: (root) Additional property name is not allowed", + "repo": "multica-ai/multica", + "created": "2026-04-20T16:28:49Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/dunglas/docker-private-composer-packages/issues/2", + "title": "OSX - build Additional property secrets is not allowed", + "repo": "dunglas/docker-private-composer-packages", + "created": "2022-09-20T22:26:08Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/UbikZ/docker-uo/issues/1", + "title": "(root) Additional property nginx is not allowed", + "repo": "UbikZ/docker-uo", + "created": "2021-09-11T03:40:35Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/containers/podman-compose/issues/1549", + "title": "Unclear error when `networks`/`volumes` are accidentally indented under `services`", + "repo": "containers/podman-compose", + "created": "2026-08-31T14:05:42Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/redTreeOnWall/memorains/issues/2", + "title": "services.reno_note_nginx Additional property proxy_pass is not allowed", + "repo": "redTreeOnWall/memorains", + "created": "2025-06-18T01:29:55Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/docker/multi-container-app/issues/22", + "title": "- ERROR: services.todo-app Additional property develop is not allowed", + "repo": "docker/multi-container-app", + "created": "2024-03-28T21:30:12Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/bigbluebutton/docker/issues/318", + "title": "Received Error 'services.webrtc-sfu.build Additional property additional_contexts is not allowed'", + "repo": "bigbluebutton/docker", + "created": "2024-02-15T16:57:08Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/matchory/docker-swarm-deployment-action/issues/183", + "title": "Support newer stack schemas for versionless Compose files", + "repo": "matchory/docker-swarm-deployment-action", + "created": "2026-08-04T14:03:22Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/ensdomains/ens-test-env/issues/12", + "title": "Running `docker compose up` does not run with error \"Additional property start_interval is not allowed\"", + "repo": "ensdomains/ens-test-env", + "created": "2025-10-02T17:09:02Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/docker/multi-container-app/issues/9", + "title": "Validating docker_tutorial/multi-container-app/compose.yaml: services.todo-app Additional property develop is not allowed", + "repo": "docker/multi-container-app", + "created": "2023-11-19T05:42:34Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/jcnewell/ergast-f1-api/issues/11", + "title": "Getting (root) Additional property ergast-db is not allowed when running docker-compose up --build -d --remove-orphans", + "repo": "jcnewell/ergast-f1-api", + "created": "2023-07-25T16:06:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/AbsaOSS/spline-getting-started/issues/47", + "title": "docker-compose up ERROR ", + "repo": "AbsaOSS/spline-getting-started", + "created": "2023-06-13T02:14:14Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/docker/multi-container-app/issues/11", + "title": "Docker compose up -d does not launch app, give error: '/multi-container-app/compose.yaml: services.todo-app Additional property develop is not allowed'", + "repo": "docker/multi-container-app", + "created": "2023-12-13T18:20:05Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/UKHomeOffice/docker-landscaper-server/issues/8", + "title": "docker compose build error", + "repo": "UKHomeOffice/docker-landscaper-server", + "created": "2024-12-05T16:30:28Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker-archive-public/docker.labs/issues/596", + "title": "wrong compose syntax", + "repo": "docker-archive-public/docker.labs", + "created": "2023-07-14T17:16:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/eip-work/kuboard-press/issues/602", + "title": "docker compose\u6267\u884c\u5931\u8d25", + "repo": "eip-work/kuboard-press", + "created": "2025-10-15T04:13:39Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/cer/event-sourcing-examples/issues/47", + "title": "Docker compose failure", + "repo": "cer/event-sourcing-examples", + "created": "2021-12-30T11:59:17Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/abhirockzz/oracle-nosql-jersey-dockercompose-sample/issues/1", + "title": "docker-compose up not working", + "repo": "abhirockzz/oracle-nosql-jersey-dockercompose-sample", + "created": "2023-01-31T14:15:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/codebygina/mediumish-theme-jekyll/issues/184", + "title": "Docker Compose file has invlaid syntax", + "repo": "codebygina/mediumish-theme-jekyll", + "created": "2021-09-16T20:39:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/knrew/decune/issues/406", + "title": "Compose v2.24.4\u5411\u3051integration gate\u3092\u8ffd\u52a0\u3057ports.name fixture\u3092\u5206\u96e2\u3059\u308b", + "repo": "knrew/decune", + "created": "2026-07-13T16:15:17Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/jmb12686/docker-multiarch-glusterfs-plugin/issues/1", + "title": "Error using compose file", + "repo": "jmb12686/docker-multiarch-glusterfs-plugin", + "created": "2021-03-06T00:09:21Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Juniper/open-nti/issues/279", + "title": "Error: \"Docker-Compose Make\"", + "repo": "Juniper/open-nti", + "created": "2022-09-13T23:00:18Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/askz/mikrotik-for-doprax/issues/1", + "title": "error at doprax ", + "repo": "askz/mikrotik-for-doprax", + "created": "2024-07-03T09:52:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DanielDent/docker-nginx-ssl-proxy/issues/35", + "title": "Documentation: fix docker-compose.yml", + "repo": "DanielDent/docker-nginx-ssl-proxy", + "created": "2022-10-06T05:19:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/cli/issues/4740", + "title": "docker stack up on compose with include not supported", + "repo": "docker/cli", + "created": "2023-12-23T02:14:31Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/docker/cli/issues/6542", + "title": "docker swarm - support for platform property in compose", + "repo": "docker/cli", + "created": "2025-10-08T05:41:14Z", + "state": "open", + "comments": 2, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 486 +} \ No newline at end of file diff --git a/bench/data/compose--variable-not-set.json b/bench/data/compose--variable-not-set.json new file mode 100644 index 0000000..4c9d1b5 --- /dev/null +++ b/bench/data/compose--variable-not-set.json @@ -0,0 +1,280 @@ +{ + "category": "compose: variable not set", + "rule": "compose.env", + "query": "\"variable is not set. Defaulting to a blank string\" is:issue created:>=2021-01-01", + "total": 2390, + "sample": [ + { + "url": "https://github.com/bausi2k/bmw-mqtt-bridge/issues/2", + "title": "WARN[0000] The \"NP\" variable is not set. Defaulting to a blank string.", + "repo": "bausi2k/bmw-mqtt-bridge", + "created": "2026-08-08T20:45:09Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/neurobagel/documentation/issues/421", + "title": "Cannot run local getting started recipe", + "repo": "neurobagel/documentation", + "created": "2026-08-11T19:31:25Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/ggml-org/llama.cpp/issues/28950", + "title": "Misc. bug: llama download -hf repo:model does not download mmproject", + "repo": "ggml-org/llama.cpp", + "created": "2026-09-15T12:55:39Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/shorin-nikita/lisa/issues/6", + "title": "[BUG] \u041e\u0448\u0438\u0431\u043a\u0430 1 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 Supabase", + "repo": "shorin-nikita/lisa", + "created": "2026-08-16T15:37:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/NVIDIA-Omniverse-blueprints/digital-twins-for-fluid-simulation/issues/17", + "title": "Lite Mode : Still needs access to the NVCR login/ NGC _Key", + "repo": "NVIDIA-Omniverse-blueprints/digital-twins-for-fluid-simulation", + "created": "2026-08-09T08:41:06Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/firecrawl/firecrawl/issues/4137", + "title": "[Self-Host] Building with Podman instead of Docker", + "repo": "firecrawl/firecrawl", + "created": "2026-07-27T09:52:59Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/langflow-ai/openrag/issues/1411", + "title": "[Bug]: opensearch unhealthy", + "repo": "langflow-ai/openrag", + "created": "2026-04-16T02:21:32Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/YFGaia/dify-plus/issues/122", + "title": "setup bug", + "repo": "YFGaia/dify-plus", + "created": "2026-06-24T13:13:29Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/veerendra2/composeflux/issues/76", + "title": "Reconcilation failures", + "repo": "veerendra2/composeflux", + "created": "2026-09-10T17:08:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/hyperledger-archives/sawtooth-core/issues/2438", + "title": "The ISOLATION_ID variable is not set. Defaulting to a blank string.", + "repo": "hyperledger-archives/sawtooth-core", + "created": "2023-02-14T16:03:24Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/transmute-industries/sidetree.js/issues/217", + "title": "WARNING: The MNEMONIC variable is not set. Defaulting to a blank string.", + "repo": "transmute-industries/sidetree.js", + "created": "2021-08-10T11:34:37Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/rodrigovp/livro-kafka-connect/issues/1", + "title": "[BUG] - The \"PWD\" variable is not set. Defaulting to a blank string. ", + "repo": "rodrigovp/livro-kafka-connect", + "created": "2024-05-28T16:52:31Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/C4illin/ConvertX/issues/404", + "title": "WARN[0000] The \"W\" variable is not set. Defaulting to a blank string.", + "repo": "C4illin/ConvertX", + "created": "2025-09-13T15:16:41Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/gitcoinco/web/issues/8521", + "title": "WARNING: The TEST_MNEMONIC variable is not set. Defaulting to a blank string.", + "repo": "gitcoinco/web", + "created": "2021-03-09T23:42:07Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/portainer/portainer/issues/6061", + "title": "Error: Variable is not set. Defaulting to a blank string - when redeploying stack", + "repo": "portainer/portainer", + "created": "2021-11-11T17:36:57Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/sugar-org/compose-go/issues/18", + "title": "WARN[0000] The \"t\" variable is not set. Defaulting to a blank string. ", + "repo": "sugar-org/compose-go", + "created": "2023-04-25T18:30:08Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/IliasHad/edit-mind/issues/125", + "title": "Warnings when execute docker compose up", + "repo": "IliasHad/edit-mind", + "created": "2026-04-27T00:18:26Z", + "state": "open", + "comments": 14, + "verified": true + }, + { + "url": "https://github.com/obytes/superset-image/issues/4", + "title": "WARN[0000] The \"CYPRESS_CONFIG\" variable is not set. Defaulting to a blank string.", + "repo": "obytes/superset-image", + "created": "2024-01-24T22:39:31Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kanbn/kan/issues/530", + "title": "Self Hosting documentation not complete or erroneous", + "repo": "kanbn/kan", + "created": "2026-07-02T09:23:59Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/kalokaman/huly-selfhost/issues/1", + "title": "docker compose up -d", + "repo": "kalokaman/huly-selfhost", + "created": "2026-07-13T10:08:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/rsdancey/BlueSpice-Multiwiki-Install/issues/1", + "title": "Installation failed", + "repo": "rsdancey/BlueSpice-Multiwiki-Install", + "created": "2025-08-04T09:48:40Z", + "state": "open", + "comments": 12, + "verified": true + }, + { + "url": "https://github.com/Graham-Williams/km-tracker/issues/69", + "title": "docker-compose.access.yml still uses bare ${VAR} \u2014 two compose warnings on every deploy", + "repo": "Graham-Williams/km-tracker", + "created": "2026-08-05T15:19:32Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Billionmail/BillionMail/issues/337", + "title": "WARN[0000] The \"BM_API_KEY\" variable is not set. Defaulting to a blank string. bug Something isn't working", + "repo": "Billionmail/BillionMail", + "created": "2026-04-14T09:46:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/FlowiseAI/Flowise/issues/6030", + "title": "Docker Compose setup result in container with \"Error: ENOENT: no such file or directory, mkdir ''\" error", + "repo": "FlowiseAI/Flowise", + "created": "2026-03-21T16:18:57Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/microservices-patterns/ftgo-consumer-web-ui/issues/13", + "title": "WARNING: The FTGO_BACKEND_API_URL variable is not set. Defaulting to a blank string.", + "repo": "microservices-patterns/ftgo-consumer-web-ui", + "created": "2021-05-25T20:48:44Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/isopen-io/meeshy/issues/5624", + "title": "Les hachages d'authentification du .env cessent de fuir dans les journaux", + "repo": "isopen-io/meeshy", + "created": "2026-09-07T20:32:25Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/videre-project/mtgo-docker/issues/1", + "title": "Unable to run on MacOS M1.", + "repo": "videre-project/mtgo-docker", + "created": "2026-04-14T17:30:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/twentyhq/twenty/issues/21035", + "title": "Oneline Installer does not work on a fresh install", + "repo": "twentyhq/twenty", + "created": "2026-05-29T05:04:33Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/mARTin-B78/dgx-spark_lite-llm_llama-swap_vllm_llama-cpp_ollama/issues/12", + "title": "PG image interrupted", + "repo": "mARTin-B78/dgx-spark_lite-llm_llama-swap_vllm_llama-cpp_ollama", + "created": "2026-06-03T14:35:26Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/quadratichq/quadratic-selfhost/issues/102", + "title": "not able to setup on local machine on macbook", + "repo": "quadratichq/quadratic-selfhost", + "created": "2026-07-08T06:52:05Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 0.9666666666666667, + "adjusted": 2310 +} \ No newline at end of file diff --git a/bench/data/container-healthcheck-unhealthy.json b/bench/data/container-healthcheck-unhealthy.json new file mode 100644 index 0000000..85a43a6 --- /dev/null +++ b/bench/data/container-healthcheck-unhealthy.json @@ -0,0 +1,280 @@ +{ + "category": "container healthcheck unhealthy", + "rule": "", + "query": "\"is unhealthy\" \"dependency failed to start\" is:issue created:>=2021-01-01", + "total": 1155, + "sample": [ + { + "url": "https://github.com/magenx/Magento-2-docker-configuration/issues/262", + "title": "dependency failed to start: container mariadb is unhealthy", + "repo": "magenx/Magento-2-docker-configuration", + "created": "2026-06-25T18:47:18Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/DadsMmoLab/dads-mmo-lab/issues/77", + "title": "Container vanilla-db is unhealthy", + "repo": "DadsMmoLab/dads-mmo-lab", + "created": "2026-08-15T10:14:51Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/xtreme1-io/xtreme1/issues/311", + "title": "dependency failed to start: container xtreme1-v091-backend-1 is unhealthy", + "repo": "xtreme1-io/xtreme1", + "created": "2025-01-15T13:00:12Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/angolo40/mikrocata2selks/issues/46", + "title": "dependency failed to start: container config-opensearch", + "repo": "angolo40/mikrocata2selks", + "created": "2025-11-27T18:19:38Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/coze-dev/coze-studio/issues/2299", + "title": "dependency failed to start: container coze-elasticsearch is unhealthy", + "repo": "coze-dev/coze-studio", + "created": "2025-09-30T06:23:05Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/overleaf/toolkit/issues/215", + "title": "dependency failed to start: container mongo is unhealthy", + "repo": "overleaf/toolkit", + "created": "2024-02-05T17:25:07Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/coze-dev/coze-studio/issues/2174", + "title": "`dependency failed to start: container coze-etcd is unhealthy`", + "repo": "coze-dev/coze-studio", + "created": "2025-09-15T10:24:49Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/dockersamples/example-voting-app/issues/361", + "title": "Dependency failed to start", + "repo": "dockersamples/example-voting-app", + "created": "2024-07-23T08:17:23Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/truefoundry/cognita/issues/421", + "title": "dependency failed to start: container cognita-postgres is unhealthy", + "repo": "truefoundry/cognita", + "created": "2025-01-16T11:26:23Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/Superflows-AI/superflows/issues/284", + "title": "dependency failed to start: container supabase-analytics is unhealthy", + "repo": "Superflows-AI/superflows", + "created": "2024-11-07T14:26:30Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/StamusNetworks/Clear-NDR-ISO/issues/484", + "title": "dependency failed to start: container selks-db-1 is unhealthy", + "repo": "StamusNetworks/Clear-NDR-ISO", + "created": "2024-12-03T08:46:19Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/frappe/bench/issues/1548", + "title": "dependency failed to start: container frappe-db-1 is unhealthy", + "repo": "frappe/bench", + "created": "2024-03-27T10:32:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/ben-2357/Torrentio-sh-Setup-Guide/issues/3", + "title": "dependency failed to start: container torrentio-selfhostio-mongodb-1 is unhealthy", + "repo": "ben-2357/Torrentio-sh-Setup-Guide", + "created": "2024-02-04T04:28:34Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/muratalioglu/spring-microservices/issues/1", + "title": "Bug: dependency failed to start: container docker-configserver-1 is unhealthy", + "repo": "muratalioglu/spring-microservices", + "created": "2025-09-06T17:37:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/apache/gravitino-playground/issues/112", + "title": "Playground fails to start with error dependency failed to start: container playground-ranger is unhealthy", + "repo": "apache/gravitino-playground", + "created": "2024-12-19T21:18:55Z", + "state": "open", + "comments": 31, + "verified": true + }, + { + "url": "https://github.com/tencentmusic/supersonic/issues/1488", + "title": "[Bug] dependency failed to start: container supersonic_mysql is unhealthy ", + "repo": "tencentmusic/supersonic", + "created": "2024-07-30T09:28:24Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/docker/genai-stack/issues/142", + "title": "dependency failed to start: container genai-stack-api-1 is unhealthy", + "repo": "docker/genai-stack", + "created": "2024-03-13T22:09:51Z", + "state": "open", + "comments": 12, + "verified": true + }, + { + "url": "https://github.com/coollabsio/coolify/issues/11695", + "title": "[Bug]: Manual Installation Fails on Alpine on Podroid", + "repo": "coollabsio/coolify", + "created": "2026-09-09T01:43:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/elastic/beats/issues/53131", + "title": "[Flaky-Test] Integration tests fail to start Elasticsearch container: ` Container libbeat_9_6_0_b05e54ada1-snapshot-elasticsearch-1 Error`", + "repo": "elastic/beats", + "created": "2026-09-09T21:43:38Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/o19s/chorus-opensearch-edition/issues/180", + "title": "Bug: opensearch-mcp-server-py fails healthcheck with 401 Unauthorized during ./quickstart.sh", + "repo": "o19s/chorus-opensearch-edition", + "created": "2026-09-07T19:28:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/apache/gravitino-playground/issues/20", + "title": "Playground fails to start with error dependency failed to start: container playground-gravitino is unhealthy", + "repo": "apache/gravitino-playground", + "created": "2024-01-16T01:15:24Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/geekau/mediastack/issues/64", + "title": "PostgreSQL is unhealthy", + "repo": "geekau/mediastack", + "created": "2026-01-05T14:41:49Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/sourmash-bio/branchwater/issues/133", + "title": "SRA scale search problem/question - healthcheck port impacted local testing deployment", + "repo": "sourmash-bio/branchwater", + "created": "2026-09-17T18:28:13Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/shorin-nikita/lisa/issues/2", + "title": "[BUG] \u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 Container supabase-db Error dependency failed to start: container supabase-db is unhealthy", + "repo": "shorin-nikita/lisa", + "created": "2026-02-02T11:13:27Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Shaunwei/RealChar/issues/515", + "title": "docker start from new\uff1adependency failed to start: container realchar-backend-1 is unhealthy", + "repo": "Shaunwei/RealChar", + "created": "2024-05-20T03:12:12Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/overleaf/toolkit/issues/431", + "title": "Container mongo Started - Error response from daemon on kernel 7.0.13", + "repo": "overleaf/toolkit", + "created": "2026-06-29T15:32:10Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/onecli/onecli/issues/489", + "title": "exec /usr/local/bin/docker-entrypoint.sh: exec format error", + "repo": "onecli/onecli", + "created": "2026-08-11T13:07:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Sorcha-Platform/Sorcha/issues/1652", + "title": "infra: mongo:8 now resolves to 8.3.x, which refuses to start on Linux kernel >= 6.19 (SERVER-121912)", + "repo": "Sorcha-Platform/Sorcha", + "created": "2026-09-15T17:46:47Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/getsentry/self-hosted/issues/4321", + "title": "Sentry Unstable and not being started", + "repo": "getsentry/self-hosted", + "created": "2026-05-10T03:11:48Z", + "state": "open", + "comments": 15, + "verified": true + }, + { + "url": "https://github.com/coze-dev/coze-studio/issues/2627", + "title": "Docker Compose deployment fails: coze-mysql is unhealthy and blocks service startup", + "repo": "coze-dev/coze-studio", + "created": "2026-03-04T14:10:47Z", + "state": "open", + "comments": 1, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 1155 +} \ No newline at end of file diff --git a/bench/data/counts.csv b/bench/data/counts.csv new file mode 100644 index 0000000..c572d65 --- /dev/null +++ b/bench/data/counts.csv @@ -0,0 +1,33 @@ +category,preflight_rule,raw_hits,sampled,verified,precision,adjusted_estimate +memory: OOMKilled,resources.memory,97607,30,11,0.37,35789 +image: tag/repo not found,image.exists,7405,30,28,0.93,6911 +network not found,,18407,30,10,0.33,6136 +volume permission denied,,6073,30,30,1.0,6073 +platform: exec format error,image.platform,5372,30,29,0.97,5193 +address already in use,ports.host,3792,30,30,1.0,3792 +image: pull access denied,image.exists,3730,30,30,1.0,3730 +platform: requested platform mismatch,image.platform,3717,30,30,1.0,3717 +OCI runtime exec failed,,3479,30,30,1.0,3479 +platform: no matching manifest,image.platform,2760,29,29,1.0,2760 +daemon: cannot connect,(root cause),2712,30,30,1.0,2712 +compose: variable not set,compose.env,2390,30,29,0.97,2310 +DNS resolution in container,,2021,30,30,1.0,2021 +build: COPY source not found,build.context,1421,30,30,1.0,1421 +emulation: qemu crash,image.platform,1301,30,30,1.0,1301 +disk: no space left,"resources.disk,host.disk",1241,30,30,1.0,1241 +port already allocated,"ports.conflict,ports.host",1239,30,30,1.0,1239 +container healthcheck unhealthy,,1155,30,30,1.0,1155 +bind: dir onto file,mounts.bind,707,30,30,1.0,707 +bind: source does not exist,mounts.bind,544,30,30,1.0,544 +compose: unsupported property,compose.version,486,30,30,1.0,486 +gpu: no device driver,resources.gpu,457,30,30,1.0,457 +build: BuildKit required,build.buildkit,443,30,29,0.97,428 +build: COPY failed legacy,build.context,417,30,30,1.0,417 +compose: required variable,compose.env,475,30,25,0.83,396 +kernel: vm.max_map_count,kernel.sysctl,369,30,30,1.0,369 +credentials helper missing,registry.credentials,260,30,30,1.0,260 +desktop: mounts denied,mounts.sharing,153,30,30,1.0,153 +app config/env missing at runtime,(learned),118,30,30,1.0,118 +build: outside build context,build.context,65,30,30,1.0,65 +rootless privileged port,ports.host,39,30,26,0.87,34 +memory: mssql minimum,resources.memory,4653,30,0,0.0,0 diff --git a/bench/data/credentials-helper-missing.json b/bench/data/credentials-helper-missing.json new file mode 100644 index 0000000..f8f6d97 --- /dev/null +++ b/bench/data/credentials-helper-missing.json @@ -0,0 +1,280 @@ +{ + "category": "credentials helper missing", + "rule": "registry.credentials", + "query": "\"error getting credentials\" \"docker-credential\" is:issue created:>=2021-01-01", + "total": 260, + "sample": [ + { + "url": "https://github.com/l8knightz/intellect-bi/issues/1", + "title": "Error getting credentials", + "repo": "l8knightz/intellect-bi", + "created": "2025-11-05T04:10:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/crossplane/cli/issues/282", + "title": "`credsStore` in docker config causes unit test failures", + "repo": "crossplane/cli", + "created": "2026-08-18T19:32:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/getumbrel/llama-gpt/issues/9", + "title": "Error getting credentials on m1 mbp", + "repo": "getumbrel/llama-gpt", + "created": "2023-08-16T21:55:24Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7445", + "title": "error getting credentials - err: exec: \"docker-credential-desktop\": executable file not found in $PATH, out: ``", + "repo": "docker/for-mac", + "created": "2024-10-07T07:20:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/boring-design/elastic-fruit-runner/issues/83", + "title": "Docker backend cannot find credential helper under Homebrew service PATH", + "repo": "boring-design/elastic-fruit-runner", + "created": "2026-06-28T19:40:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/rancher/rancher/issues/46868", + "title": "[BUG] WSL integration docker/credential login errors on reference to windows executable ", + "repo": "rancher/rancher", + "created": "2024-08-28T15:33:07Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/cheeselemon/ophiuchi-desktop/issues/18", + "title": "Fix for error getting credentials - err: exec: \"docker-credential-osxkeychain\": executable file not found in $PATH, out: ", + "repo": "cheeselemon/ophiuchi-desktop", + "created": "2024-06-26T08:10:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/subev/libratory/issues/20", + "title": "Crash: Error: Postgres would not start: error getting credentials - err: exec: \"docker-credential", + "repo": "subev/libratory", + "created": "2026-09-11T05:31:36Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/podman-container-tools/container-libs/issues/94", + "title": "Misleading messages when login/logout with docker-credential-pass", + "repo": "podman-container-tools/container-libs", + "created": "2021-06-10T15:37:12Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/anthropics/claude-code/issues/90758", + "title": "Claude ran a credential-helper `get` command and printed a live access token into the transcript", + "repo": "anthropics/claude-code", + "created": "2026-08-30T13:40:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7535", + "title": "err: exec: \"docker-credential-osxkeychain\": executable file not found in $PATH, out", + "repo": "docker/for-mac", + "created": "2025-01-10T07:41:44Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/10443", + "title": "Linux binary directories in Windows `%PATH%` break Docker CLI in other WSL distros (credential helper conflict)", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2026-06-11T00:00:05Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/smol-machines/smolvm/issues/1246", + "title": "support Docker credential helpers (host-side)", + "repo": "smol-machines/smolvm", + "created": "2026-09-13T11:15:33Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/pantsbuild/pants/issues/23411", + "title": "docker_image builds fail with \"docker-credential-osxkeychain not found in $PATH\" after macOS tmp reaper deletes pantsd's materialized immutable_inputs shims", + "repo": "pantsbuild/pants", + "created": "2026-06-09T23:39:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/fabiogra/moseca/issues/15", + "title": "ERROR: failed to solve: python:3.10: failed to resolve source metadata for docker.io/library/python:3.10: error getting credentials", + "repo": "fabiogra/moseca", + "created": "2024-12-06T04:55:55Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/abiosoft/colima/issues/1437", + "title": "Not able to pull image", + "repo": "abiosoft/colima", + "created": "2025-10-26T10:41:07Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/geopython/geopython-workshop/issues/106", + "title": "Can't start workshop on WSL linux on Windows 11", + "repo": "geopython/geopython-workshop", + "created": "2022-08-22T07:22:21Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/3566", + "title": "Setting up credential helper for GCP container registry + nerdctl", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2022-12-07T19:58:58Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/2847", + "title": "Selenium Dynamic Grid failed to start with mounting error", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2022-08-31T14:44:03Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/wupasscat/continent-bot/issues/3", + "title": "Make a Docker container", + "repo": "wupasscat/continent-bot", + "created": "2023-03-01T14:54:16Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/jasonacox/Powerwall-Dashboard/issues/786", + "title": "Vr1 setup problem", + "repo": "jasonacox/Powerwall-Dashboard", + "created": "2026-06-19T09:42:19Z", + "state": "open", + "comments": 48, + "verified": true + }, + { + "url": "https://github.com/podman-container-tools/podman/issues/22462", + "title": "Podman fails to pull images with GCP Docker Credential Helpers", + "repo": "podman-container-tools/podman", + "created": "2024-04-22T22:11:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/GoogleCloudPlatform/docker-credential-gcr/issues/113", + "title": "Handle reauth / invalid_rapt errors more gracefully", + "repo": "GoogleCloudPlatform/docker-credential-gcr", + "created": "2022-05-31T14:35:57Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/coollabsio/coolify/issues/4763", + "title": "[Bug]: pulling private gcr.io (Google Cloud Artifacts Registry) Docker image fails", + "repo": "coollabsio/coolify", + "created": "2025-01-07T08:36:47Z", + "state": "open", + "comments": 13, + "verified": true + }, + { + "url": "https://github.com/earthly/earthly/issues/4320", + "title": "Sanity check not working on OS X + Podman", + "repo": "earthly/earthly", + "created": "2025-02-26T10:27:49Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/runfinch/finch/issues/800", + "title": "Support BYO credential helpers", + "repo": "runfinch/finch", + "created": "2024-02-08T12:19:28Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kinow/auto-mhm-test-domains/issues/5", + "title": "Document singularity & apptainer", + "repo": "kinow/auto-mhm-test-domains", + "created": "2023-04-14T22:14:19Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/cytopia/devilbox/issues/938", + "title": "[Bug]: Pulled the master branch then it won't start anymore", + "repo": "cytopia/devilbox", + "created": "2022-12-16T08:09:28Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/kimhxsong/Inception/issues/2", + "title": "ERROR [internal] load metadata for docker.io/library/...", + "repo": "kimhxsong/Inception", + "created": "2022-06-13T12:42:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/GoogleContainerTools/kaniko/issues/2808", + "title": "On 1.17.0, instance metadata ECR credentials authorization on EC2 doesn't work anymore", + "repo": "GoogleContainerTools/kaniko", + "created": "2023-10-19T17:56:15Z", + "state": "open", + "comments": 2, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 260 +} \ No newline at end of file diff --git a/bench/data/daemon--cannot-connect.json b/bench/data/daemon--cannot-connect.json new file mode 100644 index 0000000..3292d0a --- /dev/null +++ b/bench/data/daemon--cannot-connect.json @@ -0,0 +1,280 @@ +{ + "category": "daemon: cannot connect", + "rule": "(root cause)", + "query": "\"Cannot connect to the Docker daemon\" is:issue created:>=2021-01-01", + "total": 2712, + "sample": [ + { + "url": "https://github.com/PerryRylance/docker-dns-proxy/issues/1", + "title": "Cannot connect to the Docker daemon", + "repo": "PerryRylance/docker-dns-proxy", + "created": "2026-08-27T06:28:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/soumyanilain/handson-l3-SoumyanilAin/issues/2", + "title": "Cannot connect to the Docker daemon at npipe:////./pipe/docker_engine", + "repo": "soumyanilain/handson-l3-SoumyanilAin", + "created": "2026-09-01T21:13:42Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/linuxserver/docker-kasm/issues/110", + "title": "[BUG] Kasm does not start after an unclean shutdown when the stale containerd pid belongs to another process", + "repo": "linuxserver/docker-kasm", + "created": "2026-09-23T13:12:29Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/sbx-releases/issues/157", + "title": "sandboxd v0.30.0 on Windows: in-process moby backend cannot self-connect to its own `docker.sock` (\"Cannot connect to the Docker daemon at unix://...docker.sock\")", + "repo": "docker/sbx-releases", + "created": "2026-05-19T15:56:15Z", + "state": "open", + "comments": 15, + "verified": true + }, + { + "url": "https://github.com/addnab/docker-run-action/issues/50", + "title": "Cannot connect to the Docker daemon", + "repo": "addnab/docker-run-action", + "created": "2024-01-26T09:49:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/nbx0/NGS_training/issues/2", + "title": "cannot connect to the docker daemon", + "repo": "nbx0/NGS_training", + "created": "2022-11-23T14:11:00Z", + "state": "open", + "comments": 15, + "verified": true + }, + { + "url": "https://github.com/sickcodes/Docker-OSX/issues/660", + "title": "Cannot connect to the Docker daemon at", + "repo": "sickcodes/Docker-OSX", + "created": "2023-05-17T19:07:17Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/erkylima/react-microfront/issues/1", + "title": "`version` is obsolete and \"Cannot connect to the Docker daemon\"", + "repo": "erkylima/react-microfront", + "created": "2024-05-31T06:35:08Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/microcks/microcks-cli/issues/537", + "title": "macOS: honor the active Docker context when /var/run/docker.sock is unavailable", + "repo": "microcks/microcks-cli", + "created": "2026-09-22T04:44:06Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/bountybench/bountytasks/issues/285", + "title": "`./run_ci_local` Cannot connect to the Docker daemon", + "repo": "bountybench/bountytasks", + "created": "2025-02-22T07:18:15Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/deviceplane/agent/issues/3", + "title": "Cannot connect to the Docker daemon, every 3 seconds", + "repo": "deviceplane/agent", + "created": "2022-01-11T08:43:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/AleksandrJelohhin/flaketriage/issues/2", + "title": "Infra signatures: Docker daemon unreachable and HTTP 429 rate limiting", + "repo": "AleksandrJelohhin/flaketriage", + "created": "2026-09-11T20:06:36Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Osmantic/ODS/issues/3823", + "title": "ods status / restart / start hide the real Docker error when the daemon is unreachable (\"no configuration file provided\", \"rootless ownership is not ready\")", + "repo": "Osmantic/ODS", + "created": "2026-09-07T19:06:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/belal-i/docksible/issues/16", + "title": "\"Cannot connect to the Docker daemon\" on some local environments", + "repo": "belal-i/docksible", + "created": "2025-02-18T21:54:07Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/containrrr/watchtower/issues/2023", + "title": "Cannot connect to the Docker daemon after Docker daemon update", + "repo": "containrrr/watchtower", + "created": "2024-09-16T09:35:35Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/devcontainers/features/issues/977", + "title": "Codespaces: \"Cannot connect to the Docker daemon\" occurs randomly (postCreateCommand)", + "repo": "devcontainers/features", + "created": "2024-05-18T08:50:20Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/drone-plugins/drone-docker/issues/414", + "title": "Cannot connect to the Docker daemon at unix:///var/run/docker.sock.", + "repo": "drone-plugins/drone-docker", + "created": "2023-10-25T11:00:02Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/githedgehog/fabricator/issues/1642", + "title": "VLAB ERROR: Cannot connect to the Docker daemon at unix:///run/docker/docker.sock", + "repo": "githedgehog/fabricator", + "created": "2026-04-08T12:17:35Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/cherishman2005/nginx-modules/issues/57", + "title": "[docker]Cannot connect to the Docker daemon at unix:///var/run/docker.sock.", + "repo": "cherishman2005/nginx-modules", + "created": "2023-03-30T05:05:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/desktop-linux/issues/20", + "title": "Cannot connect to the Docker daemon after installing docker desktop on Linux", + "repo": "docker/desktop-linux", + "created": "2022-05-13T21:37:46Z", + "state": "open", + "comments": 32, + "verified": true + }, + { + "url": "https://github.com/lil5/lazypodman/issues/2", + "title": "Looking for docker?", + "repo": "lil5/lazypodman", + "created": "2026-09-12T17:58:32Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-win/issues/14759", + "title": "Cannot connect to the Docker daemon at unix:///var/run/docker.sock.", + "repo": "docker/for-win", + "created": "2025-05-05T16:07:49Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/actions/actions-runner-controller/issues/3794", + "title": "Intermittently getting \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock\"", + "repo": "actions/actions-runner-controller", + "created": "2024-11-05T11:21:43Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/nektos/act/issues/5836", + "title": "`Cannot connect to the Docker daemon` when calling `docker run` inside a local action", + "repo": "nektos/act", + "created": "2025-06-24T17:46:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/EinSpi/scripts/issues/24", + "title": "docker\u91cd\u542f\u5931\u8d25\u62a5\u9519", + "repo": "EinSpi/scripts", + "created": "2026-08-20T06:57:49Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/solutionforest/ephemeral-action-runner/issues/51", + "title": "Windows Docker Sandboxes startup blocked by sbx internal image API failure", + "repo": "solutionforest/ephemeral-action-runner", + "created": "2026-09-23T06:02:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/pagopa/github-self-hosted-runner-azure/issues/16", + "title": "Pipleine fail: Cannot connect to the Docker daemon at unix:///var/run/docker.sock", + "repo": "pagopa/github-self-hosted-runner-azure", + "created": "2023-11-28T22:07:56Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/cnrancher/autok3s/issues/524", + "title": "[BUG] docker-compose - windows - Cannot connect to the Docker daemon at unix:///var/run/docker.sock", + "repo": "cnrancher/autok3s", + "created": "2022-11-14T11:31:09Z", + "state": "open", + "comments": 17, + "verified": true + }, + { + "url": "https://github.com/docker/for-win/issues/14910", + "title": "Virtualization support not detected", + "repo": "docker/for-win", + "created": "2025-08-18T07:15:41Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/keploy/keploy/issues/3109", + "title": "[bug]: If the current docker context is not default then use the correct context", + "repo": "keploy/keploy", + "created": "2025-10-09T13:36:36Z", + "state": "open", + "comments": 4, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 2712 +} \ No newline at end of file diff --git a/bench/data/desktop--mounts-denied.json b/bench/data/desktop--mounts-denied.json new file mode 100644 index 0000000..4f992b5 --- /dev/null +++ b/bench/data/desktop--mounts-denied.json @@ -0,0 +1,280 @@ +{ + "category": "desktop: mounts denied", + "rule": "mounts.sharing", + "query": "\"Mounts denied\" \"is not shared from the host\" is:issue created:>=2021-01-01", + "total": 153, + "sample": [ + { + "url": "https://github.com/docker/for-mac/issues/6759", + "title": "Error response from daemon: Mounts denied: The path **** is not shared from the host and is not known to Docker.", + "repo": "docker/for-mac", + "created": "2023-03-09T20:28:17Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/top-bettercode/docker-wechat/issues/55", + "title": "docker: Error response from daemon: Mounts denied", + "repo": "top-bettercode/docker-wechat", + "created": "2023-02-14T21:49:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ahoone/ahoonepi-proxypi/issues/14", + "title": "Mount volume denied on fresh installation", + "repo": "ahoone/ahoonepi-proxypi", + "created": "2026-07-07T10:27:35Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7589", + "title": "v4.38.0 Pro - Mounts denied - /mutagen-file-shares/fshr_553e66d098fc19abc8fb8c715ad7666d3898cac7000/root is not shared from the host and is not known to Docker", + "repo": "docker/for-mac", + "created": "2025-02-12T05:04:39Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/wizeline/docker-wordpress-minimal/issues/2", + "title": "Error on Mac OSX", + "repo": "wizeline/docker-wordpress-minimal", + "created": "2021-08-03T18:22:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/passivedns/pdns-docker/issues/1", + "title": "Prod environment not working properly on macos", + "repo": "passivedns/pdns-docker", + "created": "2024-07-03T14:16:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/spinframework/otel-plugin/issues/37", + "title": "issue running `spin otel setup`", + "repo": "spinframework/otel-plugin", + "created": "2026-04-02T22:25:04Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/AudreyBeard/compressure/issues/47", + "title": "Make Build Failing", + "repo": "AudreyBeard/compressure", + "created": "2023-09-01T04:02:34Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/KatharaFramework/Kathara/issues/388", + "title": "macOS Docker Desktop shared mount path issue when running Kathara inside a container", + "repo": "KatharaFramework/Kathara", + "created": "2026-05-11T22:17:17Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Azure-Samples/azure-postgres-pgvector-python/issues/35", + "title": "Workspace path error when using Docker Desktop for Mac with VSCode devcontainers extension", + "repo": "Azure-Samples/azure-postgres-pgvector-python", + "created": "2024-11-21T19:07:39Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RADIUSdesk/rdcore/issues/39", + "title": "Doesnt Work", + "repo": "RADIUSdesk/rdcore", + "created": "2023-06-18T12:37:03Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/sickcodes/Docker-OSX/issues/673", + "title": "Error running Docker-OSX on Fedora", + "repo": "sickcodes/Docker-OSX", + "created": "2023-06-28T08:14:53Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/tsukasaI/serverless_with_go/issues/1", + "title": "provided.al2 not running", + "repo": "tsukasaI/serverless_with_go", + "created": "2023-11-09T05:17:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/microsoft/vscode-remote-release/issues/5388", + "title": "Clone repository in container volume with Docker Compose fails due to permissions for non-existant folder", + "repo": "microsoft/vscode-remote-release", + "created": "2021-07-27T18:57:15Z", + "state": "open", + "comments": 16, + "verified": true + }, + { + "url": "https://github.com/athombv/homey-apps-sdk-issues/issues/303", + "title": "SDK Docs - Please add Docker fileshare guide ", + "repo": "athombv/homey-apps-sdk-issues", + "created": "2023-07-10T07:57:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/eliasgranderubio/dagda/issues/103", + "title": "docker-compose.yaml unfriendly to macos version of docker?", + "repo": "eliasgranderubio/dagda", + "created": "2022-04-07T18:33:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ansible/ansible-navigator/issues/1286", + "title": "Unable to extract collection json from stdout, when listing collections through navigator", + "repo": "ansible/ansible-navigator", + "created": "2022-09-08T17:00:59Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/CIDARLAB/homework1-template/issues/1", + "title": "RuntimeError: Unable to find logic.csv using poetry", + "repo": "CIDARLAB/homework1-template", + "created": "2021-03-29T04:11:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ozee/vm-workspace/issues/1", + "title": "Failed tasks when running the application", + "repo": "ozee/vm-workspace", + "created": "2023-06-14T19:59:51Z", + "state": "open", + "comments": 27, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7105", + "title": "Trying to mount directories in Docker", + "repo": "docker/for-mac", + "created": "2023-12-08T19:47:43Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/php-actions/composer/issues/97", + "title": "Exit code 125 and .gitconfig error ", + "repo": "php-actions/composer", + "created": "2023-02-12T14:49:50Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/RADIUSdesk/rdcore/issues/41", + "title": "Unable to create Docker image ", + "repo": "RADIUSdesk/rdcore", + "created": "2023-07-24T20:43:01Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/tabledog/datasette-stripe/issues/1", + "title": "Suggestion for \"Docker Run\" section of README", + "repo": "tabledog/datasette-stripe", + "created": "2022-07-21T02:15:28Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/lando/lando/issues/3472", + "title": "Docker warnings \u201cYou have opted to share your home directory with a container\u201d", + "repo": "lando/lando", + "created": "2022-11-22T22:44:36Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/testcontainers/testcontainers-python/issues/621", + "title": "todo - run tests against docker desktop on linux", + "repo": "testcontainers/testcontainers-python", + "created": "2024-06-28T03:03:34Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/Part-DB/Part-DB-server/issues/437", + "title": "Help needed installing Part-DB on MacOS in Docker", + "repo": "Part-DB/Part-DB-server", + "created": "2023-11-24T08:36:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/DataTalksClub/faq/issues/291", + "title": "[FAQ] Kestra does not run because of Docker error \"mounts denied: The path /tmp/... is not shared from the host\"", + "repo": "DataTalksClub/faq", + "created": "2026-07-01T10:14:46Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7478", + "title": "Docker run doesn't exit on macOS in case of wrong mount", + "repo": "docker/for-mac", + "created": "2024-11-07T09:20:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7519", + "title": "Not able to add paths to latest Docker Desktop File Sharing on MacOS Monterey", + "repo": "docker/for-mac", + "created": "2025-01-05T12:36:26Z", + "state": "open", + "comments": 22, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7514", + "title": "Synchronized file shares can not mount a single file", + "repo": "docker/for-mac", + "created": "2024-12-28T05:18:27Z", + "state": "open", + "comments": 1, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 153 +} \ No newline at end of file diff --git a/bench/data/disk--no-space-left.json b/bench/data/disk--no-space-left.json new file mode 100644 index 0000000..83ed63a --- /dev/null +++ b/bench/data/disk--no-space-left.json @@ -0,0 +1,280 @@ +{ + "category": "disk: no space left", + "rule": "resources.disk,host.disk", + "query": "\"no space left on device\" docker pull is:issue created:>=2021-01-01", + "total": 1241, + "sample": [ + { + "url": "https://github.com/TonyTromp/tidal-connect-docker/issues/13", + "title": "docker pull --> no space left on device", + "repo": "TonyTromp/tidal-connect-docker", + "created": "2022-03-08T09:11:42Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/SCUTlihaoyu/open-chat-video-editor/issues/14", + "title": "no space left on device", + "repo": "SCUTlihaoyu/open-chat-video-editor", + "created": "2023-05-11T14:41:48Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Dispatcharr/Dispatcharr/issues/692", + "title": "[Bug-Fix]: No space left on device (Postgres-issue)", + "repo": "Dispatcharr/Dispatcharr", + "created": "2025-11-27T22:01:05Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/awslabs/genomics-secondary-analysis-using-aws-step-functions-and-aws-batch/issues/9", + "title": "No Space left on device", + "repo": "awslabs/genomics-secondary-analysis-using-aws-step-functions-and-aws-batch", + "created": "2021-11-01T19:10:47Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/openpredictionmarkets/socialpredict/issues/374", + "title": "No Space Left on Device Error", + "repo": "openpredictionmarkets/socialpredict", + "created": "2024-10-26T16:55:02Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/david-coincodex/pm/issues/110", + "title": "Production deploy never prunes old images \u2014 inode exhaustion took Postgres down for ~9h", + "repo": "david-coincodex/pm", + "created": "2026-09-21T09:11:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/vmware-archive/vctl-docs/issues/48", + "title": "no space left on device when `vctl pull`", + "repo": "vmware-archive/vctl-docs", + "created": "2021-06-23T17:11:58Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/y-taka-23/wasm-pandoc/issues/3", + "title": "no space left on device", + "repo": "y-taka-23/wasm-pandoc", + "created": "2022-03-13T08:02:54Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tlc-pack/tlcpack/issues/186", + "title": "[CI] [Conda] [Cuda] No space left on device", + "repo": "tlc-pack/tlcpack", + "created": "2023-08-03T14:57:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/vectordotdev/vector/issues/22288", + "title": "Vector keeps reading from a log file that has been deleted when no space left on device", + "repo": "vectordotdev/vector", + "created": "2025-01-23T03:28:10Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/asyncapi/cli/issues/1966", + "title": "linux/arm64 Docker build fails with \"No space left on device\" during chown", + "repo": "asyncapi/cli", + "created": "2026-01-08T14:11:38Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/autowarefoundation/autoware/issues/5840", + "title": "No space left on device for docker-build workflow", + "repo": "autowarefoundation/autoware", + "created": "2025-03-05T04:01:23Z", + "state": "open", + "comments": 14, + "verified": true + }, + { + "url": "https://github.com/ROCm/ROCm-docker/issues/92", + "title": "Pulling docker image uses too many inodes (no space left on device)", + "repo": "ROCm/ROCm-docker", + "created": "2022-06-13T22:03:06Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tektoncd/catalog/issues/1305", + "title": "Tekton Buildah Task failed No Space left On device", + "repo": "tektoncd/catalog", + "created": "2024-10-02T09:28:49Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/driftless-star/driftless-star/issues/92", + "title": "fix: Apptainer GPU builds fail with \"no space left on device\" during SIF creation", + "repo": "driftless-star/driftless-star", + "created": "2026-06-18T20:48:23Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/tinaudio/synth-setter/issues/2351", + "title": "fix(ci-automation): prevent VST runner disk exhaustion during image pulls", + "repo": "tinaudio/synth-setter", + "created": "2026-07-23T18:09:06Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nf-core/viralrecon/issues/497", + "title": "MAKE_VARIANTS_LONG_TABLE fails in CI build due to no space left on device", + "repo": "nf-core/viralrecon", + "created": "2025-04-30T17:24:11Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/jonohill/docker-openvpn-proxy/issues/14", + "title": "No space left on device: many files created.", + "repo": "jonohill/docker-openvpn-proxy", + "created": "2024-01-18T09:32:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/leanprover-community/docgen-action/issues/16", + "title": "Error: `docker: failed to register layer: write [...] no space left on device`", + "repo": "leanprover-community/docgen-action", + "created": "2025-12-29T20:36:43Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/isopen-io/meeshy/issues/6556", + "title": "Le disque de l'h\u00f4te de staging est plein : \u00ab Deploy to staging \u00bb \u00e9choue au `docker pull`, et staging sert une version p\u00e9rim\u00e9e en silence", + "repo": "isopen-io/meeshy", + "created": "2026-09-14T17:14:36Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/jonaswinkler/paperless-ng/issues/1171", + "title": "[BUG] Error during installation: \"[Errno 28] No space left on device\"", + "repo": "jonaswinkler/paperless-ng", + "created": "2021-07-15T13:23:47Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/airbytehq/airbyte/issues/71134", + "title": "[abctl] fills up /tmp directory causing \"no space left on device\" errors", + "repo": "airbytehq/airbyte", + "created": "2026-01-06T12:41:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ollama/ollama/issues/1731", + "title": "`pulling manifest Error: EOF` when pulling after disk is full", + "repo": "ollama/ollama", + "created": "2023-12-28T00:32:29Z", + "state": "open", + "comments": 12, + "verified": true + }, + { + "url": "https://github.com/appotry/docker-hexo/issues/42", + "title": "no space left on device \u4f46\u6211U\u76d8\u670920G\u5bb9\u91cf", + "repo": "appotry/docker-hexo", + "created": "2026-09-16T06:57:39Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/sheynkman-lab/LRP2/issues/144", + "title": "Investigate optimizing Apptainer and Singularity caching setup", + "repo": "sheynkman-lab/LRP2", + "created": "2026-07-30T18:42:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/podman-container-tools/buildah/issues/4423", + "title": "No space left on device while building 3.26Gb image with 11Gb space available", + "repo": "podman-container-tools/buildah", + "created": "2022-11-18T09:15:05Z", + "state": "open", + "comments": 33, + "verified": true + }, + { + "url": "https://github.com/soflyy/katalystwp/issues/84", + "title": "Docker disk exhaustion: orphan images, layer generations, and health reporting the wrong volume", + "repo": "soflyy/katalystwp", + "created": "2026-09-20T04:09:04Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/MinaProtocol/mina/issues/19374", + "title": "Verify mina-toolchain cache job never finishes: it validates every tag ever cached, not the build's", + "repo": "MinaProtocol/mina", + "created": "2026-09-06T03:05:13Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/tektoncd/pipeline/issues/9052", + "title": "Alpha e2e tests fail often", + "repo": "tektoncd/pipeline", + "created": "2025-10-01T08:53:10Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/QuantumNous/new-api/issues/5878", + "title": "ARMv7 / \u73a9\u5ba2\u4e91 \u73af\u5883\u4e0b\u9ed8\u8ba4 Docker \u6784\u5efa\u94fe\u8def\u517c\u5bb9\u6027\u8f83\u5dee", + "repo": "QuantumNous/new-api", + "created": "2026-07-03T10:31:16Z", + "state": "open", + "comments": 3, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 1241 +} \ No newline at end of file diff --git a/bench/data/dns-resolution-in-container.json b/bench/data/dns-resolution-in-container.json new file mode 100644 index 0000000..a607c6e --- /dev/null +++ b/bench/data/dns-resolution-in-container.json @@ -0,0 +1,280 @@ +{ + "category": "DNS resolution in container", + "rule": "", + "query": "\"Temporary failure in name resolution\" docker is:issue created:>=2021-01-01", + "total": 2021, + "sample": [ + { + "url": "https://github.com/langgenius/dify/issues/40601", + "title": "http Request [Errno -3] Temporary failure in name resolution", + "repo": "langgenius/dify", + "created": "2026-08-12T08:45:54Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/synesthesiam/homeassistant-satellite/issues/79", + "title": "Temporary failure in name resolution", + "repo": "synesthesiam/homeassistant-satellite", + "created": "2023-12-02T18:41:47Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/johanmeijer/grott/issues/296", + "title": "Temporary failure in name resolution", + "repo": "johanmeijer/grott", + "created": "2023-02-19T17:31:42Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/octavius64/Gazelle/issues/4", + "title": "Temporary failure in name resolution", + "repo": "octavius64/Gazelle", + "created": "2023-03-18T08:17:44Z", + "state": "open", + "comments": 12, + "verified": true + }, + { + "url": "https://github.com/raskitoma/pls_admin/issues/9", + "title": "plsworker error: Temporary failure in name resolution...", + "repo": "raskitoma/pls_admin", + "created": "2024-07-29T11:04:41Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/samply/focus/issues/386", + "title": "Startup since 0.24.1", + "repo": "samply/focus", + "created": "2026-09-21T12:25:50Z", + "state": "open", + "comments": 20, + "verified": true + }, + { + "url": "https://github.com/StackStorm/st2-docker/issues/216", + "title": "Problem installing or searching pack, temporary failure in name resolution", + "repo": "StackStorm/st2-docker", + "created": "2021-02-26T00:10:13Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/docker/for-win/issues/13808", + "title": "Error \"Temporary failure in name resolution\" when resolving hosts", + "repo": "docker/for-win", + "created": "2023-11-24T11:27:14Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/Azure/azure-cli/issues/26213", + "title": "az login problem: [Errno -3] Temporary failure in name resolution", + "repo": "Azure/azure-cli", + "created": "2023-04-20T12:16:01Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/schubergphilis/towerlib/issues/108", + "title": "CI test failled (Temporary failure in name resolution)", + "repo": "schubergphilis/towerlib", + "created": "2022-10-04T09:35:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/aau-zid/BigBlueButton-liveStreaming/issues/170", + "title": "Docker Compose Error: Temporary Failure in Name Resolution for BigBlueButton Instance", + "repo": "aau-zid/BigBlueButton-liveStreaming", + "created": "2023-09-06T13:39:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/scylladb/scylladb/issues/11967", + "title": "scylla docker scylla_io_setup fails - hostname: Temporary failure in name resolution", + "repo": "scylladb/scylladb", + "created": "2022-11-14T11:15:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/MODSetter/SurfSense/issues/1716", + "title": "Unable to add OpenAI compatible Local AI providers such as LM Studio or Lemonade", + "repo": "MODSetter/SurfSense", + "created": "2026-08-25T15:11:19Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/OpenSPG/KAG/issues/535", + "title": "[Bug] [Module Name] Bug title java.net.UnknownHostException: mysql: Temporary failure in name resolution", + "repo": "OpenSPG/KAG", + "created": "2025-05-13T08:46:22Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/UnstoppableMango/the-cluster/issues/4458", + "title": "Node resolvers have no upstream fallback, making a two-replica pihole outage unrecoverable", + "repo": "UnstoppableMango/the-cluster", + "created": "2026-09-20T19:45:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/MarkusMcNugen/docker-qBittorrentvpn/issues/121", + "title": "docker freezes ", + "repo": "MarkusMcNugen/docker-qBittorrentvpn", + "created": "2022-02-26T18:40:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/midas-research/audino/issues/112", + "title": "Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')", + "repo": "midas-research/audino", + "created": "2023-05-25T05:56:07Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/oracle/graalvm-reachability-metadata/issues/9630", + "title": "Bug: transient network outage during the host gate kills the do-work loop permanently", + "repo": "oracle/graalvm-reachability-metadata", + "created": "2026-08-29T19:11:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/podman-container-tools/podman/issues/24790", + "title": "`podman login` works fine and authenticates but `podman pull` fails with `dial tcp: lookup: Temporary failure in name resolution`", + "repo": "podman-container-tools/podman", + "created": "2024-12-06T19:42:35Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/bluerobotics/BlueOS/issues/1695", + "title": "bug: No Extensions available.", + "repo": "bluerobotics/BlueOS", + "created": "2023-05-23T08:02:01Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/infiniflow/ragflow/issues/19117", + "title": "[Question]: Getting error when configuring postgres as metadata db", + "repo": "infiniflow/ragflow", + "created": "2026-09-01T13:03:03Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Bess-Gosling/zaproxy/issues/381", + "title": "ZAP error messages when DNS is not working in docker scripts could be more forth coming", + "repo": "Bess-Gosling/zaproxy", + "created": "2026-09-10T08:54:47Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/lnsolspvtltd/propops/issues/76", + "title": "Post-deploy propagation steps for PropOps", + "repo": "lnsolspvtltd/propops", + "created": "2026-08-04T18:50:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/podman-container-tools/podman/issues/16342", + "title": "No retry on temporary failure in network name resolution", + "repo": "podman-container-tools/podman", + "created": "2022-10-29T09:46:16Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/cooneycw/mcp-second-opinion/issues/5", + "title": "Attach aws-secrets-agent sidecar to external mcp-net durably (fixes recurring gemma-bot outages)", + "repo": "cooneycw/mcp-second-opinion", + "created": "2026-08-02T16:10:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DecaturMakers/equipment-status-board/issues/82", + "title": "App fails to boot when Slack is unreachable: init_slack() does a blocking auth.test during create_app()", + "repo": "DecaturMakers/equipment-status-board", + "created": "2026-08-29T13:26:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/demonsxxxxxx/ai-platform/issues/409", + "title": "B2: Docker egress evidence lacks policy-bound deny proof", + "repo": "demonsxxxxxx/ai-platform", + "created": "2026-07-12T12:38:11Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/farabisina25/echofinder-test/issues/142", + "title": "Docker Networking", + "repo": "farabisina25/echofinder-test", + "created": "2025-12-20T16:44:54Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/farabisina25/echofinder-test/issues/131", + "title": "Docker Networking Failure", + "repo": "farabisina25/echofinder-test", + "created": "2025-12-20T15:54:57Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/ramon-victor/freegpt-webui/issues/45", + "title": "synology docker enable automatic proxy", + "repo": "ramon-victor/freegpt-webui", + "created": "2023-07-05T14:01:27Z", + "state": "open", + "comments": 2, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 2021 +} \ No newline at end of file diff --git a/bench/data/emulation--qemu-crash.json b/bench/data/emulation--qemu-crash.json new file mode 100644 index 0000000..38aadae --- /dev/null +++ b/bench/data/emulation--qemu-crash.json @@ -0,0 +1,280 @@ +{ + "category": "emulation: qemu crash", + "rule": "image.platform", + "query": "\"qemu: uncaught target signal\" is:issue created:>=2021-01-01", + "total": 1301, + "sample": [ + { + "url": "https://github.com/llvm/llvm-project/issues/223314", + "title": "[libcxx][test] qemu: uncaught target signal 4 (Illegal instruction) - core dumped", + "repo": "llvm/llvm-project", + "created": "2026-09-14T06:58:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/2moe/tmoe/issues/273", + "title": "qemu: uncaught target signal 11", + "repo": "2moe/tmoe", + "created": "2023-02-25T15:17:11Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/askdba/myvector/issues/138", + "title": "docker-publish.yml: emulated arm64 apt install crashed with QEMU segfault (flaky)", + "repo": "askdba/myvector", + "created": "2026-09-22T06:32:22Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/montimage-projects/mmt-dpi/issues/421", + "title": "ci: emulated ldconfig intermittently segfaults on ubuntu-22.04 arm64 package job", + "repo": "montimage-projects/mmt-dpi", + "created": "2026-09-23T05:15:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RPi-Distro/pi-gen/issues/656", + "title": "Error: qemu: uncaught target signal 11, Segmentation fault", + "repo": "RPi-Distro/pi-gen", + "created": "2022-12-07T15:25:47Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/redis/redis/issues/10794", + "title": "[BUG] qemu: uncaught target signal 11 (Segmentation fault)", + "repo": "redis/redis", + "created": "2022-05-29T13:11:48Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/evilmartians/fullstaq-ruby-docker/issues/17", + "title": "qemu: uncaught target signal 6 (Aborted) - core dumped", + "repo": "evilmartians/fullstaq-ruby-docker", + "created": "2022-08-23T09:54:55Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/dullage/eyelign/issues/21", + "title": "qemu: uncaught target signal 4 (Illegal instruction) - core dumped", + "repo": "dullage/eyelign", + "created": "2023-08-19T00:52:25Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/travisgoodspeed/md380tools/issues/953", + "title": "qemu: uncaught target signal 11 (Segmentation fault) - core dumped", + "repo": "travisgoodspeed/md380tools", + "created": "2024-07-14T21:10:03Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/gtrll/gpmp2/issues/52", + "title": "qemu: uncaught target signal 11 (Segmentation fault) - core dumped", + "repo": "gtrll/gpmp2", + "created": "2021-08-29T03:05:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/openswoole/ext-openswoole/issues/332", + "title": "qemu: uncaught target signal 11 (Segmentation fault) - core dumped", + "repo": "openswoole/ext-openswoole", + "created": "2023-10-01T01:38:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/lmnr-ai/lmnr/issues/913", + "title": "Self Hosted version does not work", + "repo": "lmnr-ai/lmnr", + "created": "2025-09-28T21:33:57Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/exadel-inc/CompreFace/issues/673", + "title": "\"qemu: uncaught target signal 6 (Aborted) - core dumped\" on m1 Mac", + "repo": "exadel-inc/CompreFace", + "created": "2021-12-07T23:19:44Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/isopen-io/meeshy/issues/6439", + "title": "La construction multi-architecture de Release rougit main une fois sur deux sans d\u00e9faut de code \u2014 \u00e9mulation arm64 et extraction bun instables", + "repo": "isopen-io/meeshy", + "created": "2026-09-14T01:45:21Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/big-data-europe/docker-hive/issues/43", + "title": "Getting qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault", + "repo": "big-data-europe/docker-hive", + "created": "2021-05-07T04:23:19Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/gingrspacecadet/coda/issues/4", + "title": "Compiled programs segfault when an if statement prints and then doesn't return", + "repo": "gingrspacecadet/coda", + "created": "2026-07-13T13:36:35Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/tjakobsson/brain/issues/27", + "title": "Candidate image build hangs after QEMU SIGILL in arm64 npm ci (v1.6.0 release blocked)", + "repo": "tjakobsson/brain", + "created": "2026-09-03T05:30:49Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/softcite/software-mentions/issues/29", + "title": "server crashes with \"qemu: uncaught target signal 6\" on Mac M1 silicon", + "repo": "softcite/software-mentions", + "created": "2023-07-31T18:38:54Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/tonistiigi/binfmt/issues/298", + "title": "Segfault on libc-bin", + "repo": "tonistiigi/binfmt", + "created": "2026-02-18T10:09:11Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/hatchet-dev/hatchet-python-quickstart/issues/1", + "title": "Migration container failing with `qemu: uncaught target signal 11 (Segmentation fault) - core dumped`", + "repo": "hatchet-dev/hatchet-python-quickstart", + "created": "2024-02-22T19:49:09Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/storaged-project/udisks/issues/1525", + "title": "spawned_job/abnormal_termination test fails when cross-testing arm64 under qemu-user", + "repo": "storaged-project/udisks", + "created": "2026-06-17T14:34:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/doemefu/homelab-device-service/issues/73", + "title": "ci: add timeout-minutes guards to the multi-arch build job (same hang class as furchert-ch#41)", + "repo": "doemefu/homelab-device-service", + "created": "2026-09-04T03:21:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7884", + "title": "Embedded BuildKit builder segfaults on linux/amd64 emulated rustc (QEMU signal 11), independent of Rosetta / Docker VMM", + "repo": "docker/for-mac", + "created": "2026-09-15T16:06:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/doemefu/homelab-auth-service/issues/87", + "title": "ci: add timeout-minutes guards to the multi-arch build job (same hang class as furchert-ch#41)", + "repo": "doemefu/homelab-auth-service", + "created": "2026-09-04T03:20:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ziglang/zig/issues/17430", + "title": "-fno-PIC targeting glibc should be legal", + "repo": "ziglang/zig", + "created": "2023-10-07T14:38:17Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/chivay/shellcodez/issues/1", + "title": "Larger payloads cause segmentation faults", + "repo": "chivay/shellcodez", + "created": "2026-08-14T05:37:44Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/bun913/go_lambda_functions/issues/3", + "title": "Apple Slicon\u3067 sam-cli\u306e\u30ed\u30fc\u30ab\u30eb\u5b9f\u884c\u304c\u3067\u304d\u306a\u3044\u554f\u984c\u3092Issue\u306b\u6295\u7a3f\u3059\u308b", + "repo": "bun913/go_lambda_functions", + "created": "2022-05-02T20:37:06Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/k8gb-io/k8gb/issues/2527", + "title": "[BUG] Local playground serves no DNS on arm64: edge BIND image is amd64-only and segfaults under emulation", + "repo": "k8gb-io/k8gb", + "created": "2026-09-08T13:35:08Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/xiangsx/gpt4free-ts/issues/46", + "title": "mac m1\u82af\u7247\u8fd0\u884camd64\u7248\u672c\u955c\u50cf\u62a5\u9519\uff0c\u65e0\u6cd5\u542f\u52a8\u6d4f\u89c8\u5668", + "repo": "xiangsx/gpt4free-ts", + "created": "2023-06-08T01:25:15Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/apache/iceberg/issues/15943", + "title": "Build 'iceberg-rest-fixture' Docker Image random failure", + "repo": "apache/iceberg", + "created": "2026-04-11T16:52:18Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 1301 +} \ No newline at end of file diff --git a/bench/data/gpu--no-device-driver.json b/bench/data/gpu--no-device-driver.json new file mode 100644 index 0000000..584ef4a --- /dev/null +++ b/bench/data/gpu--no-device-driver.json @@ -0,0 +1,280 @@ +{ + "category": "gpu: no device driver", + "rule": "resources.gpu", + "query": "\"could not select device driver\" \"capabilities: [[gpu]]\" is:issue created:>=2021-01-01", + "total": 457, + "sample": [ + { + "url": "https://github.com/dev-it-with-me/RagUltimateAdvisor/issues/3", + "title": "Could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "dev-it-with-me/RagUltimateAdvisor", + "created": "2026-04-01T07:56:55Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/xserrat/docker-facebook-demucs/issues/47", + "title": "[Bug]: could not select device driver with capabilities [[gpu]]", + "repo": "xserrat/docker-facebook-demucs", + "created": "2026-02-28T15:07:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kinu-garage/hut_10sqft/issues/818", + "title": "p16s: rocker fails: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "kinu-garage/hut_10sqft", + "created": "2023-04-04T13:49:18Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/LinkSoul-AI/Chinese-Llama-2-7b/issues/32", + "title": "could not select device driver \"\" with capabilities: [[gpu]]", + "repo": "LinkSoul-AI/Chinese-Llama-2-7b", + "created": "2023-07-27T06:33:52Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/basujindal/stable-diffusion/issues/217", + "title": "could not select device driver \"nvidia\" with capabilities [[gpu]]", + "repo": "basujindal/stable-diffusion", + "created": "2022-11-03T05:33:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/jianchang512/ChatTTS-ui/issues/212", + "title": "could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "jianchang512/ChatTTS-ui", + "created": "2024-08-07T04:22:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/openads-project/openads-project.github.io/issues/16", + "title": "nvidia-ctk missing from requirements", + "repo": "openads-project/openads-project.github.io", + "created": "2026-08-14T13:56:45Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/n0k0m3/pyspark-notebook-deltalake-docker/issues/8", + "title": "Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]]", + "repo": "n0k0m3/pyspark-notebook-deltalake-docker", + "created": "2023-10-01T19:55:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tyson-swetnam/cloudcompare-docker/issues/3", + "title": "could not select device driver - Kubuntu 22.04", + "repo": "tyson-swetnam/cloudcompare-docker", + "created": "2024-05-26T20:09:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Neo-Diamons/Docker-AI-Webui/issues/1", + "title": "Error response from daemon: could not select device driver \"nvidia\"", + "repo": "Neo-Diamons/Docker-AI-Webui", + "created": "2024-04-28T20:24:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/devnen/Chatterbox-TTS-Server/issues/15", + "title": "Error response from daemon: could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "devnen/Chatterbox-TTS-Server", + "created": "2025-06-07T10:20:03Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/lkwq007/stablediffusion-infinity/issues/25", + "title": "Error response from daemon: could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "lkwq007/stablediffusion-infinity", + "created": "2022-09-25T04:40:06Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/automateyournetwork/packet_buddy/issues/9", + "title": "Error response from daemon: could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "automateyournetwork/packet_buddy", + "created": "2025-03-23T18:05:45Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/FMXExpress/AI-Translate/issues/1", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "FMXExpress/AI-Translate", + "created": "2024-01-10T13:30:31Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/AIR-DISCOVER/ICRA-RM-Sim2Real/issues/20", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "AIR-DISCOVER/ICRA-RM-Sim2Real", + "created": "2022-02-20T14:00:15Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Huanshere/VideoLingo/issues/442", + "title": "(HTTP code 500) server error - could not select device driver \"\" with capabilities: [[gpu]]", + "repo": "Huanshere/VideoLingo", + "created": "2025-04-29T09:39:18Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/SortAnon/ControllableTalkNet/issues/31", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "SortAnon/ControllableTalkNet", + "created": "2023-02-04T20:01:14Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/danchitnis/sycl-container/issues/1", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "danchitnis/sycl-container", + "created": "2023-01-10T20:28:57Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/getumbrel/llama-gpt/issues/150", + "title": "Can't use GPU: could not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "getumbrel/llama-gpt", + "created": "2024-02-24T14:44:53Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/soulteary/docker-llama2-chat/issues/22", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "soulteary/docker-llama2-chat", + "created": "2023-09-12T09:41:53Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/NVlabs/stylegan2-ada-pytorch/issues/227", + "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "NVlabs/stylegan2-ada-pytorch", + "created": "2022-03-26T10:17:41Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/FoundationVision/ByteTrack/issues/302", + "title": "Docker-Error: could not select device driver with GPU capabilities", + "repo": "FoundationVision/ByteTrack", + "created": "2023-01-02T09:32:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/netease-youdao/QAnything/issues/93", + "title": "[BUG] ", + "repo": "netease-youdao/QAnything", + "created": "2024-01-31T16:43:39Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/kineticsystem/find-me-a-freaking-job/issues/3", + "title": "Compose requires the NVIDIA runtime and host networking even when the model server runs outside the container", + "repo": "kineticsystem/find-me-a-freaking-job", + "created": "2026-09-20T16:03:03Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/jianchang512/ChatTTS-ui/issues/68", + "title": "\u62a5\u9519\u89e3\u51b3\u65b9\u6848\uff1acould not select device driver \"nvidia\" with capabilities: [[gpu]]", + "repo": "jianchang512/ChatTTS-ui", + "created": "2024-06-03T13:16:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/qixuema/envs/issues/25", + "title": "Error response from daemon: Cannot restart container xxx: could not select device driver \"\" with capabilities: [[gpu]]", + "repo": "qixuema/envs", + "created": "2024-07-05T12:25:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nikmcfly/MiroFish-Offline/issues/24", + "title": "Does it work on mac book pro?", + "repo": "nikmcfly/MiroFish-Offline", + "created": "2026-04-01T18:22:55Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/wilicc/gpu-burn/issues/93", + "title": "Docker run fails: docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]]", + "repo": "wilicc/gpu-burn", + "created": "2023-12-02T10:56:58Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/huan/docker-wechat/issues/173", + "title": "3.3.0.115 docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "huan/docker-wechat", + "created": "2022-05-06T20:33:29Z", + "state": "open", + "comments": 13, + "verified": true + }, + { + "url": "https://github.com/replicate/cog-stable-diffusion/issues/12", + "title": "AMD GPU on Ubuntu - docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", + "repo": "replicate/cog-stable-diffusion", + "created": "2022-08-31T13:47:41Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 457 +} \ No newline at end of file diff --git a/bench/data/image--pull-access-denied.json b/bench/data/image--pull-access-denied.json new file mode 100644 index 0000000..4d49910 --- /dev/null +++ b/bench/data/image--pull-access-denied.json @@ -0,0 +1,280 @@ +{ + "category": "image: pull access denied", + "rule": "image.exists", + "query": "\"pull access denied\" \"may require\" is:issue created:>=2021-01-01", + "total": 3730, + "sample": [ + { + "url": "https://github.com/PeerDB-io/peerdb/issues/4843", + "title": "[Bug]: minio/minio image no longer available on Docker Hub", + "repo": "PeerDB-io/peerdb", + "created": "2026-09-23T07:54:57Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Dokploy/dokploy/issues/5469", + "title": "Docker source: \"Login Succeeded\" then \"pull access denied\" \u2014 Registry URL never reaches the image name", + "repo": "Dokploy/dokploy", + "created": "2026-09-16T12:45:29Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/confluentinc/demo-siem-optimization/issues/30", + "title": "pull access denied for localbuild/zeek-tcpreplay-kafka, repository does not exist or may require 'docker login'", + "repo": "confluentinc/demo-siem-optimization", + "created": "2026-07-10T04:06:23Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ariadata/qbittorrent-warp/issues/1", + "title": "Pull Access Denied", + "repo": "ariadata/qbittorrent-warp", + "created": "2025-11-17T06:47:50Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/irods/irods_capability_automated_ingest/issues/325", + "title": "GitHub Action Workflow cannot pull minio docker image", + "repo": "irods/irods_capability_automated_ingest", + "created": "2026-09-15T13:54:07Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/EpicGames/lore/issues/208", + "title": "Integration tests failed because minio/minio:latest is no longer available", + "repo": "EpicGames/lore", + "created": "2026-09-15T06:37:53Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/aneisch/thermostat_mqtt_docker/issues/1", + "title": "pull access denied", + "repo": "aneisch/thermostat_mqtt_docker", + "created": "2021-08-20T23:19:38Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/lg/emugaming/issues/3", + "title": "pull access denied ", + "repo": "lg/emugaming", + "created": "2022-07-04T09:27:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/thorrak/fermentrack/issues/783", + "title": "Manual install unable to find an initialized, responsive instance of Fermentrack", + "repo": "thorrak/fermentrack", + "created": "2026-08-28T00:39:01Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dusty-nv/jetson-containers/issues/1707", + "title": "build fails with pull access denied", + "repo": "dusty-nv/jetson-containers", + "created": "2026-06-09T05:37:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/stump-wtf/cairn/issues/2", + "title": "docker-compose.prod.yml: minio/minio:latest is no longer pullable from Docker Hub (use quay.io/minio/minio)", + "repo": "stump-wtf/cairn", + "created": "2026-09-22T19:44:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/victoradrianjimenez/dockerized-zotero/issues/6", + "title": "\"pull access denied for ...\" messages", + "repo": "victoradrianjimenez/dockerized-zotero", + "created": "2025-11-05T17:16:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/containerd/containerd/issues/11103", + "title": "pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials", + "repo": "containerd/containerd", + "created": "2024-12-05T10:34:19Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/coollabsio/coolify/issues/11855", + "title": "[Bug]: Supabase deployment/restart fails because minio/mc image cannot be pulled", + "repo": "coollabsio/coolify", + "created": "2026-09-16T12:08:11Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/rustfs/cli/issues/380", + "title": "Docker usage fails with \"login required\"", + "repo": "rustfs/cli", + "created": "2026-09-21T22:19:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DBRepo-Project/dbrepo/issues/97", + "title": "The install script fails to pull the docker images", + "repo": "DBRepo-Project/dbrepo", + "created": "2026-08-17T11:48:46Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/hcengineering/huly-selfhost/issues/335", + "title": "MinIO removed from Docker Huber - can't finish setup", + "repo": "hcengineering/huly-selfhost", + "created": "2026-09-22T17:35:01Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/cies/low-code-backend-dockered/issues/2", + "title": "Hasura pull access denied", + "repo": "cies/low-code-backend-dockered", + "created": "2022-10-19T15:07:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/0xPolygon/zkevm-node/issues/3771", + "title": "pull access denied zkevm-node", + "repo": "0xPolygon/zkevm-node", + "created": "2024-08-17T21:21:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/sigil-enterprises/ducklake/issues/110", + "title": "MinIO images are gone from Docker Hub: scripts/docker-compose.yml must re-point at quay.io", + "repo": "sigil-enterprises/ducklake", + "created": "2026-09-12T09:17:53Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/epilif1017a/big-data-open-os/issues/2", + "title": "pull access denied for hadoop-base", + "repo": "epilif1017a/big-data-open-os", + "created": "2021-11-16T19:38:57Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/o2ac/o2ac-ur/issues/4", + "title": "o2ac-ur pull access denied", + "repo": "o2ac/o2ac-ur", + "created": "2021-11-18T05:04:11Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/nektos/act/issues/2585", + "title": "Pull access denied, repository does not exist or may require 'docker login'", + "repo": "nektos/act", + "created": "2024-12-24T06:18:05Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/sidpalas/mern-docker-compose/issues/1", + "title": "pull access denied for react-app", + "repo": "sidpalas/mern-docker-compose", + "created": "2022-12-30T13:38:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/trevezani/kong-consul-springboot/issues/1", + "title": "Pull access denied for census-zipcode", + "repo": "trevezani/kong-consul-springboot", + "created": "2021-02-04T13:18:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/indrz/indrz-be/issues/129", + "title": "Pull access denied for indrz/gogse", + "repo": "indrz/indrz-be", + "created": "2021-09-22T11:51:14Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/OpenSourcePolitics/decidim-ditp/issues/4", + "title": "pull access denied for decidim-app", + "repo": "OpenSourcePolitics/decidim-ditp", + "created": "2022-06-17T12:40:16Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/AchimPieters/ESP-HomeKit-SDK-Revised-Installation/issues/1", + "title": "pull access denied for esp-sdk", + "repo": "AchimPieters/ESP-HomeKit-SDK-Revised-Installation", + "created": "2021-10-31T17:21:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/HKUDS/AI-Researcher/issues/80", + "title": "Bug: Docker image 'tjbtech1/airesearcher:v1' pull access denied", + "repo": "HKUDS/AI-Researcher", + "created": "2025-12-25T12:29:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/swiftlang/swift-org-website/issues/1346", + "title": "Run OpenAPI Tester: Pull access denied for swift-website-builder", + "repo": "swiftlang/swift-org-website", + "created": "2026-03-06T19:30:21Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 3730 +} \ No newline at end of file diff --git a/bench/data/image--tag-repo-not-found.json b/bench/data/image--tag-repo-not-found.json new file mode 100644 index 0000000..44b7e47 --- /dev/null +++ b/bench/data/image--tag-repo-not-found.json @@ -0,0 +1,280 @@ +{ + "category": "image: tag/repo not found", + "rule": "image.exists", + "query": "\"manifest unknown\" docker is:issue created:>=2021-01-01", + "total": 7405, + "sample": [ + { + "url": "https://github.com/openwhistle/OpenWhistle/issues/69", + "title": "Docker image - manifest unknown", + "repo": "openwhistle/OpenWhistle", + "created": "2026-09-22T09:24:54Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/memiiso/debezium-server-iceberg/issues/744", + "title": "docker version 1.1.0.Final manifest unknown", + "repo": "memiiso/debezium-server-iceberg", + "created": "2026-09-10T11:21:09Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/metadatastician/paint-type/issues/88", + "title": "Sustainability Analysis (OikosBot): pinned container digest returns manifest unknown", + "repo": "metadatastician/paint-type", + "created": "2026-09-22T21:57:24Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/decolua/9router/issues/4167", + "title": "Docker image decolua/9router:0.5.81 is not available", + "repo": "decolua/9router", + "created": "2026-09-19T07:06:20Z", + "state": "open", + "comments": 9, + "verified": true + }, + { + "url": "https://github.com/wazuh/wazuh/issues/38861", + "title": "Wazuh 5.0.0 beta docker manifest unknown - EDIT : wrong image names in docs", + "repo": "wazuh/wazuh", + "created": "2026-09-03T15:38:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/CoreNovaLabs/CoreNovaLaunch/issues/22", + "title": "verify(drawio): unknown FAILED (MANUAL_REQUIRED)", + "repo": "CoreNovaLabs/CoreNovaLaunch", + "created": "2026-09-23T20:47:49Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/marcopiovanello/yt-dlp-web-ui/issues/379", + "title": "v4 Docker images missing", + "repo": "marcopiovanello/yt-dlp-web-ui", + "created": "2026-07-25T07:05:25Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/CoreNovaLabs/CoreNovaLaunch/issues/10", + "title": "verify(ghost): unknown FAILED (MANUAL_REQUIRED)", + "repo": "CoreNovaLabs/CoreNovaLaunch", + "created": "2026-09-08T20:25:25Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/conversun/fnos-apps/issues/306", + "title": "[Bug]", + "repo": "conversun/fnos-apps", + "created": "2026-09-16T09:58:37Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ublue-os/bazzite/issues/4764", + "title": "Rebase to version 44.20260429 fails with \"manifest unknown\" error", + "repo": "ublue-os/bazzite", + "created": "2026-04-29T08:53:30Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/jeremy-albinet/Stitch-Revitalized-For-Roku/issues/152", + "title": "Error manifest unknown when pulling ghcr.io/jeremy-albinet/fmp4-demux-proxy:main", + "repo": "jeremy-albinet/Stitch-Revitalized-For-Roku", + "created": "2026-07-20T21:03:00Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/golusoris/golusoris/issues/563", + "title": "build(ai/tiny): publish digest-pinnable Gemma and LiteRT trainer images", + "repo": "golusoris/golusoris", + "created": "2026-09-19T20:10:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dniku/free-lunch-saliency/issues/1", + "title": "Docker Image manifest unknown", + "repo": "dniku/free-lunch-saliency", + "created": "2022-02-22T21:28:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Softcatala/whisper-ctranslate2/issues/148", + "title": "docker image broken? workaround provided", + "repo": "Softcatala/whisper-ctranslate2", + "created": "2026-07-30T11:07:33Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/safak/microservices-ecommerce/issues/3", + "title": "manifest for bitnami/kafka:latest not found: manifest unknown: manifest unknown", + "repo": "safak/microservices-ecommerce", + "created": "2025-10-07T13:26:07Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/elfhosted/newtarr/issues/16", + "title": "Missing Docker Image", + "repo": "elfhosted/newtarr", + "created": "2026-07-02T14:40:52Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/k8snetworkplumbingwg/multus-cni/issues/1551", + "title": "v4.3.1 thin container image was not published", + "repo": "k8snetworkplumbingwg/multus-cni", + "created": "2026-09-20T09:48:17Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/nextbsd/nextbsd/issues/423", + "title": "CI: toolchain dispatches downstream from the amd64 matrix leg, racing the arm64 image push (manifest unknown)", + "repo": "nextbsd/nextbsd", + "created": "2026-08-27T02:46:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DamianB-BitFlipper/proton-drive-sync/issues/127", + "title": "Can't pull docker image", + "repo": "DamianB-BitFlipper/proton-drive-sync", + "created": "2026-03-07T13:16:45Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/bgshih/crnn/issues/159", + "title": "manifest unknown -> manifest for kaixhin/cuda-torch:latest not found: manifest unknown: manifest unknown", + "repo": "bgshih/crnn", + "created": "2021-04-29T08:54:23Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RedHatQuickCourses/rhdh-idp/issues/7", + "title": "Module 2: Build fails: error: build error: failed to pull image: openjdk:17", + "repo": "RedHatQuickCourses/rhdh-idp", + "created": "2026-09-14T16:49:58Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/tuna-os/xfce-linux/issues/145", + "title": "[shared-ci] base image ghcr.io/tuna-os/xfce-linux:latest manifest unknown \u2014 breaks E2E on main and PRs", + "repo": "tuna-os/xfce-linux", + "created": "2026-09-03T04:11:31Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/conversun/fnos-apps/issues/289", + "title": "[Bug]", + "repo": "conversun/fnos-apps", + "created": "2026-09-02T11:37:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/conversun/fnos-apps/issues/288", + "title": "[Bug]", + "repo": "conversun/fnos-apps", + "created": "2026-09-02T07:43:40Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/ben1234560/k8s_PaaS/issues/52", + "title": "Using default tag: latest Error response from daemon: manifest for kubernetes/pause:latest not found: manifest unknown: manifest unknown", + "repo": "ben1234560/k8s_PaaS", + "created": "2024-08-17T11:57:51Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/mehmetgoren/feniks/issues/12", + "title": "docker-compose occurs error that manifest unknown", + "repo": "mehmetgoren/feniks", + "created": "2023-05-04T07:07:47Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/christiaandouma/fronius-auth-proxy/issues/17", + "title": "Addon will not install on HA 2026.8.0 - deprecated methods", + "repo": "christiaandouma/fronius-auth-proxy", + "created": "2026-08-07T16:12:36Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/BreachSAFE/qureddy/issues/540", + "title": "docs: consolidate README \u00a71 Docker examples + add Docker Hub rate-limit guidance", + "repo": "BreachSAFE/qureddy", + "created": "2026-08-31T01:28:37Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/imdingtalk/image-mirror/issues/1854", + "title": "kubewatch/kubewatch:2.16.1 (\u5171 1 \u4e2a\u955c\u50cf)", + "repo": "imdingtalk/image-mirror", + "created": "2026-09-18T07:57:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/sickcodes/Docker-OSX/issues/889", + "title": "Error response from daemon: manifest for sickcodes/docker-osx:naked not found: manifest unknown: manifest unknown", + "repo": "sickcodes/Docker-OSX", + "created": "2025-06-25T04:07:51Z", + "state": "open", + "comments": 6, + "verified": true + } + ], + "precision": 0.9333333333333333, + "adjusted": 6911 +} \ No newline at end of file diff --git a/bench/data/kernel--vm-max-map-count.json b/bench/data/kernel--vm-max-map-count.json new file mode 100644 index 0000000..d896ff4 --- /dev/null +++ b/bench/data/kernel--vm-max-map-count.json @@ -0,0 +1,280 @@ +{ + "category": "kernel: vm.max_map_count", + "rule": "kernel.sysctl", + "query": "\"vm.max_map_count\" \"is too low\" is:issue created:>=2021-01-01", + "total": 369, + "sample": [ + { + "url": "https://github.com/memgraph/memgraph/issues/3881", + "title": "v3.8.x hard-exits when vm.max_map_count < 262144 in IN_MEMORY_ANALYTICAL mode", + "repo": "memgraph/memgraph", + "created": "2026-03-10T04:06:02Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/isejalabs/homelab/issues/134", + "title": "Mongo startup message `vm.max_map_count is too low`", + "repo": "isejalabs/homelab", + "created": "2024-12-27T11:28:02Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/seonwoojh/TIL/issues/4", + "title": "[elasticsearch] max virtual memory areas vm.max_map_count [65530] is too low", + "repo": "seonwoojh/TIL", + "created": "2022-07-07T00:59:59Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/elastic/elasticsearch/issues/86634", + "title": "Max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]", + "repo": "elastic/elasticsearch", + "created": "2022-05-10T18:22:04Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/wazuh/wazuh-docker/issues/2403", + "title": "Issues docker compose multi node possible solutions", + "repo": "wazuh/wazuh-docker", + "created": "2026-05-18T06:10:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/questdb/documentation/issues/370", + "title": "Update /deployment/docker", + "repo": "questdb/documentation", + "created": "2026-02-18T11:33:29Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/3450", + "title": "[BUG] `/proc/sys/vm/max_map_count` from host is not leveraged for running containers", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2022-11-23T18:13:25Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/MarquezProject/marquez/issues/3025", + "title": "Docker - OpenSearch Installation Documentation", + "repo": "MarquezProject/marquez", + "created": "2025-01-30T03:41:12Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/opensearch-project/OpenSearch/issues/6925", + "title": "TroubleShooting Guide for students, later to transfer for DEVELOPER.md as single source of truth ", + "repo": "opensearch-project/OpenSearch", + "created": "2023-04-01T07:09:52Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/memgraph/memgraph/issues/3607", + "title": "Data persistence issue when deploying Memgraph with Docker on Railway - seeking backup/restore solutions", + "repo": "memgraph/memgraph", + "created": "2026-01-04T21:52:09Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/aprenderdevops/docker-sonarqube/issues/1", + "title": "Sonarqube container error", + "repo": "aprenderdevops/docker-sonarqube", + "created": "2022-05-03T15:05:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Enigma-IIITS/enigma-site/issues/7", + "title": "explore and try to fix Mongo db startup warnings in Digital Ocean VM", + "repo": "Enigma-IIITS/enigma-site", + "created": "2024-02-24T10:57:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/opensearch-project/project-website/issues/354", + "title": "[BUG] Suggested docker-compose.yml doesn't work with Docker Desktop for Windows, WSL2 mode", + "repo": "opensearch-project/project-website", + "created": "2021-10-01T14:42:54Z", + "state": "open", + "comments": 17, + "verified": true + }, + { + "url": "https://github.com/Tae4an/Smart-Office/issues/28", + "title": "ELK Stack \ud658\uacbd \uc124\uc815 \ubc0f \uc77c\ubc18\uc801\uc778 \ubb38\uc81c \ud574\uacb0 \uac00\uc774\ub4dc", + "repo": "Tae4an/Smart-Office", + "created": "2024-11-20T13:39:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ddev/ddev-elasticsearch/issues/11", + "title": "[question]: Elastic Enterprise Search", + "repo": "ddev/ddev-elasticsearch", + "created": "2023-07-18T01:58:34Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/bryanlittlefield/TUGBOAT/issues/82", + "title": "Add Elastic Search Container + Configs", + "repo": "bryanlittlefield/TUGBOAT", + "created": "2022-06-09T16:22:17Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/opensearch-project/OpenSearch-Dashboards/issues/3759", + "title": "TroubleShooting Guide for students, later to transfer for DEVELOPER Guide.md as single source of truth", + "repo": "opensearch-project/OpenSearch-Dashboards", + "created": "2023-03-31T21:51:44Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/r-universe-org/help/issues/509", + "title": "MongoDB 8 server warnings", + "repo": "r-universe-org/help", + "created": "2024-10-10T13:15:45Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/rkaehdaos/docker-elk/issues/14", + "title": "fix error", + "repo": "rkaehdaos/docker-elk", + "created": "2022-03-24T01:55:51Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/arangodb/kube-arangodb/issues/1303", + "title": "Setup initContainer for recommended sysctls", + "repo": "arangodb/kube-arangodb", + "created": "2023-04-28T12:25:52Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/elastic/elasticsearch/issues/101401", + "title": "Fix docker compose default \"Getting Started\"", + "repo": "elastic/elasticsearch", + "created": "2023-10-26T18:48:34Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/713", + "title": "Increase open file limit in the VM / inside containers", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2021-10-01T16:12:18Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/anaer/blog/issues/169", + "title": "elasticsearch-7.6.2\u5b89\u88c5", + "repo": "anaer/blog", + "created": "2025-11-11T07:59:21Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/soon530/data-study/issues/31", + "title": "MongoDB \u4e92\u52d5\u4e00\u4e0b", + "repo": "soon530/data-study", + "created": "2022-11-04T09:04:34Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/UW-COSMOS/Cosmos/issues/167", + "title": "Elasticsearch virtual memory error", + "repo": "UW-COSMOS/Cosmos", + "created": "2022-08-12T08:20:37Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/community-scripts/ProxmoxVED/issues/2139", + "title": "Elasticsearch", + "repo": "community-scripts/ProxmoxVED", + "created": "2026-08-04T06:36:37Z", + "state": "closed", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/aws/containers-roadmap/issues/1452", + "title": "[Fargate] [request]: EKS Fargate not allowing to set system limits on mmap counts require to run Elasticsearch", + "repo": "aws/containers-roadmap", + "created": "2021-07-27T12:36:36Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/Mininglamp-OSS/octo-deployment/issues/179", + "title": "feat: add vm.max_map_count preflight check before starting search profile (OpenSearch)", + "repo": "Mininglamp-OSS/octo-deployment", + "created": "2026-08-13T08:09:48Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/nestybox/sysbox/issues/351", + "title": "EPERM during setrlimit() execution prevents apps from initializing", + "repo": "nestybox/sysbox", + "created": "2021-07-14T23:50:47Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/agentscope-ai/AgentTeams/issues/888", + "title": "v1.1.2 ERROR: Higress Gateway not ready after 120s", + "repo": "agentscope-ai/AgentTeams", + "created": "2026-05-30T18:52:00Z", + "state": "open", + "comments": 11, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 369 +} \ No newline at end of file diff --git a/bench/data/memory--mssql-minimum.json b/bench/data/memory--mssql-minimum.json new file mode 100644 index 0000000..15f7f54 --- /dev/null +++ b/bench/data/memory--mssql-minimum.json @@ -0,0 +1,280 @@ +{ + "category": "memory: mssql minimum", + "rule": "resources.memory", + "query": "\"requires a machine with at least 2000 megabytes\" is:issue created:>=2021-01-01", + "total": 4653, + "sample": [ + { + "url": "https://github.com/ultralytics/yolov5/issues/2000", + "title": "Live streaming after Cloud Engine", + "repo": "ultralytics/yolov5", + "created": "2021-01-21T04:46:17Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/ultrabug/py3status/issues/2000", + "title": "`window` does not work under sway", + "repo": "ultrabug/py3status", + "created": "2021-01-18T19:19:09Z", + "state": "closed", + "comments": 4, + "verified": false + }, + { + "url": "https://github.com/Waiviogit/waivio/issues/2000", + "title": "Remove the intermediate screen waivio when loading the site", + "repo": "Waiviogit/waivio", + "created": "2021-02-10T09:14:50Z", + "state": "closed", + "comments": 2, + "verified": false + }, + { + "url": "https://github.com/actesrun/appcenter-alerting-test-int/issues/2000", + "title": "Fix System.IO.IOException: Network down in Crash Group # 4054616594u", + "repo": "actesrun/appcenter-alerting-test-int", + "created": "2021-08-26T10:29:29Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/KadeArchive/Kade-Engine/issues/2000", + "title": "Chart Speed Bug", + "repo": "KadeArchive/Kade-Engine", + "created": "2021-08-26T13:03:09Z", + "state": "open", + "comments": 2, + "verified": false + }, + { + "url": "https://github.com/type-challenges/type-challenges/issues/2000", + "title": "14 - First of Array", + "repo": "type-challenges/type-challenges", + "created": "2021-06-28T11:19:30Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/DarkPacks/SkyFactory-4/issues/2000", + "title": "SK4 v4.2.2 crashes on SSP world-load ; `IllegalStateException: failed to create a child event loop`", + "repo": "DarkPacks/SkyFactory-4", + "created": "2021-11-20T10:06:10Z", + "state": "open", + "comments": 3, + "verified": false + }, + { + "url": "https://github.com/julia-vscode/julia-vscode/issues/2000", + "title": "Use VS-Code integrated terminal insted of VS-Code system terminal", + "repo": "julia-vscode/julia-vscode", + "created": "2021-03-06T03:30:05Z", + "state": "closed", + "comments": 9, + "verified": false + }, + { + "url": "https://github.com/tarantool/doc/issues/2000", + "title": "[1pt] Give link from Getting started with Cartridge to the Cartridge docs", + "repo": "tarantool/doc", + "created": "2021-03-26T08:02:06Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/swig/swig/issues/2000", + "title": "Swig go not working with output char * argument", + "repo": "swig/swig", + "created": "2021-04-22T08:55:28Z", + "state": "closed", + "comments": 2, + "verified": false + }, + { + "url": "https://github.com/espruino/Espruino/issues/2000", + "title": "advertising broken with S140 >= 6.1.0", + "repo": "espruino/Espruino", + "created": "2021-04-21T22:48:13Z", + "state": "closed", + "comments": 12, + "verified": false + }, + { + "url": "https://github.com/wandb/wandb/issues/2000", + "title": "[Feature] Add support for running Wandb inside of a celery task", + "repo": "wandb/wandb", + "created": "2021-03-24T19:40:47Z", + "state": "closed", + "comments": 2, + "verified": false + }, + { + "url": "https://github.com/mainIine/foe-helfer-extension/issues/2000", + "title": "Bug: Menu Content settings with right menu not aligned correctly", + "repo": "mainIine/foe-helfer-extension", + "created": "2021-05-05T08:30:03Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/bigcommerce/cornerstone/issues/2000", + "title": "concat combined with json is returning an object with a string parameter", + "repo": "bigcommerce/cornerstone", + "created": "2021-02-28T03:39:30Z", + "state": "closed", + "comments": 3, + "verified": false + }, + { + "url": "https://github.com/airsdk/Adobe-Runtime-Support/issues/2000", + "title": "Dealing with emojis \ud83d\ude0c", + "repo": "airsdk/Adobe-Runtime-Support", + "created": "2022-07-01T11:32:55Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/aceblockID/monitoring/issues/2000", + "title": "\ud83d\uded1 AceBlock Swagger UI is down", + "repo": "aceblockID/monitoring", + "created": "2022-07-16T14:27:18Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/dapr/components-contrib/issues/2000", + "title": "[redis Configuration Api]The specified redisDB should be supported", + "repo": "dapr/components-contrib", + "created": "2022-08-23T05:54:53Z", + "state": "open", + "comments": 7, + "verified": false + }, + { + "url": "https://github.com/xlwings/xlwings/issues/2000", + "title": "pivot_item.visible does not work ", + "repo": "xlwings/xlwings", + "created": "2022-08-26T06:21:23Z", + "state": "closed", + "comments": 4, + "verified": false + }, + { + "url": "https://github.com/kubernetes-sigs/controller-runtime/issues/2000", + "title": "Add a util method to recognize if resource in reconcile loop is being deleted", + "repo": "kubernetes-sigs/controller-runtime", + "created": "2022-09-13T16:06:04Z", + "state": "closed", + "comments": 7, + "verified": false + }, + { + "url": "https://github.com/FreezingMoon/AncientBeast/issues/2000", + "title": "proper hexagon tile hovering [bounty: 35 XTR]", + "repo": "FreezingMoon/AncientBeast", + "created": "2022-01-01T04:39:15Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/BetaMasaheft/Documentation/issues/2000", + "title": "HTTP ERROR 500 EMML6451", + "repo": "BetaMasaheft/Documentation", + "created": "2022-03-10T15:58:35Z", + "state": "closed", + "comments": 3, + "verified": false + }, + { + "url": "https://github.com/TrueBlocks/trueblocks-core/issues/2000", + "title": "Names: database doesn't populate", + "repo": "TrueBlocks/trueblocks-core", + "created": "2022-01-07T20:21:31Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/javisu/monitor/issues/2000", + "title": "\ud83d\uded1 Joaquin Bau, 5 is down", + "repo": "javisu/monitor", + "created": "2022-06-07T19:52:25Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/incubateur-ademe/territoires-en-transitions/issues/2000", + "title": "Mettre la partie longue du titre en description CAE 5.1.1.1.3", + "repo": "incubateur-ademe/territoires-en-transitions", + "created": "2022-05-23T15:39:56Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/glium/glium/issues/2000", + "title": "clear_color_srgb(red: 0.0,green: 0.0,blue: 0.0,alpha: 0.0) ot working", + "repo": "glium/glium", + "created": "2022-03-19T14:46:26Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/apache/hop/issues/2000", + "title": "[Task]: Cleanup XML of action Wait for SQL", + "repo": "apache/hop", + "created": "2022-12-07T11:07:04Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/withfig/fig/issues/2000", + "title": "bug: Autocomplete pupup always in top left corner of Alacritty", + "repo": "withfig/fig", + "created": "2022-11-06T09:17:10Z", + "state": "closed", + "comments": 12, + "verified": false + }, + { + "url": "https://github.com/devfsa/vagas/issues/2000", + "title": "[Remoto] Frontend Angular Developer na Coodesh", + "repo": "devfsa/vagas", + "created": "2022-10-28T15:20:19Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/Oleksandra2/QAGreen/issues/2000", + "title": "Tutorial Page abap-environment-create-service-consumption-model.md Issue. LOCAL", + "repo": "Oleksandra2/QAGreen", + "created": "2023-01-19T05:02:00Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/tahowallet/extension/issues/2000", + "title": "Gwei gas prices are not updating live on Optimism", + "repo": "tahowallet/extension", + "created": "2022-08-22T13:45:59Z", + "state": "closed", + "comments": 3, + "verified": false + } + ], + "precision": 0.0, + "adjusted": 0 +} \ No newline at end of file diff --git a/bench/data/memory--oomkilled.json b/bench/data/memory--oomkilled.json new file mode 100644 index 0000000..de24fa4 --- /dev/null +++ b/bench/data/memory--oomkilled.json @@ -0,0 +1,280 @@ +{ + "category": "memory: OOMKilled", + "rule": "resources.memory", + "query": "OOMKilled \"exit code 137\" is:issue created:>=2021-01-01", + "total": 97607, + "sample": [ + { + "url": "https://github.com/devmahmoudi/laravel-todolist/issues/76", + "title": "resolve Docker process exit code 137 in GitHub Actions CI/CD pipeline", + "repo": "devmahmoudi/laravel-todolist", + "created": "2025-11-10T09:13:51Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/kestra-io/plugin-kubernetes/issues/339", + "title": "io.kestra.plugin.kubernetes.PodCreate Fails with Exit Code 137 Despite Resource Limits", + "repo": "kestra-io/plugin-kubernetes", + "created": "2025-06-10T09:56:28Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/Jersyfi/taktus/issues/29", + "title": "The container adapter's memory-kill test is flaky: the engine does not always report OOMKilled", + "repo": "Jersyfi/taktus", + "created": "2026-09-23T12:52:31Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/apache/airflow/issues/73164", + "title": "KubernetesExecutor: Event log says \"Pod failed because of None\" for OOMKilled pods", + "repo": "apache/airflow", + "created": "2026-09-15T06:42:02Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/KDM-cli/kdm-cli/issues/275", + "title": "[v4.0.0] Phase 4: Deterministic Kubernetes/Docker Failure Rule Engine", + "repo": "KDM-cli/kdm-cli", + "created": "2026-09-10T22:48:57Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/open-telemetry/opentelemetry-demo/issues/3811", + "title": "[prometheus] Default Helm memory limit can cause an OOMKilled restart loop", + "repo": "open-telemetry/opentelemetry-demo", + "created": "2026-08-06T03:21:53Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/MaRDI4NFDI/MaRDIRoadmap/issues/235", + "title": "qlever-updater OOMKilled crash loop due to insufficient memory limit", + "repo": "MaRDI4NFDI/MaRDIRoadmap", + "created": "2026-09-17T07:33:09Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/world-federation-of-advertisers/cross-media-measurement/issues/4500", + "title": "edp-aggregator API servers are OOMKilled under VID-labeling load, hanging edpa-cloud-test", + "repo": "world-federation-of-advertisers/cross-media-measurement", + "created": "2026-09-12T14:33:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/AstrBotDevs/shipyard-neo/issues/32", + "title": "Warm Pool \u6b63\u5e38\u8f6e\u6362\u65f6\u5f3a\u5236\u5220\u9664\u8fd0\u884c\u4e2d\u5bb9\u5668\uff0c\u5bfc\u81f4 SIGKILL / Exit Code 137", + "repo": "AstrBotDevs/shipyard-neo", + "created": "2026-09-05T14:22:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/zyra-project/zyra/issues/153", + "title": "`visualize-timeseries` crashes with OOM (exit code 137) in headless/Kubernetes environments", + "repo": "zyra-project/zyra", + "created": "2026-04-27T20:38:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/achourisoufiene/cylmaaaaaaaaa/issues/1", + "title": "[Test] OOMKilled error in Docker container", + "repo": "achourisoufiene/cylmaaaaaaaaa", + "created": "2026-06-08T23:20:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/BarminGeorge/ShuKnow/issues/137", + "title": "\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435: \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u0438 \u0432 \u0447\u0430\u0442\u0435", + "repo": "BarminGeorge/ShuKnow", + "created": "2026-04-24T07:33:55Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/ChatLab/ChatLab/issues/137", + "title": "\u5916\u90e8\u57df\u540d\u8bf7\u6c42\u5b58\u5728\u5b89\u5168\u98ce\u9669", + "repo": "ChatLab/ChatLab", + "created": "2026-04-13T12:52:11Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/parkerhancock/patent_client/issues/137", + "title": "\"Event Loop is closed\"/Deadlocks for simultaneous requests", + "repo": "parkerhancock/patent_client", + "created": "2024-01-10T17:10:06Z", + "state": "closed", + "comments": 4, + "verified": false + }, + { + "url": "https://github.com/ImAdrenalize/qkd-digital-twin-project/issues/137", + "title": "Development environment", + "repo": "ImAdrenalize/qkd-digital-twin-project", + "created": "2026-04-04T20:30:31Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/modelcontextprotocol/registry/issues/137", + "title": "Document convention: server.json presence in package artifact", + "repo": "modelcontextprotocol/registry", + "created": "2025-06-13T13:09:59Z", + "state": "closed", + "comments": 6, + "verified": false + }, + { + "url": "https://github.com/ITU-DevOps2026/ITU-minitwit/issues/137", + "title": "Refactor - Function that fetches own timeline is very slow", + "repo": "ITU-DevOps2026/ITU-minitwit", + "created": "2026-04-11T19:40:12Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/okdevme/DiscordPlugins/issues/137", + "title": "ChannelsPreview error with new update", + "repo": "okdevme/DiscordPlugins", + "created": "2025-09-26T15:45:53Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/knishioka/ib-sec-mcp/issues/137", + "title": "bug(validators): validate_isin rejects valid ISINs (Luhn check digit bug)", + "repo": "knishioka/ib-sec-mcp", + "created": "2026-06-04T06:24:10Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/PRX/The-World-FE-Nextjs/issues/137", + "title": "Opt website out of Google FLoC", + "repo": "PRX/The-World-FE-Nextjs", + "created": "2021-04-29T16:46:50Z", + "state": "closed", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/hasherwi/Archipelago-kirbyam/issues/137", + "title": "Refactor KirbyAM address schema: separate AP transport mailbox from native game-state flags", + "repo": "hasherwi/Archipelago-kirbyam", + "created": "2026-03-19T15:50:59Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/margaritauk/home-offer-direct/issues/137", + "title": "As a buyer, I want to manually update my offer status when the agent responds so that my dashboard reflects reality", + "repo": "margaritauk/home-offer-direct", + "created": "2026-06-03T19:10:12Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/gocronx-team/gocron/issues/137", + "title": "feat: task template management, script versioning, and code editor", + "repo": "gocronx-team/gocron", + "created": "2026-04-17T00:45:52Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/ix-infrastructure/Ix/issues/137", + "title": "Add R parser support (.r, .R)", + "repo": "ix-infrastructure/Ix", + "created": "2026-04-03T21:56:12Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/Shaurya1907/PYSCHECARE-main/issues/137", + "title": "docs: CODE_OF_CONDUCT.md Missing", + "repo": "Shaurya1907/PYSCHECARE-main", + "created": "2026-06-05T19:45:18Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/eslint/eslint-github-bot/issues/137", + "title": "shorten the text in the comment, to make less annoying", + "repo": "eslint/eslint-github-bot", + "created": "2021-01-22T03:14:08Z", + "state": "closed", + "comments": 7, + "verified": false + }, + { + "url": "https://github.com/robe070/cookbooks/issues/137", + "title": "Implement AWS JPN images CI pipelines", + "repo": "robe070/cookbooks", + "created": "2021-03-30T03:12:15Z", + "state": "closed", + "comments": 4, + "verified": false + }, + { + "url": "https://github.com/denoland/denokv/issues/137", + "title": "remote: expired metadata token is used without refresh or retry, surfacing auth errors to callers", + "repo": "denoland/denokv", + "created": "2026-06-05T19:35:13Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/plures/pares-radix/issues/137", + "title": "[ci-feedback] Post-merge CI failure at c2cfd14", + "repo": "plures/pares-radix", + "created": "2026-05-14T22:14:21Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/aliendomain/workable/issues/137", + "title": "Remove public id-based system and definition APIs", + "repo": "aliendomain/workable", + "created": "2026-06-06T23:55:08Z", + "state": "closed", + "comments": 0, + "verified": false + } + ], + "precision": 0.36666666666666664, + "adjusted": 35789 +} \ No newline at end of file diff --git a/bench/data/network-not-found.json b/bench/data/network-not-found.json new file mode 100644 index 0000000..495852d --- /dev/null +++ b/bench/data/network-not-found.json @@ -0,0 +1,280 @@ +{ + "category": "network not found", + "rule": "", + "query": "docker \"network\" \"not found\" compose is:issue created:>=2021-01-01", + "total": 18407, + "sample": [ + { + "url": "https://github.com/tmwclaxton/clashofdots/issues/12", + "title": "INC: LGS Pipeline deploy recreate \u2014 Compose temp name not found (2026-09-18)", + "repo": "tmwclaxton/clashofdots", + "created": "2026-09-18T20:22:50Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/tmwclaxton/clashofdots/issues/11", + "title": "INC: LGS Pipeline ctr not found after Compose mid-replace rename (2026-09-18)", + "repo": "tmwclaxton/clashofdots", + "created": "2026-09-18T20:21:23Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/Finsys/dockhand/issues/1493", + "title": "[BUG] env file not found with remote host running Hawser", + "repo": "Finsys/dockhand", + "created": "2026-08-30T06:40:19Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/microsoft/vscode/issues/331774", + "title": "Git diff fails with GitFileSystemProvider Repository not found on Windows", + "repo": "microsoft/vscode", + "created": "2026-08-20T10:46:14Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/orkestra-cc/orkestra/issues/300", + "title": "bug: backup.sh reports rustfs as backed up when the S3 sync fails (network not found)", + "repo": "orkestra-cc/orkestra", + "created": "2026-08-26T19:27:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/JoeRegnier/retiree-plan/issues/138", + "title": "Cannot bootstrap myself using Docker", + "repo": "JoeRegnier/retiree-plan", + "created": "2026-09-19T14:40:02Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/treeseed-ai/deployment/issues/369", + "title": "Remove active TreeSeed Compose endpoints before managed networks", + "repo": "treeseed-ai/deployment", + "created": "2026-09-01T03:29:55Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/cameri/schematics/issues/88", + "title": "restrict-docker-api-access: skeleton pins a nonexistent image, tecnativa/restrict-docker-api-access", + "repo": "cameri/schematics", + "created": "2026-09-20T13:14:10Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/filippolmt/toolbox/issues/969", + "title": "Make the session container's network configurable, and keep local Docker networks off VPN-routed subnets", + "repo": "filippolmt/toolbox", + "created": "2026-09-09T15:48:43Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/OpenSDLC-Dev/managed-agent-platform/issues/467", + "title": "executor: validate SANDBOX_DOCKER_GATE_NETWORK at startup \u2014 a wrong-but-existing gate network fails silently, per session", + "repo": "OpenSDLC-Dev/managed-agent-platform", + "created": "2026-08-23T04:02:28Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Proaxiom-Cyber/guacamole-saml-sso/issues/30", + "title": "Diagnose nginx network loss after port conflict and improve installer recovery", + "repo": "Proaxiom-Cyber/guacamole-saml-sso", + "created": "2026-09-23T04:51:33Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/petercort/chaotic-ecommerce/issues/2", + "title": "[Chaos] S7: JVM Heap Exhaustion \u2014 Docker network not found (stale network name from Java-era compose)", + "repo": "petercort/chaotic-ecommerce", + "created": "2026-04-22T01:06:12Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/unihosted/unifi-os-server-docker/issues/4", + "title": "Network Application not always comming up after host reboot", + "repo": "unihosted/unifi-os-server-docker", + "created": "2026-07-31T10:01:33Z", + "state": "open", + "comments": 7, + "verified": false + }, + { + "url": "https://github.com/Finsys/dockhand/issues/1278", + "title": "[BUG] Stack creation from Git fails with external network not found, while local Compose and regular stack creation work", + "repo": "Finsys/dockhand", + "created": "2026-07-11T13:13:18Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/kasmtech/workspaces-issues/issues/673", + "title": "[Bug] - network not found", + "repo": "kasmtech/workspaces-issues", + "created": "2024-12-26T23:11:14Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/docker/desktop-feedback/issues/645", + "title": "docker vmm does not use the docker CLI", + "repo": "docker/desktop-feedback", + "created": "2026-09-01T11:41:13Z", + "state": "open", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/groupsky/homy/issues/1559", + "title": "ci: subnet-overlap guards check example.env only, so a host whose .env differs is unprotected", + "repo": "groupsky/homy", + "created": "2026-09-08T21:33:43Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/vale46n1/immich_duplicate_finder/issues/57", + "title": "Network bridge not found", + "repo": "vale46n1/immich_duplicate_finder", + "created": "2025-01-22T16:30:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/testcontainers/testcontainers-go/issues/2952", + "title": "[Bug]: `panic: rootless Docker not found` with Colima on macos", + "repo": "testcontainers/testcontainers-go", + "created": "2025-01-30T17:18:49Z", + "state": "open", + "comments": 9, + "verified": false + }, + { + "url": "https://github.com/goharbor/harbor/issues/23001", + "title": "CSRF token not found in request", + "repo": "goharbor/harbor", + "created": "2026-03-16T14:44:33Z", + "state": "open", + "comments": 7, + "verified": false + }, + { + "url": "https://github.com/smokin-salmon/smoked-salmon/issues/426", + "title": "Spectrals web server not working; `/spectrals` results in 404 not found; welcome page on `/` is served", + "repo": "smokin-salmon/smoked-salmon", + "created": "2026-07-15T04:23:36Z", + "state": "open", + "comments": 3, + "verified": false + }, + { + "url": "https://github.com/rtCamp/Frappe-Manager/issues/480", + "title": "Bench nginx races the frappe container at startup; compose templates define no restart policy, depends_on, or healthchecks", + "repo": "rtCamp/Frappe-Manager", + "created": "2026-09-20T18:10:19Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/deepfence/ThreatMapper/issues/2425", + "title": "Docker Compose Deployment - 404 page not found", + "repo": "deepfence/ThreatMapper", + "created": "2025-07-19T15:15:37Z", + "state": "open", + "comments": 8, + "verified": false + }, + { + "url": "https://github.com/FullStack-AITech/Online-Shop-Microservices/issues/71", + "title": "Kafka: create topics from a one-shot init container", + "repo": "FullStack-AITech/Online-Shop-Microservices", + "created": "2026-09-23T16:10:25Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/chatwoot/chatwoot/issues/15404", + "title": "WhatsApp Cloud API and Dualhook: outbound messages from Chatwoot UI fail with `Not found`, while inbound and direct sends work", + "repo": "chatwoot/chatwoot", + "created": "2026-08-10T20:16:48Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/R-s0n/ars0n-framework-v2/issues/117", + "title": "x8 build stage fails during `docker-compose up --build` \u2014 404 on openssl (stale bullseye-security mirror)", + "repo": "R-s0n/ars0n-framework-v2", + "created": "2026-09-12T13:45:38Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/moby/moby/issues/44403", + "title": "Swarm: network none not found", + "repo": "moby/moby", + "created": "2022-11-03T11:53:19Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/achimdehnert/platform/issues/2389", + "title": "deploy.sh: 'compose run --rm' und 'up -d --force-recreate' konkurrieren um das Projekt-Netz", + "repo": "achimdehnert/platform", + "created": "2026-08-27T12:41:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/UNITRONIX/BetterDesk/issues/385", + "title": "/opt/rustdesk/.admin_credentials credentials do not work on Docker version of BetterDesk (docker-compose.single.yml and docker-compose.quick.yml builds)", + "repo": "UNITRONIX/BetterDesk", + "created": "2026-08-24T12:30:11Z", + "state": "open", + "comments": 18, + "verified": false + }, + { + "url": "https://github.com/PascaleBeier/hitkeep/issues/353", + "title": "[Bug]: s3 backup status failing; duckdb httpfs extension loading", + "repo": "PascaleBeier/hitkeep", + "created": "2026-09-21T18:45:46Z", + "state": "open", + "comments": 5, + "verified": false + } + ], + "precision": 0.3333333333333333, + "adjusted": 6136 +} \ No newline at end of file diff --git a/bench/data/oci-runtime-exec-failed.json b/bench/data/oci-runtime-exec-failed.json new file mode 100644 index 0000000..1b1d7ae --- /dev/null +++ b/bench/data/oci-runtime-exec-failed.json @@ -0,0 +1,280 @@ +{ + "category": "OCI runtime exec failed", + "rule": "", + "query": "\"OCI runtime exec failed\" is:issue created:>=2021-01-01", + "total": 3479, + "sample": [ + { + "url": "https://github.com/mdubourg001/glci/issues/14", + "title": "OCI runtime exec failed", + "repo": "mdubourg001/glci", + "created": "2021-02-24T21:58:28Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/lockc-project/lockc/issues/184", + "title": "OCI runtime exec failed", + "repo": "lockc-project/lockc", + "created": "2022-02-24T14:17:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/shimataro/ssh-key-action/issues/196", + "title": "OCI runtime exec failed", + "repo": "shimataro/ssh-key-action", + "created": "2021-11-30T13:40:48Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Finsys/dockhand/issues/1519", + "title": "[BUG] Exec/shell fails with exec: \"/app/dockhand\": on direct-connections", + "repo": "Finsys/dockhand", + "created": "2026-09-04T01:35:49Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Twinki14/palworld-server-chart/issues/38", + "title": "Enabling TCP health check breaks daily reboot cronjob", + "repo": "Twinki14/palworld-server-chart", + "created": "2026-08-20T23:32:55Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/opf/openproject-docker-compose/issues/150", + "title": "Healthcheck for web container fails!", + "repo": "opf/openproject-docker-compose", + "created": "2026-03-11T14:40:21Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/NinjaMonkeyGames/palette-controller-professional/issues/3", + "title": "Unit Tests on CI is Broken", + "repo": "NinjaMonkeyGames/palette-controller-professional", + "created": "2026-08-27T00:39:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Datura-ai/lium-io/issues/190", + "title": "Adding an Executor", + "repo": "Datura-ai/lium-io", + "created": "2025-01-15T06:31:14Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/ResearchDataCom/actions/issues/9", + "title": "Linting fails when run via Act due to missing commands", + "repo": "ResearchDataCom/actions", + "created": "2026-07-29T22:26:57Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/CLOUDIS-log-analysis/lets-reproduce-logs/issues/2", + "title": "\uc7ac\ud604 \uae30\ub85d", + "repo": "CLOUDIS-log-analysis/lets-reproduce-logs", + "created": "2026-08-15T09:27:31Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/tbmobb813/WireAssist/issues/180", + "title": "DEPLOYMENT.md's debug command doesn't work \u2014 wget isn't in the runtime image", + "repo": "tbmobb813/WireAssist", + "created": "2026-08-24T08:17:36Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Minsolimbu/dokploy/issues/7", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "Minsolimbu/dokploy", + "created": "2025-10-05T20:38:08Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Muhammad7839/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "Muhammad7839/dokploy", + "created": "2025-09-30T02:07:22Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/timothy1ee/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "timothy1ee/dokploy", + "created": "2025-09-30T01:38:09Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/JanteZhou/dokploy/issues/5", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "JanteZhou/dokploy", + "created": "2025-09-30T01:31:27Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/aliasofsyn/dokploy/issues/4", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "aliasofsyn/dokploy", + "created": "2025-09-30T00:45:23Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docksal/docksal/issues/1856", + "title": "fin db create broken with MariaDB 11.4", + "repo": "docksal/docksal", + "created": "2026-07-20T10:16:48Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/williamyang10/dokploy/issues/7", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "williamyang10/dokploy", + "created": "2025-10-12T23:30:11Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/zenocross/dokploy/issues/5", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "zenocross/dokploy", + "created": "2025-12-10T09:07:03Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/davidfmajek/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "davidfmajek/dokploy", + "created": "2025-09-30T03:51:57Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nathanz19/dokploy/issues/1", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "nathanz19/dokploy", + "created": "2025-09-30T03:28:19Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Thenewgirl04/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "Thenewgirl04/dokploy", + "created": "2025-09-30T01:43:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nehaask/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "nehaask/dokploy", + "created": "2025-09-30T01:08:01Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Praise-creator/dokploy/issues/5", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "Praise-creator/dokploy", + "created": "2025-09-30T00:17:33Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ishs-cloud-computing/eks-study/issues/34", + "title": "[PART-2] module-07: distroless \ucee8\ud14c\uc774\ub108\uc5d0\uc11c JWT \ud1a0\ud070 \ud30c\uc77c \uc811\uadfc \ubd88\uac00", + "repo": "ishs-cloud-computing/eks-study", + "created": "2026-05-31T05:58:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/seunshix/dokploy/issues/7", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "seunshix/dokploy", + "created": "2025-10-10T15:32:58Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nwang10/dokploy/issues/7", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "nwang10/dokploy", + "created": "2025-10-11T14:30:01Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ArmaghanAb/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "ArmaghanAb/dokploy", + "created": "2025-09-30T03:45:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/AbdoulayeSedego/dokploy/issues/3", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "AbdoulayeSedego/dokploy", + "created": "2025-09-30T03:44:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/funny1dog/dokploy/issues/4", + "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", + "repo": "funny1dog/dokploy", + "created": "2025-09-30T00:29:47Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 3479 +} \ No newline at end of file diff --git a/bench/data/platform--exec-format-error.json b/bench/data/platform--exec-format-error.json new file mode 100644 index 0000000..b2ddc91 --- /dev/null +++ b/bench/data/platform--exec-format-error.json @@ -0,0 +1,280 @@ +{ + "category": "platform: exec format error", + "rule": "image.platform", + "query": "\"exec format error\" docker is:issue created:>=2021-01-01", + "total": 5372, + "sample": [ + { + "url": "https://github.com/pashword/pashword/issues/24", + "title": "docker compose install not working", + "repo": "pashword/pashword", + "created": "2026-09-17T05:29:36Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/onecli/onecli/issues/489", + "title": "exec /usr/local/bin/docker-entrypoint.sh: exec format error", + "repo": "onecli/onecli", + "created": "2026-08-11T13:07:20Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/imagegenius/docker-immich/issues/810", + "title": "When pulling >= v3 on unraid I get an error - Exec format error", + "repo": "imagegenius/docker-immich", + "created": "2026-09-03T20:16:57Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/Muatasim-Aswad/job-tracker/issues/26", + "title": "[Bug]: \"exec uvicorn failed: Exec format error\" when attempting to run job-tracker from docker", + "repo": "Muatasim-Aswad/job-tracker", + "created": "2026-09-11T09:54:57Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Turbootzz/Vaultwarden-API/issues/47", + "title": "Multi-arch image ships the amd64 binary for arm64/arm-v7 (exec format error)", + "repo": "Turbootzz/Vaultwarden-API", + "created": "2026-09-08T23:33:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ResearchDataCom/actions/issues/17", + "title": "\"Exec format error\" running pinact via ResearchDataCom/actions/pre-commit on ubuntu-24.04-arm runners", + "repo": "ResearchDataCom/actions", + "created": "2026-09-01T17:36:46Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Wei-Shaw/sub2api/issues/2061", + "title": "docker image bug\uff1adocker-entrypoint.sh: exec format error", + "repo": "Wei-Shaw/sub2api", + "created": "2026-04-28T09:58:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kimschles/k8s-microservices-examples/issues/1", + "title": "Exec format error", + "repo": "kimschles/k8s-microservices-examples", + "created": "2024-12-30T16:51:39Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dmccormack/nut-client/issues/2", + "title": "exec format error", + "repo": "dmccormack/nut-client", + "created": "2023-12-06T19:03:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/cubicecho/mcp-ragdown/issues/2", + "title": "Publish an arm64 (Apple Silicon) Docker image", + "repo": "cubicecho/mcp-ragdown", + "created": "2026-09-13T22:59:45Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/fonoster/fonoster/issues/862", + "title": "apiserver arm64 image is broken: ships amd64 dockerize binary (Exec format error)", + "repo": "fonoster/fonoster", + "created": "2026-07-02T14:06:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RedisTimeSeries/RedisTimeSeries/issues/869", + "title": "Docker image exec format error", + "repo": "RedisTimeSeries/RedisTimeSeries", + "created": "2021-10-26T17:27:52Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/675", + "title": "exec format error", + "repo": "AbdBarho/stable-diffusion-webui-docker", + "created": "2024-03-12T11:57:24Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/mporrato/alpine-h700/issues/1", + "title": "Exec format error", + "repo": "mporrato/alpine-h700", + "created": "2024-07-28T12:57:43Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/mercxry/p110-energy-monitor/issues/17", + "title": "exec format error", + "repo": "mercxry/p110-energy-monitor", + "created": "2023-03-20T07:54:54Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/getchoo-archive/packwiz-serve/issues/2", + "title": "Exec format error", + "repo": "getchoo-archive/packwiz-serve", + "created": "2023-12-07T03:32:17Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/ex0nuss/Remote-Wake-Sleep-On-LAN-Docker/issues/3", + "title": "exec format error", + "repo": "ex0nuss/Remote-Wake-Sleep-On-LAN-Docker", + "created": "2022-03-09T11:23:14Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/headroomlabs-ai/headroom/issues/2700", + "title": "[BUG] Docker arm64 image ships wrong-arch rtk binary \u2014 dashboard shows \"RTK not installed\" (Exec format error)", + "repo": "headroomlabs-ai/headroom", + "created": "2026-08-01T00:53:19Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/ewfian/faiss-node/issues/53", + "title": "Docker image fail : exec format error", + "repo": "ewfian/faiss-node", + "created": "2025-05-21T16:38:18Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/indiefan/home_assistant_nanit/issues/22", + "title": "exec format error", + "repo": "indiefan/home_assistant_nanit", + "created": "2025-01-24T01:28:50Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/rickraven/conntrack-exporter/issues/1", + "title": "Docker build defaults to amd64 binary on arm64 hosts (exec format error)", + "repo": "rickraven/conntrack-exporter", + "created": "2026-03-29T10:41:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/home-assistant/plugin-dns/issues/207", + "title": "amd64-hassio-dns:2026.08.0 image ships with 0-byte /usr/bin/coredns binary \u2014 DNS plugin fails to start with \"Exec format error\"", + "repo": "home-assistant/plugin-dns", + "created": "2026-08-24T19:45:33Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/christhomas/go-networkfs/issues/16", + "title": "Two test-server images are amd64-only, so the containerised suite cannot run on arm64", + "repo": "christhomas/go-networkfs", + "created": "2026-09-18T10:46:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/TheAppgineer/flatpak-flutter/issues/127", + "title": "docker run command isn't working for linux/arm64/v8", + "repo": "TheAppgineer/flatpak-flutter", + "created": "2026-09-20T09:31:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/argoproj-labs/argocd-ephemeral-access/issues/180", + "title": "Publish multi-arch images (linux/arm64)", + "repo": "argoproj-labs/argocd-ephemeral-access", + "created": "2026-09-02T12:48:12Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/monitoror/monitoror/issues/403", + "title": "exec format error", + "repo": "monitoror/monitoror", + "created": "2021-12-04T15:16:08Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/aws/context-ontology-accelerator/issues/51", + "title": "[Docs]: Update docker configuration instructions for cross-architecture builds", + "repo": "aws/context-ontology-accelerator", + "created": "2026-08-07T22:57:48Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/OCSInventory-NG/OCSInventory-Docker-Image/issues/89", + "title": "/docker-entrypoint.sh: exec format error", + "repo": "OCSInventory-NG/OCSInventory-Docker-Image", + "created": "2022-06-24T12:46:20Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/pathwae/proxy/issues/3", + "title": "Exec format error", + "repo": "pathwae/proxy", + "created": "2022-05-24T17:21:44Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/docker/desktop-feedback/issues/528", + "title": "4.82.0: WSL integration broken \u2014 docker-desktop-user-distro published as 0 bytes \u2192 \"Exec format error\"", + "repo": "docker/desktop-feedback", + "created": "2026-07-19T12:16:25Z", + "state": "open", + "comments": 1, + "verified": true + } + ], + "precision": 0.9666666666666667, + "adjusted": 5193 +} \ No newline at end of file diff --git a/bench/data/platform--no-matching-manifest.json b/bench/data/platform--no-matching-manifest.json new file mode 100644 index 0000000..fdab202 --- /dev/null +++ b/bench/data/platform--no-matching-manifest.json @@ -0,0 +1,271 @@ +{ + "category": "platform: no matching manifest", + "rule": "image.platform", + "query": "\"no matching manifest for\" is:issue created:>=2021-01-01", + "total": 2760, + "sample": [ + { + "url": "https://github.com/ggml-org/whisper.cpp/issues/2081", + "title": "Docker \"no matching manifest for `linux/arm64`\"", + "repo": "ggml-org/whisper.cpp", + "created": "2024-04-20T08:19:44Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/nextcloud/docker/issues/2601", + "title": "35-apache: Pulling from library/nextcloud - no matching manifest for linux/amd64 in the manifest list entries", + "repo": "nextcloud/docker", + "created": "2026-09-17T05:35:40Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/ray-manaloto/dotfiles/issues/985", + "title": "`:dev`'s amd64 half is unpullable on a GHA runner: `no matching manifest for linux/amd64`", + "repo": "ray-manaloto/dotfiles", + "created": "2026-09-09T01:55:15Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/debridmediamanager/debrid-media-manager/issues/146", + "title": "ERROR: no matching manifest for linux/amd64 in the manifest list entries", + "repo": "debridmediamanager/debrid-media-manager", + "created": "2024-12-07T00:08:46Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/NginxProxyManager/nginx-proxy-manager/issues/5379", + "title": "docker pull - no matching manifest for linux/arm/v8", + "repo": "NginxProxyManager/nginx-proxy-manager", + "created": "2026-03-06T06:14:16Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/Smeagolworms4/omv2mqtt/issues/4", + "title": "no matching manifest for linux/386", + "repo": "Smeagolworms4/omv2mqtt", + "created": "2026-03-17T15:25:17Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/lando/pantheon/issues/296", + "title": "no matching manifest for linux/arm64/v8", + "repo": "lando/pantheon", + "created": "2025-11-13T21:54:48Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/calcom/docker/issues/208", + "title": "no matching manifest for linux/arm64/v8", + "repo": "calcom/docker", + "created": "2023-01-30T06:21:20Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/GreenFrogSB/LMDS/issues/76", + "title": "no matching manifest for linux/arm/v8", + "repo": "GreenFrogSB/LMDS", + "created": "2023-10-21T18:58:19Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/helingfeng/Docker-LNMP/issues/10", + "title": "no matching manifest for linux/arm64/v8", + "repo": "helingfeng/Docker-LNMP", + "created": "2022-09-09T12:52:19Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/pglombardo/PasswordPusher/issues/4095", + "title": "Unable to update: \"no matching manifest for linux/arm64/v8\"", + "repo": "pglombardo/PasswordPusher", + "created": "2026-01-09T07:57:49Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/hassancs91/PyRunner/issues/3", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries error", + "repo": "hassancs91/PyRunner", + "created": "2026-05-23T02:13:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/coolguy1842/SaveSyncd/issues/13", + "title": "Mac arm64 compatibility (no matching manifest for linux/arm64/v8)", + "repo": "coolguy1842/SaveSyncd", + "created": "2026-02-18T19:57:39Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/papermerge/papermerge-core/issues/590", + "title": "Unable to pull papermerge/papermerge:3.4 no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "papermerge/papermerge-core", + "created": "2025-03-06T03:19:24Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/OpenCSGs/csghub/issues/661", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "OpenCSGs/csghub", + "created": "2024-09-23T07:51:19Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/SecuritySilverbacks/SAPMAP/issues/47", + "title": "[Documentation] pulling the prebuilt Docker image on macOS (Silicon)", + "repo": "SecuritySilverbacks/SAPMAP", + "created": "2026-09-17T08:20:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/naroat/tools-web/issues/16", + "title": "\u65e0\u6cd5\u62c9\u53d6Docker compose", + "repo": "naroat/tools-web", + "created": "2026-09-16T03:04:59Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/linkwarden/linkwarden/issues/273", + "title": "no matching manifest for linux/arm/v8 in the manifest list entries", + "repo": "linkwarden/linkwarden", + "created": "2023-11-03T15:58:04Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/alpinelinux/docker-alpine/issues/426", + "title": "no matching manifest for linux/amd64 in the manifest list entries", + "repo": "alpinelinux/docker-alpine", + "created": "2024-11-18T17:59:44Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/automation-avenue/youtube-39-arr-apps-1-click/issues/5", + "title": "no matching manifest for linux/amd64 in the manifest list entries", + "repo": "automation-avenue/youtube-39-arr-apps-1-click", + "created": "2025-07-23T03:23:05Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/docker/docs/issues/26086", + "title": "tutorial example image missing for Pi32", + "repo": "docker/docs", + "created": "2026-09-13T04:33:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/multiarch/qemu-user-static/issues/215", + "title": "docker: no matching manifest for linux/amd64 in the manifest list entries", + "repo": "multiarch/qemu-user-static", + "created": "2025-10-22T23:37:26Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Unstructured-IO/unstructured/issues/4028", + "title": "bug/no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "Unstructured-IO/unstructured", + "created": "2025-06-19T13:45:28Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/huntingmill/image-nfs/issues/2", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "huntingmill/image-nfs", + "created": "2024-12-05T03:43:03Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/bryangerlach/rdgen/issues/121", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "bryangerlach/rdgen", + "created": "2025-08-21T14:24:36Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/nicolaka/netshoot/issues/119", + "title": "no matching manifest for linux/arm/v7 in the manifest list entries", + "repo": "nicolaka/netshoot", + "created": "2022-11-08T14:43:33Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on/issues/15", + "title": "no matching manifest for linux/arm/v7 in the manifest list entries", + "repo": "ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on", + "created": "2023-09-09T11:56:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/apache/rocketmq-docker/issues/92", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "apache/rocketmq-docker", + "created": "2023-09-21T02:32:49Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/VKSRC/Github-Monitor/issues/131", + "title": "no matching manifest for linux/arm64/v8 in the manifest list entries", + "repo": "VKSRC/Github-Monitor", + "created": "2022-12-01T10:34:51Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 2760 +} \ No newline at end of file diff --git a/bench/data/platform--requested-platform-mismatch.json b/bench/data/platform--requested-platform-mismatch.json new file mode 100644 index 0000000..35cd6b2 --- /dev/null +++ b/bench/data/platform--requested-platform-mismatch.json @@ -0,0 +1,280 @@ +{ + "category": "platform: requested platform mismatch", + "rule": "image.platform", + "query": "\"does not match the detected host platform\" is:issue created:>=2021-01-01", + "total": 3717, + "sample": [ + { + "url": "https://github.com/Kanka-CE/kanka-ce-deploy/issues/8", + "title": "ARM image", + "repo": "Kanka-CE/kanka-ce-deploy", + "created": "2026-09-07T10:57:03Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/SteveLTN/https-portal/issues/326", + "title": "does not match the detected host platform (linux/s390x)", + "repo": "SteveLTN/https-portal", + "created": "2022-11-08T01:26:17Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/super-productivity/plainspace/issues/37", + "title": "ARM64 Support - Docker Compose", + "repo": "super-productivity/plainspace", + "created": "2026-08-31T21:37:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/spectrum-finance/ergo-dex-backend/issues/99", + "title": "events-tracker image does not match the detected host platform", + "repo": "spectrum-finance/ergo-dex-backend", + "created": "2024-02-20T03:11:21Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/qusong0627/QuantMind/issues/24", + "title": "Mac MINI \u7684 VMware \u91cc\u9762\u4f7f\u7528 Ubuntu \u5b89\u88c5\u62a5\u51fa", + "repo": "qusong0627/QuantMind", + "created": "2026-09-06T10:36:17Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/maxking/docker-mailman/issues/731", + "title": "linux/arm64 - The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", + "repo": "maxking/docker-mailman", + "created": "2024-11-10T17:58:05Z", + "state": "open", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/postgis/docker-postgis/issues/371", + "title": "RaspberryPi: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested.", + "repo": "postgis/docker-postgis", + "created": "2023-12-07T21:34:55Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/TomasTomecek/sen/issues/191", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", + "repo": "TomasTomecek/sen", + "created": "2026-04-08T14:15:04Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/NilsLeo/kcc-cloud/issues/28", + "title": "[Feature]: ARM64 image support", + "repo": "NilsLeo/kcc-cloud", + "created": "2026-09-01T08:30:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/hkyutong/Wechat-Claw/issues/1", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", + "repo": "hkyutong/Wechat-Claw", + "created": "2026-03-17T02:47:50Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/portainer/helper-reset-password/issues/7", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform", + "repo": "portainer/helper-reset-password", + "created": "2022-09-09T22:12:36Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/TheAppgineer/flatpak-flutter/issues/127", + "title": "docker run command isn't working for linux/arm64/v8", + "repo": "TheAppgineer/flatpak-flutter", + "created": "2026-09-20T09:31:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/logicallyincorrect/onvif2mqtt/issues/57", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform", + "repo": "logicallyincorrect/onvif2mqtt", + "created": "2022-06-20T13:40:43Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/moby/buildkit/issues/7110", + "title": "BuildKit fails to start container process under Rosetta emulation", + "repo": "moby/buildkit", + "created": "2026-09-02T18:34:23Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/jaegertracing/jaeger-idl/issues/117", + "title": "[Bug]: make protocompile command giving error on apple silicon(arm64)", + "repo": "jaegertracing/jaeger-idl", + "created": "2025-01-15T14:12:20Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/5577", + "title": "platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", + "repo": "rancher-sandbox/rancher-desktop", + "created": "2023-09-23T09:35:14Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/lmnr-ai/lmnr/issues/1299", + "title": "Doesn't work on Mac Apple Silicon", + "repo": "lmnr-ai/lmnr", + "created": "2026-03-02T07:34:54Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/hei85/vohive-qdc507-nas-docker/issues/1", + "title": "\u5927\u4f6c\uff0carm64\u7684\u955c\u50cf\u8981\u600e\u4e48\u505a\u554a\uff1f", + "repo": "hei85/vohive-qdc507-nas-docker", + "created": "2026-08-02T11:22:59Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/TyrantUT/Qt_Docker/issues/1", + "title": " (linux/arm/v7) does not match the detected host platform (linux/amd64/v3)", + "repo": "TyrantUT/Qt_Docker", + "created": "2023-04-18T13:31:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/aahnik/tgcf/issues/550", + "title": "WARNING: The requested image's platform (linux/amd64) does not match the detected host platform", + "repo": "aahnik/tgcf", + "created": "2023-12-25T13:17:39Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/silenceboychen/silenceboychen.github.io/issues/50", + "title": "docker\u8de8\u5e73\u53f0\u6253\u5305\u95ee\u9898does not match the detected host platform | silenceboychen", + "repo": "silenceboychen/silenceboychen.github.io", + "created": "2022-06-28T03:19:35Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/google/grr/issues/1133", + "title": "ARM missing and hung docker compose deployment", + "repo": "google/grr", + "created": "2025-04-22T16:47:30Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/timwuthenow/ibamoe-docker-compose/issues/1", + "title": "The image's platform (linux/arm64) does not match the detected host platform (linux/amd64/v3)", + "repo": "timwuthenow/ibamoe-docker-compose", + "created": "2023-06-29T12:44:31Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/illinoisdata/DeepOLA/issues/180", + "title": "The requested image's platform (linux/arm64/v8) does not match the detected host platform", + "repo": "illinoisdata/DeepOLA", + "created": "2023-08-01T17:57:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tonistiigi/binfmt/issues/115", + "title": "image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) ", + "repo": "tonistiigi/binfmt", + "created": "2022-12-01T06:47:12Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/iboates/osm-utilities-docker/issues/80", + "title": "Multi-arch support: please publish linux/arm64 images", + "repo": "iboates/osm-utilities-docker", + "created": "2026-08-10T10:55:24Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/mincong-h/finance-toolkit/issues/46", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", + "repo": "mincong-h/finance-toolkit", + "created": "2022-03-20T16:51:27Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/sdelrio/rpi-torrent-box/issues/25", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7)", + "repo": "sdelrio/rpi-torrent-box", + "created": "2021-11-18T18:44:44Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/solana-foundation/solana-verifiable-build/issues/312", + "title": "Solana verified", + "repo": "solana-foundation/solana-verifiable-build", + "created": "2026-05-28T18:19:38Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/Red5d/docker-autocompose/issues/27", + "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7)", + "repo": "Red5d/docker-autocompose", + "created": "2021-10-03T08:53:10Z", + "state": "open", + "comments": 1, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 3717 +} \ No newline at end of file diff --git a/bench/data/port-already-allocated.json b/bench/data/port-already-allocated.json new file mode 100644 index 0000000..50798f4 --- /dev/null +++ b/bench/data/port-already-allocated.json @@ -0,0 +1,280 @@ +{ + "category": "port already allocated", + "rule": "ports.conflict,ports.host", + "query": "\"port is already allocated\" is:issue created:>=2021-01-01", + "total": 1239, + "sample": [ + { + "url": "https://github.com/cilium/cilium/issues/48950", + "title": "CI: ci-conformance-race: K8sAgentPolicyTest: provided port is already allocated", + "repo": "cilium/cilium", + "created": "2026-09-22T18:10:05Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/cilium/cilium/issues/45792", + "title": "CI: `Invalid value: 31414: provided port is already allocated`", + "repo": "cilium/cilium", + "created": "2026-05-05T15:01:46Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/open-crs/automatic_exploit_generation/issues/7", + "title": "`exploit` command fails with `port is already allocated`", + "repo": "open-crs/automatic_exploit_generation", + "created": "2026-07-05T22:33:40Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/abbgrade/PsSqlTestServer/issues/13", + "title": "Port is already allocated", + "repo": "abbgrade/PsSqlTestServer", + "created": "2022-04-03T13:32:15Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kactlabs/error-archive/issues/306", + "title": "Port is already allocated", + "repo": "kactlabs/error-archive", + "created": "2022-09-23T09:09:46Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/hkust-nlp/Toolathlon/issues/45", + "title": "poste & woocommerce containers fail again (with \"port is already allocated\")", + "repo": "hkust-nlp/Toolathlon", + "created": "2026-05-29T04:28:42Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/SociallyIneptWeeb/LanguageLeapAI/issues/91", + "title": "Error port is already allocated", + "repo": "SociallyIneptWeeb/LanguageLeapAI", + "created": "2023-03-29T15:30:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/docker/for-mac/issues/7130", + "title": "Port is already allocated when trying to start a container", + "repo": "docker/for-mac", + "created": "2024-01-10T20:44:45Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/Liarea/lazyslice/issues/70", + "title": "T-0217: internal/discover/provision: drop Force from the failed-attempt container removal, fix the retry count's off-by-one, and keep the daemon's port error when the range is exhausted", + "repo": "Liarea/lazyslice", + "created": "2026-09-16T19:45:30Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/smartcontractkit/chainlink-node-compose/issues/13", + "title": "Bind for 0.0.0.0:6711 failed: port is already allocated", + "repo": "smartcontractkit/chainlink-node-compose", + "created": "2022-09-29T17:49:40Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/karmada-io/karmada/issues/7823", + "title": "Karmada API server unexpectedly assigned nodePort for service", + "repo": "karmada-io/karmada", + "created": "2026-08-12T09:54:39Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/coleam00/ai-agents-masterclass/issues/7", + "title": "Bind for 0.0.0.0:5432 failed: port is already allocated", + "repo": "coleam00/ai-agents-masterclass", + "created": "2024-10-24T06:07:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/yohan-work/minidog/issues/25", + "title": "Make the Collector's OTLP ports configurable in deploy/compose.yaml", + "repo": "yohan-work/minidog", + "created": "2026-09-15T07:01:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/balena-os/balena-supervisor/issues/1634", + "title": "Device gets stuck in download loop with error `port is already allocated`", + "repo": "balena-os/balena-supervisor", + "created": "2021-03-29T13:44:19Z", + "state": "open", + "comments": 7, + "verified": true + }, + { + "url": "https://github.com/ReddyNikhila/payment-gateway/issues/1", + "title": "[Peer Review] [Setup Blocker] Docker compose fails to start due to port conflicts and corrupted README instructions", + "repo": "ReddyNikhila/payment-gateway", + "created": "2026-07-18T06:48:18Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/open-source-labs/Docketeer/issues/178", + "title": "Docketeer Docker Extension: Bind for 0.0.0.0:5432 failed: port is already allocated", + "repo": "open-source-labs/Docketeer", + "created": "2025-01-24T03:54:51Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/fabric8io/docker-maven-plugin/issues/1874", + "title": "Using docker-maven-plugin from two profiles with different ports causes 'port is already allocated' error", + "repo": "fabric8io/docker-maven-plugin", + "created": "2025-06-23T12:51:44Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ndelangen/dunezone/issues/1055", + "title": "The e2e log stops announcing an expected port collision and two expected curl misses", + "repo": "ndelangen/dunezone", + "created": "2026-09-06T08:59:58Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/trydirect/stacker/issues/241", + "title": "Observability: surface the real failure cause instead of generic \"local-exec provisioner error\" / \"paused due to internal error\"", + "repo": "trydirect/stacker", + "created": "2026-08-22T14:45:18Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/jentic/jentic-one/issues/976", + "title": "[bug] jenticctl update: a host port already in use (5432) fails the stack half after the CLI is swapped, leaving cli/stack diverged \u2014 and the re-run says \"Up to date\"", + "repo": "jentic/jentic-one", + "created": "2026-08-06T11:11:51Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/kazurayam/VisualInspectionInKatalonStudio_Reborn/issues/14", + "title": "How to restort work after \"Bind for 0.0.0.0:3080 failed: port is already allocated.\"", + "repo": "kazurayam/VisualInspectionInKatalonStudio_Reborn", + "created": "2022-02-21T01:24:13Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/YannicHock/claude-mail-mcp/issues/57", + "title": "The integration fixture cannot run in two checkouts at once", + "repo": "YannicHock/claude-mail-mcp", + "created": "2026-09-09T14:30:33Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/sahithi9755/product-catalog-redis-api/issues/1", + "title": "[Peer Review] setup-blocker: API container fails because port 8080 is already allocated", + "repo": "sahithi9755/product-catalog-redis-api", + "created": "2026-06-30T04:37:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kljensen/yelukerest/issues/382", + "title": "REST test stack: pick free ports instead of failing on 55432/8080/8443", + "repo": "kljensen/yelukerest", + "created": "2026-09-10T11:21:31Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/velero-io/velero/issues/3419", + "title": "Restoring a LoadBalancer type service gives failed to allocate requested HealthCheck NodePort: provided port is already allocated error", + "repo": "velero-io/velero", + "created": "2021-02-08T16:26:10Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/nnn-training/faq/issues/9", + "title": "Docker \u306e port is already allocated \u30a8\u30e9\u30fc\u306b\u5bfe\u3059\u308b\u5bfe\u5fdc\u3092\u8ffd\u52a0\u3057\u305f\u3044", + "repo": "nnn-training/faq", + "created": "2021-12-22T04:15:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/watch-wolf/WatchWolf/issues/40", + "title": "Starting WatchWolf fails, yet reports ok", + "repo": "watch-wolf/WatchWolf", + "created": "2026-02-28T13:43:09Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/kosson/koha-alpine/issues/2", + "title": "problem building and starting Koha stack following production Mode B", + "repo": "kosson/koha-alpine", + "created": "2026-08-17T19:27:19Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/opensandbox-group/OpenSandbox/issues/1705", + "title": "Port allocation race: concurrent sandbox creation fails with \"port is already allocated\"", + "repo": "opensandbox-group/OpenSandbox", + "created": "2026-09-02T16:25:33Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/yaso09/tengiz/issues/1983", + "title": "MEDIUM: old port is freed even when the old container removal fails \u2014 freed-but-bound port breaks the next deploy", + "repo": "yaso09/tengiz", + "created": "2026-08-10T09:33:34Z", + "state": "open", + "comments": 0, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 1239 +} \ No newline at end of file diff --git a/bench/data/rootless-privileged-port.json b/bench/data/rootless-privileged-port.json new file mode 100644 index 0000000..564fa1a --- /dev/null +++ b/bench/data/rootless-privileged-port.json @@ -0,0 +1,280 @@ +{ + "category": "rootless privileged port", + "rule": "ports.host", + "query": "\"cannot expose privileged port\" is:issue created:>=2021-01-01", + "total": 39, + "sample": [ + { + "url": "https://github.com/faramirezs/voice-chef/issues/227", + "title": "[Integration/Network] cannot expose privileged port 80", + "repo": "faramirezs/voice-chef", + "created": "2026-05-07T13:43:27Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/gutmensch/docker-dmarc-report/issues/66", + "title": "rootlessport cannot expose privileged port 80", + "repo": "gutmensch/docker-dmarc-report", + "created": "2025-01-13T00:10:56Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/abdo2048/Ask-Brave-Chat-Exporter/issues/3", + "title": "Export error", + "repo": "abdo2048/Ask-Brave-Chat-Exporter", + "created": "2026-08-19T06:51:54Z", + "state": "open", + "comments": 0, + "verified": false + }, + { + "url": "https://github.com/docker/awesome-compose/issues/324", + "title": "wordpress-mysql - port mapping issue", + "repo": "docker/awesome-compose", + "created": "2023-02-06T07:49:49Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/ublue-os/forge/issues/28", + "title": "Prerequisites check on forge.sh heat-up", + "repo": "ublue-os/forge", + "created": "2024-05-02T06:16:37Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/yuzu-juice/ft_transcendence/issues/129", + "title": "[bug] failed to set up container networking", + "repo": "yuzu-juice/ft_transcendence", + "created": "2026-09-10T08:38:42Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/tim-daria/poolaki/issues/78", + "title": "Clarify Docker rootless mode and privileged ports (80/443)", + "repo": "tim-daria/poolaki", + "created": "2026-07-23T05:40:01Z", + "state": "closed", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/cvoya-com/spring-voyage/issues/2926", + "title": "dispatcher-smoke-full.yml: prep unprivileged-port floor before `deploy.sh up`", + "repo": "cvoya-com/spring-voyage", + "created": "2026-05-30T01:41:37Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/devobagmbh/talos-platform-apps/issues/168", + "title": "docs(AGENTS+build-CONVENTIONS): reconcile stale \"no live cluster\" claim with the local Talos cluster", + "repo": "devobagmbh/talos-platform-apps", + "created": "2026-06-14T13:46:04Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Blackhole-Megalaser/transcendence/issues/49", + "title": "chat seems broken, cannot connect to redis", + "repo": "Blackhole-Megalaser/transcendence", + "created": "2026-05-08T13:02:44Z", + "state": "closed", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/LibreBooking/docker/issues/139", + "title": "podman: rootlessport cannot expose privileged port 80", + "repo": "LibreBooking/docker", + "created": "2026-01-23T08:59:48Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/cvoya-com/spring-voyage/issues/2924", + "title": "install.sh: rootless Podman can't bind 80/443 \u2014 pre-flight checks availability, not bindability", + "repo": "cvoya-com/spring-voyage", + "created": "2026-05-30T01:23:06Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/knative-extensions/kn-plugin-quickstart/issues/542", + "title": "Using port 80 causes a fail on kind with rootless podman", + "repo": "knative-extensions/kn-plugin-quickstart", + "created": "2024-10-08T13:42:13Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/bbvch-ai/aihub-core/issues/1364", + "title": "web image healthcheck targets port 80 but nginx listens on 8080", + "repo": "bbvch-ai/aihub-core", + "created": "2026-05-27T09:58:51Z", + "state": "closed", + "comments": 2, + "verified": false + }, + { + "url": "https://github.com/ddev/ddev/issues/8382", + "title": "\"linux\" missing from OSTYPE options", + "repo": "ddev/ddev", + "created": "2026-05-03T13:57:06Z", + "state": "closed", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/podman-desktop/podman-desktop/issues/1219", + "title": "Warn user when the pod cannot be started ", + "repo": "podman-desktop/podman-desktop", + "created": "2023-01-23T09:45:40Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/podman-desktop/podman-desktop/issues/2305", + "title": "Provide an option to configure the podman-machine to be rootless or rootful", + "repo": "podman-desktop/podman-desktop", + "created": "2023-05-02T14:31:39Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/markshust/docker-magento/issues/1370", + "title": "Neither the automated setup nor the manual setup are able to install docker-magento in Ubuntu with Docker Rootless mode", + "repo": "markshust/docker-magento", + "created": "2025-08-23T17:08:28Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/mikesvoboda/nemotron-v3-home-security-intelligence/issues/3050", + "title": "Fix FRONTEND_HTTPS_PORT default causing privileged port bind error", + "repo": "mikesvoboda/nemotron-v3-home-security-intelligence", + "created": "2026-01-14T21:28:44Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/CanastaWiki/Canasta-CLI/issues/555", + "title": "create fails", + "repo": "CanastaWiki/Canasta-CLI", + "created": "2026-05-11T00:04:24Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/appwrite/appwrite/issues/2463", + "title": "\ud83d\ude80 Feature: running in Podman - a writeup how to go about it", + "repo": "appwrite/appwrite", + "created": "2021-12-06T10:14:50Z", + "state": "closed", + "comments": 11, + "verified": true + }, + { + "url": "https://github.com/ft-trans/ft-transcendence/issues/147", + "title": "\u6821\u820e\u74b0\u5883\u3067\u306f\u6a29\u9650\u4e0d\u8db3\u306e\u305f\u30811024\u4ee5\u4e0b\u306e\u30dd\u30fc\u30c8\u304c\u4f7f\u7528\u3067\u304d\u306a\u3044", + "repo": "ft-trans/ft-transcendence", + "created": "2025-10-18T03:26:41Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/yyamasak02/ft_transcendence/issues/35", + "title": "\u3010\u30d0\u30b0\u3011\u6821\u820e\u74b0\u5883\u3067\u30d3\u30eb\u30c9\uff06\u5b9f\u884c\u3067\u304d\u306a\u3044", + "repo": "yyamasak02/ft_transcendence", + "created": "2025-11-06T06:11:52Z", + "state": "closed", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/DRYTRIX/TimeTracker/issues/104", + "title": "Recommended Install not working", + "repo": "DRYTRIX/TimeTracker", + "created": "2025-10-21T09:58:30Z", + "state": "closed", + "comments": 13, + "verified": true + }, + { + "url": "https://github.com/Blue-Dots-Economy/signals-dpg/issues/539", + "title": "[Sec-Audit][A4] Migrate container base images to Docker Hardened Images (all repos)", + "repo": "Blue-Dots-Economy/signals-dpg", + "created": "2026-08-12T11:49:52Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/onyx-dot-app/onyx/issues/5560", + "title": "Change port from 80 for rootless podman", + "repo": "onyx-dot-app/onyx", + "created": "2025-10-01T10:32:15Z", + "state": "closed", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/Blue-Dots-Economy/bluedots-automation/issues/136", + "title": "Migrate all org container images to Docker Hardened Images (DHI)", + "repo": "Blue-Dots-Economy/bluedots-automation", + "created": "2026-08-12T11:56:58Z", + "state": "closed", + "comments": 1, + "verified": false + }, + { + "url": "https://github.com/fosrl/pangolin/issues/1428", + "title": "Unable to start traefik container due to \"Error: statfs /home/ubuntu/config/traefik/logs: no such file or directory\"", + "repo": "fosrl/pangolin", + "created": "2025-09-07T14:54:54Z", + "state": "closed", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/masaruo/transcendence/issues/53", + "title": "\u672c\u756a\u74b0\u5883\uff1a\u6821\u820e\u306ePC\u3067\u5b9f\u884c", + "repo": "masaruo/transcendence", + "created": "2025-05-27T11:25:28Z", + "state": "closed", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Scrybbling-together/scrybble-site/issues/5", + "title": "Change port", + "repo": "Scrybbling-together/scrybble-site", + "created": "2024-01-13T13:06:27Z", + "state": "closed", + "comments": 8, + "verified": true + } + ], + "precision": 0.8666666666666667, + "adjusted": 34 +} \ No newline at end of file diff --git a/bench/data/volume-permission-denied.json b/bench/data/volume-permission-denied.json new file mode 100644 index 0000000..f4224b2 --- /dev/null +++ b/bench/data/volume-permission-denied.json @@ -0,0 +1,280 @@ +{ + "category": "volume permission denied", + "rule": "", + "query": "docker volume \"permission denied\" container is:issue created:>=2021-01-01", + "total": 6073, + "sample": [ + { + "url": "https://github.com/Dodoooh/brother_ql_app/issues/50", + "title": "permission denied on container start", + "repo": "Dodoooh/brother_ql_app", + "created": "2026-09-11T17:09:35Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/kavix/why/issues/8", + "title": "[Adapter] Docker Diagnostic Adapter: why docker compose up", + "repo": "kavix/why", + "created": "2026-09-20T03:39:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dvd-dev/hilo/issues/1028", + "title": "[Bug] [Errno 13] Permission denied on /run/s6-rc in Docker / Unraid environments", + "repo": "dvd-dev/hilo", + "created": "2026-09-03T02:00:20Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/AppDaemon/appdaemon/issues/2642", + "title": "requirements.txt not installed on container startup: permission denied", + "repo": "AppDaemon/appdaemon", + "created": "2026-06-16T09:43:25Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Part-DB/Part-DB-server/issues/1412", + "title": "[Docker] Permission denied on manual backups when mounting persistent backup volume", + "repo": "Part-DB/Part-DB-server", + "created": "2026-06-15T08:04:52Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/headroomlabs-ai/headroom/issues/3534", + "title": "Docker wrapper: wrap opencode broken - missing .config mount, unbound variable, empty OPENCODE_CONFIG_CONTENT", + "repo": "headroomlabs-ai/headroom", + "created": "2026-09-10T17:27:00Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/microsoft/mssql-docker/issues/940", + "title": "SQL Server 2025-latest container fails to start", + "repo": "microsoft/mssql-docker", + "created": "2025-08-07T18:22:55Z", + "state": "open", + "comments": 17, + "verified": true + }, + { + "url": "https://github.com/algorandfoundation/intermezzo/issues/34", + "title": "EACCES Permission Denied on `/opt/app/node_modules`", + "repo": "algorandfoundation/intermezzo", + "created": "2026-06-02T11:16:25Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/officialjaware/focalboard-reborn/issues/36", + "title": "[issue#5011] permission denied", + "repo": "officialjaware/focalboard-reborn", + "created": "2026-04-08T17:20:41Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/mathieu-keller/anki-sync-server/issues/78", + "title": "Permission denied when creating SYNC_BASE inside Docker container", + "repo": "mathieu-keller/anki-sync-server", + "created": "2026-05-25T22:26:30Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/dave0875/fitness-pals.com/issues/170", + "title": "Prevent production deploys from colliding with legacy Compose containers", + "repo": "dave0875/fitness-pals.com", + "created": "2026-09-08T12:26:59Z", + "state": "open", + "comments": 5, + "verified": true + }, + { + "url": "https://github.com/Dispatcharr/Dispatcharr/issues/1742", + "title": "[Bug]: Installed plugins become unreadable (Errno 13) after container recreate on SELinux hosts \u2014 installer copies SELinux labels via cross-filesystem shutil.move", + "repo": "Dispatcharr/Dispatcharr", + "created": "2026-09-23T18:19:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/taso-labs/freeciv-llm/issues/7", + "title": "Fresh Docker Compose setup cannot write service logs", + "repo": "taso-labs/freeciv-llm", + "created": "2026-09-09T19:54:31Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/testcontainers/testcontainers-go/issues/3157", + "title": "[Bug]: Permission denied reading redpanda.yaml stopping container from proper start", + "repo": "testcontainers/testcontainers-go", + "created": "2025-05-07T09:07:22Z", + "state": "open", + "comments": 10, + "verified": true + }, + { + "url": "https://github.com/zarf-dev/zarf/issues/4669", + "title": "\"filesystem: mkdir /var/lib/registry/docker: permission denied\" during zarf init", + "repo": "zarf-dev/zarf", + "created": "2026-03-03T09:35:28Z", + "state": "open", + "comments": 8, + "verified": true + }, + { + "url": "https://github.com/rmcrackan/Libation/issues/2061", + "title": "Docker duplicate not persisting permissions on Synology NAS", + "repo": "rmcrackan/Libation", + "created": "2026-09-14T03:11:05Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/Finsys/dockhand/issues/1076", + "title": "[BUG] Trivy and Grype scans fail on Hawser with rootless Podman during container update", + "repo": "Finsys/dockhand", + "created": "2026-05-20T19:05:43Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/Dadoum/anisette-v3-server/issues/8", + "title": "Permission denied error", + "repo": "Dadoum/anisette-v3-server", + "created": "2023-11-20T10:19:40Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/mutcherlarahulkumar/leetcode-clone/issues/3", + "title": "Add sandboxed code execution for submissions", + "repo": "mutcherlarahulkumar/leetcode-clone", + "created": "2026-09-09T18:00:45Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/zvchei/docker-seed/issues/29", + "title": "Root-stage mkdirs under $HOME break the user-stage volume mkdirs", + "repo": "zvchei/docker-seed", + "created": "2026-09-02T09:01:56Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/radius-project/ai-extensions/issues/752", + "title": "containers: no way to set fsGroup, so non-root images cannot write to a mounted persistentVolume", + "repo": "radius-project/ai-extensions", + "created": "2026-09-03T21:47:39Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/azerothcore/azerothcore-wotlk/issues/27362", + "title": "Docker, fresh install fails to start due to ac-client-data-init", + "repo": "azerothcore/azerothcore-wotlk", + "created": "2026-08-28T08:28:11Z", + "state": "open", + "comments": 4, + "verified": true + }, + { + "url": "https://github.com/elicify-ai/omnipus/issues/655", + "title": "docker/Dockerfile.heavy: image cannot boot with a Docker-managed volume \u2014 .omnipus is created root-owned", + "repo": "elicify-ai/omnipus", + "created": "2026-08-28T03:47:16Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/RijksICTGilde/hackathon-claude-code/issues/82", + "title": "userns-remap: container-naar-container-netwerken en container-root loskoppelen van host-root", + "repo": "RijksICTGilde/hackathon-claude-code", + "created": "2026-08-03T11:04:40Z", + "state": "open", + "comments": 2, + "verified": true + }, + { + "url": "https://github.com/t0mer/skryol/issues/2", + "title": "Settings save fails with 'permission denied' in the official Docker image (cwd is unwritable)", + "repo": "t0mer/skryol", + "created": "2026-07-12T19:06:38Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/kestra-io/kestra/issues/19626", + "title": "Podman Compose rootless deployment mounts Docker socket instead of the Podman socket", + "repo": "kestra-io/kestra", + "created": "2026-09-19T12:14:08Z", + "state": "open", + "comments": 3, + "verified": true + }, + { + "url": "https://github.com/heuwels/lector/issues/606", + "title": "Linux bind-mount ./data is unusable on first boot (EACCES)", + "repo": "heuwels/lector", + "created": "2026-09-02T23:58:26Z", + "state": "open", + "comments": 0, + "verified": true + }, + { + "url": "https://github.com/joecarl/mularr/issues/35", + "title": "Appdata folder issue", + "repo": "joecarl/mularr", + "created": "2026-09-05T06:10:04Z", + "state": "open", + "comments": 1, + "verified": true + }, + { + "url": "https://github.com/internetarchive/openlibrary/issues/13586", + "title": "Linux Docker Issues: Fresh clone does not boot: web exits 3 writing _testing-prs.json into a bind mount it cannot write", + "repo": "internetarchive/openlibrary", + "created": "2026-09-08T01:35:48Z", + "state": "open", + "comments": 6, + "verified": true + }, + { + "url": "https://github.com/codidact/qpixel/issues/2070", + "title": "`mysqld: File './binlog.index' not found (OS errno 13 - Permission denied)`", + "repo": "codidact/qpixel", + "created": "2026-06-18T14:26:43Z", + "state": "open", + "comments": 3, + "verified": true + } + ], + "precision": 1.0, + "adjusted": 6073 +} \ No newline at end of file diff --git a/bench/fresh.py b/bench/fresh.py new file mode 100644 index 0000000..7bb20f0 --- /dev/null +++ b/bench/fresh.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Draw a held-out test sample, disjoint from the development sample. + +Uses the same categories and exact-text verification as mine.py and +precision.py, but a different search ordering (oldest first), excludes every +issue seen during development, and picks N verified issues per category with +a new seed. Run only after the rules are frozen (git tag eval-frozen). +""" +import glob, json, os, random, subprocess, sys, urllib.parse + +sys.path.insert(0, os.path.dirname(__file__)) +from mine import CATEGORIES, gh_api # noqa: E402 +from precision import MUST, text_of # noqa: E402 +from sample import excerpt # noqa: E402 + +N, SEED, PAGE = 4, 777013, 50 +here = os.path.dirname(__file__) +seen = set() +for p in glob.glob(os.path.join(here, "data", "*.json")): + seen |= {i["url"] for i in json.load(open(p))["sample"]} + +rng = random.Random(SEED) +out = open(os.path.join(here, "labels", "test_sample.jsonl"), "w") +for cat, rule, phrase in CATEGORIES: + q = f"{phrase} is:issue created:>=2021-01-01" + res = gh_api("search/issues?per_page=%d&sort=created&order=asc&q=%s" % (PAGE, urllib.parse.quote(q))) + pool = [i for i in res.get("items", []) if i["html_url"] not in seen] + rng.shuffle(pool) + picked = 0 + for it in pool: + if picked == N: + break + body = text_of(it["html_url"]) + if not all((m.search(body) is not None) if hasattr(m, "search") else (m in body) for m in MUST[cat]): + continue + out.write(json.dumps({"url": it["html_url"], "category": cat, "rule": rule, + "title": it["title"], "excerpt": excerpt(body, MUST[cat][0])}) + "\n") + picked += 1 + print(f"{picked} {cat}", file=sys.stderr) diff --git a/bench/labels/labels_claude.tsv b/bench/labels/labels_claude.tsv new file mode 100644 index 0000000..3b7c664 --- /dev/null +++ b/bench/labels/labels_claude.tsv @@ -0,0 +1,125 @@ +idx scope predict rule reason +0 in no nginx inside the container binds a port already used inside its network namespace, not a host publish conflict +1 in no app inside the container (net=host) binds a busy port; not declared in Compose ports +2 out no host app, not a container failure +3 out no app hot-reload bug +4 out no Elixir migration error +5 in no Rancher Desktop port forwarding for a non-standard IP +6 out no deployment tool path collision +7 in partial learned postgres without POSTGRES_PASSWORD: predicted only after being learned once +8 in yes mounts.bind config file missing, so Docker created a directory +9 in yes mounts.bind config files created as directories +10 in yes mounts.bind entrypoint file missing on the Portainer host +11 in yes mounts.bind config file missing +12 in partial mounts.bind /sys/class/powercap absent on this kernel; flagged only for create_host_path=false +13 in no docker run --mount; path hidden from snap/Desktop daemon; not a Compose input +14 out no devcontainer variable +15 in partial mounts.bind certificate not yet generated; flagged when long syntax disables create_host_path +16 in partial build.buildkit COPY --chmod through a legacy API client; buildx installed, so not flagged +17 out no Podman +18 out no not a failure report +19 out no remote ACR builder +20 in yes build.context COPY source missing (not built yet) +21 in yes build.context COPY source missing +22 in yes build.context binary must be built first +23 in no COPY source uses an ARG; skipped by design +24 in yes build.context COPY source missing +25 in yes build.context COPY source missing +26 in yes build.context COPY source missing +27 in yes build.context COPY source missing +28 in no Dockerfile itself outside the context (skaffold); only COPY sources are checked +29 in yes build.context COPY outside context via Compose +30 in yes build.context COPY ../.. outside context +31 in yes build.context COPY outside context via Compose +32 in yes compose.env required variable missing +33 in yes compose.env required variable missing +34 in yes compose.env required variable missing +35 out no compose-go library bug +36 in yes (root cause) invalid Compose file reported as root cause +37 out no Swarm stack schema via a CI action +38 out no apt error during build +39 in no top-level `name` unsupported by older Compose; not in the feature table +40 in partial compose.env unset-variable warning shown, but the failure was an interrupted pull +41 in yes compose.env unset variable +42 in yes compose.env unset variable +43 out no warning unrelated to the reported bug +44 in no postgres data dir mode must be 0700/0750 (WSL); image starts as root so permission rule skips it +45 in no unhealthy container on WSL +46 in no unhealthy redis on Windows +47 in no permission via user: from variables +48 in partial registry.credentials credential helper resolved from current directory (WSL) +49 in no DNS in Colima VM +50 in partial registry.credentials credential helper resolved from current directory +51 in yes registry.credentials credsStore desktop not installed +52 in partial (root cause) daemon unreachable reported; real cause (virtualization off in BIOS) not named +53 in no container using the Docker socket after daemon upgrade +54 in yes (root cause) no engine installed +55 out no third-party tool bug +56 in partial mounts.sharing mounts denied, but via a CLI that runs containers itself +57 in no docker-in-docker path translation +58 in partial mounts.sharing docker run, Linux Docker Desktop; rule is macOS-only +59 in partial mounts.sharing Linux Docker Desktop shares; rule is macOS-only +60 in yes image.platform arm64-only tag on amd64 CI agent +61 in no disk filled at runtime +62 in no inode exhaustion in production +63 in no inode exhaustion during pull; disk rule counts bytes +64 in no DNS inside app container +65 out no Podman +66 in no no internet in device +67 in no service name not resolvable +68 in partial image.platform QEMU segfault; emulation only warned +69 in partial image.platform QEMU SIGILL; emulation only warned +70 out no qemu outside Docker +71 in partial image.platform amd64 image under QEMU via SAM CLI; warned only +72 in yes resources.gpu no NVIDIA runtime +73 in yes resources.gpu no NVIDIA runtime +74 in yes resources.gpu no NVIDIA runtime +75 in yes resources.gpu no NVIDIA runtime +76 in yes image.exists image not in registry (expected to be built locally) +77 in yes image.exists image removed from registry +78 in yes image.exists image removed from Docker Hub +79 in partial image.exists docker run from a guide, not a Compose project +80 in partial image.exists docker pull of a removed tag, not a Compose project +81 in yes image.exists tag not published +82 in partial image.exists docker pull of a removed tag +83 in partial image.exists latest manifest missing, via docker pull +84 out no configuration example, not a failure +85 in yes kernel.sysctl vm.max_map_count too low +86 out no LXC script request +87 in yes kernel.sysctl vm.max_map_count too low +88 out no feature request +89 out no Kubernetes +90 out no Kubernetes +91 out no flaky test +92 out no Docker VMM on Windows +93 in no network name from a different project name +94 in no transient during recreate +95 in yes ports.host older project's container holds 443 +96 in no exec working directory +97 in no CI exec failure +98 in no exec working directory (duplicate report) +99 in no exec working directory (duplicate report) +100 in no image ships a broken binary +101 in no image mislabelled: amd64 binary in arm64 manifest +102 in partial image.platform cross-build RUN without emulation +103 in partial image.platform self-built images on aarch64 +104 in yes image.platform no arm64 variant +105 in yes image.platform no arm64 variant (Lando, Compose based) +106 in partial image.platform no arm/v7 variant, via Home Assistant +107 in partial image.platform no arm/v7 variant, via docker run +108 in yes image.platform amd64-only image on arm64 +109 in partial image.platform amd64 on arm64 via docker run +110 in partial image.platform s390x build with empty TARGETPLATFORM +111 in yes image.platform arm64 image built on M1 deployed to amd64 server (preflight --host) +112 in yes ports.host another project's container holds the port +113 out no Maven plugin +114 in no port allocation race +115 in yes ports.conflict two services publish the same port +116 out no unrelated tooling +117 out no Podman +118 in yes ports.host rootless Docker, privileged port 80 +119 in partial ports.host Podman rootless, same condition +120 out no Podman +121 in no build-time mkdir as non-root +122 in no named volume ownership +123 in no anonymous volume ownership diff --git a/bench/labels/labels_claude_v2.tsv b/bench/labels/labels_claude_v2.tsv new file mode 100644 index 0000000..2646c60 --- /dev/null +++ b/bench/labels/labels_claude_v2.tsv @@ -0,0 +1,125 @@ +idx scope predict rule reason +0 in no nginx inside the container binds a port already used inside its network namespace, not a host publish conflict +1 in no app inside the container (net=host) binds a busy port; not declared in Compose ports +2 out no host app, not a container failure +3 out no app hot-reload bug +4 out no Elixir migration error +5 in no Rancher Desktop port forwarding for a non-standard IP +6 out no deployment tool path collision +7 in partial learned postgres without POSTGRES_PASSWORD: predicted only after being learned once +8 in yes mounts.bind config file missing, so Docker created a directory +9 in yes mounts.bind config files created as directories +10 in yes mounts.bind entrypoint file missing on the Portainer host +11 in yes mounts.bind config file missing +12 in partial mounts.bind /sys/class/powercap absent on this kernel; flagged only for create_host_path=false +13 in no docker run --mount; path hidden from snap/Desktop daemon; not a Compose input +14 out no devcontainer variable +15 in partial mounts.bind certificate not yet generated; flagged when long syntax disables create_host_path +16 in partial build.buildkit COPY --chmod through a legacy API client; buildx installed, so not flagged +17 out no Podman +18 out no not a failure report +19 out no remote ACR builder +20 in yes build.context COPY source missing (not built yet) +21 in yes build.context COPY source missing +22 in yes build.context binary must be built first +23 in no COPY source uses an ARG; skipped by design +24 in yes build.context COPY source missing +25 in yes build.context COPY source missing +26 in yes build.context COPY source missing +27 in yes build.context COPY source missing +28 in no Dockerfile itself outside the context (skaffold); only COPY sources are checked +29 in yes build.context COPY outside context via Compose +30 in yes build.context COPY ../.. outside context +31 in yes build.context COPY outside context via Compose +32 in yes compose.env required variable missing +33 in yes compose.env required variable missing +34 in yes compose.env required variable missing +35 out no compose-go library bug +36 in yes (root cause) invalid Compose file reported as root cause +37 out no Swarm stack schema via a CI action +38 out no apt error during build +39 in yes compose.version top-level name now in feature table +40 in partial compose.env unset-variable warning shown, but the failure was an interrupted pull +41 in yes compose.env unset variable +42 in yes compose.env unset variable +43 out no warning unrelated to the reported bug +44 in partial mounts.permissions Postgres data dir rule fires only when the CLI runs on Windows; WSL shell reads as Linux +45 in no unhealthy container on WSL +46 in no unhealthy redis on Windows +47 in no permission via user: from variables +48 in partial registry.credentials credential helper resolved from current directory (WSL) +49 in no DNS in Colima VM +50 in partial registry.credentials credential helper resolved from current directory +51 in yes registry.credentials credsStore desktop not installed +52 in partial (root cause) daemon unreachable reported; real cause (virtualization off in BIOS) not named +53 in no container using the Docker socket after daemon upgrade +54 in yes (root cause) no engine installed +55 out no third-party tool bug +56 in partial mounts.sharing mounts denied, but via a CLI that runs containers itself +57 in no docker-in-docker path translation +58 in yes mounts.sharing docker run via --run; Linux Desktop shares home only +59 in yes mounts.sharing Linux Desktop shares home only +60 in yes image.platform arm64-only tag on amd64 CI agent +61 in no disk filled at runtime +62 in no inode exhaustion in production +63 in no inode exhaustion during pull; disk rule counts bytes +64 in no DNS inside app container +65 out no Podman +66 in no no internet in device +67 in no service name not resolvable +68 in partial image.platform QEMU segfault; emulation only warned +69 in partial image.platform QEMU SIGILL; emulation only warned +70 out no qemu outside Docker +71 in partial image.platform amd64 image under QEMU via SAM CLI; warned only +72 in yes resources.gpu no NVIDIA runtime +73 in yes resources.gpu no NVIDIA runtime +74 in yes resources.gpu no NVIDIA runtime +75 in yes resources.gpu no NVIDIA runtime +76 in yes image.exists image not in registry (expected to be built locally) +77 in yes image.exists image removed from registry +78 in yes image.exists image removed from Docker Hub +79 in yes image.exists docker run via --run +80 in yes image.exists docker pull via --run (verified live) +81 in yes image.exists tag not published +82 in yes image.exists docker pull via --run (verified live) +83 in yes image.exists docker pull via --run +84 out no configuration example, not a failure +85 in yes kernel.sysctl vm.max_map_count too low +86 out no LXC script request +87 in yes kernel.sysctl vm.max_map_count too low +88 out no feature request +89 out no Kubernetes +90 out no Kubernetes +91 out no flaky test +92 out no Docker VMM on Windows +93 in no network name from a different project name +94 in no transient during recreate +95 in yes ports.host older project's container holds 443 +96 in no exec working directory +97 in no CI exec failure +98 in no exec working directory (duplicate report) +99 in no exec working directory (duplicate report) +100 in no image ships a broken binary +101 in no image mislabelled: amd64 binary in arm64 manifest +102 in partial image.platform cross-build RUN without emulation +103 in partial image.platform self-built images on aarch64 +104 in yes image.platform no arm64 variant +105 in yes image.platform no arm64 variant (Lando, Compose based) +106 in partial image.platform no arm/v7 variant, via Home Assistant +107 in yes image.platform docker run via --run +108 in yes image.platform amd64-only image on arm64 +109 in yes image.platform docker run via --run +110 in partial image.platform s390x build with empty TARGETPLATFORM +111 in yes image.platform arm64 image built on M1 deployed to amd64 server (preflight --host) +112 in yes ports.host another project's container holds the port +113 out no Maven plugin +114 in no port allocation race +115 in yes ports.conflict two services publish the same port +116 out no unrelated tooling +117 out no Podman +118 in yes ports.host rootless Docker, privileged port 80 +119 in partial ports.host Podman rootless, same condition +120 out no Podman +121 in no build-time mkdir as non-root +122 in no named volume ownership +123 in no anonymous volume ownership diff --git a/bench/labels/rater_seed.json b/bench/labels/rater_seed.json new file mode 100644 index 0000000..66b01b5 --- /dev/null +++ b/bench/labels/rater_seed.json @@ -0,0 +1 @@ +[{"action": "set", "collection": "issues", "doc_id": "00", "data": {"n": 0, "idx": 1, "category": "address already in use", "title": " what(): bind: Address already in use", "url": "https://github.com/lgsvl/lanefollowing/issues/17", "excerpt": "xiayu@xiayu-Lenovo-Legion-R7000P2021H:~/Desktop/lanefollowing$ docker-compose up drive\r\nStarting lanefollowing_drive ... done\r\nAttaching to lanefollowing_drive\r\ndrive_1 | terminate called after throwing an instance of 'boost::exception_detail::clone_impl >'\r\ndrive_1 | what(): bind: Address already in use\r\ndrive_1 | /lanefollowing/scripts/drive.sh: line 14: 2729 Aborted lgsvl_bridge\r\n"}}, {"action": "set", "collection": "issues", "doc_id": "01", "data": {"n": 1, "idx": 5, "category": "app config/env missing at runtime", "title": "Unable to bind to address other than 127.0.0.1 or 0.0.0.0", "url": "https://github.com/rancher-sandbox/rancher-desktop/issues/6760", "excerpt": "ll tell the guest agent to forward that interface as well:\r\n\r\n```console\r\n$ grep '15432' ~/Library/Logs/rancher-desktop/lima.ha.stderr.log\r\n{\"level\":\"debug\",\"msg\":\"guest agent event: {Time:2024-04-25 16:20:37.783086267 +0000 UTC LocalPortsAdded:[{IP:127.0.0.11 Port:15432}] LocalPortsRemoved:[] Errors:[]}\",\"time\":\"2024-04-25T09:20:39-07:00\"}\r\n{\"level\":\"info\",\"msg\":\"Forwarding TCP from 127.0.0.11:15432 to 127.0.0.11:15432\",\"time\":\"2024-04-25T09:20:39-07:00\"}\r\n```\r\n\r\nThe `lsof` command still didn't show anything for me, but that was because the database didn't actually start properly, so the port was closed again right away:\r\n\r\n```console\r\n$ docker logs db\r\nError: Database is uninitialized and superuser password is not specified.\r\n You must specify POSTGRES_PASSWORD to a non-empty value for the\r\n superuser. For example, \"-e POSTGRES_PASSWORD=password\" on \"docker run\".\r\n\r\n You may also use \"POSTGRES_HOST_AUTH_METHOD=trust\" to allow all\r\n connections without a password. This is *not* recommended.\r\n\r\n See PostgreSQL documentation about \"trust\":\r\n https://www.postgresql.org/docs/current/auth-trust.html\r\n```\r\n\r\nNote that the `override.yaml` file will be deleted if you ever perform a factory reset, and must be recreated manually again afterwards.\r\n\r\n\n---\nInteresting. Would this work if we want to do this with multiple IP addresses? Ideally we want to "}}, {"action": "set", "collection": "issues", "doc_id": "02", "data": {"n": 2, "idx": 6, "category": "app config/env missing at runtime", "title": "stacker deploy --target server writes every project to the same remote path, causing real cross-project deployment damage", "url": "https://github.com/trydirect/stacker/issues/240", "excerpt": "produced via `stacker-projects/duplicati` colliding with a pre-existing `stacker-projects/rallly` deployment, both targeting the same `EXISTING_SERVER_HOST`, in trydirect/stacker-project-examples\n- Related: #235 (same bug class, `--target local` variant)\n---\nUpdating with a more severe detail found on further investigation: this wasn't just compose-file thrashing \u2014 **rallly's actual database volume was recreated empty**, i.e. real data loss.\n\n\\`docker volume inspect project_rallly_db\\` shows \\`CreatedAt: 2026-08-20T17:40:21Z\\` \u2014 today, during this exact testing window \u2014 and \\`du -sh\\` on it shows only 8.0K (empty, no real data). Postgres now refuses to start: \\`Database is uninitialized and superuser password is not specified\\` (rallly's own compose has \\`POSTGRES_PASSWORD: ''\\`, which was presumably fine against the *original* initialized volume but fails cold-start validation against a fresh empty one).\n\nSo the actual sequence was worse than \"wrote a different compose file over the old one\": something in the \\`--target server\\` deploy path for \\`duplicati\\` appears to have torn down and recreated volumes under the shared \\`project\\` compose project scope too \u2014 not just the compose file/containers. This raises the severity from \"silent overwrite\" to \"silent data loss\" for whatever was in the previous occupant's volumes.\n---\nFixed. Each project now gets its own directory /home/"}}, {"action": "set", "collection": "issues", "doc_id": "03", "data": {"n": 3, "idx": 7, "category": "app config/env missing at runtime", "title": "Any support with podman-compose?", "url": "https://github.com/mattermost/docker/issues/163", "excerpt": "I'm running podman compose 1.3.0 (latest version) and lots of errors, certainly due to the lack of podman support.\n\n```\n[postgres] | Error: Database is uninitialized and superuser password is not specified.\n[postgres] | You must specify POSTGRES_PASSWORD to a non-empty value for the\n[postgres] | superuser. For example, \"-e POSTGRES_PASSWORD=password\" on \"docker run\".\n[postgres] | \n[postgres] | You may also use \"POSTGRES_HOST_AUTH_METHOD=trust\" to allow all\n[postgres] | connections without a password. This is *not* recommended.\n[postgres] | \n[postgres] | See PostgreSQL documentation about \"trust\":\n[postgres] | https://www.postgresql.org/docs/current/auth-trust.html\n[mattermost] | Error: failed to load configuration: could not create config file: open /mattermost/config/config.json: permission denied\n[m"}}, {"action": "set", "collection": "issues", "doc_id": "04", "data": {"n": 4, "idx": 8, "category": "bind: dir onto file", "title": "Error running docker compose", "url": "https://github.com/canyanio/janus-gateway-docker/issues/29", "excerpt": "Hi, I'm running into the following error running the docker compose example in the readme:\r\n\r\n\r\n> ERROR: for janusdock_janus-gateway_1 Cannot start service janus-gateway: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/XXXXX/janusDock/etc/janus/janus.jcfg\" to rootfs at \"/usr/local/etc/janus/janus.jcfg\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\n> \r\n> ERROR: for janus-gateway Cannot start service janus-gateway: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/XXXXX/janusDock/etc/janus/janus.jcfg\" to rootfs at \"/usr/local/etc/janus/janus.jcfg\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\n> ERROR: Encountered errors while bringing up the project.\r\n\r\n\r\nAny thoughts wha"}}, {"action": "set", "collection": "issues", "doc_id": "05", "data": {"n": 5, "idx": 15, "category": "bind: source does not exist", "title": "Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.le", "url": "https://github.com/zdeneksvarc/postal-tls/issues/3", "excerpt": "docker compose up -d when i do this i get this error.\r\n\r\nError response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt\n---\nDid you follow the guide? There are 8 steps before this one. What directory are you running `docker compose up -d` inside?\n---\nAs @sinnbeck wrote, if all the steps are followed, Caddy will generate the certificates to the path mentioned. If this problem persists after proper installation, please @mucktobrak open a new issue with more information attached.\n---\ni did everything but i still get the same error @zdeneksvarc \n---\nOk and is `/opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt `existing"}}, {"action": "set", "collection": "issues", "doc_id": "06", "data": {"n": 6, "idx": 16, "category": "build: BuildKit required", "title": "\u4fee\u6539docker demon\u914d\u7f6e\u540e\uff0cdocker\u6784\u5efa\u6ca1\u6709\u4f7f\u7528\u65b0\u914d\u7f6e", "url": "https://github.com/dromara/Jpom/issues/49", "excerpt": "Dockerfile\u91cc\u4f7f\u7528\u4e86COPY --chmod=xxx\uff0c\u4fee\u6539\u4e86daemon.json\u6dfb\u52a0\r\n```\r\n\"features\": {\r\n \"buildkit\": true\r\n}\r\n```\r\n\u91cd\u65b0\u6784\u5efa\u8fd8\u662f\u62a5errorDetail={message=the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled},error=the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled\r\n\u5c1d\u8bd5\u4e86\u91cd\u542fserver\u3001agent\u7b49\u5747\u4e0d\u751f\u6548\r\n\u4f46\u662f\u4f7f\u7528\u547d\u4ee4\u884c\u5728jpom\u521b\u5efa\u7684source\u76ee\u5f55\u4e0b\u53ef\u4ee5\u751f\u6548"}}, {"action": "set", "collection": "issues", "doc_id": "07", "data": {"n": 7, "idx": 19, "category": "build: BuildKit required", "title": "Allow `buildkit` build in `az acr build`", "url": "https://github.com/Azure/acr/issues/721", "excerpt": "Registry/{{.Values.image}}\"\n```\n\nCommand to use\n```shell\ncd \naz acr run \\\n -f ./acr-build-task.yml \\\n --registry \\\n --set image=\":\" .\n```\n\nIt worked for me\n---\nAny news on this?\n---\nHello--we are also wondering about buildkit support in ACR. Any update?\n---\nAs of the moment, we don't have plans to support the flag. However, buildkit is supported through the steps that @doanduyhai showed above\n---\nRan into this issue today. Here's my acr-task.yml file that got the job done. If there's a better way around this, please let me know.\n\n```\n# This is necessary because `az acr build` with the `--secret-build-arg` flag fails with a \"the --mount option requires BuildKit\" error message.\n# @see https://github.com/Azure/acr/issues/721\n# @see https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tasks-reference-yaml\n\nversion: v1.1.0\n\nsteps:\n - build: >-\n -t $Registry/{{.Values.IMAGE_REPO}}:{{.Values.tag}}\n -f Dockerfile\n .\n --secret id=github_token,env=GITHUB_TOKEN\n env:\n - DOCKER_BUILDKIT=1\n - GITHUB_TOKEN={{.Values.GITHUB_TOKEN}}\n\n - push:\n - $Registry/{{.Values.IMAGE_REPO}}:{{.Values.tag}}\n\n```\n\nThen the associated GitHub Workflow step:\n\n```\n # - I originally tried passing the `--secret-build-arg` flag to `az acr build`, but the step fails with a \"the --mount option requir"}}, {"action": "set", "collection": "issues", "doc_id": "08", "data": {"n": 8, "idx": 20, "category": "build: COPY failed legacy", "title": "Dockerfile fails because drake_install does not exist", "url": "https://github.com/ChristopherSweeney/RGBD_SIM/issues/1", "excerpt": "Step 6/21 : COPY drake_install/ /opt/drake\r\nCOPY failed: file not found in build context or excluded by .dockerignore: stat drake_install/: file does not exist"}}, {"action": "set", "collection": "issues", "doc_id": "09", "data": {"n": 9, "idx": 31, "category": "build: outside build context", "title": "docker-compose build FAILED", "url": "https://github.com/AxonIQ/axon-observability-demo/issues/1", "excerpt": "Hello, thanks for awesome demo project and webinar! Really enjoyed wathing \r\n\r\nBut can't launch demo project, when I run docker-compose build I see the following error\r\n\r\n```\r\nvladimir@pc:~/IdeaProjects/axon-observability-demo/src/main/docker$ docker-compose build\r\ndemo-app-2 uses an image, skipping\r\ndemo-app-1 uses an image, skipping\r\nBuilding axonserver-enterprise-1\r\nSending build context to Docker daemon 101.7MB\r\nStep 1/8 : FROM openjdk:8-jre-alpine3.9\r\n ---> f7a292bbb70c\r\nStep 2/8 : RUN apk add --update ttf-dejavu fontconfig\r\n ---> Using cache\r\n ---> a39a5be23357\r\nStep 3/8 : COPY ../docker/axon-server/axonserver.jar /axonserver/axonserver-enterprise.jar\r\nCOPY failed: forbidden path outside the build context: ../docker/axon-server/axonserver.jar ()\r\n```"}}, {"action": "set", "collection": "issues", "doc_id": "10", "data": {"n": 10, "idx": 36, "category": "compose: unsupported property", "title": "wrong compose syntax", "url": "https://github.com/docker-archive-public/docker.labs/issues/596", "excerpt": "https://github.com/docker/labs/blob/1bcbb14346cacd47446934926315e3f4d5222a55/security/apparmor/README.md?plain=1#L266\r\n\r\nthere should be the next code\r\n```dockerfile\r\nservices:\r\n``` \r\non top of the `docker-compose.yml` file otherwise you'll receive the error\r\n```shell\r\n Additional property mysql is not allowed\r\n``` \r\n\r\nRegards"}}, {"action": "set", "collection": "issues", "doc_id": "11", "data": {"n": 11, "idx": 42, "category": "compose: variable not set", "title": "WARNING: The MNEMONIC variable is not set. Defaulting to a blank string.", "url": "https://github.com/transmute-industries/sidetree.js/issues/217", "excerpt": "p -d mongo ganache ipfs\",`\r\n\r\nand picks up correct mnemonics.\r\n\r\n\n---\nhmm, seems like we probably need to separate the docker compose files so that running a local node is easier.\n---\nI ll let it open so that you can close it, when it done in future releases \n---\nI think I've seen this when starting up a server. Want to see if it's happening, and why it's happening, because the seed should be defined in the configuration file. \n---\nTaking some notes, it looks like this error can be reproduced by running the test for the `cas-ipfs` module. \r\n\r\n```\r\n> @sidetree/cas-ipfs@0.3.1-unstable.25 pretest ~/Github/sidetree.js/packages/cas-ipfs\r\n> docker-compose up -d ipfs mongo\r\n\r\nWARNING: The MNEMONIC variable is not set. Defaulting to a blank string.\r\nsidetreejs_ipfs_1 is up-to-date\r\nsidetreejs_mongo_1 is up-to-date\r\n\r\n> @sidetree/cas-ipfs@0.3.1-unstable.25 test ~/Github/sidetree.js/packages/cas-ipfs\r\n> tsdx test --passWithNoTests\r\n```\r\n\r\nSo we need to track down where that warning is coming from, and if it's needed or not. \n---\nThis should be defaulted to an example."}}, {"action": "set", "collection": "issues", "doc_id": "12", "data": {"n": 12, "idx": 44, "category": "container healthcheck unhealthy", "title": "dependency failed to start: container cognita-postgres is unhealthy", "url": "https://github.com/truefoundry/cognita/issues/421", "excerpt": " \ncognita-postgres | 2025-01-16 10:59:37.027 UTC [83] FATAL: data directory \"/var/lib/postgresql/data\" has invalid permissions\ncognita-postgres | 2025-01-16 10:59:37.027 UTC [83] DETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).\ncognita-postgres | child process exited with exit code 1\ncognita-postgres | initdb: removing contents of data directory \"/var/lib/postgresql/data\"\ncognita-postgres | running bootstrap script ...\ncognita-postgres exited with code 1\nGracefully stopping... (press Ctrl+C again to force)\ndependency failed to start: container cognita-postgres is unhealthy\nPS C:\\Users\\AmitTiwari\\PycharmProjects\\cognita> \n```\n\n\n\nHere is the configuration at models_cofig.yaml, I have been trying to deploy with - \n\n\n```\nmodel_providers:\n ############################ Local ############################################\n # Uncomment this provider if you want to use local models providers #\n # using ollama and infinity model server #\n ###############################################################################\n\n# - provider_name: local-ollama\n# api_format: openai\n# base_url: http://ollama-server:11434/v1/\n# api_key_env_var: \"\"\n# llm_model_ids:\n# - \"qwen2:1.5b\"\n# embedding_model_ids"}}, {"action": "set", "collection": "issues", "doc_id": "13", "data": {"n": 13, "idx": 46, "category": "container healthcheck unhealthy", "title": "Dependency failed to start", "url": "https://github.com/dockersamples/example-voting-app/issues/361", "excerpt": "Cloned this project into my windows 11 machine.\r\nAs suggested in readme.md file installed docker for windows and run the application using command \"docker compose up\".\r\nI was getting following error: **dependency failed to start: container example-voting-app-redis-1 is unhealthy**\r\n![Screenshot 2024-07-23 134013](https://github.com/user-attachments/assets/d2ff29bc-414c-4fa9-b587-75071772b852)\r\n\n---\nI would like to know if there is any kind of development on this issue. I am trying to install example-voting-app on my raspberry pi (ARM64 machine) and I get the same error. Sometime it's the \"...-redis-1\", sometimes it's the \"...db-1\" that gives me the error. "}}, {"action": "set", "collection": "issues", "doc_id": "14", "data": {"n": 14, "idx": 47, "category": "container healthcheck unhealthy", "title": "dependency failed to start: container genai-stack-api-1 is unhealthy", "url": "https://github.com/docker/genai-stack/issues/142", "excerpt": "First ran into /data problem. Followed the thread #134 and implemented three changes: (a) chown /home/casev/../genai-stack/data directory to casev for userID and groupID. (2) added to /home/casev/.profile two statements: export USER_ID=$(id -u) and export GROUP_ID=$(id -g). (3) modified docker-compose.yml to set database: user: ${USER_ID}:${GROUP_ID}.\r\nNext, run docker compose --profile linux up again. This time, the /data file error did not appear, and installation went further.\r\nHowever, it still stopped with an error message: dependency failed to start: container genai-stack-api-1 is unhealthy.\r\nEven after shutdown and restart, docker compose seemed to be stuck for hours displaying with different port numbers:\r\nINFO: 127.0.0.1:xxxxxx - \"GET / HTTP/1.1\" 200 OK with different port numbers.\r\n\n---\nTried again and again. Finally the installation seemed to be OK even with the INFO messages which would stop after perhaps 30+.\r\nNow I use nohup docker compose ... & to run it. Can get most of the demo apps working, except the support agent bot: able to get the web page. However, it only showed the section for Select RAG mode. Do not see a textbox for entering a prompt. \n---\nI have installed genai stack many times but it has failed.\r\n\r\nThe error situation is as follows:\r\n\r\n> dep"}}, {"action": "set", "collection": "issues", "doc_id": "15", "data": {"n": 15, "idx": 50, "category": "credentials helper missing", "title": "[Bug]: Pulled the master branch then it won't start anymore", "url": "https://github.com/cytopia/devilbox/issues/938", "excerpt": " 0.0s\r\n \u280b mysql Pulling 0.0s\r\n \u280b pgsql Pulling 0.0s\r\n \u280b bind Pulling 0.0s\r\nerror getting credentials - err: docker-credential-pass resolves to executable in current directory (./docker-credential-pass), out: ``\r\n```\r\n\r\n\r\n### (Optional) Additional information\r\n\r\n_No response_\n---\n@luchmewep this doesn't seem to be an issue with the Devilbox, but rather with your setup in regards to `docker` and/or `docker-compose`/`docker compose`.\r\n\r\nThe error message you're receiving:\r\n```\r\nerror getting credentials - err: docker-credential-pass resolves to executable in current directory (./docker-credential-pass), out: ``\r\n```\r\nThis is before the Devilbox even starts. I would check your config.\n---\nActually, when I revert back to the older version, it goes thru.\n---\nNot sure how"}}, {"action": "set", "collection": "issues", "doc_id": "16", "data": {"n": 16, "idx": 55, "category": "daemon: cannot connect", "title": "[bug]: If the current docker context is not default then use the correct context", "url": "https://github.com/keploy/keploy/issues/3109", "excerpt": " \u2593\u2593\u2593\u2593\u2588\u2588\u2593\u2588\u2593\u2584\n \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\n \u2580\u2593\u2593\u2588\u2588\u2588\u2584 \u2584\u2584 \u2584 \u258c\n \u2584\u258c\u258c\u2593\u2593\u2588\u2588\u2588\u2588\u2584 \u2588\u2588 \u2593\u2588\u2580 \u2584\u258c\u2580\u2584 \u2593\u2593\u258c\u2584 \u2593\u2588 \u2584\u258c\u2593\u2593\u258c\u2584 \u258c\u258c \u2593\n \u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258c\u2593\u2593 \u2588\u2588\u2593\u2588\u2584 \u2593\u2588\u2584\u2593\u2593 \u2590\u2588\u258c \u2588\u2588 \u2593\u2588 \u2588\u258c \u2588\u2588 \u2588\u258c \u2588\u2593\n \u2593\u2593\u2593\u2593\u2580\u2580\u2580\u2580\u2593\u2593\u2593\u2593\u2593\u2593\u258c \u2588\u2588 \u2588\u2593 \u2593\u258c\u2584\u2584 \u2590\u2588\u2593\u2584\u2593\u2588\u2580 \u2588\u2593\u2588 \u2580\u2588\u2584\u2584\u2588\u2580 \u2588\u2593\u2588\n \u2593\u258c \u2590\u2588\u258c \u2588\u258c\n \u2593\n\nversion: 2.11.5\n\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.154601+05:30 \tINFO\tStarting keploy in docker with image\t{\"image:\": \"ghcr.io/keploy/keploy:v2.11.5\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.220479+05:30 \tINFO\tStarting keploy in docker with default context, as that is the current context.\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222794+05:30 \tERROR\tfailed to list docker volumes\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222816+05:30 \tERROR\tfailed to debugfs volume\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222824+05:30 \tERROR\tfailed to run the command in docker\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222833+05:30 \tERROR\tfailed to validate flags\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\nUsage:\n keploy record [flags]\n"}}, {"action": "set", "collection": "issues", "doc_id": "17", "data": {"n": 17, "idx": 57, "category": "desktop: mounts denied", "title": "macOS Docker Desktop shared mount path issue when running Kathara inside a container", "url": "https://github.com/KatharaFramework/Kathara/issues/388", "excerpt": " reproducible issue related to shared folder mounting when Kathara itself is executed inside a Docker container.\n\nEnvironment:\n\n* macOS\n* Docker Desktop\n* Kathara 3.8.3\n* Ubuntu 22.04 container used to execute Kathara\n\nProblem:\nWhen Kathara is executed inside a Docker container, shared folder mounts are generated using the container filesystem path instead of the corresponding host filesystem path.\n\nExample generated path:\n\n/labs/progetti/lab1/shared\n\ninstead of the actual host path:\n\n/Users/username/dockers/kathara/progetti/lab1/shared\n\n(where \u201cdockers\u201d is only an example host-side folder used to collect Docker-related projects)\n\nDocker Desktop rejects the mount with the following error:\n\n\u201cMounts denied:\nThe path /labs/progetti/lab1/shared is not shared from the host and is not known to Docker.\u201d\n\nAnalysis:\nThe issue appears in DockerMachine.py where:\n\nmachine.lab.shared_path\n\nis directly passed to Docker volume creation.\n\nSince Kathara is running inside a container, this path represents the container-side filesystem path instead of the real host filesystem path required by Docker Desktop on macOS.\n\nProposed fix:\nIntroduce host/container path translation support using environment variables:\n\n* KATHARA_CONTAINER_LAB_ROOT\n* KATHARA_HOST_LAB_ROOT\n\nBefore creating Docker volume mounts, translate:\n\ncontainer path -> host path\n\nExample:\n\n/labs/progetti/lab1/shared\n\u2192\n/Users/username/d"}}, {"action": "set", "collection": "issues", "doc_id": "18", "data": {"n": 18, "idx": 64, "category": "DNS resolution in container", "title": "[Question]: Getting error when configuring postgres as metadata db", "url": "https://github.com/infiniflow/ragflow/issues/19117", "excerpt": "timeout, **kwargs\nragflow-cpu-1 | )\nragflow-cpu-1 | File \"/root/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/socket.py\", line 840, in create_connection\nragflow-cpu-1 | for res in getaddrinfo(host, port, 0, SOCK_STREAM):\nragflow-cpu-1 | ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nragflow-cpu-1 | File \"/root/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/socket.py\", line 977, in getaddrinfo\nragflow-cpu-1 | for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\nragflow-cpu-1 | ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nragflow-cpu-1 | socket.gaierror: [Errno -3] Temporary failure in name resolution\nragflow-cpu-1 | \nragflow-cpu-1 | During handling of the above exception, another exception occurred:\nragflow-cpu-1 | \nragflow-cpu-1 | Traceback (most recent call last):\nragflow-cpu-1 | File \"/ragflow/.venv/lib/python3.13/site-packages/peewee.py\", line 3263, in connect\nragflow-cpu-1 | self._state.set_connection(self._connect())\nragflow-cpu-1 | ~~~~~~~~~~~~~^^\nragflow-cpu-1 | File \"/ragflow/.venv/lib/python3.13/site-packages/peewee.py\", line 4229, in _connect\nragflow-cpu-1 | conn = mysql.connect(db=self.database, autocommit=True,\nragflow-cpu-1 | **self.connect_params)\nragflow-cpu-"}}, {"action": "set", "collection": "issues", "doc_id": "19", "data": {"n": 19, "idx": 66, "category": "DNS resolution in container", "title": "bug: No Extensions available.", "url": "https://github.com/bluerobotics/BlueOS/issues/1695", "excerpt": "### Bug description\r\n\r\nNo Extensions available. Make sure the vehicle has internet access and try again.\r\n\r\n### Steps to reproduce\r\n\r\n1. Access: http://192.168.2.2/tools/extensions-manager\r\n2. The error pop-up: No Extensions available. Make sure the vehicle has internet access and try again.\r\n\r\nI check the internet, all work file. I tried on BlueOS version 1.1.0-beta-21 and 18. And also for Remote Versions: error fetching online tags: Cannot connect to host auth.docker.io:443 ssl:default [Temporary failure in name resolution]\r\n![error](https://github.com/bluerobotics/BlueOS-docker/assets/28943896/d7bebf7f-9a07-45d4-88f5-d8a82c675f79)\r\n\r\n### Primary pain point(s)\r\n\r\n_No response_\r\n\r\n### Prerequisites\r\n\r\n- [X] I have checked to make sure that a similar request has not already been filed or fixed.\n---\nHi @phamquandung,\r\n\r\nThanks for reporting the issue, is this a consistent problem ? Is it working fine now ?\n---\n> Hi @phamquandung,\r\n> \r\n> Thanks for reporting the issue, is this a consistent problem ? Is it working fine now ?\r\nHello @patrickelectric . It's still there. Please check\r\n![error](https://github.com/bluerobotics/BlueOS-docker/assets/28943896/96540316-d6f7-400c-be6b-d10"}}, {"action": "set", "collection": "issues", "doc_id": "20", "data": {"n": 20, "idx": 68, "category": "emulation: qemu crash", "title": "ci: emulated ldconfig intermittently segfaults on ubuntu-22.04 arm64 package job", "url": "https://github.com/montimage-projects/mmt-dpi/issues/421", "excerpt": "\n\n## Type\nBug\n\n## Description\nUnder QEMU, the ubuntu-22.04 arm64 leg of `.github/workflows/release-packages.yml` sometimes fails with `qemu: uncaught target signal 11` from `ldconfig`. The failure is at `tools/ci/build-package.sh:151`. It happened with setup-qemu-action v4.3.0 and v4.4.0, and every run used the same binfmt image digest (`tonistiigi/binfmt@sha256:400a4873\u2026`, qemu v10.2.3). It surfaced on PR #420 and passed on a rerun. Earlier runs 35811132281 and 35802233452 show the same segfault in the apt libc-bin trigger, which does not fail the job.\n\n## Acceptance Criteria\n- [ ] Pin the binfmt image by digest in the setup-qemu step, and/or make the emulated `ldconfig` step in build-package.sh retry or tolerate a crash without masking real failures\n- [ ] ubuntu-22.04 arm64 package job passes reliably\n\n## Metadata\n**Prior"}}, {"action": "set", "collection": "issues", "doc_id": "21", "data": {"n": 21, "idx": 69, "category": "emulation: qemu crash", "title": "Candidate image build hangs after QEMU SIGILL in arm64 npm ci (v1.6.0 release blocked)", "url": "https://github.com/tjakobsson/brain/issues/27", "excerpt": "**What failed:** Candidate image run on main for prepare commit fafe9658 (v1.6.0) was cancelled by the 40-min job timeout; no image for `sha-fafe965` reached GHCR.\n**Run:** https://github.com/tjakobsson/brain/actions/runs/33716434026\n**Key log:** `#15 [linux/arm64 dependencies 4/4] RUN npm ci --omit=dev` -> `qemu: uncaught target signal 4 (Illegal instruction) - core dumped` at 04:50:08, then no further output until `The operation was canceled` at 05:29:14.\n**Likely cause:** intermittent QEMU user-mode crash emulating arm64 node/npm; same chainguard/node (d6ca8dfc) and binfmt (400a4873) digests as the last green run, so not a version change. The arm64 layer was a cache miss because the version bump changed package-lock.json. BuildKit hung instead of failing the step after the crash.\n**Suggested next step:** rerun the workflow (`gh run rerun 33716434026` or workflow_dispatch with publish=true) to unblock the release; longer term build arm64 on a native `ubuntu-24.04-arm` runner (as action-parity."}}, {"action": "set", "collection": "issues", "doc_id": "22", "data": {"n": 22, "idx": 76, "category": "image: pull access denied", "title": "pull access denied zkevm-node", "url": "https://github.com/0xPolygon/zkevm-node/issues/3771", "excerpt": "\r\n[+] Running 1/1\r\n \u2714 Container zkevm-event-db Started 0.9s\r\ndocker compose -f docker-compose.yml up -d zkevm-mock-l1-network\r\n[+] Running 1/0\r\n \u2714 Container zkevm-mock-l1-network Running 0.0s\r\nsleep 1\r\ndocker compose -f docker-compose.yml up -d zkevm-prover\r\n[+] Running 1/1\r\n \u2714 Container zkevm-prover Started 10.9s\r\ndocker compose -f docker-compose.yml up -d zkevm-approve\r\n[+] Running 1/1\r\n \u2718 zkevm-approve Error pull access denied for zkevm-node, repository does not exist or may require 'docker l... 2.0s\r\nError response from daemon: pull access denied for zkevm-node, repository does not exist or may require 'docker login': denied: requested access to the resource is denied\r\nmake: *** [Makefile:575: run] Error 18\r\n\r\n#### Actual behaviour\r\n\r\n\r\n#### Steps to reproduce the behaviour\r\n\r\n\r\n#### Backtrace\r\n\r\n````\r\n[backtrace]\r\n````\r\n\r\nWhen submitting logs: please submit them as text and not screenshots."}}, {"action": "set", "collection": "issues", "doc_id": "23", "data": {"n": 23, "idx": 79, "category": "image: pull access denied", "title": "pull access denied ", "url": "https://github.com/lg/emugaming/issues/3", "excerpt": "on running the run command you give in the guide the pulling of the image fails with \r\nError from deamon : pull access denied for emugaming, repository does not exsist or may require docker login : requested acces to resource denied \r\n\r\ndid you take re docker repo down or do you need to update de scripts to incorporate the login creds for docker-hub \r\n"}}, {"action": "set", "collection": "issues", "doc_id": "24", "data": {"n": 24, "idx": 80, "category": "image: tag/repo not found", "title": "Error response from daemon: manifest for sickcodes/docker-osx:naked not found: manifest unknown: manifest unknown", "url": "https://github.com/sickcodes/Docker-OSX/issues/889", "excerpt": "\nWhen I ran this command:\n\n`docker pull sickcodes/docker-osx:naked` I got this error:\n\n`Error response from daemon: manifest for sickcodes/docker-osx:naked not found: manifest unknown: manifest unknown`\n\nI don't have this problem with the latest image so I'm wondering if the naked image is always online?\n---\nSame issue here. Looks like only one image is currently available:\nhttps://hub.docker.com/r/sickcodes/docker-osx/tags\n---\nI need to add this tag back, will work on it today/tomorrow\n---\nhi, is there any proggress on it? because i'm trying to run my own image.(I builded localy)\n---\nYeah, doesn't seem to work anymore. I would presume the developer is busy and does not have the time to fix it. \n---\nWould #833 work for you? \n---\nI tried to use #833 dickhub naked image to run container with Tahoe img, sadly it fails on booting.\n\nThe dickhub image shows 2 y"}}, {"action": "set", "collection": "issues", "doc_id": "25", "data": {"n": 25, "idx": 81, "category": "image: tag/repo not found", "title": "Docker image decolua/9router:0.5.81 is not available", "url": "https://github.com/decolua/9router/issues/4167", "excerpt": "The repository/changelog indicates that version `v0.5.81` is available, but the corresponding Docker image cannot be pulled.\n\nTrying to deploy:\n\n```yaml\nservices:\n 9router:\n image: decolua/9router:0.5.81\n```\n\nresults in:\n\n```text\nmanifest for decolua/9router:0.5.81 not found:\nmanifest unknown: manifest unknown\n```\n\n### Steps to reproduce\n\n```bash\ndocker pull decolua/9router:0.5.81\n```\n\n### Actual behavior\n\nDocker returns:\n\n```text\nError response from daemon:\nmanifest for decolua/9router:0.5.81 not found:\nmanifest unknown: manifest unknown\n```\n\n### Expected behavior\n\nThe Docker image for the current release should be available as:\n\n```text\ndecolua/9router:0.5.81\n```\n\nor the documentation/release notes should clarify which Docker tag should be used.\n\n### Environment\n\n* 9Router version: `v0.5.81`\n* Deployment: Docker Compose / Dokploy\n* Docker image: `decolua/9router:0.5.81`\n* Host OS: Linux\n\n### Additional context\n\nThe repository changelog already references `v0.5."}}, {"action": "set", "collection": "issues", "doc_id": "26", "data": {"n": 26, "idx": 82, "category": "image: tag/repo not found", "title": "Using default tag: latest Error response from daemon: manifest for kubernetes/pause:latest not found: manifest unknown: manifest unknown", "url": "https://github.com/ben1234560/k8s_PaaS/issues/52", "excerpt": "![image](https://github.com/user-attachments/assets/ae637c3a-66a3-4b94-a017-52ec5315fc8e)\r\n[root@hdss178-132 certs]# docker pull kubernetes/pause\r\nUsing default tag: latest\r\nError response from daemon: manifest for kubernetes/pause:latest not found: manifest unknown: manifest unknown\r\n[root@hdss178-132 certs]# docker pull kubernetes/pause\r\n\u8fd9\u4e2a\u955c\u50cf\u7528\u4e0d\u4e86\u561b\uff1f\u5361\u4f4f\u5566\uff0c\u5927\u54e5\u600e\u4e48\u641e\u5462\uff1f\n---\ndocker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:latest\uff0c\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\uff0c\u5185\u5bb9\u662f\u4e00\u6837\u7684\r\n\n---\n\u8c22\u8c22\u5927\u54e5"}}, {"action": "set", "collection": "issues", "doc_id": "27", "data": {"n": 27, "idx": 84, "category": "kernel: vm.max_map_count", "title": "Add Elastic Search Container + Configs", "url": "https://github.com/bryanlittlefield/TUGBOAT/issues/82", "excerpt": " - discovery.type=single-node\r\n ulimits:\r\n memlock:\r\n soft: -1\r\n hard: -1\r\n nofile:\r\n soft: 65536\r\n hard: 65536\r\n cap_add:\r\n - IPC_LOCK\r\n volumes:\r\n - elasticsearch-data:/usr/share/elasticsearch/data\r\n - ./config/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml\r\n ports:\r\n - \"9200:9200\"\r\n - \"9300:9300\"\r\n```\r\n\r\n\r\n\r\n**elasticsearch/elasticsearch.yml**\r\n```\r\ncluster.name: \"docker-cluster\"\r\nnetwork.host: elasticsearch\r\n```\r\n\r\n---\r\n\r\n**Know Issue with Indexing Larger Elastic Search DB's:**\r\n\r\n- [ ] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] : https://stackoverflow.com/questions/51445846/elasticsearch-max-virtual-memory-areas-vm-max-map-count-65530-is-too-low-inc\r\n\r\n\n---\nrun `sysctl -w vm.max_map_count=262144` on your host for ElasticSearch to work properly.\r\n\r\nhttps://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod-mode"}}, {"action": "set", "collection": "issues", "doc_id": "28", "data": {"n": 28, "idx": 86, "category": "kernel: vm.max_map_count", "title": "Elasticsearch", "url": "https://github.com/community-scripts/ProxmoxVED/issues/2139", "excerpt": "### Name of the Script\nElasticsearch\n\n### Script Type\nCT (LXC Container)\n\n### Does this script support arm64?\narm64 supported\n\n### \ud83d\udccb Script Details\nSingle-node Elasticsearch from the official Elastic repository. Requested in [discussion #5074](https://github.com/community-scripts/ProxmoxVE/discussions/5074).\n\n**The open question from the earlier assessment \u2014 `vm.max_map_count` in an unprivileged LXC \u2014 is resolved.** Per Elastic's docs, bootstrap checks are only warnings in *development mode* (loopback binding) but hard failures in *production mode* (non-loopback), and an LXC is only useful bound to the LAN. However `vm.max_map_count` is **not namespaced**: the container inherits it from the Proxmox host. So it cannot and need not be set inside the container.\n\nThe script therefore checks the inherited value and aborts with an actionable message if it is too low:\n\n```\nvm.max_map_count is , Elasticsearch needs at least 262144\nSet it on the PROXMOX HOST, not in this container:\n echo 'vm.max_map_count=1048576' >/etc/sysctl.d/99-elasticsearch.conf "}}, {"action": "set", "collection": "issues", "doc_id": "29", "data": {"n": 29, "idx": 93, "category": "network not found", "title": "bug: backup.sh reports rustfs as backed up when the S3 sync fails (network not found)", "url": "https://github.com/orkestra-cc/orkestra/issues/300", "excerpt": "### Affected surface\nops tooling (`backup.sh`, `restore.sh`)\n\n### Tenancy tier (if relevant)\nn/a\n\n### What happened?\n`backup.sh` reports the RustFS component as successfully backed up even when the S3 sync never ran. The `aws-cli` helper container is attached to `NETWORK=\"${STACK}_default\"` (computed as `${APP_NAME}-${ENV}_default`); when that network does not exist \u2014 in my case the stack had been brought up under a different `COMPOSE_PROJECT_NAME` \u2014 `docker run` fails with `network \u2026 not found`, but the script still prints `\u2713 rustfs: synced bucket 'orkestra-avatars' (0)` and lists `rustfs` among the components included in the tarball. The archive then contains an empty `rustfs/` tree while looking like a complete backup. `restore.sh` has the same construct in `restore_rustfs()` (the `s3 mb` failure is deliberately ignored, but a failing `s3 sync` is also not surfaced as a hard error).\n\nA second, minor point: the scheduled unit (`scripts/backup-sched"}}, {"action": "set", "collection": "issues", "doc_id": "30", "data": {"n": 30, "idx": 101, "category": "platform: exec format error", "title": "Docker build defaults to amd64 binary on arm64 hosts (exec format error)", "url": "https://github.com/rickraven/conntrack-exporter/issues/1", "excerpt": "First, thanks for building this exporter \u2014 it's exactly what I needed for conntrack bytes.\nI hit an architecture issue that seems caused by Dockerfile defaults:\n## What happened\nOn an arm64 host (`uname -m` => `aarch64`), running images from Docker Hub gave:\n\n```bash\ndocker run --rm --platform linux/arm64 rickraven/conntrack-exporter:latest --version\n# exec /conntrack-exporter: exec format error\n```\n\nI cloned this repo and built locally on the same host:\n\n`docker build -f docker/Dockerfile.alpine -t local/conntrack-exporter:arm64 .`\n\nBuild logs show:\n`CGO_ENABLED=0 GOOS=\"linux\" GOARCH=\"amd64\" go build ...`\n\nThen runtime fails:\n```bash\ndocker run --rm local/conntrack-exporter:arm64 --version\n# exec /conntrack-exporter: exec format error\n```\n\nIf I force build args, it works:\n\n```bash\ndocker build -f docker/Dockerfile.alpine \\\n --build-arg TARGETOS=linux \\\n --build-arg TARGETARCH=arm64 \\\n -t local/conntrack-exporter:arm64 .\ndocker run --rm local/conntrack-exporter:arm64 --version\n# works\n```\n\nSuspected root cause\nIn Dockerfiles, TARGETARCH defaults to amd64:\n\n```\nA"}}, {"action": "set", "collection": "issues", "doc_id": "31", "data": {"n": 31, "idx": 107, "category": "platform: no matching manifest", "title": "no matching manifest for linux/arm/v7 in the manifest list entries", "url": "https://github.com/nicolaka/netshoot/issues/119", "excerpt": "Hi Nikolaka,\r\n\r\nI'm trying to install netshoot on my RPI with this command:\r\n`_sudo docker run -it --net host nicolaka/netshoot_\r\n`\r\n\r\nafter a few seconds this is what I get in return:\r\n`_docker: no matching manifest for linux/arm/v7 in the manifest list entries._\r\n`\r\n\r\nNot sure what I'm doing wrong.\n---\nIndeed, an arm v7 build would be great.\n---\nBuilding the image on arm v7 also fails with:\n\n```sh \n$ buildah build .\n...\n[1/2] STEP 4/4: RUN /tmp/fetch_binaries.sh\n--2025-02-05 12:40:49-- https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-armv7l\nResolving github.com (github.com)... 140.82.121.3\nConnecting to github.com (github.com)|140.82.121.3|:443... connected.\nHTTP request sent, awaiting response... 404 Not Found\n2025-02-05 12:40:49 ERROR 404: Not Found.\n\nError: building at STEP \"RUN /tmp/fetch_binaries.sh\": while running runtime: exit status 8\n\n```\n---\nFR to"}}, {"action": "set", "collection": "issues", "doc_id": "32", "data": {"n": 32, "idx": 108, "category": "platform: requested platform mismatch", "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", "url": "https://github.com/TomasTomecek/sen/issues/191", "excerpt": "Hi @TomasTomecek , Can you please provide also an docker image for ARM(v8)? Thank you very much!\n---\nI'm busy these days so it would take me weeks at minimum to get to this. I also don't have an armv8 device where I'd verify it works properly. Happy to accept a contribution."}}, {"action": "set", "collection": "issues", "doc_id": "33", "data": {"n": 33, "idx": 111, "category": "platform: requested platform mismatch", "title": "docker\u8de8\u5e73\u53f0\u6253\u5305\u95ee\u9898does not match the detected host platform | silenceboychen", "url": "https://github.com/silenceboychen/silenceboychen.github.io/issues/50", "excerpt": "https://www.silenceboy.com/2022/04/29/docker%E8%B7%A8%E5%B9%B3%E5%8F%B0%E6%89%93%E5%8C%85%E9%97%AE%E9%A2%98does-not-match-the-detected-host-platform/ \n\n \u95ee\u9898\u6700\u8fd1\u5728mac M1\u4e0a\u6784\u5efa\u7684docker\u955c\u50cf\uff0c\u53d1\u5e03\u5230ubuntu20\u7cfb\u7edf\u7684\u670d\u52a1\u5668\u4e0a\u540e\uff0c\u4e00\u76f4\u8fd0\u884c\u5931\u8d25\u3002\u8f93\u51fa\u4ee5\u4e0b\u62a5\u9519\u4fe1\u606f\uff1a 1The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was req"}}, {"action": "set", "collection": "issues", "doc_id": "34", "data": {"n": 34, "idx": 112, "category": "port already allocated", "title": "REST test stack: pick free ports instead of failing on 55432/8080/8443", "url": "https://github.com/kljensen/yelukerest/issues/382", "excerpt": "Seen 2026-09-10 while shipping milestone 21: `bin/test-rest-stack.sh` could not run because another project's Postgres container already listened on `127.0.0.1:55432`.\n\nTwo problems, one fix:\n\n1. The script accepts `YELUKEREST_TEST_DB_PORT` (and HTTP/HTTPS) overrides for the docker port mapping, but `YELUKEREST_TEST_DATABASE_URL` / `YELUKEREST_TEST_MIGRATOR_DATABASE_URL` in `.env` carry a fixed port. Overriding the port therefore brings the container up on one port while zapadka and the tests connect to another (\"cannot connect to the target: Connection refused\").\n2. There is no detection at all: the failure is docker's \"Bind for 127.0.0.1:55432 failed: port is already allocated\", after the script has already torn down the dev stack.\n\nProposal, keep it simple:\n\n- [ ] Before starting anything, probe the three ports (`nc -z` or `lsof -nP -iTCP: -sTCP:LISTEN`). If one is taken and no override is set, pick the next free port in a small range (e.g. 55432\u201355441) and say so on stderr.\n- [ ] Derive the database URLs the script uses from the chosen port: take the URLs from `.env`, rewrite only the port (`sed` on `:/`), and export them for zapadka and the test runner. The `.env` values stay the documented defaults.\n- [ ] Do the probe **before** `docker compose down` so a port clash never leaves the dev stack down.\n- [ ] One line in `CLAUD"}}, {"action": "set", "collection": "issues", "doc_id": "35", "data": {"n": 35, "idx": 113, "category": "port already allocated", "title": "Using docker-maven-plugin from two profiles with different ports causes 'port is already allocated' error", "url": "https://github.com/fabric8io/docker-maven-plugin/issues/1874", "excerpt": "file tries to start the database Docker Image using its own distinct port (10096 and 10097 respectively). I have checked that those ports are not already in use on my system. When I run the profiles manually from the command line each works fine, but when run together I get the following error:\n\n```\n[ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.46.0:start (docker-db-api-7-it-start) on project monex: I/O Error: Unable to start container id [0a0eb824aada] : {\"message\":\"failed to set up container networking: driver failed programming external connectivity on endpoint elemental-2 (e63a42680265a7ccc251142192e9b5773e54ec193a3c651878204ecbbd63d4ef): Bind for 0.0.0.0:10097 failed: port is already allocated\"} (Internal Server Error: 500) -> [Help 1]\n```\n\nMy `pom.xml` has these significant bits:\n\n```xml\n\n\n \n\n \n \n docker-integration-test-db-api-7\n \n true\n \n \n \n \n io.fa"}}, {"action": "set", "collection": "issues", "doc_id": "36", "data": {"n": 36, "idx": 114, "category": "port already allocated", "title": "Port allocation race: concurrent sandbox creation fails with \"port is already allocated\"", "url": "https://github.com/opensandbox-group/OpenSandbox/issues/1705", "excerpt": "## Summary\n\nWith `runtime.type = \"docker\"` and `docker.network_mode = \"bridge\"`, concurrent sandbox creation\nfails intermittently because the server hands out a host port that another in-flight creation is\nalready using. The failure surfaces to the caller as HTTP 500:\n\n```\nFailed to create or start container: 500 Server Error for\nhttp+docker://localhost/v1.55/containers//start: Internal Server Error\n(\"failed to set up container networking: driver failed programming external connectivity\n on endpoint sandbox-: Bind for 0.0.0.0:41106 failed: port is already allocated\")\n```\n\nThe port appears to be **chosen at random from `docker.port_range_*` and then handed to Docker to\nbind, with nothing reserving it in between**. Two creations racing between the pick and the bind get\nthe same port.\n\n## Evidence: the failure rate follows the birthday paradox\n\nEach sandbox consumes 2 host ports, so N concurrent creations draw 2N ports from the range. If the\ndraws are independent and unreserved, the expected number of collisions is `(2N)\u00b2 / (2 \u00b7 R)` for a\nrange of R ports. Measured on a single node, server `v0.2.3`, `secure_runtime.type = \"gvisor\"`:\n\n| Concurrent creations | Draws | Range | Expected collisions | **Observed failures** |\n|---|---|-"}}, {"action": "set", "collection": "issues", "doc_id": "37", "data": {"n": 37, "idx": 120, "category": "volume permission denied", "title": "Podman Compose rootless deployment mounts Docker socket instead of the Podman socket", "url": "https://github.com/kestra-io/kestra/issues/19626", "excerpt": "ra trying to access `/var/run/docker.sock`, which is not the Podman rootless socket.\n\nSteps to reproduce on Fedora Linux with rootless Podman:\n\n```sh\nsudo dnf install podman podman-compose\n\nsystemctl --user enable --now podman.socket\n\ncurl -o docker-compose.yml \\\n https://raw.githubusercontent.com/kestra-io/kestra/develop/docker-compose.yml\n\npodman compose up\n```\n\n### Actual behavior\n\nThe current compose file mounts:\n\n```\nvolumes:\n - /var/run/docker.sock:/var/run/docker.sock\n```\n\nThe rootless Podman API socket is instead available at `/run/user/$UID/podman/podman.sock`.\n\nKestra fails to access the container runtime and reports an error similar to:\n\n```sh\nError: statfs /var/run/docker.sock: permission denied\n```\n\n### Expected behavior\n\nSince the documentation explicitly states that the provided Compose file works with Podman Compose and describes the setup as a rootless Podman deployment, the compose configuration should either: use the appropriate Podman rootless socket or explicitly document that the provided compose file requires additional configuration to connect Kestra to the Podman socket.\n\n### Proposed documentation/configuration change\n\nThe Podman Compose guide could provide a Podman-specific compose override or configuration showing how to mount the rootless Podman socket, for example:\n\n```\nvolumes:\n - ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/docker.sock\n```\n\n#"}}, {"action": "set", "collection": "issues", "doc_id": "38", "data": {"n": 38, "idx": 121, "category": "volume permission denied", "title": "Root-stage mkdirs under $HOME break the user-stage volume mkdirs", "url": "https://github.com/zvchei/docker-seed/issues/29", "excerpt": "A template that creates a directory under `$HOME` in its `root.Dockerfile` leaves it owned by `root`. The generated user stage later runs `mkdir -p` for every declared volume path as `${USER}`, so any volume nested under that directory fails the build.\n\nThe `jupyter` template hits this: its `root.Dockerfile` runs `mkdir -p $HOME/.local`, so a volume at `.local/share/` cannot be created.\n\nReproduce with:\n\n```json\n[\n {\n \"name\": \"jupyter_repro\",\n \"templates\": [\"jupyter\"],\n \"volumes\": { \"state\": \".local/share/example\" }\n }\n]\n```\n\n`docker compose build jupyter_repro` fails with:\n\n```\nmkdir: cannot create directory '/home/user/.local/share': Permission denied\n```\n\nThe generated Dockerfile shows the cause \u2014 `USER root` creates `$HOME/.local`, then the volume mkdirs run after `USER ${USER}`:\n\n```\nUSER root\n# --- jupyter ---\nRUN mkdir -p $HOME/.local && \\\n mkdir -p $HOME/.jupyter\n\nUSER ${USER}\nRUN mkdir -p \\\n $HOME/.local/share/example\n```\n\nPossible fixes: `chown` root-stage `$HOME` directories back to the container user, emit the volume mkdirs before the root fragments, or drop the redundant `mkdir` calls from `jupyter/root.Dockerfile` since the volume mkdirs already cover them."}}, {"action": "set", "collection": "issues", "doc_id": "39", "data": {"n": 39, "idx": 122, "category": "volume permission denied", "title": "docker/Dockerfile.heavy: image cannot boot with a Docker-managed volume \u2014 .omnipus is created root-owned", "url": "https://github.com/elicify-ai/omnipus/issues/655", "excerpt": "ed.\n\nVerified against `release/v0.1.1` @ `aa97bcea574ebf5c3a56058b7d2095716a6f5da4`.\n\n## Reproduce\n\n```sh\ndocker build -f docker/Dockerfile.heavy -t omnipus-heavy:repro .\ndocker run --rm -v repro-vol:/home/omnipus/.omnipus -p 127.0.0.1:5199:5000 \\\n -e OMNIPUS_GATEWAY_HOST=0.0.0.0 -e OMNIPUS_SANDBOX_MODE=permissive \\\n omnipus-heavy:repro\n```\n\nObserved \u2014 container exits, `/health` never becomes available:\n\n```\nWarning: could not ensure cli token: update config.json: read config.json: open /home/omnipus/.omnipus/config.json: no such file or directory\nOpen the dashboard / log in as admin:\n This machine: http://localhost:5000\nError: creating log directory: mkdir /home/omnipus/.omnipus/logs: permission denied\n```\n\n## Cause\n\n`useradd -m -d /home/omnipus` (`docker/Dockerfile.heavy:179`) creates the home directory, but **nothing ever creates `/home/omnipus/.omnipus`**. `VOLUME /home/omnipus/.omnipus` (`:184`) then declares a mount point that does not exist in the image.\n\nDocker seeds a fresh volume from whatever is at that path in the image. Finding nothing, it creates the directory as `root:root`. The container runs as `USER omnipus` (`:182`, uid 1000), which cannot write into it.\n\nConfirmed directly \u2014 on the unmodified image the mount point is root-owned; after creating and chowning it before `VOLUME`, the same volume comes up owned by uid 1000 and the instance boots:\n\n```\n# unmo"}}] \ No newline at end of file diff --git a/bench/labels/rater_subset.json b/bench/labels/rater_subset.json new file mode 100644 index 0000000..b9a49f2 --- /dev/null +++ b/bench/labels/rater_subset.json @@ -0,0 +1 @@ +[0, 1, 2, 3, 6, 8, 10, 13, 17, 21, 28, 30, 31, 34, 37, 39, 42, 46, 48, 54, 55, 57, 58, 60, 65, 75, 79, 81, 87, 88, 98, 100, 101, 105, 106, 108, 109, 117, 118, 120] \ No newline at end of file diff --git a/bench/labels/sample.jsonl b/bench/labels/sample.jsonl new file mode 100644 index 0000000..8c6d16f --- /dev/null +++ b/bench/labels/sample.jsonl @@ -0,0 +1,124 @@ +{"url": "https://github.com/NginxProxyManager/nginx-proxy-manager/issues/5852", "category": "address already in use", "rule": "ports.host", "title": "Address already in use", "excerpt": "this but is marked as closed but as of 2.15.1 it still exists\nways to reproduce it:\n1- edit random host\n2- RANDOMLY it starts throwing errors:\n\n```\nnginx | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)\nnginx | nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)\nnginx | nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)\nnginx | nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)\nnginx | nginx: [emerg] bind() to 0.0.0.0:81 failed (98: Address already in use)\nnginx | nginx: [emerg] bind() to [::]:81 failed (98: Address already in use)\n```\n\nthere is no definite way of checking what triggers it\n\nnginx is installed as docker compose:\n\n ```\ncat docker-compose.yaml | grep -v '#'\nservices:\n\n container_name: nginx\n image: 'docker.io/jc21/nginx-proxy-manager:latest'\n restart: unless-stopped\n environment"} +{"url": "https://github.com/lgsvl/lanefollowing/issues/17", "category": "address already in use", "rule": "ports.host", "title": " what(): bind: Address already in use", "excerpt": "xiayu@xiayu-Lenovo-Legion-R7000P2021H:~/Desktop/lanefollowing$ docker-compose up drive\r\nStarting lanefollowing_drive ... done\r\nAttaching to lanefollowing_drive\r\ndrive_1 | terminate called after throwing an instance of 'boost::exception_detail::clone_impl >'\r\ndrive_1 | what(): bind: Address already in use\r\ndrive_1 | /lanefollowing/scripts/drive.sh: line 14: 2729 Aborted lgsvl_bridge\r\n"} +{"url": "https://github.com/dmohanja/GT7Monitor/issues/5", "category": "address already in use", "rule": "ports.host", "title": "Error Address already in use", "excerpt": "Any idea how to get this working\n\npython3 main.py\nERROR:root:Unable to bind socket to 0.0.0.0 at port 33740. [Errno 98] Address already in use\nINFO:root:Starting to listen for UDP packets from 192.168.0.254:33740\n---\nI solved address already in use. It was a docker running at startup taking that 0.0.0.0 address.\n\nBut now when I run main.py I get a more cryptic error.\n\nAny help much apprecitated\n\npython3 main.py\nINFO:root:Starting to listen for UDP packets from 192.168.0.254:33740\nINFO:root:updated IP to: 192.168.0.254\nProcess Process-2:\nTraceback (most recent call last):\n File \"/usr/lib/python3.10/multiprocessing/process.py\", line 314, in _bootstrap\n self.run()\n File \"/usr/lib/python3.10/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/home/osaka78/Down"} +{"url": "https://github.com/KurtzL/nestjs-temporal/issues/54", "category": "address already in use", "rule": "ports.host", "title": "Worker restarts: address already in use", "excerpt": "Everything starts fine on the first run, but when changing code and hot reloading is triggered, the worker seems to gracefully shutdown successfully, but upon restarting, the process complains the default 3000 port is already in use(I assume the one nestjs is listening. Now, I have a feeling this is because the worker is spawned as a child process, and it tries to bind to the same address. Maybe I'm wrong, but I can't seem to find a workaround. Any ideas would be appreciated.\n---\nit seems like you are missing `app.enableShutdownHooks()`\r\n```\r\nasync function bootstrap() {\r\n const port = 3000\r\n\r\n const app = await NestFactory.create(AppModule, {\r\n bufferLogs: true,\r\n autoFlushLogs: true,\r\n })\r\n app.enableShutdownHooks()\r\n\r\n await app.listen(port, () => {\r\n /* eslint-disable no-console */\r\n console.log(`[server]: Server is running at http://localhost:${port}`)\r\n })\r\n}\r\n\r\nbootstrap().catch(err => {\r\n /* eslint-disable no-console */\r\n console.error(err)\r\n process.exit(1)\r\n})\r\n```\n---\nApart from a warn saying worker was not cleanly shutdown, this seems to be doing the job. An alternative I used so far is what I described here https://github.com/temporalio/sdk-typescript/issues/1437 \r\nbasically, running the codebase in 2 processes, one regular http app and the worker running in an application context only, which might adhere bette"} +{"url": "https://github.com/dyne/reflow-os/issues/25", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Initialization fails on MACOS with readme instructions", "excerpt": "\n\r\n (ecto_sql 3.7.1) lib/ecto/adapters/sql.ex:760: Ecto.Adapters.SQL.raise_sql_call_error/1\r\n (elixir 1.12.3) lib/enum.ex:1582: Enum.\"-map/2-lists^map/1-0-\"/2\r\n (ecto_sql 3.7.1) lib/ecto/adapters/sql.ex:852: Ecto.Adapters.SQL.execute_ddl/4\r\n (ecto_sql 3.7.1) lib/ecto/migrator.ex:678: Ecto.Migrator.verbose_schema_migration/3\r\n (ecto_sql 3.7.1) lib/ecto/migrator.ex:504: Ecto.Migrator.lock_for_migrations/4\r\n (ecto_sql 3.7.1) lib/ecto/migrator.ex:419: Ecto.Migrator.run/4\r\n (ecto_sql 3.7.1) lib/ecto/migrator.ex:146: Ecto.Migrator.with_repo/3\r\n lib/repo/release_tasks.ex:7: Bonfire.Repo.ReleaseTasks.migrate/1\r\n\r\n```\r\n\r\nAnd then :\r\n\r\n```\r\nError: Database is uninitialized and superuser password is not specified.\r\n\r\n You must specify POSTGRES_PASSWORD to a non-empty value for the\r\n\r\n superuser. For example, \"-e POSTGRES_PASSWORD=password\" on \"docker run\".\r\n\r\n\r\n You may also use \"POSTGRES_HOST_AUTH_METHOD=trust\" to allow all\r\n\r\n connections without a password. This is *not* recommended.\r\n```\r\n\r\nAnd this in the db service logs.\n---\nFor the record I used : \r\n```\r\n environment:\r\n - POSTGRES_HOST_AUTH_METHOD=trust\r\n```\r\n\r\nIn the docker compose file at the db service description which solved the \"problem\".\n---\nI tried adding that line but still same error"} +{"url": "https://github.com/rancher-sandbox/rancher-desktop/issues/6760", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Unable to bind to address other than 127.0.0.1 or 0.0.0.0", "excerpt": "ll tell the guest agent to forward that interface as well:\r\n\r\n```console\r\n$ grep '15432' ~/Library/Logs/rancher-desktop/lima.ha.stderr.log\r\n{\"level\":\"debug\",\"msg\":\"guest agent event: {Time:2024-04-25 16:20:37.783086267 +0000 UTC LocalPortsAdded:[{IP:127.0.0.11 Port:15432}] LocalPortsRemoved:[] Errors:[]}\",\"time\":\"2024-04-25T09:20:39-07:00\"}\r\n{\"level\":\"info\",\"msg\":\"Forwarding TCP from 127.0.0.11:15432 to 127.0.0.11:15432\",\"time\":\"2024-04-25T09:20:39-07:00\"}\r\n```\r\n\r\nThe `lsof` command still didn't show anything for me, but that was because the database didn't actually start properly, so the port was closed again right away:\r\n\r\n```console\r\n$ docker logs db\r\nError: Database is uninitialized and superuser password is not specified.\r\n You must specify POSTGRES_PASSWORD to a non-empty value for the\r\n superuser. For example, \"-e POSTGRES_PASSWORD=password\" on \"docker run\".\r\n\r\n You may also use \"POSTGRES_HOST_AUTH_METHOD=trust\" to allow all\r\n connections without a password. This is *not* recommended.\r\n\r\n See PostgreSQL documentation about \"trust\":\r\n https://www.postgresql.org/docs/current/auth-trust.html\r\n```\r\n\r\nNote that the `override.yaml` file will be deleted if you ever perform a factory reset, and must be recreated manually again afterwards.\r\n\r\n\n---\nInteresting. Would this work if we want to do this with multiple IP addresses? Ideally we want to "} +{"url": "https://github.com/trydirect/stacker/issues/240", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "stacker deploy --target server writes every project to the same remote path, causing real cross-project deployment damage", "excerpt": "produced via `stacker-projects/duplicati` colliding with a pre-existing `stacker-projects/rallly` deployment, both targeting the same `EXISTING_SERVER_HOST`, in trydirect/stacker-project-examples\n- Related: #235 (same bug class, `--target local` variant)\n---\nUpdating with a more severe detail found on further investigation: this wasn't just compose-file thrashing \u2014 **rallly's actual database volume was recreated empty**, i.e. real data loss.\n\n\\`docker volume inspect project_rallly_db\\` shows \\`CreatedAt: 2026-08-20T17:40:21Z\\` \u2014 today, during this exact testing window \u2014 and \\`du -sh\\` on it shows only 8.0K (empty, no real data). Postgres now refuses to start: \\`Database is uninitialized and superuser password is not specified\\` (rallly's own compose has \\`POSTGRES_PASSWORD: ''\\`, which was presumably fine against the *original* initialized volume but fails cold-start validation against a fresh empty one).\n\nSo the actual sequence was worse than \"wrote a different compose file over the old one\": something in the \\`--target server\\` deploy path for \\`duplicati\\` appears to have torn down and recreated volumes under the shared \\`project\\` compose project scope too \u2014 not just the compose file/containers. This raises the severity from \"silent overwrite\" to \"silent data loss\" for whatever was in the previous occupant's volumes.\n---\nFixed. Each project now gets its own directory /home/"} +{"url": "https://github.com/mattermost/docker/issues/163", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Any support with podman-compose?", "excerpt": "I'm running podman compose 1.3.0 (latest version) and lots of errors, certainly due to the lack of podman support.\n\n```\n[postgres] | Error: Database is uninitialized and superuser password is not specified.\n[postgres] | You must specify POSTGRES_PASSWORD to a non-empty value for the\n[postgres] | superuser. For example, \"-e POSTGRES_PASSWORD=password\" on \"docker run\".\n[postgres] | \n[postgres] | You may also use \"POSTGRES_HOST_AUTH_METHOD=trust\" to allow all\n[postgres] | connections without a password. This is *not* recommended.\n[postgres] | \n[postgres] | See PostgreSQL documentation about \"trust\":\n[postgres] | https://www.postgresql.org/docs/current/auth-trust.html\n[mattermost] | Error: failed to load configuration: could not create config file: open /mattermost/config/config.json: permission denied\n[m"} +{"url": "https://github.com/canyanio/janus-gateway-docker/issues/29", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "Error running docker compose", "excerpt": "Hi, I'm running into the following error running the docker compose example in the readme:\r\n\r\n\r\n> ERROR: for janusdock_janus-gateway_1 Cannot start service janus-gateway: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/XXXXX/janusDock/etc/janus/janus.jcfg\" to rootfs at \"/usr/local/etc/janus/janus.jcfg\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\n> \r\n> ERROR: for janus-gateway Cannot start service janus-gateway: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/XXXXX/janusDock/etc/janus/janus.jcfg\" to rootfs at \"/usr/local/etc/janus/janus.jcfg\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\n> ERROR: Encountered errors while bringing up the project.\r\n\r\n\r\nAny thoughts wha"} +{"url": "https://github.com/Open-Location-Stack/open-location-hub/issues/59", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "local-hub want to create clickhouse but config files appear as directories", "excerpt": "straps SigNoz and creates the needed docker images. \n\nDuring the SigNoz bootstrap, creating the clickhouse image fails because he creates the config files as directories. \n\nError response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting \"./open-location-hub/local-hub/common/clickhouse/config.xml\" to rootfs at \"/etc/clickhouse-server/config.xml\": mount src=./open-location-hub/local-hub/common/clickhouse/config.xml, dst=/etc/clickhouse-server/config.xml, dstFd=/proc/thread-self/fd/15, flags=MS_BIND|MS_REC: not a directory: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\n\n\n```\n$ ls -la ./open-location-hub/local-hub/common/clickhouse/\ntotal 28\ndrwxr-xr-x 7 user user 4096 Jun 26 08:15 .\ndrwxr-xr-x 3 user user 4096 Jun 26 07:55 ..\ndrwxr-xr-x 2 root root 4096 Jun 26 08:15 cluster.xml\ndrwxr-xr-x 2 root root 4096 Jun 26 08:15 config.xml\ndrwxr-xr-x 2 root root 4096 Jun 26 08:15 custom-function.xml\ndrwxr-xr-x 2 user user 4096 Jun 26 08:15 user_scripts\ndrwxr-xr-x 2 root root 4096 Jun 26 08:15 users.xml\n```\n\nTo get the default config file, it can be copied from the signoz repo before docker-compose is call"} +{"url": "https://github.com/BillyOutlast/rocm-automated/issues/2", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "Error while deploying in portainer", "excerpt": "Hi,\n\nI\u2019m trying to deploy stack from your repo in portainer (it works in commandline) but getting following error:\n\nFailed to deploy a stack: compose up operation failed: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting \"/data/compose/2/comfyui-build/docker-entrypoint.sh\" to rootfs at \"/docker-entrypoint.sh\": mount src=/data/compose/2/comfyui-build/docker-entrypoint.sh, dst=/docker-entrypoint.sh, dstFd=/proc/thread-self/fd/11, flags=MS_BIND|MS_REC: not a directory: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\n\nAny idea how to fix it? Thanks!"} +{"url": "https://github.com/paschmann/changd/issues/3", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "Problem starting ui_server", "excerpt": " latest fixes and updated Docker environment, I encounter new problems when running `docker-compose up`:\r\n\r\n```\r\n$ docker-compose up\r\nCreating network \"changd_default\" with the default driver\r\nCreating changd_db_1 ... done\r\nCreating changd_api_1 ... done\r\nCreating changd_ui_server_1 ... error\r\n\r\nERROR: for changd_ui_server_1 Cannot start service ui_server: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/kerbe/git/docker/changd/frontend/nginx/default.conf\" to rootfs at \"/etc/nginx/conf.d/default.conf\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\n\r\nERROR: for ui_server Cannot start service ui_server: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/home/kerbe/git/docker/changd/frontend/nginx/default.conf\" to rootfs at \"/etc/nginx/conf.d/default.conf\" caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type\r\nERROR: Encountered errors while bringing up the project.\r\n```\r\n\r\nCurrent envir"} +{"url": "https://github.com/hubblo-org/publications/issues/1", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "Erreur ", "excerpt": "Bonjour,\r\nSuite a l'article dans le Programmez 249, j'ai voulu tester Scaphandre, mais je rencontre une soucis.\r\nAu docker compose j'ai ce retour.\r\n\r\n**article-programmez-09-2021_app_1 is up-to-date\r\nCreating article-programmez-09-2021_scaphandre_1 ... error\r\nERROR: for article-programmez-09-2021_scaphandre_1 Cannot create container for service scaphandre: invalid mount config for type \"bind\": bind source path does not exist: /sys/class/powercap\r\nERROR: for scaphandre Cannot create container for service scaphandre: invalid mount config for type \"bind\": bind source ------path does not exist: /sys/class/powercap\r\nERROR: Encountered errors while bringing up the project.**\r\n\r\n\r\ncordialement\r\nFabien\r\n\n---\nHi,\r\n\r\nYou need to have the powercap module installed on your linux machine. Then you'll get the /sys/class/powercap folder.\r\n\r\nThe very first steps of requirements are described here : https://hubblo-org.github.io/scaphandre-documentation/tutorials/quickstart.html\n---\nthanks, I'll try it"} +{"url": "https://github.com/tribut/homeassistant-docker-venv/issues/35", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "--mount: \"bind source path does not exist\", but it does", "excerpt": "command : `docker run --device /dev/ttyUSB0:/dev/ttyUSB0 -d --name=\"home-assistant\" --mount type=bind,source=/home/USERNAME,target=/config2 -v /etc/localtime:/etc/localtime:ro --net=host ghcr.io/home-assistant/home-assistant`\r\n\r\n docker: Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /home/USERNAME.\r\n\r\nbut source path exists\r\n![image](https://github.com/user-attachments/assets/0f2ec2d7-6cc1-41c2-967b-c517a04b7536)\r\n\n---\nThis does not appear to be related to this repo, but some quick searching suggest this may be related to having docker installed as a snap. What OS are you using? How did you install docker?\r\n\r\nCf. https://forums.docker.com/t/bind-source-path-does-not-exist-but-it-does-exist/124250/8\n---\nHi, Not completely sure.\r\nI am using a raspbery pi 5 and installed the home assistant operating system which includes the docker. (and then updated to the latest version)"} +{"url": "https://github.com/devcontainers/spec/issues/335", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "Proposal: Predefined variables for user's home directory", "excerpt": "e are hitting is the fact that Windows has a different env for the Home directory then Linux/Mac. If you are doing 1 or 3, it does not matter as much because for Windows you can do from within WSL first. Codespaces is always Linux.\r\n\r\nI have seen some other people use _both_ envs but that is still often resulting in a blank env that generates an error:\r\n\r\n```json\r\n\"mounts\": [\r\n \"source=${localEnv:HOME}${localEnv:USERPROFILE}/.docker,target=/home/app/.docker,type=bind,consistency=cached\"\r\n]\r\n```\r\n\r\nresults in the following if I do \"Clone Repository into Container Volume\" straight from VS Code on Windows:\r\n\r\n```\r\ndocker: Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /.docker.\r\n```\r\n\r\nHaving a cross-platform and _always_ defined way of providing the user's home directory on the host machine would help a ton. \r\n\r\n(we are getting around the mount point not always existing with an initializeCommand)\r\n\r\n```json\r\n\"initializeCommand\": {\r\n \"mkdir-posix\": \"mkdir -p $HOME/.config $HOME/.docker $HOME/.cloudflared || true\",\r\n \"mkdir-windows\": \"mkdir %USERPROFILE/.config %USERPROFILE/.docker %USERPROFILE/.cloudflared || true\"\r\n},\r\n```\n---\nHi \ud83d\udc4b \n\nThanks for opening the issue. \n\n`\"${localEnv:HOME}${localEnv:USERPROFILE}\"` is expected to work across Windows and Linux, as either one must be set depending on the OS.\n\n> docker: Error"} +{"url": "https://github.com/zdeneksvarc/postal-tls/issues/3", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "Error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt", "excerpt": "docker compose up -d when i do this i get this error.\r\n\r\nError response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt\n---\nDid you follow the guide? There are 8 steps before this one. What directory are you running `docker compose up -d` inside?\n---\nAs @sinnbeck wrote, if all the steps are followed, Caddy will generate the certificates to the path mentioned. If this problem persists after proper installation, please @mucktobrak open a new issue with more information attached.\n---\ni did everything but i still get the same error @zdeneksvarc \n---\nOk and is `/opt/postal-tls/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dom/mail.dom.crt `existing"} +{"url": "https://github.com/dromara/Jpom/issues/49", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "\u4fee\u6539docker demon\u914d\u7f6e\u540e\uff0cdocker\u6784\u5efa\u6ca1\u6709\u4f7f\u7528\u65b0\u914d\u7f6e", "excerpt": "Dockerfile\u91cc\u4f7f\u7528\u4e86COPY --chmod=xxx\uff0c\u4fee\u6539\u4e86daemon.json\u6dfb\u52a0\r\n```\r\n\"features\": {\r\n \"buildkit\": true\r\n}\r\n```\r\n\u91cd\u65b0\u6784\u5efa\u8fd8\u662f\u62a5errorDetail={message=the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled},error=the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled\r\n\u5c1d\u8bd5\u4e86\u91cd\u542fserver\u3001agent\u7b49\u5747\u4e0d\u751f\u6548\r\n\u4f46\u662f\u4f7f\u7528\u547d\u4ee4\u884c\u5728jpom\u521b\u5efa\u7684source\u76ee\u5f55\u4e0b\u53ef\u4ee5\u751f\u6548"} +{"url": "https://github.com/NVIDIA/NemoClaw/issues/10007", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "Hermes Portable Dockerfile requires BuildKit-only features on Podman", "excerpt": "3-vl:4b`.\n3. Observe onboarding reach Hermes image creation at step 6/8.\n4. Without the first repair, observe `ADD --chmod=0444 --checksum=sha256:...` stop the build.\n5. With the first repair, observe the empty `TARGETARCH` value produce `hermes-managed-teams--wheels`.\n\n## Environment\n\n- OS: Ubuntu 22.04 x86_64\n- Hardware: NVIDIA L40S\n- Runtime: rootless Podman client/server 5.7.0, cgroup v2, netavark\n- First tested revision: `ede33e2e4312b0db58103bbfb6ec89e598416577`\n- Second tested revision: `0f41e83c0c144e13c0c3140808e7c4ba5a1acd12`\n- Profile: Hermes Portable, managed Ollama, `qwen3-vl:4b`\n\n## Debug Output\n\nCredential-free retained output:\n\n```text\nDocker stream error: the --chmod option requires BuildKit\nError: initializing source docker://hermes-managed-teams--wheels:latest\n```\n\nStrict host preparation and reboot qualification passed before each product installation. No retry, resume, probe, lifecycle operation, or cleanup followed either failure.\n\n## Acceptance\n\n- Remote wheel `ADD` instructions retain exact SHA-256 checksums and omit BuildKit-only permission options.\n- The global Dockerfile arguments provide `TARGETARCH=amd64` before the first `FROM`.\n- The wheel-selection stage continues to use `${TARGETARCH}` so managed multi-platform builds can override the default.\n- Staged-context authority accepts only the reviewed checksum option and rejects additional remote `ADD"} +{"url": "https://github.com/o1-labs/submission-updater/issues/6", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "Restructure the dual-binary Dockerfile: variant stages + directory COPY", "excerpt": "-fork-disabled` resolves to `busybox`; today's version pulls the multi-GB toolchain to run four no-op layers.\n- **Removes the remaining duplication.** #3 already hoisted the pinned digest into a single `ARG MINA_TOOLCHAIN` (review item 7), but the clone/submodule/dune-build body is still duplicated between the two stages; a shared `build-delegation-verify.sh` collapses it.\n- `GENESIS_LEDGER_FILE_POST_FORK` deserves the same treatment \u2014 an ARG defaulting to empty, set only when the post-fork build is on \u2014 complementing the build-time existence guard added in #3.\n\n## Prerequisite / caveat\n\n`FROM post-fork-${POST_FORK_VARIANT}` needs the ARG declared in global scope before the first `FROM` and requires BuildKit. That is the default in modern Docker and on the GitHub runner, but it breaks under `DOCKER_BUILDKIT=0`, so the switch needs a note in the README and a check that nothing in CI pins the legacy builder.\n\nAlso worth folding in when this is picked up: the `warn_profile` smoke alarm from glyh's `scripts/build.sh` inline thread (warn when a profile has `proof_level != full`), and the runtime-side fix it points at \u2014 always passing `--config-file` rather than gating on `configFile != \"\"`.\n\n---\nsee above"} +{"url": "https://github.com/Azure/acr/issues/721", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "Allow `buildkit` build in `az acr build`", "excerpt": "Registry/{{.Values.image}}\"\n```\n\nCommand to use\n```shell\ncd \naz acr run \\\n -f ./acr-build-task.yml \\\n --registry \\\n --set image=\":\" .\n```\n\nIt worked for me\n---\nAny news on this?\n---\nHello--we are also wondering about buildkit support in ACR. Any update?\n---\nAs of the moment, we don't have plans to support the flag. However, buildkit is supported through the steps that @doanduyhai showed above\n---\nRan into this issue today. Here's my acr-task.yml file that got the job done. If there's a better way around this, please let me know.\n\n```\n# This is necessary because `az acr build` with the `--secret-build-arg` flag fails with a \"the --mount option requires BuildKit\" error message.\n# @see https://github.com/Azure/acr/issues/721\n# @see https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tasks-reference-yaml\n\nversion: v1.1.0\n\nsteps:\n - build: >-\n -t $Registry/{{.Values.IMAGE_REPO}}:{{.Values.tag}}\n -f Dockerfile\n .\n --secret id=github_token,env=GITHUB_TOKEN\n env:\n - DOCKER_BUILDKIT=1\n - GITHUB_TOKEN={{.Values.GITHUB_TOKEN}}\n\n - push:\n - $Registry/{{.Values.IMAGE_REPO}}:{{.Values.tag}}\n\n```\n\nThen the associated GitHub Workflow step:\n\n```\n # - I originally tried passing the `--secret-build-arg` flag to `az acr build`, but the step fails with a \"the --mount option requir"} +{"url": "https://github.com/ChristopherSweeney/RGBD_SIM/issues/1", "category": "build: COPY failed legacy", "rule": "build.context", "title": "Dockerfile fails because drake_install does not exist", "excerpt": "Step 6/21 : COPY drake_install/ /opt/drake\r\nCOPY failed: file not found in build context or excluded by .dockerignore: stat drake_install/: file does not exist"} +{"url": "https://github.com/IntelSmartEdge/open-developer-experience-kits/issues/1", "category": "build: COPY failed legacy", "rule": "build.context", "title": "New Release setup failed due to file does not exist", "excerpt": "Kindly refer to builder.log attached, \r\n[builder.log](https://github.com/smart-edge-open/open-developer-experience-kits/files/7334416/builder.log)\r\n\r\nStep 5/12 : COPY files/conf/ /opt/core/conf/\r\nCOPY failed: file not found in build context or excluded by .dockerignore: stat files/conf/: file does not exist\r\n\r\nSteps:\r\n1. Follow installation steps from Smart Edge Open (v21.09) Developer Experience Kits\r\n2. Build and Run the Provisioning Services will failed due to error above.\r\n![Screenshot from 2021-10-11 15-15-38](https://user-images.githubusercontent.com/56580721/137059504-18832835-1883-4c52-85e4-54b160388db6.png)\r\n\n---\nWe have looked into the log file and it seems to be an issue with the proxy. We would suggest you to confirm if you had set the proxy correctly and proceed and let us know if you continue to face the issue.\r\n\r\nAlso we would suggest you to set the proxy for docker an"} +{"url": "https://github.com/CycloneDX/cyclonedx-cli/issues/259", "category": "build: COPY failed legacy", "rule": "build.context", "title": "Dockerfile Problem", "excerpt": "Hi,\r\n\r\nWhen I try create image from Dockerfile in github, \"COPY failed: file not found in build context or excluded by .dockerignore: stat bin/linux-x64/cyclonedx: file does not exist\"\r\n\r\n![image](https://user-images.githubusercontent.com/17831255/185028157-5b409b12-d3f8-47e8-a3af-c7a6d7c9c92b.png)\r\n\r\nDockerfile ;\r\n![image](https://user-images.githubusercontent.com/17831255/185028224-a822239f-b2e9-4856-96e1-71220bc02618.png)\r\n\n---\nHi @kmlr05, you need to build the binary first like the release process does https://github.com/CycloneDX/cyclonedx-cli/blob/5d836f69f3c07c1f993b22aaba1b74aabe87c0d9/.github/workflows/release.yml#L46-L55\r\n\r\nAlthough you can skip the extra runtimes and just publish it for \"linux-x64\"."} +{"url": "https://github.com/linera-io/linera-protocol/issues/2873", "category": "build: COPY failed legacy", "rule": "build.context", "title": "issue while docker build", "excerpt": "after executing ``docker build --build-arg git_commit=\"$(git rev-parse --short HEAD)\" -f docker/Dockerfile . -t linera`` command, i face\r\n``COPY failed: file not found in build context or excluded by .dockerignore: stat linera: file does not exist`` for ``Step 39/50 : COPY \"$binaries\"/linera \"$binaries\"/linera-server \"$binaries\"/linera-proxy \"$binaries\"/linera-db ./``\n---\nCould you confirm that you're running this from the root of your `linera-protocol` checkout?\n---\nyes, i run it from ``linera-protocol`` directory\n---\nCould you send the full output of the command?"} +{"url": "https://github.com/analogdevicesinc/microcontroller-hackathon/issues/1", "category": "build: COPY source not found", "rule": "build.context", "title": "Docker container build fail", "excerpt": "Docker container build failed with: **ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 190e2863-f816-4f1e-bde4-c28ba893d10c::kqz5b0w9rzbe75y6631wf5ab5: \"/quartus\": not found**\nUse:\n```\nmkdir -p resources/docker/quartus\ntouch resources/docker/quartus/.gitkeep\n```\nto create an empty folder to skip quartus installation."} +{"url": "https://github.com/PlaiPin/rosclaw/issues/3", "category": "build: COPY source not found", "rule": "build.context", "title": "Packages not found", "excerpt": "Why did the `packages` folder and link disappear?\nhttps://github.com/PlaiPin/rosclaw/blob/main/packages/rosbridge-client\n---\nNew repo and architecture coming soon. Hang tight. Thanks for checking it out\n---\ntarget rosclaw: failed to solve: failed to compute cache key: failed to calculate checksum of ref 490797a1-c53a-4735-8e9b-e064f780bdba::sc074gusrvphu53g28ar1trbx: \"/packages\": not found\n\n---\nYou can run it locally; don't use Docker, just start rosbridge_server.\n---\n> New repo and architecture coming soon. Hang tight. Thanks for checking it out\n\nI wonder if the packages have been supplied? This work is very interesting, so I couldn't help but try.\n\n\"Image\"\n---\n> You can run it locally; don't use Docker, just start rosbridge_server.\n\nHi, could you please share the total steps of starting rosbridge_server"} +{"url": "https://github.com/fyrlove/r0re/issues/1", "category": "build: COPY source not found", "rule": "build.context", "title": "The Docker build fails because container-android/AGENTS.md is missing", "excerpt": "\n\n```\n\u276f ./scripts/setup-dev.sh\n....\n => CACHED [29/30] WORKDIR /home/reverser/workspace 0.0s\n => ERROR [30/30] COPY AGENTS.md /home/reverser/AGENTS.md 0.0s\n------\n > [30/30] COPY AGENTS.md /home/reverser/AGENTS.md:\n------\nDockerfile:133\n--------------------\n 131 |\n 132 | # \u2500\u2500 AGENTS.md (AI Agent\u6307\u5f15) \u2500\u2500\n 133 | >>> COPY AGENTS.md /home/reverser/AGENTS.md\n 134 |\n 135 | # \u2500\u2500 \u73af\u5883\u53d8\u91cf (\u5e2e\u52a9\u5bb9\u5668\u68c0\u6d4b\u81ea\u8eab\u73af\u5883) \u2500\u2500\n--------------------\nERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 3641b669-9cb8-4ef8-97a4-04166e827b03::qeuqn0d075spwwhahwnosd38l: \"/AGENTS.md\": not found\n```"} +{"url": "https://github.com/coleschaffer/Gabagool/issues/3", "category": "build: COPY source not found", "rule": "build.context", "title": "failed to solve: failed to compute cache key: failed to calculate checksum of ref 686290d4-7997-43f4-8fd3-a67552da50d3::78wd65fbco1b74i7qffzq6jhr: \"/app/public\": not found", "excerpt": "failed to solve: failed to compute cache key: failed to calculate checksum of ref 686290d4-7997-43f4-8fd3-a67552da50d3::78wd65fbco1b74i7qffzq6jhr: \"/app/public\": not found\n---\n@JonaFly create public folder inside dashboard folder and it will work"} +{"url": "https://github.com/GoogleContainerTools/skaffold/issues/7504", "category": "build: outside build context", "rule": "build.context", "title": "build can not use dockerfiles out of the docker context", "excerpt": "\r\n\r\n`skaffold build` will complain with:\r\n\r\n```text\r\nError response from daemon: forbidden path outside the build context: ../platform/microservice/python3.9-poetry-microservice.dockerfile (). Docker build ran into internal error. Please retry.\r\nIf this keeps happening, please open an issue..\r\n```\r\n\r\n### Expected behavior\r\nSkaffold should be able to map the configuration to `docker build my-app/ -f platform/microservice/python3.9-poetry-microservice.dockerfile` (even not sure why skaffold is using dockerfile path relative to the context, the documentation says that it is relative to the workspace)\r\n\r\n### Actual behavior\r\nSkaffold is failing complaining with an error message indicating the dockerfile is out of the docker context. But docker has not that limitation.\r\n\r\n### Information\r\n\r"} +{"url": "https://github.com/colanode/colanode/issues/32", "category": "build: outside build context", "rule": "build.context", "title": "Error running docker-compose", "excerpt": "server\nDEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n Install the buildx component to build images with BuildKit:\n https://docs.docker.com/go/buildx/\n\nSending build context to Docker daemon 97.19MB\nStep 1/19 : FROM node:20-alpine\n ---> 0160beacba2d\nStep 2/19 : WORKDIR /app\n ---> Using cache\n ---> cc5896c9ceb0\nStep 3/19 : ARG VERSION\n ---> Using cache\n ---> 3a775bc60a4d\nStep 4/19 : ARG SHA\n ---> Using cache\n ---> ff4bafc851a3\nStep 5/19 : RUN echo \"{\\\"version\\\":\\\"$VERSION\\\",\\\"sha\\\":\\\"$SHA\\\"}\" > build.json\n ---> Using cache\n ---> 8052a3d996b5\nStep 6/19 : COPY ../../package.json ../../package-lock.json ./\nCOPY failed: forbidden path outside the build context: ../../package.json ()\nERROR: Service 'server' failed to build : Build failed\n\n\nps)It is installed properly on the Silicon MacBook Pro.\n---\n> I'm working on Ubuntu 24.04 CT environment.\n> \n> Error running docker-compose. Looks like it's a path issue.\n> \n> Building server DEPRECATED: The legacy builder is deprecated and will be removed in a future release. Install the buildx component to build images with BuildKit: https://docs.docker.com/go/buildx/\n> \n> Sending build context to Docker daemon 97.19MB Step 1/19 : FROM node:20-alpine ---> 0160beacba2d Step 2/19 : WORKDIR /app ---> Using cache ---> cc5896c9ceb0 Step 3/19 : ARG VERSION ---> Using cache ---> 3a775bc60a4d "} +{"url": "https://github.com/aws-samples/iot-network-traffic-control-and-load-testing-simulator/issues/6", "category": "build: outside build context", "rule": "build.context", "title": "npx cdk deploy IoTFaultInjectionSimulatorStack", "excerpt": "By running npx cdk deploy IoTFaultInjectionSimulatorStack Its stops here.\r\n\r\n\r\n```\r\nBuilding dependency tree...\r\nReading state information...\r\n1 package can be upgraded. Run 'apt list --upgradable' to see it.\r\n22d926dbbf1f: Pull complete\r\n4f4fb700ef54: Pull complete\r\nDigest: sha256:7a5d4fba3541e7988424833e2aca8073e3cceb3d5951a087d38d93eac742e01a\r\nStatus: Downloaded newer image for locustio/locust:2.13.0\r\n ---> 042b162d1b70\r\nStep 2/4 : COPY ../.. ./\r\nCOPY failed: forbidden path outside the build context: ../.. ()\r\n[85%] fail: docker build --tag cdkasset-12e5ddc6ac16fcc79c381c0807ff4e4e309cae4bb8015dd04714151ac7035f86 --file docker/master.Dockerfile . exited with error code 1: COPY failed: forbidden path outside the build context: ../.. ()\r\n```"} +{"url": "https://github.com/AxonIQ/axon-observability-demo/issues/1", "category": "build: outside build context", "rule": "build.context", "title": "docker-compose build FAILED", "excerpt": "Hello, thanks for awesome demo project and webinar! Really enjoyed wathing \r\n\r\nBut can't launch demo project, when I run docker-compose build I see the following error\r\n\r\n```\r\nvladimir@pc:~/IdeaProjects/axon-observability-demo/src/main/docker$ docker-compose build\r\ndemo-app-2 uses an image, skipping\r\ndemo-app-1 uses an image, skipping\r\nBuilding axonserver-enterprise-1\r\nSending build context to Docker daemon 101.7MB\r\nStep 1/8 : FROM openjdk:8-jre-alpine3.9\r\n ---> f7a292bbb70c\r\nStep 2/8 : RUN apk add --update ttf-dejavu fontconfig\r\n ---> Using cache\r\n ---> a39a5be23357\r\nStep 3/8 : COPY ../docker/axon-server/axonserver.jar /axonserver/axonserver-enterprise.jar\r\nCOPY failed: forbidden path outside the build context: ../docker/axon-server/axonserver.jar ()\r\n```"} +{"url": "https://github.com/TAIPANBOX/stack-single/issues/62", "category": "compose: required variable", "rule": "compose.env", "title": "install.sh gives .env no backup path, and a re-run with .env gone regenerates a Postgres password pgdata does not know", "excerpt": "Measured 2026-09-17 on the appliance proving run (stack-single v1.1.3 on a Debian 13 box, its gateway on a tailnet address, two customer agents in AWS and GCP). Public record: the 2026-09-17 rows of `estate-gates/PROVEN.md`.\n\n`.env` holds every secret this deployment has and the README's whole advice is to keep it at 0600. The run rehearsed losing it: with `.env` moved aside, `docker compose config` refuses (`required variable POLICY_DB_PASSWORD is missing a value`) and nothing running changes, which is fine. What a customer would do next is re-run `install.sh`, and section 3 then writes a new `.env`: a new `POLICY_DB_PASSWORD` that the existing `pgdata` volume does not know, so wardryx exits on `open postgres` and restart-loops, and both doors fail closed until somebody notices; new `CLOUD_KEYS`, `WARDRYX_KEYS` and `GATEWAY_ADMIN` (environment only, harmless); the override's variables absent, so compose refuses until they are re-added.\n\nAsk: (1) the README says in one paragraph that `.env` is the thing to back up, how, and what a re-run without it does; (2) `install.sh` refuses to write a fresh `.env` when `pgdata` (or any named vo"} +{"url": "https://github.com/frappe/crm/issues/2230", "category": "compose: required variable", "rule": "compose.env", "title": "SITES_RULE Missing on Production install", "excerpt": "I am having the following error while running the production installation command \n\n`\nSetting Up Production Instance\n \nDocker is already installed \n \nPlease refer to /root/crm_prod_setup.env to know which keys to set\n\nerror while interpolating services.frontend.labels.[]: required variable SITES_RULE is missing a value: SITES_RULE not set\n \nGenerating Compose File failed\n`\n\nNote: I did not change anything in the setup env before hand this happens on fresh install.\n\nWhen I add my sites_url manually and run the command, it fails and rewites the env by removing the sites_url i just added. \n\nIt only works when I do export the sites_url \n\n`\nsudo SITES_RULE=\"Host(`crm.mydomain.com`)\" python3 ./easy-install.py deploy \\\n --project=crm_prod_setup \\\n --email=myemail@mydomain.com \\\n --image=ghcr.io/frappe/crm \\\n --version=stable \\\n --app=crm \\\n --sitename crm.mydomain.com\n`\n\nPlease fix this\n---\nI also faced the same issue and after implementing the same solution as given I got the"} +{"url": "https://github.com/geekau/mediastack/issues/49", "category": "compose: required variable", "rule": "compose.env", "title": ".restart.sh: variable VPN_USERNAME is missing a value: err", "excerpt": "after configurating the .env with wireguard and mullvad generally following the your guide, the folders are created correctly but gluetun can not be deployed:\n\n\n> Creating folders and setting permissions...\n> Validating Docker Compose configuration...\n> error while interpolating services.gluetun.environment.[]: required variable VPN_USERNAME is missing a value: err\n> Docker Compose configuration is invalid or missing required variables...\n\nI am not using Tailscale etc. \n\nI have not specified the following lines:\n\n>Fill in these items ONLY if you change VPN_TYPE to \"wireguard\"\n>VPN_ENDPOINT_IP=\n>VPN_ENDPOINT_PORT=\n>WIREGUARD_PUBLIC_KEY=\n>WIREGUARD_PRIVATE_KEY=\n>WIREGUARD_PRESHARED_KEY=\n>WIREGUARD_ADDRESSES= \n---\nare you trying to use wireguard or not? If you are, then you need to fill out some of those variables, namely the public, and private key \n---\noh frick.\n\ni added the data but the error remains. I can edit the docker-compose.yaml and remove :?err from the VPN_USERNAME but still cant download:\n\n> no matching manifest for li"} +{"url": "https://github.com/compose-spec/compose-go/issues/934", "category": "compose: required variable", "rule": "compose.env", "title": "`ExtractVariables` does not report a variable used inside a `${VAR:?\u2026}` message", "excerpt": "2/template\"\n)\n\nfunc main() {\n\tfor _, tmpl := range []string{\"${U:-${B}}\", \"${U:+${B}}\", \"${U:?${B}}\", \"${U?$B}\"} {\n\t\tvars := template.ExtractVariables(map[string]interface{}{\"k\": tmpl}, nil)\n\t\tnames := make([]string, 0, len(vars))\n\t\tfor name := range vars {\n\t\t\tnames = append(names, name)\n\t\t}\n\t\tsort.Strings(names)\n\t\tfmt.Printf(\"%-12s %v\\n\", tmpl, names)\n\t}\n\n\tmapping := func(name string) (string, bool) {\n\t\tif name == \"B\" {\n\t\t\treturn \"value of B\", true\n\t\t}\n\t\treturn \"\", false\n\t}\n\t_, err := template.SubstituteWithOptions(\"${U:?${B}}\", mapping, template.WithoutLogging)\n\tfmt.Println(err)\n}\n```\n\nOutput:\n\n```\n${U:-${B}} [B U]\n${U:+${B}} [B U]\n${U:?${B}} [U]\n${U?$B} [U]\nrequired variable U is missing a value: value of B\n```\n\nThe specification lists `${VARIABLE?$FOO}` among the nested interpolations, and substitution does read `B` when building the message, so I expected `ExtractVariables` to report `B` for the `:?` and `?` forms as it does for `:-` and `:+`.\n\nTested on compose-go v2.15.0 and on current `main` (f18e211).\n\nBTW, this was found by an automated program that writes property-based tests for various open source projects using [hegel](https://github.com/hegeldev/hegel-go) (but it has been reviewed by hand before reporting). We've also potentially found (but not yet hand validated) 2 other bugs in compose-go. You can see the tests at https://github.com/hegeldev/hegel-zo"} +{"url": "https://github.com/docker-archive-public/docker.labs/issues/596", "category": "compose: unsupported property", "rule": "compose.version", "title": "wrong compose syntax", "excerpt": "https://github.com/docker/labs/blob/1bcbb14346cacd47446934926315e3f4d5222a55/security/apparmor/README.md?plain=1#L266\r\n\r\nthere should be the next code\r\n```dockerfile\r\nservices:\r\n``` \r\non top of the `docker-compose.yml` file otherwise you'll receive the error\r\n```shell\r\n Additional property mysql is not allowed\r\n``` \r\n\r\nRegards"} +{"url": "https://github.com/matchory/docker-swarm-deployment-action/issues/183", "category": "compose: unsupported property", "rule": "compose.version", "title": "Support newer stack schemas for versionless Compose files", "excerpt": "We ran into an issue using `healthcheck.start_interval` in a versionless stack file.\n\nThe file works with a direct `docker stack deploy`, but fails through this action:\n\n```text\nservices.test.healthcheck Additional property start_interval is not allowed\n```\n\nThe action adds `version: \"3.9\"` when no version is specified. Docker added\n`start_interval` to stack schema 3.12 in\n[docker/cli#4611](https://github.com/docker/cli/pull/4611), with runtime support\navailable in Docker Engine 25.0.1+.\n\nFor now, explicitly adding this works around the problem:\n\n```yaml\nversion: \"3.12\"\n```\n\nThere seem to be several possible ways the action could handle versionless files:\n\n- Raise the default from 3.9 to 3.12. This may break deployments using older Docker versions.\n- Omit the generated version and let the runner's Docker CLI select its latest supported schema. This changes existing behavior and makes the res"} +{"url": "https://github.com/Juniper/open-nti/issues/279", "category": "compose: unsupported property", "rule": "compose.version", "title": "Error: \"Docker-Compose Make\"", "excerpt": " your current version.\r\n*** fstrim (Y/I/N/O/D/Z) [default=N] ? dpkg: error processing package util-linux (--configure):\r\n end of file on stdin at conffile prompt\r\nErrors were encountered while processing:\r\n util-linux\r\nE: Sub-process /usr/bin/dpkg returned an error code (1)\r\nThe command '/bin/sh -c apt-get -y update && apt-get -y upgrade && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*' returned a non-zero code: 100\r\nmake: *** [Makefile:32: build-main] Error 100\r\n```\r\nRunning \"make start\"\r\n```\r\nroot@flow:/docker/open-nti# sudo make start\r\nUse docker compose file: docker-compose.yml\r\nIMAGE_TAG=latest docker-compose -f docker-compose.yml up -d\r\n(root) Additional property input-jti is not allowed\r\nmake: *** [Makefile:81: start] Error 15\r\n```\r\n\r\nRunning \"make start-persistent\"\r\n```\r\nroot@flow:/docker/open-nti# sudo make start-persistent \r\nUse docker compose file: docker-compose-persistent.yml\r\nIMAGE_TAG=latest docker-compose -f docker-compose-persistent.yml up -d\r\n(root) Additional property input-jti is not allowed\r\nmake: *** [Makefile:85: start-persistent] Error 15\r\n```\n---\nDear Mr Murray:\r\nI just cloned this project and faced exactly the same problem after the execution of \"make start\".\r\n\r\nroot@gloki:~/project/JJESS/open-nti# make start\r\nUse docker compose file: docker-compose.yml\r\nIMAGE_TAG=latest docker-compose -f docker-compose.yml up "} +{"url": "https://github.com/AbsaOSS/spline-getting-started/issues/47", "category": "compose: unsupported property", "rule": "compose.version", "title": "docker-compose up ERROR ", "excerpt": "Hello everyone, I started docker-compose up, and the error log: \u201d(root)Additional property name is not allowed\u201c \r\nWhere is the problem?\r\nDocker Compose version v2.2.2\n---\nany more details? logs?\n---\n[root@Cluster spline]# docker-compose up\r\n(root) Additional property name is not allowed\r\n[root@Cluster spline]# docker-compose ps\r\n(root) Additional property name is not allowed\r\n[root@Cluster spline]# docker-compose down\r\n(root) Additional property name is not allowed\r\n[root@Cluster spline]# docker-compose -f compose.yaml up \r\n(root) Additional property name is not allowed\n---\nThe current docker-compose command is available, I don\u2019t know where the problem is, please help, thank you very much!\n---\nsorry, what docker version did you say you were using? \"2.2.2\"? I gu"} +{"url": "https://github.com/quadratichq/quadratic-selfhost/issues/102", "category": "compose: variable not set", "rule": "compose.env", "title": "not able to setup on local machine on macbook", "excerpt": "getting this error when i try to setup on macbook\n\nWhat's next:\n View a summary of image vulnerabilities and recommendations \u2192 docker scout quickview hello-world\nWARN[0000] The \"QUADRATIC_CONNECTION_AWS_S3_BUCKET_NAME\" variable is not set. Defaulting to a blank string. \nWARN[0000] The \"CONNECTION_DEMO\" variable is not set. Defaulting to a blank string. \nWARN[0000] The \"CONNECTION_FINANCIAL_DATA\" variable is not set. Defaulting to a blank string. \n[+] up 13/13\n ! Image pgvector/pgvector:pg17 Interrupted 1.5s\n ! Image redis/redis-stack:latest Interrupted 1.5s\n ! Image oryd/kratos-selfservice-ui-node:v1.2.0 Interrupted "} +{"url": "https://github.com/microservices-patterns/ftgo-consumer-web-ui/issues/13", "category": "compose: variable not set", "rule": "compose.env", "title": "WARNING: The FTGO_BACKEND_API_URL variable is not set. Defaulting to a blank string.", "excerpt": "This happens when running start-server.sh\n---\nAnd where is `BACKEND_API_URL` actually used?\r\n\r\n![image](https://user-images.githubusercontent.com/246234/119569844-27f9e580-bd64-11eb-8213-02d18f7adbe8.png)\r\n"} +{"url": "https://github.com/transmute-industries/sidetree.js/issues/217", "category": "compose: variable not set", "rule": "compose.env", "title": "WARNING: The MNEMONIC variable is not set. Defaulting to a blank string.", "excerpt": "p -d mongo ganache ipfs\",`\r\n\r\nand picks up correct mnemonics.\r\n\r\n\n---\nhmm, seems like we probably need to separate the docker compose files so that running a local node is easier.\n---\nI ll let it open so that you can close it, when it done in future releases \n---\nI think I've seen this when starting up a server. Want to see if it's happening, and why it's happening, because the seed should be defined in the configuration file. \n---\nTaking some notes, it looks like this error can be reproduced by running the test for the `cas-ipfs` module. \r\n\r\n```\r\n> @sidetree/cas-ipfs@0.3.1-unstable.25 pretest ~/Github/sidetree.js/packages/cas-ipfs\r\n> docker-compose up -d ipfs mongo\r\n\r\nWARNING: The MNEMONIC variable is not set. Defaulting to a blank string.\r\nsidetreejs_ipfs_1 is up-to-date\r\nsidetreejs_mongo_1 is up-to-date\r\n\r\n> @sidetree/cas-ipfs@0.3.1-unstable.25 test ~/Github/sidetree.js/packages/cas-ipfs\r\n> tsdx test --passWithNoTests\r\n```\r\n\r\nSo we need to track down where that warning is coming from, and if it's needed or not. \n---\nThis should be defaulted to an example."} +{"url": "https://github.com/ggml-org/llama.cpp/issues/28950", "category": "compose: variable not set", "rule": "compose.env", "title": "Misc. bug: llama download -hf repo:model does not download mmproject", "excerpt": "### Name and Version\n\nUsing latest docker images in docker compose\n\n```\ndocker compose exec llama.cpp /app/llama --version\nWARN[0000] The \"HF_TOKEN\" variable is not set. Defaulting to a blank string. \nversion: 0.4.1-dev (build 10975, commit 4c9233c03)\nbuilt with GNU 14.2.0 for Linux x86_64\n```\n\n### Operating systems\n\nLinux\n\n### Which llama.cpp modules do you know to be affected?\n\n_No response_\n\n### Command line\n\n```shell\n\n```\n\n### Problem description & steps to reproduce\n\nUsing latest docker images in docker compose\n \n```\nservices:\n llama.cpp:\n image: ghcr.io/ggml-org/llama.cpp:server-cuda13\n container_name: llama.cpp-cuda13\n```\n\nand then running\n\n```\ndocker compose exec llama.cpp /app/llama download -hf unsloth/gemma-4-12b-it-GGUF:Q4_0\nWARN[0000] The \"HF_TOKEN\" variable is not set. Defaulting to a blank string. \n/root/.cache/hugg"} +{"url": "https://github.com/truefoundry/cognita/issues/421", "category": "container healthcheck unhealthy", "rule": "", "title": "dependency failed to start: container cognita-postgres is unhealthy", "excerpt": " \ncognita-postgres | 2025-01-16 10:59:37.027 UTC [83] FATAL: data directory \"/var/lib/postgresql/data\" has invalid permissions\ncognita-postgres | 2025-01-16 10:59:37.027 UTC [83] DETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).\ncognita-postgres | child process exited with exit code 1\ncognita-postgres | initdb: removing contents of data directory \"/var/lib/postgresql/data\"\ncognita-postgres | running bootstrap script ...\ncognita-postgres exited with code 1\nGracefully stopping... (press Ctrl+C again to force)\ndependency failed to start: container cognita-postgres is unhealthy\nPS C:\\Users\\AmitTiwari\\PycharmProjects\\cognita> \n```\n\n\n\nHere is the configuration at models_cofig.yaml, I have been trying to deploy with - \n\n\n```\nmodel_providers:\n ############################ Local ############################################\n # Uncomment this provider if you want to use local models providers #\n # using ollama and infinity model server #\n ###############################################################################\n\n# - provider_name: local-ollama\n# api_format: openai\n# base_url: http://ollama-server:11434/v1/\n# api_key_env_var: \"\"\n# llm_model_ids:\n# - \"qwen2:1.5b\"\n# embedding_model_ids"} +{"url": "https://github.com/apache/gravitino-playground/issues/112", "category": "container healthcheck unhealthy", "rule": "", "title": "Playground fails to start with error dependency failed to start: container playground-ranger is unhealthy", "excerpt": "**Expected Behavior:**\r\nFollowing the instructions in the documentation, Gravitino Playground containers should be healthy\r\n\r\n**Current Behavior**: \r\nStarting playground with `./playground.sh start` shows that the playground-ranger container is unhealthy\r\n\r\n**Steps to Reproduce:**\r\n1. [Build Apache Gravitino on Windows (Using WSL)](https://gravitino.apache.org/docs/0.7.0-incubating/how-to-build/#how-to-build-apache-gravitino-on-windows-using-wsl)\r\n2. [Clone or download Gravitino playground repository](https://github.com/apache/gravitino-playground)\r\n3. `cd gravitino-playground`\r\n4. Start playground with `./playground.sh start`\r\n5. After running, playground-ranger's status is unhealthy\n---\nSeem like `playground.sh` line 55 `echo \"Checking ports with sudo permission ...'` unexpected EOF while looking for matching\n---\nI also encountered the same problem.\n---\nHi @truth1024, when I initially ran `./playground.sh start`, the status of"} +{"url": "https://github.com/dockersamples/example-voting-app/issues/361", "category": "container healthcheck unhealthy", "rule": "", "title": "Dependency failed to start", "excerpt": "Cloned this project into my windows 11 machine.\r\nAs suggested in readme.md file installed docker for windows and run the application using command \"docker compose up\".\r\nI was getting following error: **dependency failed to start: container example-voting-app-redis-1 is unhealthy**\r\n![Screenshot 2024-07-23 134013](https://github.com/user-attachments/assets/d2ff29bc-414c-4fa9-b587-75071772b852)\r\n\n---\nI would like to know if there is any kind of development on this issue. I am trying to install example-voting-app on my raspberry pi (ARM64 machine) and I get the same error. Sometime it's the \"...-redis-1\", sometimes it's the \"...db-1\" that gives me the error. "} +{"url": "https://github.com/docker/genai-stack/issues/142", "category": "container healthcheck unhealthy", "rule": "", "title": "dependency failed to start: container genai-stack-api-1 is unhealthy", "excerpt": "First ran into /data problem. Followed the thread #134 and implemented three changes: (a) chown /home/casev/../genai-stack/data directory to casev for userID and groupID. (2) added to /home/casev/.profile two statements: export USER_ID=$(id -u) and export GROUP_ID=$(id -g). (3) modified docker-compose.yml to set database: user: ${USER_ID}:${GROUP_ID}.\r\nNext, run docker compose --profile linux up again. This time, the /data file error did not appear, and installation went further.\r\nHowever, it still stopped with an error message: dependency failed to start: container genai-stack-api-1 is unhealthy.\r\nEven after shutdown and restart, docker compose seemed to be stuck for hours displaying with different port numbers:\r\nINFO: 127.0.0.1:xxxxxx - \"GET / HTTP/1.1\" 200 OK with different port numbers.\r\n\n---\nTried again and again. Finally the installation seemed to be OK even with the INFO messages which would stop after perhaps 30+.\r\nNow I use nohup docker compose ... & to run it. Can get most of the demo apps working, except the support agent bot: able to get the web page. However, it only showed the section for Select RAG mode. Do not see a textbox for entering a prompt. \n---\nI have installed genai stack many times but it has failed.\r\n\r\nThe error situation is as follows:\r\n\r\n> dep"} +{"url": "https://github.com/wupasscat/continent-bot/issues/3", "category": "credentials helper missing", "rule": "registry.credentials", "title": "Make a Docker container", "excerpt": "containers are cool\r\n#4 \r\n- [x] Docker basics #5 \r\n- [ ] docker compose\r\n- [x] dockerhub ci\n---\nUsing docker compose gives me a weird error on WSL:\r\n```\r\n[+] Running 0/0\r\n \u280b continentbot Pulling 0.1s\r\nerror getting credentials - err: docker-credential-desktop.exe resolves to executable in current directory (./docker-credential-desktop.exe), out: ``\r\n```\r\nI'll try it on my Linux machine tomorrow"} +{"url": "https://github.com/abiosoft/colima/issues/1437", "category": "credentials helper missing", "rule": "registry.credentials", "title": "Not able to pull image", "excerpt": "16c373f8158d7f5d6\": dial tcp: lookup docker-images-prod.6aa30f8b08e16409b46e0173d6de2f56.r2.cloudflarestorage.com on 192.168.5.1:53: no such host\n\n### Expected behaviour\n\nI expect when I pull any docker image it should pull the image\n\n### Additional context\n\n_No response_\n---\nHave you tried just using 'colima start'? Followed by creating a dockerfile that pulls the ubuntu image?\n---\nYup still won't work @xdanielgonzalez \n---\nI have the same problem\n---\n## Dev Containers + Colima: Credential Helper Fix\n\n**Problem:** VS Code fails to open the project in a Dev Container when using [Colima](https://github.com/abacusai/colima) instead of Docker Desktop. The `docker pull` command fails with:\n\n```\nerror getting credentials - err: exec: \"docker-credential-desktop\": executable file not found in $PATH\n```\n\n**Cause:** `~/.docker/config.json` contains `\"credsStore\": \"desktop\"`, which tells Docker to use `docker-credential-desktop` for authentication \u2014 a binary that only ships with Docker Desktop. Since Colima doesn't include it, all image pulls fail.\n\n**Fix:** Remove the `credsStore` entry from your Docker config:\n\n```bash\n# Check your current config\ncat ~/.docker/config.json\n\n# If you see \"credsStore\": \"desktop\", remove it:\n# Before:\n# { \"auths\": {}, \"credsStore\": \"desktop\", \"currentContext\": \"colima\" }\n\n# After:\n# { \"auths\": {}, \"currentContext\": \"colima\" }\n```\n\nOr as a one-liner:\n\n```ba"} +{"url": "https://github.com/cytopia/devilbox/issues/938", "category": "credentials helper missing", "rule": "registry.credentials", "title": "[Bug]: Pulled the master branch then it won't start anymore", "excerpt": " 0.0s\r\n \u280b mysql Pulling 0.0s\r\n \u280b pgsql Pulling 0.0s\r\n \u280b bind Pulling 0.0s\r\nerror getting credentials - err: docker-credential-pass resolves to executable in current directory (./docker-credential-pass), out: ``\r\n```\r\n\r\n\r\n### (Optional) Additional information\r\n\r\n_No response_\n---\n@luchmewep this doesn't seem to be an issue with the Devilbox, but rather with your setup in regards to `docker` and/or `docker-compose`/`docker compose`.\r\n\r\nThe error message you're receiving:\r\n```\r\nerror getting credentials - err: docker-credential-pass resolves to executable in current directory (./docker-credential-pass), out: ``\r\n```\r\nThis is before the Devilbox even starts. I would check your config.\n---\nActually, when I revert back to the older version, it goes thru.\n---\nNot sure how"} +{"url": "https://github.com/fabiogra/moseca/issues/15", "category": "credentials helper missing", "rule": "registry.credentials", "title": "ERROR: failed to solve: python:3.10: failed to resolve source metadata for docker.io/library/python:3.10: error getting credentials", "excerpt": "ERROR: failed to solve: python:3.10: failed to resolve source metadata for docker.io/library/python:3.10: error getting credentials - err: exec: \"docker-credential-desktop\": executable file not found in $PATH, out: ``\r\n\r\nI've found this issue while trying to build a docker image. But I've found a way to make it work. \r\nhere's a way to fix it:\r\nWithin ~/.docker/config.json, if you rename \"credsStore\" to => \"credStore\" it will build with no issue. I'm not exacly sure why, but it works. \r\n\r\n"} +{"url": "https://github.com/docker/for-win/issues/14910", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "Virtualization support not detected", "excerpt": "lization (VT-x/AMD-V) is enabled in the BIOS. I also enabled the WSL 2 and VirtualMachinePlatform features, updated the WSL 2 kernel, and set the default WSL version to 2.\n\nI am trying to install the Ubuntu 22.04 distribution, but the installation gets stuck around 14% and does not progress. Running wsl --list --verbose shows \u201cNo installed distributions found for the Windows Subsystem for Linux,\u201d and Docker still displays the \u201cVirtualization support not detected\u201d error.\n\nI have also run DISM and SFC scans, but the issue persists.\n\n### Reproduce\n\nwsl --update\nwsl --set-default-version 2\n\nwsl --install -d Ubuntu-22.04\n\n\n\n### Expected behavior\n\n_No response_\n\n### docker version\n\n```bash\nERROR: Cannot connect to the Docker daemon at npipe:////./pipe/docker_engine. Is the docker daemon running?\n```\n\n### docker info\n\n```bash\nClient:\n Context: default\n Debug Mode: false\n\nServer:\n ERROR: Cannot connect to the Docker daemon at npipe:////./pipe/docker_engine. Is the docker daemon running?\n```\n\n### Diagnostics ID\n\na\n\n### Additional Info\n\n_No response_\n---\nsame error. It was all ok and work perfect but after just download a docker update today - it show\n\nVirtualization support not detected\n\n---\nI\u2019m hitting the same issue on Windows 11 IoT Enterprise, Docker Desktop sometimes shows \u201cVirtualization support not detected\u201d, but restarting Docker usually clears it. Looks like a race between "} +{"url": "https://github.com/containrrr/watchtower/issues/2023", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "Cannot connect to the Docker daemon after Docker daemon update", "excerpt": "st\r\n container_name: watchtower\r\n restart: always\r\n network_mode: bridge\r\n volumes:\r\n - /var/run/docker.sock:/var/run/docker.sock\r\n - /etc/localtime:/etc/localtime:ro\r\n environment:\r\n - WATCHTOWER_WARN_ON_HEAD_FAILURE=never\r\n - WATCHTOWER_CLEANUP=true\r\n - WATCHTOWER_SCHEDULE=0 15 5 * * *\r\n - WATCHTOWER_INCLUDE_RESTARTING=true\r\n```\r\n2) Update Docker Daemon with apt upgrade\r\n3) Wait for Watchtower check interval\n\n### Expected behavior\n\nThe Watchtower should still be able to communicate via the socket after the update.\n\n### Screenshots\n\n_No response_\n\n### Environment\n\n- OS: Debian 12\r\n- Arch: amd64\r\n- Docker Version: 27.2.1\r\n\n\n### Your logs\n\n```text\nCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\n```\n\n\n### Additional context\n\n_No response_\n---\nHi there! \ud83d\udc4b\ud83c\udffc As you're new to this repo, we'd like to suggest that you read our [code of conduct](https://github.com/containrrr/.github/blob/master/CODE_OF_CONDUCT.md) as well as our [contribution guidelines](https://github.com/containrrr/watchtower/blob/master/CONTRIBUTING.md). Thanks a bunch for opening your first issue! \ud83d\ude4f\n---\nHi @brechsteiner,\r\n\r\ndo you have `\"live-restore\": true` set in the `/etc/docker/daemon.json`?\r\n\r\nIt is a common issue that after an update of the Docker daemon the socket connections are dysfuntional, so that the client has"} +{"url": "https://github.com/belal-i/docksible/issues/16", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "\"Cannot connect to the Docker daemon\" on some local environments", "excerpt": "*****************\n> localhost : ok=11 changed=8 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0\n> ```\n\nCould you please upgrade, try again, and let me know how it goes?\n\nBy the way, when the host is `localhost` or `127.0.0.1`, you don't have to specify the user - so you can simply run `docksible localhost wordpress` for example.\n\nThanks and kind regards\n---\n**steps in colab with docksible 0.8.1**\n```\npip install -U docksible\n!docksible localhost wordpress\n```\n\n**result**\n```\nTASK [wordpress : Run WordPress] ***********************************************\nfatal: [localhost]: FAILED! => {\"changed\": true, \"msg\": \"non-zero return code\", \"rc\": 1, \"stderr\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\\n\", \"stderr_lines\": [\"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"], \"stdout\": \"\", \"stdout_lines\": []}\n\nPLAY RECAP *********************************************************************\nlocalhost : ok=13 changed=10 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 \n```\n\n**execute**\n`!service docker status`\n\n**result**\n`Docker is not running`\n\n**execute**\n`!service docker start`\n\n**result**\n`mkdir: cannot create directory \u2018cpuset\u2019: Read-only file system`\n\nthanks and best regards\n---\nHi @sugizo \n\nThanks for th"} +{"url": "https://github.com/keploy/keploy/issues/3109", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "[bug]: If the current docker context is not default then use the correct context", "excerpt": " \u2593\u2593\u2593\u2593\u2588\u2588\u2593\u2588\u2593\u2584\n \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\n \u2580\u2593\u2593\u2588\u2588\u2588\u2584 \u2584\u2584 \u2584 \u258c\n \u2584\u258c\u258c\u2593\u2593\u2588\u2588\u2588\u2588\u2584 \u2588\u2588 \u2593\u2588\u2580 \u2584\u258c\u2580\u2584 \u2593\u2593\u258c\u2584 \u2593\u2588 \u2584\u258c\u2593\u2593\u258c\u2584 \u258c\u258c \u2593\n \u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258c\u2593\u2593 \u2588\u2588\u2593\u2588\u2584 \u2593\u2588\u2584\u2593\u2593 \u2590\u2588\u258c \u2588\u2588 \u2593\u2588 \u2588\u258c \u2588\u2588 \u2588\u258c \u2588\u2593\n \u2593\u2593\u2593\u2593\u2580\u2580\u2580\u2580\u2593\u2593\u2593\u2593\u2593\u2593\u258c \u2588\u2588 \u2588\u2593 \u2593\u258c\u2584\u2584 \u2590\u2588\u2593\u2584\u2593\u2588\u2580 \u2588\u2593\u2588 \u2580\u2588\u2584\u2584\u2588\u2580 \u2588\u2593\u2588\n \u2593\u258c \u2590\u2588\u258c \u2588\u258c\n \u2593\n\nversion: 2.11.5\n\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.154601+05:30 \tINFO\tStarting keploy in docker with image\t{\"image:\": \"ghcr.io/keploy/keploy:v2.11.5\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.220479+05:30 \tINFO\tStarting keploy in docker with default context, as that is the current context.\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222794+05:30 \tERROR\tfailed to list docker volumes\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222816+05:30 \tERROR\tfailed to debugfs volume\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222824+05:30 \tERROR\tfailed to run the command in docker\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\n\ud83d\udc30 Keploy: 2025-10-09T19:01:04.222833+05:30 \tERROR\tfailed to validate flags\t{\"error\": \"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\"}\nUsage:\n keploy record [flags]\n"} +{"url": "https://github.com/athombv/homey-apps-sdk-issues/issues/303", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "SDK Docs - Please add Docker fileshare guide ", "excerpt": " error on clean install:\r\n```\r\n***@snijplank ***% homey app run \r\n\u2713 Pre-processing app...\r\n\u2713 Typescript detected. Compiling...\r\n\u2713 Typescript compilation successful\r\n\u2713 Validating app...\r\n\u2713 App validated successfully against level `debug`\r\n\u2713 Creating Remote Debug Session...\r\n\u2713 Preparing Environment Variables...\r\n\u2713 Connecting to `Tim's Homey Pro`...\r\n\u2713 Starting `***1.0.0` remotely...\r\n\u2713 Starting debugger at 0.0.0.0:9229...\r\n \u2014 Open `about://inspect` in Google Chrome and select the remote target.\r\n\u2713 Starting `***@1.0.0` in a Docker container...\r\n \u2014 Press CTRL+C to quit.\r\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Logging stdout & stderr \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\u2716 (HTTP code 500) server error - Mounts denied: \r\nThe path /***/.homeybuild is not shared from the host and is not known to Docker.\r\nYou can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.\r\nSee https://docs.docker.com/desktop/mac for more info.\r\n```\r\nYes, the answer is kind of in the log. But as a newby that's easily to be ignored when using the [step-by-step guide in the docs](https://apps.developer.homey.app/the-basics/getting-started)."} +{"url": "https://github.com/KatharaFramework/Kathara/issues/388", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "macOS Docker Desktop shared mount path issue when running Kathara inside a container", "excerpt": " reproducible issue related to shared folder mounting when Kathara itself is executed inside a Docker container.\n\nEnvironment:\n\n* macOS\n* Docker Desktop\n* Kathara 3.8.3\n* Ubuntu 22.04 container used to execute Kathara\n\nProblem:\nWhen Kathara is executed inside a Docker container, shared folder mounts are generated using the container filesystem path instead of the corresponding host filesystem path.\n\nExample generated path:\n\n/labs/progetti/lab1/shared\n\ninstead of the actual host path:\n\n/Users/username/dockers/kathara/progetti/lab1/shared\n\n(where \u201cdockers\u201d is only an example host-side folder used to collect Docker-related projects)\n\nDocker Desktop rejects the mount with the following error:\n\n\u201cMounts denied:\nThe path /labs/progetti/lab1/shared is not shared from the host and is not known to Docker.\u201d\n\nAnalysis:\nThe issue appears in DockerMachine.py where:\n\nmachine.lab.shared_path\n\nis directly passed to Docker volume creation.\n\nSince Kathara is running inside a container, this path represents the container-side filesystem path instead of the real host filesystem path required by Docker Desktop on macOS.\n\nProposed fix:\nIntroduce host/container path translation support using environment variables:\n\n* KATHARA_CONTAINER_LAB_ROOT\n* KATHARA_HOST_LAB_ROOT\n\nBefore creating Docker volume mounts, translate:\n\ncontainer path -> host path\n\nExample:\n\n/labs/progetti/lab1/shared\n\u2192\n/Users/username/d"} +{"url": "https://github.com/top-bettercode/docker-wechat/issues/55", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "docker: Error response from daemon: Mounts denied", "excerpt": "docker: Error response from daemon: Mounts denied: \r\nThe path /tmp/.X11-unix is not shared from the host and is not known to Docker.\r\nYou can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.\r\nSee https://docs.docker.com/ for more info.\r\n\r\n\u5fae\u4fe1\u548cQQ\u90fd\u6709\u8fd9\u4e2a\u95ee\u9898\u3002\u6211\u5df2\u7ecf\u8fd0\u884c\u8fc7xhost +\u4e86\u3002\r\n\r\nEdit:\u6211\u8bd5\u7740\u628a/tmp\u52a0\u5230file sharing\u91cc\u9762\uff0c\u62a5/home/lin/WechatFiles\u4e0dshared\uff0c\u6211\u53c8\u628a/home/lin\u52a0\u5230\u91cc\u9762\uff0c\u7136\u540e\u62a5\u201cdocker: Error response from daemon: error gathering device information while adding custom device \"/dev/snd\": no such file or directory.\r\n\u201d\r\n\r\n\u8bf7\u95ee\u8fd9\u4e2a\u600e\u4e48\u89e3\u51b3\uff1f\u8c22\u8c22\uff01"} +{"url": "https://github.com/DataTalksClub/faq/issues/291", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "[FAQ] Kestra does not run because of Docker error \"mounts denied: The path /tmp/... is not shared from the host\"", "excerpt": "### Course\n\nllm-zoomcamp\n\n### Question\n\nHow do I fix the Docker error \"mounts denied: The path /tmp/... is not shared from the host\"?\n\n### Answer\n\n### Add the path to Docker File Sharing (Recommended)\nYou need to explicitly tell Docker Desktop that it is allowed to access your host's /tmp directory.\n1. Open Docker Desktop.\n2. Click the Gear icon (Settings) in the top right corner.\n3. Navigate to Resources > File Sharing.\n4. Click the + (Add) button.\n5. Enter /tmp (or the specific path like /tmp/kestra-wd) and press Enter.\n6. Click Apply & restart.\n\nOnce the changes are applied, go to the terminal and rerun the docker compose command (docker compose up -d) to stand up Kestra\n\n### Checklist\n\n- [x] I have searched existing FAQs and this question is not already ans"} +{"url": "https://github.com/MinaProtocol/mina/issues/19374", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "Verify mina-toolchain cache job never finishes: it validates every tag ever cached, not the build's", "excerpt": "*arm64 tags can never verify.** Every `*-bookworm-devnet-arm64` entry fails on an amd64 agent:\n\n ```\n no matching manifest for linux/amd64 in the manifest list entries\n WARNING: failed to pull ...-arm64 from docker.io \u2014 skipping\n ```\n\n They are then reported as \"cached but missing on docker.io\" when they are in fact present \u2014 the agent simply cannot pull that platform. The pull is attempted every run regardless. `docker pull --platform` would fix the report.\n\n2. **Every loaded image stays in the agent's docker daemon.** The loop `docker load`s a ~10 GB image per iteration and never removes it, on agents where `buildkite/scripts/docker/disk-cleanup.sh` exists specifically to fight \"no space left on device\". A `docker image rm` at the end of each iteration would bound it.\n\n3. **It runs even when the build produced nothing.** In 438 all four amd64 image jobs failed, so there was nothing new to validate, yet the verification still walked the whole cache.\n\n## Suggested fix\n\nScope the loop to the tags the current build actually produced, and keep the exhaustive sweep for the nightly pipeline only, where it belongs \u2014 the script's own header calls itself \"nightly validation\", but `buildkite/src/Jobs/Test/MinaToolchainCacheValidation.dhall` carries the `Toolchain` tag, so it also runs on every `!ci-toolchain-me`.\n\nWhatever the scoping decision, the loop also wants:\n\n- a per-it"} +{"url": "https://github.com/jonohill/docker-openvpn-proxy/issues/14", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "No space left on device: many files created.", "excerpt": "I had this image running for some time. As you can see, I pulled the image about a year ago, maybe this has been fixed since then. If that's the case, please discard this issue.\r\n```\r\n$ docker ps\r\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\r\n926fa6835834 jonoh/openvpn-proxy \"runsvdir /app\" 12 months ago Up 2 months 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:8081->80/tcp, :::8081->80/tcp docker-openvpn-proxy_ovpn_proxy_1\r\n```\r\nUntil I started gettifg many errors on this machine, apparently there was \"no space left on device\". \r\nSeemed alright by me:\r\n```\r\n$ df -h /\r\nFilesystem Size Used Avail Use% Mounted on\r\n/dev/nvme0n1p5 610G 490G 90G 85% /\r\n```\r\nUntil I understood the problem was with Inodes:\r\n```\r\n$ df -i /\r\nFilesystem Inodes IUsed IFree IUse% Mounted on\r\n/dev/nvme0n1p5 40665088 40665086 2 100% /\r\n```\r\n\r\nAfter a bit of investigation, I tracked the issue down to `/var/lib/docker/`:\r\n```\r\n[\u2026]\r\n/var/lib/docker/overlay2/5cfe9f7fa471bde78bcf5671676ecf30074efe942af3cd1243d0423c6ee41dcf/diff/tmp/tmp.boblke\r\n/var/lib/docker/overlay2/5cfe9f7fa471bde78bcf5671676ecf30074efe942af3cd1243d0423c6ee41dcf/diff/tmp/tmp.boblke/config.ovpn\r\n/var/lib/docker/overlay2/5cfe9f7fa47"} +{"url": "https://github.com/david-coincodex/pm/issues/110", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "Production deploy never prunes old images \u2014 inode exhaustion took Postgres down for ~9h", "excerpt": "## What happened\n\nOn 2026-09-21 production went into a ~9-hour degraded outage that no disk alert caught.\n\n`promode-prod` ran out of **inodes** \u2014 not disk space:\n\n```\n/dev/sda1 75G 44G 29G 61% / \u2190 bytes: 29 GB free\n/dev/sda1 4940208 4940208 0 100% / \u2190 inodes: ZERO free\n```\n\nInode exhaustion returns the same `ENOSPC` errno as a full disk, so Postgres reported \"No space left on device\" and PANICked at every checkpoint:\n\n```\n08:27:26 PANIC: could not create file \"pg_logical/replorigin_checkpoint.tmp\": No space left on device\n08:32:27 PANIC: could not create file \"pg_logical/replorigin_checkpoint.tmp\": No space left on device\n08:37:27 PANIC: could not create file \"pg_logical/replorigin_checkpoint.tmp\": No space left on device\n```\n\n14 startups in one hour \u2014 a 5-minute crash-recovery cycle (matching the default `checkpoint_timeout`), dropping every connection each time. Image writes had started failing around 23:00 the night before; the last successful roster sync was 06:12.\n\nTwo things made it hard to spot:\n\n- **`df -h` read 61%.** Every byte-based di"} +{"url": "https://github.com/ROCm/ROCm-docker/issues/92", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "Pulling docker image uses too many inodes (no space left on device)", "excerpt": "I kept hitting the following error while trying to use this image:\r\n\r\n```\r\nSending build context to Docker daemon 384kB\r\nStep 1/19 : FROM docker.io/rocm/tensorflow-autobuilds:latest\r\nlatest: Pulling from rocm/tensorflow-autobuilds\r\n...\r\n7043cf977ac9: Pull complete \r\n29590d8cf13a: Extracting [==================================================>] 2.295GB/2.295GB\r\n...\r\ndfdc21b64fe2: Download complete \r\nfailed to register layer: ApplyLayer exit status 1 stdout: stderr: write /opt/rocm-5.1.0/rocfft/lib/librocfft-device-2.so.0.1.50100: no space left on device\r\n```\r\n\r\nIt wasn't obvious that I'm not running out of *disk* space, but ext4's inode space on my root partition (see `df -i`).\r\n\r\nFor anyone else who is stuck with this error, my solution was to move Docker data directory, via `/etc/docker/daemon.json`:\r\n```json\r\n{\r\n \"data-root\": \"/home/docker\"\r\n}\r\n```\r\n\r\nBut it would be preferrable to reduce the inode usage of this image.\r\n"} +{"url": "https://github.com/infiniflow/ragflow/issues/19117", "category": "DNS resolution in container", "rule": "", "title": "[Question]: Getting error when configuring postgres as metadata db", "excerpt": "timeout, **kwargs\nragflow-cpu-1 | )\nragflow-cpu-1 | File \"/root/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/socket.py\", line 840, in create_connection\nragflow-cpu-1 | for res in getaddrinfo(host, port, 0, SOCK_STREAM):\nragflow-cpu-1 | ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nragflow-cpu-1 | File \"/root/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/socket.py\", line 977, in getaddrinfo\nragflow-cpu-1 | for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\nragflow-cpu-1 | ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nragflow-cpu-1 | socket.gaierror: [Errno -3] Temporary failure in name resolution\nragflow-cpu-1 | \nragflow-cpu-1 | During handling of the above exception, another exception occurred:\nragflow-cpu-1 | \nragflow-cpu-1 | Traceback (most recent call last):\nragflow-cpu-1 | File \"/ragflow/.venv/lib/python3.13/site-packages/peewee.py\", line 3263, in connect\nragflow-cpu-1 | self._state.set_connection(self._connect())\nragflow-cpu-1 | ~~~~~~~~~~~~~^^\nragflow-cpu-1 | File \"/ragflow/.venv/lib/python3.13/site-packages/peewee.py\", line 4229, in _connect\nragflow-cpu-1 | conn = mysql.connect(db=self.database, autocommit=True,\nragflow-cpu-1 | **self.connect_params)\nragflow-cpu-"} +{"url": "https://github.com/podman-container-tools/podman/issues/16342", "category": "DNS resolution in container", "rule": "", "title": "No retry on temporary failure in network name resolution", "excerpt": "342e1b05692c99e897706d (image=, name=dyndns)\r\nOkt 27 15:27:33 servername podman[1873]: Trying to pull ghcr.io/linuxserver/swag:latest...\r\nOkt 27 15:27:33 servername podman[1873]: time=\"2022-10-27T15:27:33+02:00\" level=error msg=\"Cleaning up service container after failure: container f0e453c1a2d73cf84f49073ab98710354aea3073d1a06ce14e8b8b04803cbb1f is the service container of pod(s) 097e5cc618b0ae068c0d6ad1167f57ca0810db2b65342e1b05692c99e897706d and cannot be removed without removing the pod(s)\"\r\nOkt 27 15:27:33 servername podman[1873]: Error: initializing source docker://ghcr.io/linuxserver/swag:latest: pinging container registry ghcr.io: Get \"https://ghcr.io/v2/\": dial tcp: lookup ghcr.io: Temporary failure in name resolution\r\nOkt 27 15:27:33 servername systemd[1782]: podman-kube@-home-servername-ServerContainerTemplate-container-services-dynds\\x2dhttps\\x2dip-dyndns\\x2dhttps\\x2dip\\x2dpod.yaml.service: Main process exited, code=exited, status=125/n/a\r\nOkt 27 15:27:33 servername systemd[1782]: podman-kube@-home-servername-ServerContainerTemplate-container-services-dynds\\x2dhttps\\x2dip-dyndns\\x2dhttps\\x2dip\\x2dpod.yaml.service: Failed with result 'exit-code'.\r\nOkt 27 15:27:33 servername systemd[1782]: Failed to start A template for running K8s workloads via podman-play-kube.\r\n```\r\n\r\n**Describe the results you expected:**\r\nA retry after a period.\r\n\r\n**Additional information you de"} +{"url": "https://github.com/bluerobotics/BlueOS/issues/1695", "category": "DNS resolution in container", "rule": "", "title": "bug: No Extensions available.", "excerpt": "### Bug description\r\n\r\nNo Extensions available. Make sure the vehicle has internet access and try again.\r\n\r\n### Steps to reproduce\r\n\r\n1. Access: http://192.168.2.2/tools/extensions-manager\r\n2. The error pop-up: No Extensions available. Make sure the vehicle has internet access and try again.\r\n\r\nI check the internet, all work file. I tried on BlueOS version 1.1.0-beta-21 and 18. And also for Remote Versions: error fetching online tags: Cannot connect to host auth.docker.io:443 ssl:default [Temporary failure in name resolution]\r\n![error](https://github.com/bluerobotics/BlueOS-docker/assets/28943896/d7bebf7f-9a07-45d4-88f5-d8a82c675f79)\r\n\r\n### Primary pain point(s)\r\n\r\n_No response_\r\n\r\n### Prerequisites\r\n\r\n- [X] I have checked to make sure that a similar request has not already been filed or fixed.\n---\nHi @phamquandung,\r\n\r\nThanks for reporting the issue, is this a consistent problem ? Is it working fine now ?\n---\n> Hi @phamquandung,\r\n> \r\n> Thanks for reporting the issue, is this a consistent problem ? Is it working fine now ?\r\nHello @patrickelectric . It's still there. Please check\r\n![error](https://github.com/bluerobotics/BlueOS-docker/assets/28943896/96540316-d6f7-400c-be6b-d10"} +{"url": "https://github.com/OpenSPG/KAG/issues/535", "category": "DNS resolution in container", "rule": "", "title": "[Bug] [Module Name] Bug title java.net.UnknownHostException: mysql: Temporary failure in name resolution", "excerpt": "### Search before asking\n\n- [x] I had searched in the [issues](https://github.com/OpenSPG/KAG/issues?q=is%3Aissue) and found no similar issues.\n\n\n### Operating system information\n\nLinux\n\n### What happened\n\njava.net.UnknownHostException: mysql: Temporary failure in name resolution\n\u542f\u52a8spg\u5bb9\u5668\u670d\u52a1\uff0c\u67e5\u770b\u65e5\u5fd7\u62a5\u9519\u4e86\u30028887\u4e5f\u65e0\u6cd5\u8bbf\u95ee\u3002kag\u4e5f\u4f1a\u62a5\u9519\u3002\n\n### How to reproduce\n\njava.net.UnknownHostException: mysql: Temporary failure in name resolution\n2025-05-13 16:34:11,352 [] [] [main] INFO c.a.o.a.s.DatabaseEnvironmentPostProcessor - getGraphStoreUrl:neo4j://release-openspg-neo4j:7687?user=neo4j&password=neo4j@openspg&database=neo4j\n2025-05-13 16:34:11,533 [] [] [pool-3-thread-1] ERROR c.a.o.s.c.s.l.i.RdbDistributeLockServiceImpl - clean time out lock fail\norg.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Fa"} +{"url": "https://github.com/montimage-projects/mmt-dpi/issues/421", "category": "emulation: qemu crash", "rule": "image.platform", "title": "ci: emulated ldconfig intermittently segfaults on ubuntu-22.04 arm64 package job", "excerpt": "\n\n## Type\nBug\n\n## Description\nUnder QEMU, the ubuntu-22.04 arm64 leg of `.github/workflows/release-packages.yml` sometimes fails with `qemu: uncaught target signal 11` from `ldconfig`. The failure is at `tools/ci/build-package.sh:151`. It happened with setup-qemu-action v4.3.0 and v4.4.0, and every run used the same binfmt image digest (`tonistiigi/binfmt@sha256:400a4873\u2026`, qemu v10.2.3). It surfaced on PR #420 and passed on a rerun. Earlier runs 35811132281 and 35802233452 show the same segfault in the apt libc-bin trigger, which does not fail the job.\n\n## Acceptance Criteria\n- [ ] Pin the binfmt image by digest in the setup-qemu step, and/or make the emulated `ldconfig` step in build-package.sh retry or tolerate a crash without masking real failures\n- [ ] ubuntu-22.04 arm64 package job passes reliably\n\n## Metadata\n**Prior"} +{"url": "https://github.com/tjakobsson/brain/issues/27", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Candidate image build hangs after QEMU SIGILL in arm64 npm ci (v1.6.0 release blocked)", "excerpt": "**What failed:** Candidate image run on main for prepare commit fafe9658 (v1.6.0) was cancelled by the 40-min job timeout; no image for `sha-fafe965` reached GHCR.\n**Run:** https://github.com/tjakobsson/brain/actions/runs/33716434026\n**Key log:** `#15 [linux/arm64 dependencies 4/4] RUN npm ci --omit=dev` -> `qemu: uncaught target signal 4 (Illegal instruction) - core dumped` at 04:50:08, then no further output until `The operation was canceled` at 05:29:14.\n**Likely cause:** intermittent QEMU user-mode crash emulating arm64 node/npm; same chainguard/node (d6ca8dfc) and binfmt (400a4873) digests as the last green run, so not a version change. The arm64 layer was a cache miss because the version bump changed package-lock.json. BuildKit hung instead of failing the step after the crash.\n**Suggested next step:** rerun the workflow (`gh run rerun 33716434026` or workflow_dispatch with publish=true) to unblock the release; longer term build arm64 on a native `ubuntu-24.04-arm` runner (as action-parity."} +{"url": "https://github.com/travisgoodspeed/md380tools/issues/953", "category": "emulation: qemu crash", "rule": "image.platform", "title": "qemu: uncaught target signal 11 (Segmentation fault) - core dumped", "excerpt": "Hello.\r\n\r\nIs anyone having the issue mentioned in the Title while trying to run md380-emu with qemu-arm version 7.2.11 (Debian 1:7.2+dfsg-7+deb12u6)\r\n\r\nThis runs well using version 7.0.0 but I have not tested this between the 2 versions.\r\n7.0.0 being the version directly from qemu, not via apt packages but within the apt packages, it seems qemu-arm version 5.2.0 (Debian 1:5.2+dfsg-11+deb11u3) is the last usable version\r\n\r\nAny ideas? \r\n\r\nThanks\r\nHarold\r\nK7ILO\n---\nYes, I am having the same problem here."} +{"url": "https://github.com/bun913/go_lambda_functions/issues/3", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Apple Slicon\u3067 sam-cli\u306e\u30ed\u30fc\u30ab\u30eb\u5b9f\u884c\u304c\u3067\u304d\u306a\u3044\u554f\u984c\u3092Issue\u306b\u6295\u7a3f\u3059\u308b", "excerpt": "```\r\nsam local invoke HelloWorldFunction\r\nInvoking hello-world (go1.x)\r\nSkip pulling image and use local one: public.ecr.aws/sam/emulation-go1.x:rapid-1.47.0-x86_64.\r\n\r\nMounting /Users/xxxx/workspace/go_lambda_functions/functions/go-lambda-samples-stop-ec2/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container\r\nSTART RequestId: 1823928a-2247-4980-a583-fc2ee15f107b Version: $LATEST\r\nqemu: uncaught target signal 11 (Segmentation fault) - core dumped\r\n02 May 2022 20:31:29,468 [ERROR] (rapid) Init failed error=Runtime exited with error: signal: segmentation fault InvokeID=\r\nqemu: uncaught target signal 11 (Segmentation fault) - core dumped\r\nqemu: uncaught target signal 11 (Segmentation fault) - core dumped\r\nFunction 'HelloWorldFunction' timed out after 5 seconds\r\nNo response from invoke container for HelloWorldFunction\r\n```"} +{"url": "https://github.com/jianchang512/ChatTTS-ui/issues/212", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "could not select device driver \"nvidia\" with capabilities: [[gpu]]", "excerpt": "docker-compose -f docker-compose.gpu.yaml up -d \u62a5\u9519\uff1a\r\n\r\nError response from daemon: could not select device driver \"nvidia\" with capabilities: [[gpu]]"} +{"url": "https://github.com/AIR-DISCOVER/ICRA-RM-Sim2Real/issues/20", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", "excerpt": "\n---\n\u5b89\u88c5nvidia\u8fd0\u884c\u73af\u5883\u518d\u91cd\u65b0\u542f\u52a8docker\u5373\u53ef\uff1a\r\napt-get install nvidia-container-runtime\r\nsystemctl restart docker"} +{"url": "https://github.com/qixuema/envs/issues/25", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "Error response from daemon: Cannot restart container xxx: could not select device driver \"\" with capabilities: [[gpu]]", "excerpt": "\u53ef\u80fd\u9700\u8981\u91cd\u88c5\u4e00\u4e0b docker \u5c31\u53ef\u4ee5\u4e86"} +{"url": "https://github.com/SortAnon/ControllableTalkNet/issues/31", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].", "excerpt": "docker: Error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].\r\n\r\ndid I set docker up wrong?\n---\nNo, docker just needs nvidia container toolkit to be installed correctly. \r\nIf you are on ubuntu or a similar distro using an nvidia card then run these commands:\r\n\r\n\r\ndistribution=$(. /etc/os-release;echo $ID$VERSION_ID) && curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list\r\n\r\nsudo apt-get update\r\n\r\nsudo apt-get install -y nvidia-docker2\r\n\r\nsudo systemctl restart docker\r\n\r\nsudo docker run --s"} +{"url": "https://github.com/0xPolygon/zkevm-node/issues/3771", "category": "image: pull access denied", "rule": "image.exists", "title": "pull access denied zkevm-node", "excerpt": "\r\n[+] Running 1/1\r\n \u2714 Container zkevm-event-db Started 0.9s\r\ndocker compose -f docker-compose.yml up -d zkevm-mock-l1-network\r\n[+] Running 1/0\r\n \u2714 Container zkevm-mock-l1-network Running 0.0s\r\nsleep 1\r\ndocker compose -f docker-compose.yml up -d zkevm-prover\r\n[+] Running 1/1\r\n \u2714 Container zkevm-prover Started 10.9s\r\ndocker compose -f docker-compose.yml up -d zkevm-approve\r\n[+] Running 1/1\r\n \u2718 zkevm-approve Error pull access denied for zkevm-node, repository does not exist or may require 'docker l... 2.0s\r\nError response from daemon: pull access denied for zkevm-node, repository does not exist or may require 'docker login': denied: requested access to the resource is denied\r\nmake: *** [Makefile:575: run] Error 18\r\n\r\n#### Actual behaviour\r\n\r\n\r\n#### Steps to reproduce the behaviour\r\n\r\n\r\n#### Backtrace\r\n\r\n````\r\n[backtrace]\r\n````\r\n\r\nWhen submitting logs: please submit them as text and not screenshots."} +{"url": "https://github.com/coollabsio/coolify/issues/11855", "category": "image: pull access denied", "rule": "image.exists", "title": "[Bug]: Supabase deployment/restart fails because minio/mc image cannot be pulled", "excerpt": "ime:v1.71.2 Pulling\nImage postgrest/postgrest:v14.6 Pulling\nImage supabase/supavisor:2.7.4 Pulling\nImage supabase/gotrue:v2.186.0 Pulling\nImage supabase/logflare:1.31.2 Pulling\nImage supabase/storage-api:v1.44.2 Pulling\nImage kong/kong:3.9.1 Pulling\nImage supabase/realtime:v2.76.5 Pulling\nImage darthsim/imgproxy:v3.30.1 Pulling\nImage supabase/studio:2026.03.16-sha-5528817 Pulling\nImage ghcr.io/coollabsio/minio:RELEASE.2025-10-15T17-29-55Z Pulling\nImage supabase/postgres:15.8.1.085 Pulling\nImage timberio/vector:0.53.0-alpine Pulling\nImage supabase/postgres-meta:v0.95.2 Pulling\nImage ghcr.io/coollabsio/minio:RELEASE.2025-10-15T17-29-55Z Pulled\nImage kong/kong:3.9.1 Pulled\nImage minio/mc Error pull access denied for minio/mc, repository does not exist or may require 'docker login': denied: requested access to the resource is denied\n\nError response from daemon:\npull access denied for minio/mc, repository does not exist or may require 'docker login':\ndenied: requested access to the resource is denied\n```\n\nThe important part is that this does not only happen during the initial deployment. It also happens when restarting an already running Supabase instance. This means that a production Supabase instance that was previously working can become unavailable simply after performing a restart, because Coolify attempts to pull minio/mc again and the pull fails.\n\n### Coolify version\n\n**I am "} +{"url": "https://github.com/hcengineering/huly-selfhost/issues/335", "category": "image: pull access denied", "rule": "image.exists", "title": "MinIO removed from Docker Huber - can't finish setup", "excerpt": "Apparently MinIO has been removed from Docker Hub which leads to not being able to finish setting up Huly or starting it manually:\n\n```Running 'docker compose up -d' now...\n[+] up 14/14\n ! Image hardcoreeng/stats:v0.7.426 Interrupted 1.4s\n \u2718 Image minio/minio Error pull access denied for ... 1.4s\n ! Image nginx:1.21.3 Interrupted 1.4s\n ! Image hardcoreeng/fulltext:v0.7.426 Interrupted 1.4s\n ! Image hardcoreeng/hulykvs:v0.7.426 Interrupted 1.4s\n ! Image hardcoreeng/rekoni-service:v0.7.426 Interrupted 1.4s\n ! Image hardcoreeng/collaborator:v0.7.426 Interrupted 1.4s\n ! Image hardcoreeng/front:v0.7.426 Interrupted 1.4s\n ! Image hardcoreeng/account:v0.7.426 "} +{"url": "https://github.com/lg/emugaming/issues/3", "category": "image: pull access denied", "rule": "image.exists", "title": "pull access denied ", "excerpt": "on running the run command you give in the guide the pulling of the image fails with \r\nError from deamon : pull access denied for emugaming, repository does not exsist or may require docker login : requested acces to resource denied \r\n\r\ndid you take re docker repo down or do you need to update de scripts to incorporate the login creds for docker-hub \r\n"} +{"url": "https://github.com/sickcodes/Docker-OSX/issues/889", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Error response from daemon: manifest for sickcodes/docker-osx:naked not found: manifest unknown: manifest unknown", "excerpt": "\nWhen I ran this command:\n\n`docker pull sickcodes/docker-osx:naked` I got this error:\n\n`Error response from daemon: manifest for sickcodes/docker-osx:naked not found: manifest unknown: manifest unknown`\n\nI don't have this problem with the latest image so I'm wondering if the naked image is always online?\n---\nSame issue here. Looks like only one image is currently available:\nhttps://hub.docker.com/r/sickcodes/docker-osx/tags\n---\nI need to add this tag back, will work on it today/tomorrow\n---\nhi, is there any proggress on it? because i'm trying to run my own image.(I builded localy)\n---\nYeah, doesn't seem to work anymore. I would presume the developer is busy and does not have the time to fix it. \n---\nWould #833 work for you? \n---\nI tried to use #833 dickhub naked image to run container with Tahoe img, sadly it fails on booting.\n\nThe dickhub image shows 2 y"} +{"url": "https://github.com/decolua/9router/issues/4167", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Docker image decolua/9router:0.5.81 is not available", "excerpt": "The repository/changelog indicates that version `v0.5.81` is available, but the corresponding Docker image cannot be pulled.\n\nTrying to deploy:\n\n```yaml\nservices:\n 9router:\n image: decolua/9router:0.5.81\n```\n\nresults in:\n\n```text\nmanifest for decolua/9router:0.5.81 not found:\nmanifest unknown: manifest unknown\n```\n\n### Steps to reproduce\n\n```bash\ndocker pull decolua/9router:0.5.81\n```\n\n### Actual behavior\n\nDocker returns:\n\n```text\nError response from daemon:\nmanifest for decolua/9router:0.5.81 not found:\nmanifest unknown: manifest unknown\n```\n\n### Expected behavior\n\nThe Docker image for the current release should be available as:\n\n```text\ndecolua/9router:0.5.81\n```\n\nor the documentation/release notes should clarify which Docker tag should be used.\n\n### Environment\n\n* 9Router version: `v0.5.81`\n* Deployment: Docker Compose / Dokploy\n* Docker image: `decolua/9router:0.5.81`\n* Host OS: Linux\n\n### Additional context\n\nThe repository changelog already references `v0.5."} +{"url": "https://github.com/ben1234560/k8s_PaaS/issues/52", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Using default tag: latest Error response from daemon: manifest for kubernetes/pause:latest not found: manifest unknown: manifest unknown", "excerpt": "![image](https://github.com/user-attachments/assets/ae637c3a-66a3-4b94-a017-52ec5315fc8e)\r\n[root@hdss178-132 certs]# docker pull kubernetes/pause\r\nUsing default tag: latest\r\nError response from daemon: manifest for kubernetes/pause:latest not found: manifest unknown: manifest unknown\r\n[root@hdss178-132 certs]# docker pull kubernetes/pause\r\n\u8fd9\u4e2a\u955c\u50cf\u7528\u4e0d\u4e86\u561b\uff1f\u5361\u4f4f\u5566\uff0c\u5927\u54e5\u600e\u4e48\u641e\u5462\uff1f\n---\ndocker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:latest\uff0c\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\uff0c\u5185\u5bb9\u662f\u4e00\u6837\u7684\r\n\n---\n\u8c22\u8c22\u5927\u54e5"} +{"url": "https://github.com/openwhistle/OpenWhistle/issues/69", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Docker image - manifest unknown", "excerpt": "Hi, \nI'm havin trouble to pull the docker image, it always says.\n\n`\ndocker pull ghcr.io/openwhistle/openwhistle:latest\n`\n`\nlatest: Pulling from openwhistle/openwhistle\n`\n`\nmanifest unknown\n`\n\nI tried it on 3 diffrent server, none of them worked.\nCould it be that something is broken with the image?\n\nI can build it my self and it works, but for security reasons I would like to pull every day the latest image tag.\n\nMy current docker version: \n> root@srv-inet02:/ docker version\n> Client: Docker Engine - Community\n> Version: 29.8.1\n> API version: 1.56\n> Go version: go1.26.8\n> Git commit: 4a63305\n> Built: Tue Sep 15 16:25:26 2026\n> OS/Arch: linux/amd64\n> Context: default\n> \n> Server: Docker Engine - Community\n> Engine:\n> Version: 29.8.1\n> API version: 1.56 (minimum version 1.40)\n"} +{"url": "https://github.com/bryanlittlefield/TUGBOAT/issues/82", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Add Elastic Search Container + Configs", "excerpt": " - discovery.type=single-node\r\n ulimits:\r\n memlock:\r\n soft: -1\r\n hard: -1\r\n nofile:\r\n soft: 65536\r\n hard: 65536\r\n cap_add:\r\n - IPC_LOCK\r\n volumes:\r\n - elasticsearch-data:/usr/share/elasticsearch/data\r\n - ./config/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml\r\n ports:\r\n - \"9200:9200\"\r\n - \"9300:9300\"\r\n```\r\n\r\n\r\n\r\n**elasticsearch/elasticsearch.yml**\r\n```\r\ncluster.name: \"docker-cluster\"\r\nnetwork.host: elasticsearch\r\n```\r\n\r\n---\r\n\r\n**Know Issue with Indexing Larger Elastic Search DB's:**\r\n\r\n- [ ] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] : https://stackoverflow.com/questions/51445846/elasticsearch-max-virtual-memory-areas-vm-max-map-count-65530-is-too-low-inc\r\n\r\n\n---\nrun `sysctl -w vm.max_map_count=262144` on your host for ElasticSearch to work properly.\r\n\r\nhttps://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod-mode"} +{"url": "https://github.com/MarquezProject/marquez/issues/3025", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Docker - OpenSearch Installation Documentation", "excerpt": "Hi,\n\nI am a new user and initially had problems with the Docker install for OpenSearch.\n\nIt originally failed and this had a knock-on effect.\n\nReading through the logs, I found the following:\n\n\"max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]\"\n\nThis seems to be easily resolved by entering the following command in your [Linux] environment...\n\n\"sysctl -w vm.max_map_count=262144\"\n\nIt might be an idea to add this to the relevant documentation.\n\nMany thanks and what a great project !\n\nRegards,\n\nJonathan\n\n\n---\nThanks for opening your first issue in the Marquez project! Please be sure to follow the issue template!\n"} +{"url": "https://github.com/community-scripts/ProxmoxVED/issues/2139", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Elasticsearch", "excerpt": "### Name of the Script\nElasticsearch\n\n### Script Type\nCT (LXC Container)\n\n### Does this script support arm64?\narm64 supported\n\n### \ud83d\udccb Script Details\nSingle-node Elasticsearch from the official Elastic repository. Requested in [discussion #5074](https://github.com/community-scripts/ProxmoxVE/discussions/5074).\n\n**The open question from the earlier assessment \u2014 `vm.max_map_count` in an unprivileged LXC \u2014 is resolved.** Per Elastic's docs, bootstrap checks are only warnings in *development mode* (loopback binding) but hard failures in *production mode* (non-loopback), and an LXC is only useful bound to the LAN. However `vm.max_map_count` is **not namespaced**: the container inherits it from the Proxmox host. So it cannot and need not be set inside the container.\n\nThe script therefore checks the inherited value and aborts with an actionable message if it is too low:\n\n```\nvm.max_map_count is , Elasticsearch needs at least 262144\nSet it on the PROXMOX HOST, not in this container:\n echo 'vm.max_map_count=1048576' >/etc/sysctl.d/99-elasticsearch.conf "} +{"url": "https://github.com/rkaehdaos/docker-elk/issues/14", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "fix error", "excerpt": "\n---\n# vm.max_map_count\ubcc0\uacbd\r\n\"image\"\r\n\r\n- 78 \uc5d0\ub7ec\ub97c \ucc3e\uc544\ubcf4\ub2c8 vm.max_map_count \ub298\ub9ac\ub77c\ub294 \r\n- https://techoverflow.net/2019/03/11/how-to-fix-elasticsearch-exited-with-code-78/\r\n\r\n- \uc5d8\ub77c\uc2a4\ud2f1 \uad8c\uc7a5\uc0ac\ud56d [\ucd5c\uc18c\uc0ac\uc591](https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_set_vm_max_map_count_to_at_least_262144)\r\n```\r\nERROR: [1] bootstrap checks failed elasticsearch | [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]\r\n```\r\n\r\nvm.max_map_count\r\n- https://www.kernel.org/doc/Documentation/sysctl/vm.txt\r\n\r\n> his file contains the maximum numb"} +{"url": "https://github.com/KDM-cli/kdm-cli/issues/275", "category": "memory: OOMKilled", "rule": "resources.memory", "title": "[v4.0.0] Phase 4: Deterministic Kubernetes/Docker Failure Rule Engine", "excerpt": "plement a deterministic rule engine that diagnoses well-known Kubernetes and Docker failure signatures in < 5ms before invoking any LLM.\n\nPart of **Milestone v4.0.0** \u2014 Phase 4 of the Multi-Agent SRE Architecture.\n\n---\n\n### \u26a0\ufe0f IMPORTANT CONTRIBUTOR & PR INSTRUCTIONS\n> **TARGET BRANCH**: All Pull Requests implementing this phase **MUST target branch `v4.0.0`** (DO NOT target `main`).\n> **PR TITLE**: `feat(agents): Phase 4 - Deterministic Diagnostic Rule Engine`\n> **PR SCOPE**: Rule engine and core Kubernetes failure signatures.\n\n---\n\n## 1. Description of What Has to Be Done\nMany Kubernetes failures are deterministic facts, not subjective opinions. If a container's last termination reason is `OOMKilled` with exit code `137`, running an LLM to \"guess\" what happened is slow, wasteful, and prone to hallucinations.\n\nContributors must:\n1. Define a `BaseRule` abstract class and a `RuleMatch` result object.\n2. Implement rules for 5 canonical Kubernetes failure signatures:\n - `OOMKilledRule`: Matches exit code 137 or reason `OOMKilled`.\n - `ImagePullRule`: Matches `ErrImagePull` and `ImagePullBackOff`.\n - `CrashLoopRule`: Matches `CrashLoopBackOff` with exit codes > 0.\n - `ProbeFailureRule`: Matches failed liveness or readiness probe events.\n - `SchedulingRule`: Matches `FailedScheduling` (insufficient CPU/memory).\n3. Implement `RuleEngine` that evaluates all registered rules a"} +{"url": "https://github.com/MaRDI4NFDI/MaRDIRoadmap/issues/235", "category": "memory: OOMKilled", "rule": "resources.memory", "title": "qlever-updater OOMKilled crash loop due to insufficient memory limit", "excerpt": "## What happened\n\nThe `qlever-updater` deployment in the `production` namespace entered a persistent crash loop. Over roughly 40 hours it accumulated 90+ terminated pods (`Error` / `ContainerStatusUnknown`) plus 94 restarts on the current pod, all caused by `OOMKilled` (exit code 137).\n\n`qlever-updater` runs `qlever update-wikidata`, which consumes the `rdf-streaming-updater.mutation.v2` SSE stream and assembles update messages into batches (up to 100,000 messages) before flushing them to QLever. At the time of the incident it was processing a backlog spanning from 2026-09-15 to 2026-09-17, with single batches assembling 45k+ messages. The in-memory batch size exceeded the container's memory limit before it could flush/checkpoint, so the kernel OOM-killed the process repeatedly \u2014 the pod would restart, re-resume from the last committed offset, build up another oversized batch, and get killed again.\n\nThe container had:\n- `limits.memory: 2Gi`\n- `r"} +{"url": "https://github.com/kestra-io/plugin-kubernetes/issues/339", "category": "memory: OOMKilled", "rule": "resources.memory", "title": "io.kestra.plugin.kubernetes.PodCreate Fails with Exit Code 137 Despite Resource Limits", "excerpt": "\"2Gi\"\n cpu: \"1\"\n nodeSelector:\n karpenter.sh/nodepool: tasks-cpu-node-pool\n resource-type: cpu\n restartPolicy: Never\n```\nOverview of what this flow does, It reads a list of images from the s3 and batch them into 200 and store those list in json format in s3. Then it will trigger another flow with json s3 file path as a input. Which is not a resource intense at all. Based on my observing this pipeline max usage of RAM was around 500MB.\n\n### Environment\n\n- Kestra Version:0.22.9 Kubernetes\n- EKS Kubernetes version 1.33\n- Mostly used spot instances for running the flow\n\n---\nHello, does the same workload fails outside of Kestra? Did you check the pod logs for OOMKilled or other termination reasons?\n\n---\nHi, I have tested outside the kestra it works fine with same resources but the strange part is it only occasionally fails in kestra with resources of memory 2GB after I have increased the resource memory to 4GB I never had any problems in Kestra. I guess there might be a memory leak in the code or it's python packages. It's hard to pin point the problem. \nHowever, if I restart the failed job in kestra (due to OOM killed) it fails again as I mentioned above but starting a new pipeline with same inputs it works fine in kestra. So not sure where is the problem but increasing the resource seems to fixed this issue for me. \n---\nExit 137 is SIGKILL, but"} +{"url": "https://github.com/Jersyfi/taktus/issues/29", "category": "memory: OOMKilled", "rule": "resources.memory", "title": "The container adapter's memory-kill test is flaky: the engine does not always report OOMKilled", "excerpt": "Found by the first live run, in the pipeline P-03 reads as its verdict.\n\n`tests/adapters/execution/test_container.py::test_a_job_that_exceeds_its_memory_limit_is_killed_and_says_so` passed in CI at 12:35 and failed at 12:44 on the same runner image, with essentially the same tree, and passes locally on macOS with Docker 29.1.2. It is flaky.\n\n```\nassert exit is not None and exit.killed == \"memory\", exit\nE AssertionError: JobExit(code=137, killed=None, reason='the unit exited with 137')\n```\n\n**Why.** The container adapter reads `state[\"OOMKilled\"]` from the engine's inspect and maps it to `killed=\"memory\"` (`src/taktus/adapters/driven/execution/container/adapter.py`). Under cgroup v2 the engine does not always set that flag when the kernel's OOM killer takes a process inside the container's cgroup rather than its PID 1; what is left is exit code 137, SIGKILL, which on its own says nothing about who sent it.\n\n**Why it matters more than a flake usually does.** P-03 Implementation runs at autonomy level 4 and its reason is \"the pipeline's verdict is the gate and never the worker's opinion\". A verdict that is red at random is not a verdict about the change: in the first live run it refused a change every other gate had passed,"} +{"url": "https://github.com/docker/desktop-feedback/issues/645", "category": "network not found", "rule": "", "title": "docker vmm does not use the docker CLI", "excerpt": "Secrets Manager Plugin (beta) (Docker Inc.)\n Version: v0.2.2\n Path: C:\\Program Files\\Docker\\cli-plugins\\docker-pass.exe\n sandbox: \"docker sandbox\" is deprecated, use Docker Sandboxes instead (Docker Inc.)\n Version: v0.13.0\n Path: C:\\Program Files\\Docker\\cli-plugins\\docker-sandbox.exe\n scout: Docker Scout (Docker Inc.)\n Version: v1.24.0\n Path: C:\\Program Files\\Docker\\cli-plugins\\docker-scout.exe\n\nServer:\n Containers: 0\n Running: 0\n Paused: 0\n Stopped: 0\n Images: 0\n Server Version: 29.7.2\n Storage Driver: overlayfs\n driver-type: io.containerd.snapshotter.v1\n Logging Driver: json-file\n Cgroup Driver: cgroupfs\n Cgroup Version: 2\n Plugins:\n Volume: local\n Network: bridge host ipvlan macvlan null overlay\n Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog\n CDI spec directories:\n /etc/cdi\n /var/run/cdi\n Discovered Devices:\n cdi: docker.com/gpu=webgpu\n Swarm: inactive\n Runtimes: io.containerd.runc.v2 runc\n Default Runtime: runc\n Init Binary: docker-init\n containerd version: aad11006b869517fcd3009450b6f82da282e1a9b\n runc version: v1.4.3-0-gbb14dabe\n init version: de40ad0\n Security Options:\n seccomp\n Profile: builtin\n cgroupns\n Kernel Version: 7.0.12-linuxkit\n Operating System: Docker Desktop\n OSType: linux\n Architecture: x86_64\n CPUs: 8\n Total Memory: 3.881GiB\n Name: docker-desktop\n ID: 52354c78-9fc8-45e8-a00f-0badc9"} +{"url": "https://github.com/orkestra-cc/orkestra/issues/300", "category": "network not found", "rule": "", "title": "bug: backup.sh reports rustfs as backed up when the S3 sync fails (network not found)", "excerpt": "### Affected surface\nops tooling (`backup.sh`, `restore.sh`)\n\n### Tenancy tier (if relevant)\nn/a\n\n### What happened?\n`backup.sh` reports the RustFS component as successfully backed up even when the S3 sync never ran. The `aws-cli` helper container is attached to `NETWORK=\"${STACK}_default\"` (computed as `${APP_NAME}-${ENV}_default`); when that network does not exist \u2014 in my case the stack had been brought up under a different `COMPOSE_PROJECT_NAME` \u2014 `docker run` fails with `network \u2026 not found`, but the script still prints `\u2713 rustfs: synced bucket 'orkestra-avatars' (0)` and lists `rustfs` among the components included in the tarball. The archive then contains an empty `rustfs/` tree while looking like a complete backup. `restore.sh` has the same construct in `restore_rustfs()` (the `s3 mb` failure is deliberately ignored, but a failing `s3 sync` is also not surfaced as a hard error).\n\nA second, minor point: the scheduled unit (`scripts/backup-sched"} +{"url": "https://github.com/tmwclaxton/clashofdots/issues/12", "category": "network not found", "rule": "", "title": "INC: LGS Pipeline deploy recreate \u2014 Compose temp name not found (2026-09-18)", "excerpt": "## Incident (2026-09-18 ~20:17\u201320:20 UTC)\n\nHost alerter fired outage then recovery for LGS Pipeline (`ctr-lgspipeline`) on admin.grantgunner.org.\n\n- Outage detail: `not found` (~20:19:11Z) while Compose replacement was `*_lgspipeline` (`com.docker.compose.replace=lgspipeline`).\n- Recovery detail: `Up 3 minutes (healthy)` at **2026-09-18T20:20:43Z**.\n- Dashboard: https://datadog.grantgunner.org\n\n### What happened\nActions deploy of image revision `bee79827` (BumbleFriendsAuto #10; also #12 health/async wait) still used `docker compose up -d` + `sleep 2`. Host-network recreate briefly/permanently missed canonical `container_name: lgspipeline` \u2192 container check `not found`. HTTP `/api/health` stayed 200. Not crash/OOM; not Cloudflare 1033.\n\n### Fix on host (sibling outage agent)\n- `docker rename` temp \u2192 `lgspipeline`\n- Alerter: accept Compose temp names ending `_`\n- Host deploy.yml: `--wait --wait-timeout 90` + rename safeguard\n- Recreated datadog only; left lgspipeline running\n\n### Recovery agent confirmation\n- Re-verified 20:22Z: healthy, `/api/health` 200, monitor 30/0, async `wait_for_job` in container.\n- No further stop/recreate.\n\n### Durable fix blocked\nAutomation token **403** for branch/PR/comment on `tmwclaxton/BumbleFriendsAuto"} +{"url": "https://github.com/Proaxiom-Cyber/guacamole-saml-sso/issues/30", "category": "network not found", "rule": "", "title": "Diagnose nginx network loss after port conflict and improve installer recovery", "excerpt": "ct, `guacamole-saml-sso`, still had an nginx container publishing host port 443. A prior manual reset targeted only the newer `guacamole` project.\n2. Starting `guacamole-nginx-1` failed with `Bind for 0.0.0.0:443 failed: port is already allocated`.\n3. The customer stopped the older nginx container and resumed setup.\n4. At 14:13:51 local time, the installer reported all four new containers healthy.\n5. The subsequent local HTTPS check retried for two minutes and ended with `127.0.0.1:443: connect: connection refused`.\n6. Docker showed the new nginx container restarting with exit code 1. Its log reported `host not found in upstream \"guacamole\"`.\n7. Targeted inspection returned `{}` for nginx's network attachments. The Guacamole application container was attached to `guacamole_guacnet` with the `guacamole` alias.\n8. We instructed the customer to recreate only nginx with `docker compose up -d --no-deps --force-recreate nginx`. End-to-end recovery is not yet confirmed.\n\n## What is established\n\nThe old deployment caused the initial port conflict. The later nginx process could not resolve its upstream, and inspection showed no network attachment. We have not established when or why the attachment disappeared. Do not describe a Docker defect or an installer action as the root cause without reproducing the sequence.\n\nThe current Compose template gives nginx no health check. The installer"} +{"url": "https://github.com/timothy1ee/dokploy/issues/3", "category": "OCI runtime exec failed", "rule": "", "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", "excerpt": "### Description\nWhen using Docker Compose with volume mounts, executing commands in containers via the terminal fails with \"OCI runtime exec failed\" error unless the container is force recreated. This is caused by the working directory not being set correctly for docker exec commands.\n\n### Current Behavior\n- Docker Compose container deployed with volume mounts\n- User attempts to open terminal/exec into container\n- Error: \"OCI runtime exec failed: exec failed: unable to start container process\"\n- Only workaround is force recreating container\n- Issue persists until manual intervention\n\n### Expected Behavior\n- Docker Compose container deployed with volume mounts\n- User opens terminal successfully\n- Commands execute in correct working directory\n- No OCI runtime errors\n- Consistent behavior with and without volume mou"} +{"url": "https://github.com/NinjaMonkeyGames/palette-controller-professional/issues/3", "category": "OCI runtime exec failed", "rule": "", "title": "Unit Tests on CI is Broken", "excerpt": "Workflow has broken for unit tests.\n\nRun # Spin up virtual X11 framebuffer for graphics services\n # Spin up virtual X11 framebuffer for graphics services\n Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n sleep 2\n \n # Run tests, print verbose output to the screen, and save it to test_output.log\n npx @gamemaker/gm-cli@latest run --verbose 2>&1 | tee test_output.log || true\n shell: sh -e {0}\n env:\n DISPLAY: :99\nOCI runtime exec failed: exec failed: unable to start container process: chdir to cwd (\"/__w/palette-controller-professional/palette-controller-professional/./grid-utility-professional\") set in config.json failed: no such file or directory\nError: Process completed with exit code 127.\n"} +{"url": "https://github.com/Muhammad7839/dokploy/issues/3", "category": "OCI runtime exec failed", "rule": "", "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", "excerpt": "### Description\nWhen using Docker Compose with volume mounts, executing commands in containers via the terminal fails with \"OCI runtime exec failed\" error unless the container is force recreated. This is caused by the working directory not being set correctly for docker exec commands.\n\n### Current Behavior\n- Docker Compose container deployed with volume mounts\n- User attempts to open terminal/exec into container\n- Error: \"OCI runtime exec failed: exec failed: unable to start container process\"\n- Only workaround is force recreating container\n- Issue persists until manual intervention\n\n### Expected Behavior\n- Docker Compose container deployed with volume mounts\n- User opens terminal successfully\n- Commands execute in correct working directory\n- No OCI runtime errors\n- Consistent behavior with and without volume mou"} +{"url": "https://github.com/williamyang10/dokploy/issues/7", "category": "OCI runtime exec failed", "rule": "", "title": "Issue #5 - [BUG] Docker Compose volume mount causes OCI runtime exec failed error", "excerpt": "### Description\nWhen using Docker Compose with volume mounts, executing commands in containers via the terminal fails with \"OCI runtime exec failed\" error unless the container is force recreated. This is caused by the working directory not being set correctly for docker exec commands.\n\n### Current Behavior\n- Docker Compose container deployed with volume mounts\n- User attempts to open terminal/exec into container\n- Error: \"OCI runtime exec failed: exec failed: unable to start container process\"\n- Only workaround is force recreating container\n- Issue persists until manual intervention\n\n### Expected Behavior\n- Docker Compose container deployed with volume mounts\n- User opens terminal successfully\n- Commands execute in correct working directory\n- No OCI runtime errors\n- Consistent behavior with and without volume mou"} +{"url": "https://github.com/home-assistant/plugin-dns/issues/207", "category": "platform: exec format error", "rule": "image.platform", "title": "amd64-hassio-dns:2026.08.0 image ships with 0-byte /usr/bin/coredns binary \u2014 DNS plugin fails to start with \"Exec format error\"", "excerpt": "### Describe the issue\n\nAfter the `hassio_dns` (DNS) system add-on updated to version `2026.08.0`,\nCoreDNS fails to start and crash-loops. There is no error in the Home\nAssistant / Supervisor logs \u2014 only in the container's own `docker logs`\noutput:\n\n s6-supervise coredns: warning: unable to spawn ./run (waiting 60 seconds): Exec format error\n\nBecause the internal DNS resolver never starts, every integration and\nadd-on that needs to resolve a hostname fails (HACS download from\nraw.githubusercontent.com, met.no weather, Alexa, Music Assistant, etc.),\nso the symptom looks like a much broader outage even though the root\ncause is just this one plugin.\n\n### Root cause found\n\nInside the `ghcr.io/home-assistant/amd64-hassio-dns:2026.08.0` image,\n`/usr/bin/coredns` is a **0-byte file** \u2014 not a valid ELF binary at all,\nwhich is exactly why exec() returns \"Exec format error\":\n\n $ docker run --rm --entrypoint sh ghcr.io/home-assistant/amd64-hassio-dns:2026.08.0 \\\n -c 'ls -la /usr/bin/coredns; head -c 4 /usr/bin/c"} +{"url": "https://github.com/rickraven/conntrack-exporter/issues/1", "category": "platform: exec format error", "rule": "image.platform", "title": "Docker build defaults to amd64 binary on arm64 hosts (exec format error)", "excerpt": "First, thanks for building this exporter \u2014 it's exactly what I needed for conntrack bytes.\nI hit an architecture issue that seems caused by Dockerfile defaults:\n## What happened\nOn an arm64 host (`uname -m` => `aarch64`), running images from Docker Hub gave:\n\n```bash\ndocker run --rm --platform linux/arm64 rickraven/conntrack-exporter:latest --version\n# exec /conntrack-exporter: exec format error\n```\n\nI cloned this repo and built locally on the same host:\n\n`docker build -f docker/Dockerfile.alpine -t local/conntrack-exporter:arm64 .`\n\nBuild logs show:\n`CGO_ENABLED=0 GOOS=\"linux\" GOARCH=\"amd64\" go build ...`\n\nThen runtime fails:\n```bash\ndocker run --rm local/conntrack-exporter:arm64 --version\n# exec /conntrack-exporter: exec format error\n```\n\nIf I force build args, it works:\n\n```bash\ndocker build -f docker/Dockerfile.alpine \\\n --build-arg TARGETOS=linux \\\n --build-arg TARGETARCH=arm64 \\\n -t local/conntrack-exporter:arm64 .\ndocker run --rm local/conntrack-exporter:arm64 --version\n# works\n```\n\nSuspected root cause\nIn Dockerfiles, TARGETARCH defaults to amd64:\n\n```\nA"} +{"url": "https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/675", "category": "platform: exec format error", "rule": "image.platform", "title": "exec format error", "excerpt": " 63.4s\r\n => [invoke xformers 3/3] RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/6.0.0/xformers- 63.8s\r\n => ERROR [invoke stage-1 2/8] RUN --mount=type=cache,target=/var/cache/apt apt-get update && apt-get install make g++ git libopencv-dev -y && apt-get c 55.3s\r\n------\r\n > [invoke stage-1 2/8] RUN --mount=type=cache,target=/var/cache/apt apt-get update && apt-get install make g++ git libopencv-dev -y && apt-get clean && cd /usr/lib/x86_64-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc:\r\n1.568 exec /bin/sh: exec format error\r\n------\r\nfailed to solve: process \"/bin/sh -c apt-get update && apt-get install make g++ git libopencv-dev -y && apt-get clean && cd /usr/lib/x86_64-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc\" did not complete successfully: exit code: 1\r\nubuntu@instance-20230910-1418:~/stablediffusion-webui$ \r\n```\r\n**Which UI**\r\n\r\nauto or auto-cpu or invoke or comfy?\r\ninvoke \r\n\r\n**Hardware / Software**\r\n\r\n- OS: [e.g. Windows 10 / Ubuntu 22.04]\r\n- OS version: Ubuntu 22.04.3 LTS\r\n- WSL version (if applicable): \r\n- Docker Version: 24.0.6\r\n- Docker compose version: v2.21.0\r\n- Repo version: master\r\n- RAM: 24GB\r\n- GPU/VRAM: No.\r\n\n---\nhey @saidhasyim did you find any solution for "} +{"url": "https://github.com/indiefan/home_assistant_nanit/issues/22", "category": "platform: exec format error", "rule": "image.platform", "title": "exec format error", "excerpt": "I'm trying to run the command to acquire the refresh token and I keep getting an exec format error. \nI'm running on aarch64 architecture. Any ideas what the problem could be?\n---\nI think there's something wrong with the docker images I'm building, but I haven't been able to figure it out.\n\nIf anyone knows what's wrong and how to fix it for the devices encountering this, I would welcome the help!\n---\nIf it helps, I'm running into the same issue on a Raspberry Pi:\n\n```\nbrian@homebridge:~ $ docker run -it -v /home/brian/nanit-data:/data --entrypoint=/app/scripts/init-nanit.sh indiefan/nanit\nexec /app/scripts/init-nanit.sh: exec format error\n```\n\nAnd my OS info:\n\n```\nbrian@homebridge:~ $ cat /etc/os-release\nPRETTY_NAME=\"Debian GNU/Linux 12 (bookworm)\"\nNAME=\"Debian GNU/Linux\""} +{"url": "https://github.com/SecuritySilverbacks/SAPMAP/issues/47", "category": "platform: no matching manifest", "rule": "image.platform", "title": "[Documentation] pulling the prebuilt Docker image on macOS (Silicon)", "excerpt": "Pulling the prebuilt Docker image on macOS (Silicon) fails with \n```\nError response from daemon: no matching manifest for linux/arm64/v8 in the manifest list entries: no match for platform in manifest: not found\n```\n\nThe following command is required instead:\n```\ndocker pull --platform=linux/amd64 ghcr.io/securitysilverbacks/sapmap:latest\n```"} +{"url": "https://github.com/lando/pantheon/issues/296", "category": "platform: no matching manifest", "rule": "image.platform", "title": "no matching manifest for linux/arm64/v8", "excerpt": "Apologies if the solution is obvious, but I've been hitting my head against the wall over this for far too long. For some unknown reason, none of my Pantheon sites will run on Lando anymore (they're all WordPress).\n\nHere's the error I keep getting (more console output below):\n\n```\nno matching manifest for linux/arm64/v8 in the manifest list entries: no match for platform in manifest: not found\n```\n\nI'm on an M1 MacBook Pro, Lando v3.25.6, Docker v4.49.0. Lando is and has been\u2014for the most part\u2014plug and play since none of my sites require advanced configuration. For most problems I've encountered, running `lando update` or uninstalling/reinstalling Lando and Docker solves it, which I've tried several times to no avail.\n\nHere's my **.lando.yml**:\n\n```\nname: my-app\nrecipe: pantheon\nconfig:\n framework: wordpress\n site: my-app\n id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n```\n\nI've tried adding the following, assuming `pantheon-mariadb` is the problem, but it doesn't seem t"} +{"url": "https://github.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on/issues/15", "category": "platform: no matching manifest", "rule": "image.platform", "title": "no matching manifest for linux/arm/v7 in the manifest list entries", "excerpt": "Tried to install on HA running on RPI4 in docker.\r\n\r\nWhen try to install the addon I get the message: no matching manifest for linux/arm/v7 in the manifest list entries\r\n"} +{"url": "https://github.com/nicolaka/netshoot/issues/119", "category": "platform: no matching manifest", "rule": "image.platform", "title": "no matching manifest for linux/arm/v7 in the manifest list entries", "excerpt": "Hi Nikolaka,\r\n\r\nI'm trying to install netshoot on my RPI with this command:\r\n`_sudo docker run -it --net host nicolaka/netshoot_\r\n`\r\n\r\nafter a few seconds this is what I get in return:\r\n`_docker: no matching manifest for linux/arm/v7 in the manifest list entries._\r\n`\r\n\r\nNot sure what I'm doing wrong.\n---\nIndeed, an arm v7 build would be great.\n---\nBuilding the image on arm v7 also fails with:\n\n```sh \n$ buildah build .\n...\n[1/2] STEP 4/4: RUN /tmp/fetch_binaries.sh\n--2025-02-05 12:40:49-- https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-armv7l\nResolving github.com (github.com)... 140.82.121.3\nConnecting to github.com (github.com)|140.82.121.3|:443... connected.\nHTTP request sent, awaiting response... 404 Not Found\n2025-02-05 12:40:49 ERROR 404: Not Found.\n\nError: building at STEP \"RUN /tmp/fetch_binaries.sh\": while running runtime: exit status 8\n\n```\n---\nFR to"} +{"url": "https://github.com/TomasTomecek/sen/issues/191", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)", "excerpt": "Hi @TomasTomecek , Can you please provide also an docker image for ARM(v8)? Thank you very much!\n---\nI'm busy these days so it would take me weeks at minimum to get to this. I also don't have an armv8 device where I'd verify it works properly. Happy to accept a contribution."} +{"url": "https://github.com/TheAppgineer/flatpak-flutter/issues/127", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "docker run command isn't working for linux/arm64/v8", "excerpt": "This is not urgent, and quite possibly a newbie configuration error -- I'm not all that familiar with docker -- but I get this:\n```\nbillf@Lenny:~$ sudo !!\nsudo docker run --rm -v \"$PWD\":/usr/src/flatpak -u `id -u`:`id -g` theappgineer/flatpak-flutter:latest\n[sudo: authenticate] Password: \nWARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\nexec /usr/src/app/flatpak-flutter: exec format error\n```\nThis is running Ubuntu in a VirtualBox VM on an Apple silicon Mac. I tried specifying \"--platform linux/arm64\" and \"--platform linux/arm64/v8\" after \"docker run,\" but no luck.\n\nI think I have a workaround -- I just cloned the github repo and am running flatpak-flutter.py directly, and is launches -- but I though you'd like to know.\n\nBTW, I'm using this to package some calculator simulators called JRPN as a flatpak. https://github.com/zathras/jrpn/issues/128 https://jrpn.jovial.com. Do you want me to let you know if I succeed?"} +{"url": "https://github.com/SteveLTN/https-portal/issues/326", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "does not match the detected host platform (linux/s390x)", "excerpt": "does not match the detected host platform (linux/s390x), Do you have a better solution?\r\n\r\n./archname: Empty TARGETPLATFORM, unsupported ARCH: s390x"} +{"url": "https://github.com/silenceboychen/silenceboychen.github.io/issues/50", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "docker\u8de8\u5e73\u53f0\u6253\u5305\u95ee\u9898does not match the detected host platform | silenceboychen", "excerpt": "https://www.silenceboy.com/2022/04/29/docker%E8%B7%A8%E5%B9%B3%E5%8F%B0%E6%89%93%E5%8C%85%E9%97%AE%E9%A2%98does-not-match-the-detected-host-platform/ \n\n \u95ee\u9898\u6700\u8fd1\u5728mac M1\u4e0a\u6784\u5efa\u7684docker\u955c\u50cf\uff0c\u53d1\u5e03\u5230ubuntu20\u7cfb\u7edf\u7684\u670d\u52a1\u5668\u4e0a\u540e\uff0c\u4e00\u76f4\u8fd0\u884c\u5931\u8d25\u3002\u8f93\u51fa\u4ee5\u4e0b\u62a5\u9519\u4fe1\u606f\uff1a 1The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was req"} +{"url": "https://github.com/kljensen/yelukerest/issues/382", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "REST test stack: pick free ports instead of failing on 55432/8080/8443", "excerpt": "Seen 2026-09-10 while shipping milestone 21: `bin/test-rest-stack.sh` could not run because another project's Postgres container already listened on `127.0.0.1:55432`.\n\nTwo problems, one fix:\n\n1. The script accepts `YELUKEREST_TEST_DB_PORT` (and HTTP/HTTPS) overrides for the docker port mapping, but `YELUKEREST_TEST_DATABASE_URL` / `YELUKEREST_TEST_MIGRATOR_DATABASE_URL` in `.env` carry a fixed port. Overriding the port therefore brings the container up on one port while zapadka and the tests connect to another (\"cannot connect to the target: Connection refused\").\n2. There is no detection at all: the failure is docker's \"Bind for 127.0.0.1:55432 failed: port is already allocated\", after the script has already torn down the dev stack.\n\nProposal, keep it simple:\n\n- [ ] Before starting anything, probe the three ports (`nc -z` or `lsof -nP -iTCP: -sTCP:LISTEN`). If one is taken and no override is set, pick the next free port in a small range (e.g. 55432\u201355441) and say so on stderr.\n- [ ] Derive the database URLs the script uses from the chosen port: take the URLs from `.env`, rewrite only the port (`sed` on `:/`), and export them for zapadka and the test runner. The `.env` values stay the documented defaults.\n- [ ] Do the probe **before** `docker compose down` so a port clash never leaves the dev stack down.\n- [ ] One line in `CLAUD"} +{"url": "https://github.com/fabric8io/docker-maven-plugin/issues/1874", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "Using docker-maven-plugin from two profiles with different ports causes 'port is already allocated' error", "excerpt": "file tries to start the database Docker Image using its own distinct port (10096 and 10097 respectively). I have checked that those ports are not already in use on my system. When I run the profiles manually from the command line each works fine, but when run together I get the following error:\n\n```\n[ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.46.0:start (docker-db-api-7-it-start) on project monex: I/O Error: Unable to start container id [0a0eb824aada] : {\"message\":\"failed to set up container networking: driver failed programming external connectivity on endpoint elemental-2 (e63a42680265a7ccc251142192e9b5773e54ec193a3c651878204ecbbd63d4ef): Bind for 0.0.0.0:10097 failed: port is already allocated\"} (Internal Server Error: 500) -> [Help 1]\n```\n\nMy `pom.xml` has these significant bits:\n\n```xml\n\n\n \n\n \n \n docker-integration-test-db-api-7\n \n true\n \n \n \n \n io.fa"} +{"url": "https://github.com/opensandbox-group/OpenSandbox/issues/1705", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "Port allocation race: concurrent sandbox creation fails with \"port is already allocated\"", "excerpt": "## Summary\n\nWith `runtime.type = \"docker\"` and `docker.network_mode = \"bridge\"`, concurrent sandbox creation\nfails intermittently because the server hands out a host port that another in-flight creation is\nalready using. The failure surfaces to the caller as HTTP 500:\n\n```\nFailed to create or start container: 500 Server Error for\nhttp+docker://localhost/v1.55/containers//start: Internal Server Error\n(\"failed to set up container networking: driver failed programming external connectivity\n on endpoint sandbox-: Bind for 0.0.0.0:41106 failed: port is already allocated\")\n```\n\nThe port appears to be **chosen at random from `docker.port_range_*` and then handed to Docker to\nbind, with nothing reserving it in between**. Two creations racing between the pick and the bind get\nthe same port.\n\n## Evidence: the failure rate follows the birthday paradox\n\nEach sandbox consumes 2 host ports, so N concurrent creations draw 2N ports from the range. If the\ndraws are independent and unreserved, the expected number of collisions is `(2N)\u00b2 / (2 \u00b7 R)` for a\nrange of R ports. Measured on a single node, server `v0.2.3`, `secure_runtime.type = \"gvisor\"`:\n\n| Concurrent creations | Draws | Range | Expected collisions | **Observed failures** |\n|---|---|-"} +{"url": "https://github.com/smartcontractkit/chainlink-node-compose/issues/13", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "Bind for 0.0.0.0:6711 failed: port is already allocated", "excerpt": "When trying to run:\r\n\r\n```bash\r\ndocker-compose -f hh.yml up\r\n```\r\n\r\nI get the following error:\r\n\r\n```bash\r\nError response from daemon: driver failed programming external connectivity on endpoint chainlink-node-1 (f0eb0fe8a8bf4c248c14c10bd23dcef33d928c341d3cbcb6dfdfe86e302a4686): Bind for 0.0.0.0:6711 failed: port is already allocated\r\n```\n---\nIt seems like the ports inside of `service.yml` under `node` are conflicting."} +{"url": "https://github.com/ddev/ddev/issues/8382", "category": "rootless privileged port", "rule": "ports.host", "title": "\"linux\" missing from OSTYPE options", "excerpt": "ble your keys.\nCustom configuration detected in project 'tryddevproject-9203':\n \u2022 Web server: /home/mike/Projects/tryddevproject-9203/.ddev/web-build/Dockerfile.test\n\nCustom configuration is updated on restart. Run 'ddev restart' if changes don't take effect.\nAdd '#ddev-silent-no-warn' comment to files if you don't want to see these warnings.\nBuilding project images.......\nProject images built in 7s.\n Network ddev-tryddevproject-9203_default Created \n Container ddev-tryddevproject-9203-web Started \n Container ddev-tryddevproject-9203-db Started \nWaiting for containers to become ready: [web db]... ready in 6.5s\nStarting ddev-router, pushing config...\nError response from daemon: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 127.0.0.1:80: bind: permission denied\nFailed to restart project: failed to start ddev-router: composeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-tryddevproject-9203 docker-compose -p ddev-router -f /home/mike/.config/ddev/.router-compose-full.yaml up --build -d', action='[up --build -d]', err='exit status 1', stdout='', stderr=' Container ddev-router Creating \n Container ddev-router Created \n Container ddev-router Starting \nError response from daemon: rootlessport cannot expose privileged port 80, you can add 'net.i"} +{"url": "https://github.com/appwrite/appwrite/issues/2463", "category": "rootless privileged port", "rule": "ports.host", "title": "\ud83d\ude80 Feature: running in Podman - a writeup how to go about it", "excerpt": "dn't try.)\r\n\r\nswitching to docker anyway\n---\n@christyjacob4 @maikeriva @daniel-v I am able to run containers rootless using podman, but having issues in connecting to them on local host via custom port say \"4003/4004\" other than default port, with traefik container giving error: `level=error msg=\"the router appwrite_realtime_wss@docker uses a non-existent resolver: dns\"` and connection on localhost failed with bad gateway. \r\n\r\nI think the problem is with this line, not sure. What are the options available for: \r\n```- traefik.http.routers.appwrite_realtime_wss.tls.certresolver=\"dns\"```\r\n\r\nIf I run it using default ports `80/443`, then it gives me error on terminal\r\n\r\n```\r\nError: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied\r\nexit code: 126\r\n```\r\nand `traefik` container does not start.\r\n\r\nI chose the manual route and changed the path of volumes in `docker-compose.yml` like this: `volumes:\r\n - $XDG_RUNTIME_DIR/podman/podman.sock:/var/run/docker.sock` in both `traefik` and `appwrite-executor`\r\n \r\nAfter that I run command on terminal to create user level podman socket: `systemctl --user enable podman.socket` & `systemctl --user start podman.socket`.\r\n\r\nI am using `debian 12` with `podman version"} +{"url": "https://github.com/faramirezs/voice-chef/issues/227", "category": "rootless privileged port", "rule": "ports.host", "title": "[Integration/Network] cannot expose privileged port 80", "excerpt": "On school computer when `make prod`\n\nError response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint voice-chef-nginx-proxy-1 (140e7166e0bb4a18501dd516c9875f1b8833f2083331b1549d7c8a13dae5c71e): error while calling RootlessKit PortManager.AddPort(): cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or set CAP_NET_BIND_SERVICE on rootlesskit binary, or choose a larger port number (>= 1024): listen tcp4 0.0.0.0:80: bind: permission denied\nmake: *** [Makefile:85: prod] Error 1\n\n\"Image\""} +{"url": "https://github.com/ublue-os/forge/issues/28", "category": "rootless privileged port", "rule": "ports.host", "title": "Prerequisites check on forge.sh heat-up", "excerpt": "The prerequisites should also be checked when `forge.sh heat-up` is executed\r\n\r\notherwise errors such a\r\n\r\n```sh\r\n\u276f ./forge.sh heat-up\r\nHeating up forge...\r\nError: starting container ab78a336183527e9d30e8880fef4e11cc67ebdd45d0924f3e11776131f05a5cf: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 443), or choose a larger port number (>= 443): listen tcp 0.0.0.0:80: bind: permission denied\r\nError: starting container 4231167c373bac3806e6214a2dbe03cdfdb07d608d773e06a6328123af9dfc4b: a dependency of container 4231167c373bac3806e6214a2dbe03cdfdb07d608d773e06a6328123af9dfc4b failed to start: container state improper\r\n837c7ece8aa3c42622af8c697761aad9bea0f8dd3b4f833616251b4aca1d661d\r\n43c3b9e7f0c14b3f5f05dfefdaafe75247b6ff8828bba82969a4322d65259764\r\nThe following containers are now running...\r\nNAMES STATUS IMAGE\r\nublue-os_f"} +{"url": "https://github.com/kestra-io/kestra/issues/19626", "category": "volume permission denied", "rule": "", "title": "Podman Compose rootless deployment mounts Docker socket instead of the Podman socket", "excerpt": "ra trying to access `/var/run/docker.sock`, which is not the Podman rootless socket.\n\nSteps to reproduce on Fedora Linux with rootless Podman:\n\n```sh\nsudo dnf install podman podman-compose\n\nsystemctl --user enable --now podman.socket\n\ncurl -o docker-compose.yml \\\n https://raw.githubusercontent.com/kestra-io/kestra/develop/docker-compose.yml\n\npodman compose up\n```\n\n### Actual behavior\n\nThe current compose file mounts:\n\n```\nvolumes:\n - /var/run/docker.sock:/var/run/docker.sock\n```\n\nThe rootless Podman API socket is instead available at `/run/user/$UID/podman/podman.sock`.\n\nKestra fails to access the container runtime and reports an error similar to:\n\n```sh\nError: statfs /var/run/docker.sock: permission denied\n```\n\n### Expected behavior\n\nSince the documentation explicitly states that the provided Compose file works with Podman Compose and describes the setup as a rootless Podman deployment, the compose configuration should either: use the appropriate Podman rootless socket or explicitly document that the provided compose file requires additional configuration to connect Kestra to the Podman socket.\n\n### Proposed documentation/configuration change\n\nThe Podman Compose guide could provide a Podman-specific compose override or configuration showing how to mount the rootless Podman socket, for example:\n\n```\nvolumes:\n - ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/docker.sock\n```\n\n#"} +{"url": "https://github.com/zvchei/docker-seed/issues/29", "category": "volume permission denied", "rule": "", "title": "Root-stage mkdirs under $HOME break the user-stage volume mkdirs", "excerpt": "A template that creates a directory under `$HOME` in its `root.Dockerfile` leaves it owned by `root`. The generated user stage later runs `mkdir -p` for every declared volume path as `${USER}`, so any volume nested under that directory fails the build.\n\nThe `jupyter` template hits this: its `root.Dockerfile` runs `mkdir -p $HOME/.local`, so a volume at `.local/share/` cannot be created.\n\nReproduce with:\n\n```json\n[\n {\n \"name\": \"jupyter_repro\",\n \"templates\": [\"jupyter\"],\n \"volumes\": { \"state\": \".local/share/example\" }\n }\n]\n```\n\n`docker compose build jupyter_repro` fails with:\n\n```\nmkdir: cannot create directory '/home/user/.local/share': Permission denied\n```\n\nThe generated Dockerfile shows the cause \u2014 `USER root` creates `$HOME/.local`, then the volume mkdirs run after `USER ${USER}`:\n\n```\nUSER root\n# --- jupyter ---\nRUN mkdir -p $HOME/.local && \\\n mkdir -p $HOME/.jupyter\n\nUSER ${USER}\nRUN mkdir -p \\\n $HOME/.local/share/example\n```\n\nPossible fixes: `chown` root-stage `$HOME` directories back to the container user, emit the volume mkdirs before the root fragments, or drop the redundant `mkdir` calls from `jupyter/root.Dockerfile` since the volume mkdirs already cover them."} +{"url": "https://github.com/elicify-ai/omnipus/issues/655", "category": "volume permission denied", "rule": "", "title": "docker/Dockerfile.heavy: image cannot boot with a Docker-managed volume \u2014 .omnipus is created root-owned", "excerpt": "ed.\n\nVerified against `release/v0.1.1` @ `aa97bcea574ebf5c3a56058b7d2095716a6f5da4`.\n\n## Reproduce\n\n```sh\ndocker build -f docker/Dockerfile.heavy -t omnipus-heavy:repro .\ndocker run --rm -v repro-vol:/home/omnipus/.omnipus -p 127.0.0.1:5199:5000 \\\n -e OMNIPUS_GATEWAY_HOST=0.0.0.0 -e OMNIPUS_SANDBOX_MODE=permissive \\\n omnipus-heavy:repro\n```\n\nObserved \u2014 container exits, `/health` never becomes available:\n\n```\nWarning: could not ensure cli token: update config.json: read config.json: open /home/omnipus/.omnipus/config.json: no such file or directory\nOpen the dashboard / log in as admin:\n This machine: http://localhost:5000\nError: creating log directory: mkdir /home/omnipus/.omnipus/logs: permission denied\n```\n\n## Cause\n\n`useradd -m -d /home/omnipus` (`docker/Dockerfile.heavy:179`) creates the home directory, but **nothing ever creates `/home/omnipus/.omnipus`**. `VOLUME /home/omnipus/.omnipus` (`:184`) then declares a mount point that does not exist in the image.\n\nDocker seeds a fresh volume from whatever is at that path in the image. Finding nothing, it creates the directory as `root:root`. The container runs as `USER omnipus` (`:182`, uid 1000), which cannot write into it.\n\nConfirmed directly \u2014 on the unmodified image the mount point is root-owned; after creating and chowning it before `VOLUME`, the same volume comes up owned by uid 1000 and the instance boots:\n\n```\n# unmo"} +{"url": "https://github.com/algorandfoundation/intermezzo/issues/34", "category": "volume permission denied", "rule": "", "title": "EACCES Permission Denied on `/opt/app/node_modules`", "excerpt": "## Symptoms\n\nThe `pawn` container exits immediately with:\n\n```\nerror Error: EACCES: permission denied, mkdir '/opt/app/node_modules'\n```\n\nContainer status shows `Exited (1)` shortly after starting. Docker logs confirm `yarn install` fails because it cannot create the `node_modules` directory.\n\n## Root Cause\n\nThe `docker-compose.yml` defines an **anonymous volume** for `/opt/app/node_modules`:\n\n```yaml\nvolumes:\n - .:/opt/app/\n - /opt/app/node_modules\n```\n\nWhen Docker creates an anonymous volume, it is initialized as an **empty directory owned by `root:root`**. The container runs as the `node` user (UID 1000) via `USER node` in the Dockerfile, so the `node` user **cannot write** to a root-owned directory.\n\nThe bind mount `.:/opt/app/` also **hides** the image's pre-built `n"} diff --git a/bench/labels/test_labels_claude.tsv b/bench/labels/test_labels_claude.tsv new file mode 100644 index 0000000..6d9d39e --- /dev/null +++ b/bench/labels/test_labels_claude.tsv @@ -0,0 +1,122 @@ +idx scope predict url +0 out no https://github.com/rook/cassandra/issues/26 +1 in partial https://github.com/WebGoat/WebGoat/issues/917 +2 in yes https://github.com/LukeChannings/moviematch/issues/27 +3 out no https://github.com/Alluxio/alluxio/issues/12704 +4 in yes https://github.com/confetti-framework/confetti/issues/100 +5 in no https://github.com/DeBaschdi/docker.solaranzeige/issues/2 +6 in yes https://github.com/Tecnativa/docker-whitelist/issues/7 +7 in yes https://github.com/SensorsIot/IOTstack/issues/279 +8 in no https://github.com/ilteoood/docker-surfshark/issues/22 +9 out no https://github.com/hexh250786313/blog/issues/11 +10 in yes https://github.com/wader/postfix-relay/issues/21 +11 in yes https://github.com/ottomated/CrewLink-server/issues/168 +12 out no https://github.com/gitpod-io/gitpod/issues/2714 +13 out no https://github.com/mikedh/trimesh/issues/1127 +14 out no https://github.com/podman-container-tools/container-libs/issues/258 +15 in partial https://github.com/Poeschl/Hassio-Addons/issues/169 +16 in partial https://github.com/docker/for-mac/issues/5217 +17 out no https://github.com/amzn/amazon-ray/issues/2 +18 out no https://github.com/containrrr/watchtower/issues/796 +19 in partial https://github.com/envygeeks/jekyll-docker/issues/305 +20 in no https://github.com/docker/compose/issues/8331 +21 out no https://github.com/aquasecurity/trivy/issues/1342 +22 in yes https://github.com/docker/compose/issues/8944 +23 in partial https://github.com/containerd/nerdctl/issues/429 +24 out no https://github.com/garden-io/garden/issues/2299 +25 out no https://github.com/earthly/earthly/issues/1016 +26 in yes https://github.com/ehn-dcc-development/hcert-testdata/issues/6 +27 in no https://github.com/moby/buildkit/issues/1939 +28 in partial https://github.com/sifive/freedom-e-sdk/issues/603 +29 in yes https://github.com/PaddlePaddle/Serving/issues/1094 +30 out no https://github.com/cupcakearmy/cryptgeon/issues/4 +31 in yes https://github.com/IntersectMBO/cardano-addresses/issues/116 +32 in no https://github.com/nabaztag2018/pynab/issues/282 +33 out no https://github.com/Tencent/CodeAnalysis/issues/57 +34 in yes https://github.com/mediacloud/story-indexer/issues/62 +35 in no https://github.com/CarnegieLearningWeb/UpGrade/issues/274 +36 out no https://github.com/moby/buildkit/issues/2671 +37 in no https://github.com/fenollp/reMarkable-tools/issues/23 +38 in partial https://github.com/mr-smithers-excellent/docker-build-push/issues/81 +39 out no https://github.com/aboutcode-org/scancode.io/issues/350 +40 in yes https://github.com/docker/compose/issues/10293 +41 out no https://github.com/docker/compose/issues/10011 +42 in partial https://github.com/microsoft/vscode-docker/issues/3437 +43 in yes https://github.com/open-condo-software/open-condo-platform/issues/2 +44 in partial https://github.com/SolRacht/WritingComDownloader/issues/3 +45 in partial https://github.com/actions/runner-images/issues/2609 +46 out no https://github.com/naim94a/lumen/issues/19 +47 in no https://github.com/skalenetwork/skale-node/issues/184 +48 out no https://github.com/marcelo-ochoa/docker-volume-plugins/issues/3 +49 in yes https://github.com/lyst/lightfm/issues/612 +50 out no https://github.com/grpc-ecosystem/grpc-spring/issues/588 +51 out no https://github.com/fastapi/full-stack-fastapi-template/issues/336 +52 out no https://github.com/freeCodeCamp/chapter/issues/471 +53 in yes https://github.com/dosvath/kerberos-containers/issues/1 +54 in yes https://github.com/PrefectHQ/prefect/issues/4147 +55 out no https://github.com/prisma/orm/issues/5304 +56 out no https://github.com/k0sproject/k0s/issues/635 +57 out no https://github.com/diyhue/diyHue/issues/561 +58 in no https://github.com/snsinfu/reverse-tunnel/issues/9 +59 in no https://github.com/mpgirro/docker-pihole-unbound/issues/13 +60 out no https://github.com/EMMC-ASBL/oteapi-services/issues/14 +61 out no https://github.com/podman-container-tools/podman/issues/13426 +62 out no https://github.com/podman-container-tools/podman/issues/18205 +63 out no https://github.com/podman-container-tools/podman/issues/17028 +64 in partial https://github.com/sensepost/routopsy/issues/1 +65 in yes https://github.com/docker/compose/issues/8305 +66 in no https://github.com/ClaudiuGeorgiu/Obfuscapk/issues/95 +67 in no https://github.com/docker/cli/issues/2994 +68 in partial https://github.com/docker-archive/compose-cli/issues/1543 +69 out no https://github.com/kubernetes/kubernetes/issues/98492 +70 out no https://github.com/docker/for-win/issues/10422 +71 out no https://github.com/portainer/portainer/issues/5037 +72 in no https://github.com/ThePorgs/Exegol/issues/104 +73 out no https://github.com/Kong/kong-pongo/issues/139 +74 in no https://github.com/kiwicampus/Turtlebot-Gazebo-Navigator/issues/1 +75 out no https://github.com/mingwiki/anki-sync-server/issues/1 +76 in yes https://github.com/justin2004/mssql_server_tiny/issues/4 +77 out no https://github.com/rapidsai/cloud-ml-examples/issues/60 +78 out no https://github.com/guysoft/CustomPiOS/issues/126 +79 out no https://github.com/Reed-CompBio/spras/issues/37 +80 out no https://github.com/NVIDIA/pyxis/issues/46 +81 in yes https://github.com/NVIDIA/dcgm-exporter/issues/33 +82 in yes https://github.com/cvat-ai/cvat/issues/3593 +83 in no https://github.com/replicate/cog/issues/280 +84 in yes https://github.com/carlini/audio_adversarial_examples/issues/40 +85 in no https://github.com/oppia/oppia/issues/11868 +86 in no https://github.com/opensearch-project/OpenSearch/issues/978 +87 in yes https://github.com/opendistro-for-elasticsearch/sample-code/issues/253 +88 in partial https://github.com/noirscape/e621-docker/issues/4 +89 out no https://github.com/rcdailey/nextcloud-cronjob/issues/9 +90 in no https://github.com/jenkinsci/helm-charts/issues/221 +91 in yes https://github.com/dockhero/heroku-buildpack-docker-compose/issues/7 +92 out no https://github.com/docker/for-win/issues/10247 +93 out no https://github.com/dockware/dockware/issues/36 +94 in no https://github.com/apache/superset/issues/12697 +95 in partial https://github.com/docker/for-mac/issues/5232 +96 out no https://github.com/XQuartz/XQuartz/issues/31 +97 out no https://github.com/podman-container-tools/podman/issues/9006 +98 out no https://github.com/alerque/libertinus/issues/418 +99 in partial https://github.com/otherguy/docker-dropbox/issues/16 +100 in no https://github.com/pi-hole/docker-pi-hole/issues/751 +101 in no https://github.com/ArchiveBox/ArchiveBox/issues/667 +102 in no https://github.com/microsoft/WSL/issues/6427 +103 out no https://github.com/GoogleCloudPlatform/cloud-code-vscode/issues/376 +104 in no https://github.com/osixia/container-openldap/issues/514 +105 in no https://github.com/pezzolabs/pezzo/issues/64 +106 in no https://github.com/bitnami/containers/issues/33325 +107 in partial https://github.com/reportportal/reportportal/issues/1995 +108 in no https://github.com/LAION-AI/Open-Assistant/issues/1119 +109 out no https://github.com/youtous/docker-mailserver-traefik/issues/4 +110 in yes https://github.com/sethuiyer/Image-to-Image-Search/issues/19 +111 out no https://github.com/raiden-network/raiden-service-bundle/issues/226 +112 in no https://github.com/traefik/traefik/issues/7738 +113 out no https://github.com/kubernauts/jmeter-operator/issues/26 +114 out no https://github.com/fabric8io/kubernetes-client/issues/2704 +115 in no https://github.com/lando/lando/issues/2834 +116 in no https://github.com/cplee/github-actions-demo/issues/5 +117 in partial https://github.com/farend/redmine_message_customize/issues/40 +118 in partial https://github.com/OpenVAA/voting-advice-application/issues/114 +119 out no https://github.com/docker/for-mac/issues/5239 +120 in no https://github.com/TandoorRecipes/recipes/issues/444 diff --git a/bench/labels/test_sample.jsonl b/bench/labels/test_sample.jsonl new file mode 100644 index 0000000..fe8ef91 --- /dev/null +++ b/bench/labels/test_sample.jsonl @@ -0,0 +1,121 @@ +{"url": "https://github.com/rook/cassandra/issues/26", "category": "platform: exec format error", "rule": "image.platform", "title": "rook cassandra arm64 image contains amd64 binaries. ", "excerpt": "rook cassandra arm64 image contains amd64 binaries. \n* bug report\r\nunable to create cassandra cluster on arm64 based cluster. the operator creates and starts ok, but after creating a cassandra.rook.io/v1alpha1 cluster, the rook-install container crashes while trying to run \"/bin/sh -c cp -a /sidecar/* /mnt/shared\". \r\n\r\nkube logs show \"standard_init_linux.go:211: exec user process caused \"exec format error\" which would suggest that sh, cp or both are the wrong architecture. \r\n\r\n**deviation from expected behavior:**\r\nexpected behavior is that the rook-install init job runs and completes. \r\n\r\n** hack to make it work: ** \r\ncreate new dockerfile to patch shell binaries: \r\n```\r\nfrom busybox as shell\r\nfrom rook/cassandra:v1.5.4\r\ncopy --from=shell /bin/ /bin/\r\n```\r\ndocker build \r\ndocker push \r\n\r\nedit image in operator.yaml to use new image. \r\nworks as expected. \r\n\r\n**environment**:\r\n* os ubuntu 20.10\r\n* kernel (e.g. `uname -a`): 5.8.0-1010-raspi rook/rook#13-ubuntu smp preempt wed dec 9 17:14:07 utc 2020 aarch64 aarch64 aarch64 gnu/linux\r\n* cloud provider or hardware configuration: "} +{"url": "https://github.com/WebGoat/WebGoat/issues/917", "category": "platform: exec format error", "rule": "image.platform", "title": "Docker run failed to start: standard_init_linux.go:211: exec user process caused \"exec format error\"", "excerpt": "docker run failed to start: standard_init_linux.go:211: exec user process caused \"exec format error\"\ndocker run failed to start, the log information is as follows:\r\n`standard_init_linux.go:211: exec user process caused \"exec format error\"`\r\n how do you solve this problem\uff1f\n\ncan you provide some more detail? like which os, which docker, what startup arguments were used?\n\n> can you provide some more detail? like which os, which docker, what startup arguments were used?\r\n\r\nsystem: armbian 5.77\r\ndocker: docker version 19.03.12, build 48a6621\r\nstartup arguments: docker run -p 8080:8080 -p 9090:9090 -e tz=europe/amsterdam webgoat/goatandwolf\r\n\r\nthe reason why the arm architecture is not compatible is that some of my data should not be queried.\r\nmay i ask if there will be any sup"} +{"url": "https://github.com/LukeChannings/moviematch/issues/27", "category": "platform: exec format error", "rule": "image.platform", "title": "[Feature Request] Support for ARM, e.g. Raspberry Pi", "excerpt": ".0. can you try it out and let me know how it does?\r\n\r\ni don't think there's a high chance of getting a 32-bit arm image, so hopefully you're not running a 32-bit arm linux.\r\n\r\nraspberry pi os and ubuntu have both been available in 64-bit for a while now.\r\n\r\nluke\n\ni'm using raspbian on a pi 4, which i guess is 32 bit :( \r\nunfortunately gave me this error: error: no matching manifest for linux/arm/v7 in the manifest list entries\r\n\n\nyep, that's 32-bit arm. i can try to get a build for 32-bit arm, but i haven't had any success thus far. \n\ni guess i could always look into upgrading to a big boy os....\n\ni tried it on a raspi 4 with an ubuntu server 20.04 lts arm64 build, and it had the classic exec format error, until i added the sha256-checksum to the docker container name in my docker-compose file (part with moviematch attached). this one works like a charm, although not automatically and probably won't update beyond the current 1.7.0 build (not 100% sure, though).\r\n\r\n\r\n``` \r\nversion: \"2.1\"\r\nservices:\r\n moviematch:\r\n image: lukechannings/moviematch:latest@sha256:9b94f9d61f2451697b4341c1a0615103a64d370f32c560374d1bd113fef23774\r\n container_name: moviematch\r\n environment:\r\n - plex_url=https://plex.example.com:443\r\n - library_filter=movies\r\n - plex_token=xxxxxxxx\r\n ports:\r\n - 7676:8000\r\n restart: always\r\n```\n\ni think possibly you haven't pulled th"} +{"url": "https://github.com/Alluxio/alluxio/issues/12704", "category": "platform: exec format error", "rule": "image.platform", "title": "Support building and testing Alluxio on ARM64 platform", "excerpt": "e.\n\n> i can confirm targeting arm platform works, and i successfully built and pushed the image here: https://hub.docker.com/r/naushadh/alluxio/tags\r\n> \r\n> ```shell\r\n> $ git clone https://github.com/alluxio/alluxio.git\r\n> $ cd integrations/docker\r\n> $ docker build -t alluxio/alluxio:2.8.1 --platform arm64 .\r\n> $ docker tag alluxio/alluxio:2.8.1 naushadh/alluxio:2.8.1\r\n> $ docker push naushadh/alluxio:2.8.1\r\n> ```\r\n> \r\n> would be nice if this can be done by the ci process so there is official docker images that work in arm.\r\n\r\n@naushadh i tried naushadh/alluxio:2.8.1 on my aarch64 machine and get this:\r\n```\r\nfri, mar 24 2023 10:19:57 am | standard_init_linux.go:228: exec user process caused: exec format error\r\n```\r\nseems this image can not run on aarch64\r\n"} +{"url": "https://github.com/confetti-framework/confetti/issues/100", "category": "platform: no matching manifest", "rule": "image.platform", "title": "Can't install with docker on M1 Mac", "excerpt": "can't install with docker on m1 mac\n```\r\npulling mysql (mysql:8.0)...\r\n8.0: pulling from library/mysql\r\nerror: no matching manifest for linux/arm64/v8 in the manifest list entries\r\n```\r\n\r\nsimply replacing 'mysql:8.0' to 'mysql/mysql-server:8.0' seem to work. but i get\r\n\r\n```\r\nstatus: downloaded newer image for mysql/mysql-server:8.0\r\npulling redis (redis:alpine)...\r\nalpine: pulling from library/redis\r\n2914792bc417: pull complete\r\n5ce28e8636b2: pull complete\r\n393e448a41a0: pull complete\r\nb2da15e8aaed: pull complete\r\n72d76ccc5dc4: pull complete\r\ned505bb98182: pull complete\r\ndigest: sha256:d2b1b0bf521f55381c81b1bc0218aec4ddc92fb545e9e8492e8ff324462eed58\r\nstatus: downloaded newer image for redis:alpine\r\nbuilding confetti.local\r\n\r\ntraceback (most recent call last):\r\n file \"compose/cli/main.py\", line 67, "} +{"url": "https://github.com/DeBaschdi/docker.solaranzeige/issues/2", "category": "platform: no matching manifest", "rule": "image.platform", "title": "ERROR: no matching manifest for unknown in the manifest list entries", "excerpt": "error: no matching manifest for unknown in the manifest list entries\nhello! thank you for your efforts!\r\ni try to install it on an openhabian-image with docker.io + docker-compose installed.\r\nwith \r\n\r\n> docker run \\\r\n -d \\\r\n -e user_id=\"99\" \\\r\n -e group_id=\"100\" \\\r\n -e timezone=\"europe/berlin\" \\\r\n -e update=\"yes\" \\\r\n -e mosquitto=\"yes\" \\\r\n -e influxdb=\"yes\" \\\r\n -p 3000:3000 \\\r\n -v {solaranzeige_storage}:/solaranzeige \\\r\n -v {influxdb_storage}:/var/lib/influxdb \\\r\n -v {grafana_storage}:/var/lib/grafana \\\r\n -v {www_storage}:/var/www \\\r\n --name=solaranzeige \\\r\n --restart unless-stopped \\\r\n --tmpfs /tmp \\\r\n --tmpfs /var/log \\\r\n takealug/solaranzeige:tag\r\n \r\nand with: \r\n> docker-compose"} +{"url": "https://github.com/Tecnativa/docker-whitelist/issues/7", "category": "platform: no matching manifest", "rule": "image.platform", "title": "Cannot start on a mac M1", "excerpt": "cannot start on a mac m1\nodoo image was built successfully but at the last step of the doodba set-up, when i perform a 'docker-compose up -d' i get the following error. does anyone have found a workaround? \r\n\r\n```\r\ndigest: sha256:e6e1d1d41fb7087250176b38c73666c1205816e8b8d2d8f8f4a69ce23f7635b3\r\nstatus: downloaded newer image for kozea/wdb:latest\r\npulling cdnjs_cloudflare_proxy (tecnativa/whitelist:)...\r\nlatest: pulling from tecnativa/whitelist\r\nerror: no matching manifest for linux/arm64/v8 in the manifest list entries\r\n```\r\n\r\n\n\nthe `tecnativa/whitelist` image is not currently available for the `linux/arm64/v8` platform and that is what is causing the issue. maybe this issue should be moved there.\n\nthis would be a good improvement, as that is quite a common architecture (also used on raspberry pi 4, for example). \r\nhowever, the build currently fails if we try this, so we ended up removing for now...\n\nthanks @joao-p-marques. looking forward for a fix. \ud83d\ude4c meanwhile, does anyone have any suggestion for a workaround, perhaps disabling the whitelist from docker-compose? in my scenario, i simply want to make the image work locally. \ud83e\udd1e \n\n@piqon"} +{"url": "https://github.com/SensorsIot/IOTstack/issues/279", "category": "platform: no matching manifest", "rule": "image.platform", "title": "InfluxDB install gives error: \"ERROR: no matching manifest for linux/arm/v7 in the manifest list entries\"", "excerpt": "influxdb install gives error: \"error: no matching manifest for linux/arm/v7 in the manifest list entries\"\ni installed grafana, influxdb, node-red and portainer-ce without issue just last week.\r\n\r\ni tried to do a new install today and influxdb seems to break everything.\r\n\r\ni see the following error:\r\nerror: no matching manifest for linux/arm/v7 in the manifest list entries\r\n\r\nwhen i checked the influx docker page, it seems they may have changed settings to use the 2.0 version of influxdb.\r\n\r\ni edited the docker-compose.yml line for influxdb, changing: \r\n\r\nimage: \"influxdb:latest\"\r\n\r\nto\r\n\r\nimage: \"influxdb:1.8\"\r\n\r\nwhich resolved the issue.\r\n\r\napologies if i have not provided all of the correct information -- docker and iotstack ar"} +{"url": "https://github.com/ilteoood/docker-surfshark/issues/22", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "unable to resolve api.surfshark.com", "excerpt": "gest you to delete your current container, remove the image, pull the latest one and re-deploy.\r\nif continue to not work, please provide you compose file.\n\ni restored omv and portainer (3 days ago). \r\nmaybe it's due to the portainer update 2.0.1 ? the rollback worked so i will let it that way. \n\nhmmm, i'm running into this same issue with `sha256:95885c2311b193a9b8db13273205cbb8a58f8d823a0e904dbb95dd132a6eb01d`, from 5 days ago (running on a raspberry pi 4), with the vanilla example docker-compose yaml (and my creds obviously).\n\nahh, probably the issue here:\r\n\r\n```\r\n$ sudo docker run -i -t --rm --entrypoint=\"/bin/sh\" byrnedo/alpine-curl\r\nwarning: the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested\r\nstandard_init_linux.go:219: exec user process caused: exec format error\r\n```\r\n\r\n(i'll break this into a separate issue)"} +{"url": "https://github.com/hexh250786313/blog/issues/11", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "\u4e00\u53e3\u6c14\u5b8c\u6210 Sentry Docker \u90e8\u7f72", "excerpt": "e, skipping\r\nweb uses an image, skipping\r\ncron uses an image, skipping\r\nworker uses an image, skipping\r\ningest-consumer uses an image, skipping\r\npost-process-forwarder uses an image, skipping\r\nsubscription-consumer-events uses an image, skipping\r\nsubscription-consumer-transactions uses an image, skipping\r\nrelay uses an image, skipping\r\nnginx uses an image, skipping\r\nbuilding snuba-cleanup\r\nsending build context to docker daemon 3.584kb\r\nstep 1/5 : arg base_image\r\nstep 2/5 : from ${base_image}\r\n ---> 5ef1ff96c8d8\r\nstep 3/5 : run apt-get update && apt-get install -y --no-install-recommends cron && rm -r /var/lib/apt/lists/*\r\n ---> [warning] the requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested\r\n ---> running in f077d4cd8859\r\nstandard_init_linux.go:228: exec user process caused: exec format error\r\nremoving intermediate container f077d4cd8859\r\nthe command '/bin/sh -c apt-get update && apt-get install -y --no-install-recommends cron && rm -r /var/lib/apt/lists/*' returned a non-zero code: 1\r\nservice 'snuba-cleanup' failed to build : build failed\r\nan error occurred, caught sigerr on line 4\r\ncleaning up...\r\n```\n\n@cnmathon \r\n\r\n```\r\n ---> [warning] the requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested\r\n"} +{"url": "https://github.com/wader/postfix-relay/issues/21", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "Provide multi-platform Docker images", "excerpt": "provide multi-platform docker images\nthe docker image in docker hub [mwader/postfix-relay](https://hub.docker.com/r/mwader/postfix-relay) currently supports only os/arch of type `linux/amd64` .\r\nit would be great to support multiple architectures (=platforms), in particular `linux/arm64` , as arm processors are widely used.\r\n\r\n### how to reproduce\r\n\r\nif you run in an arm machine:\r\n\r\n```bash\r\n$ dpkg --print-architecture\r\narm64\r\n```\r\n\r\nyou get the following error:\r\n\r\n```bash\r\n$ docker run -it --rm mwader/postfix-relay:latest bash\r\n\r\nwarning: the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\r\nstandard_init_linux.go:219: exec user process caused: exec format error\r\n```\r\n\r\n### usecases\r\n\r\n- my usecase is to deploy the container in a raspberrypi, which has an arm processor.\r\n- any other arm machine.\r\n\r\n### suggested solution\r\n\r\nyou can use [buildx](https://github.com/docker/buildx). it can build and push a multi-platform image without modifying the dockerfile.\r\nit integrates very well with ci/cd pipelines: \r\nexample of github actions: https://github.com/marketplace/actions/build-and-push-docker-images#multi-platform-image\r\n\r\n### tests\r\n\r\ni tested a multi-architecture build with buildx,"} +{"url": "https://github.com/ottomated/CrewLink-server/issues/168", "category": "platform: requested platform mismatch", "rule": "image.platform", "title": "Raspberry Pi 4 B amd64 vs arm/v8 Docker Issue", "excerpt": "arm/v8 docker issue\ni keep running into the amd64 vs arm/v8 issue with docker when i go to build it.. i tried reading around but i'm not really understanding.\r\n\r\ni believe the issue is the version of docker that's being installed so i guess i just need to understand what i'm doing wrong.\n\ni've also gotten a yarn permissions error doing it the manual way.\n\nokay i realized after posting this, i didn't give enough information.\r\n\r\ni'm running ubuntu 20.10 on my raspberry pi 4 b. i get all the way to the portion where trying to run it using:\r\n`docker run -d -p 9736:9736 ottomated/crewlink-server:latest`\r\nthis results in the following error:\r\n`warning: the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested`\r\ndocker builds this and it remains unable to start without this error.\r\n\r\ni have also tried running it like this, due to the environment address error:\r\n`docker run -e address=http://[mypublicip]:9736 -d -p 9736:9736 ottomated/crewlink-server`\r\nbut it just results in the same error. \r\n\r\neverywhere i read is talking about 32bit systems vs 64bit systems but this is a 64 bit version of ubuntu so i'm very confused.\r\n\r\nthe firewall is disabled for now for troubleshooting purposes.\n\ni have answered this over here, hope it helps, **docker-compose** is great.\r\nhttps://github.com/ottomated/crewlink-serv"} +{"url": "https://github.com/gitpod-io/gitpod/issues/2714", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Workspace image pulled from wrong registry when feature preview is enabled", "excerpt": "notfound desc = failed to pull and unpack image ...\r\n```\r\n\r\nand from registry-facade\r\n\r\n```\r\nhost: reg.mydomain.com:3000\r\naccept: application/vnd.docker.distribution.manifest.v2+json, */*\r\naccept-encoding: gzip\r\nuser-agent: containerd/v1.3.9-k3s1\r\n\r\n{\"level\":\"debug\",\"message\":\"get manifest\",\"servicecontext\":{\"service\":\"registry-facade\",\"version\":\"\"},\"severity\":\"debug\",\"spec\":{\"base_ref\":\"myregistry.com:5000/gitpod/workspace-images:ad3d7518084c1e73e3615401986db8f936fc850151005b8eb473c435a8de541b\",\"ide_ref\":\"gcr.io/gitpod-io/self-hosted/theia-ide:0.6.0-beta5\"},\"time\":\"2021-01-11t09:25:40z\"}\r\n{\"@type\":\"type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.reportederrorevent\",\"error\":\"manifest unknown: accept header does not include ociv1 or v2 manifests\",\"level\":\"error\",\"message\":\"cannot get manifest\",\"servicecontext\":{\"service\":\"registry-facade\",\"version\":\"\"},\"severity\":\"error\",\"spec\":{\"base_ref\":\"myregistry.com:5000/gitpod/workspace-images:ad3d7518084c1e73e3615401986db8f936fc850151005b8eb473c435a8de541b\",\"ide_ref\":\"gcr.io/gitpod-io/self-hosted/theia-ide:0.6.0-beta5\"},\"time\":\"2021-01-11t09:25:40z\"}\r\n```\r\n\r\nthis one sounds important\r\n\"error\":\"manifest unknown: accept header does not include ociv1 or v2 manifests\"\n\ncertificates seems to be ok \r\n\r\n```\r\ncurl -v -i -h \"accept: application/vnd.docker.distribution.manifest.v2+json\" https://reg.mydomain.com:3000/v2/remote/aaa88"} +{"url": "https://github.com/mikedh/trimesh/issues/1127", "category": "image: tag/repo not found", "rule": "image.exists", "title": "[Bug] AttributeError: module 'trimesh.voxel' has no attribute 'creation'", "excerpt": "rnings/venv\r\n\r\n[notice] a new release of pip available: 22.2.2 -> 22.3.1\r\n[notice] to update, run: pip install --upgrade pip\r\nroot@3d8b25c2742e:/# pythonpython 3.10.8 (main, nov 15 2022, 21:06:05) [gcc 10.2.1 20210110] on linux\r\ntype \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> import trimesh\r\n>>> m = trimesh.creation.box()\r\n>>> m.voxelized(pitch=0.5)\r\n\r\n>>> m.voxelized(pitch=0.5).volume\r\n3.250000000000001\r\n```\r\n\r\n3.7:\r\n```\r\nmikedh@orion:~/trimesh$ docker run -it python:3.5-slim-bullseye /bin/bash\r\nunable to find image 'python:3.5-slim-bullseye' locally\r\ndocker: error response from daemon: manifest for python:3.5-slim-bullseye not found: manifest unknown: manifest unknown.\r\nsee 'docker run --help'.\r\nmikedh@orion:~/trimesh$ docker run -it python:3.7-slim-bullseye /bin/bash\r\nunable to find image 'python:3.7-slim-bullseye' locally\r\n3.7-slim-bullseye: pulling from library/python\r\na603fa5e3b41: already exists \r\nb00aaacf759c: already exists \r\nbfd5215df481: pull complete \r\n646c640d7dca: pull complete \r\n2ca40dc2918a: pull complete \r\ndigest: sha256:7816ff9e4f2c31671cc7db97ea99e05a2e5fd508eaeced99e0939dbadf4f670a\r\nstatus: downloaded newer image for python:3.7-slim-bullseye\r\nroot@3e51ac02d5f2:/# pip install trimesh\r\ncollecting trimesh\r\n downloading trimesh-3.16.4-py3-none-any.whl (663 kb)\r\n \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"} +{"url": "https://github.com/podman-container-tools/container-libs/issues/258", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Errors returned are not typed making it difficult to distinguish for approriate handling.", "excerpt": "or e.g. \"dial connection timeout\", \"tls timeout\" or 429 \"too many requests\" (transient).\r\n\r\nwithout string matching it is not possible to distinguish one from another and in order to handle approriately. \r\n\r\nref: https://github.com/ibm/portieris/issues/238\n\nspecifically for the docker client, there is at least https://github.com/containers/image/blob/122b16af75d13b9dacda1b04111fa7fdffde30c5/docker/errors.go#l12-l23 . that\u2019s not a general solution, but probably enough at least for the \u201ccredentials rejected, give up\u201d case.\r\n\r\nhttps://github.com/containers/common/tree/master/pkg/retry might be useful as well.\n\nanother example of an error (from `image/docker/errors.go`) that should be typed is `manifest unknown`.\r\n\r\nwhen writing an application (using this library), i want to be able to ignore cases where source image does not exist. currently the only way to do this is with a string compare for `manifest unknown`.\r\nit would be extremely helpful if the containers image library returned a specific error (or typed error) in this case.\n\nthat\u2019s a reasonable request.\r\n\r\n`manifest unknown` is actually, _currently_, typed as `github.com/docker/distribution/registry/api/v2.errorcodemanifestunknown` \u2014 but that\u2019s not an api commitment, and it\u2019s not something we\u2019d want to _make_ an api commitment, because registries behave inconsistently in this (iirc some just report a http 404 status). so id"} +{"url": "https://github.com/Poeschl/Hassio-Addons/issues/169", "category": "image: tag/repo not found", "rule": "image.exists", "title": "Ngrok Client Install Error", "excerpt": "ngrok client install error\n**which addon?**\r\nngrok client\r\n\r\n**describe the bug**\r\nfailed to install addon\r\n404 client error for http+docker://localhost/v1.40/images/create?tag=2.1.5&fromimage=thepicklenat0r%2farmv7-hassio-ngrok: not found (\"manifest for thepicklenat0r/armv7-hassio-ngrok:2.1.5 not found: manifest unknown: manifest unknown\")\r\n\r\n**to reproduce**\r\nsteps to reproduce the behavior:\r\n1. go to 'addon store'\r\n2. click on 'ngrok client'\r\n3. scroll down to '.install'\r\n4. see error\r\n\r\n\r\n\r\n**system**\r\n\r\n* supervisor version: supervisor-2021.01.4 \r\n* host system version: core-2021.1.4\r\n\r\n\n\nit seems that you got the wrong repository \ud83d\ude09\r\n\r\nthis might be the place for the ngrok addon: https://github.com/thepicklenat0r/hassio-addons/issues\n\ni am sorry\n\nall good \ud83d\ude09 have a nice sunday. "} +{"url": "https://github.com/docker/for-mac/issues/5217", "category": "image: pull access denied", "rule": "image.exists", "title": "Docker Pull access denied on private repository", "excerpt": "docker pull access denied on private repository\n### expected behavior\r\ndocker pull after successful login to private registry\r\n### actual behavior\r\npull access denied\r\n### information\r\n using cache\r\n ---> 118b67f11e76\r\nstep 5/19 : arg qemu_tarball=riscv-qemu-5.1.0-2020.08.1-x86_64-linux-ubuntu14.tar.gz\r\n ---> using cache\r\n ---> ad8b21ce0f1c\r\nstep 6/19 : run apt-get update && apt-get upgrade -y && apt-get install -y bzip2 rsync wget\r\n ---> using cache\r\n ---> 6a79e93f6f8c\r\nstep 7/19 : run wget --no-verbose ${sifive_tools_url}/${riscv_tools_tarball} && tar xzf ${riscv_tools_tarball} && mkdir -p /tools && rsync -a ${riscv_tools_tarball%.tar.gz}/* /tools/\r\n ---> using cache\r\n ---> 879098681049\r\nstep 8/19 : copy ./segger-libc/${riscv_segger_libc_tarball} ./\r\ncopy failed: file not found in build context or excluded by .dockerignore: stat segger-libc/segger_libc-2020.08.2.tar.bz2: file does not exist\r\n\r\n```\n\nlooks like segger materials were dropped in this commit: https://github.com/sifive/freedom-e-sdk/commit/b52804644a5272770a18654b8fef26201854e926. you can build without it."} +{"url": "https://github.com/PaddlePaddle/Serving/issues/1094", "category": "build: COPY failed legacy", "rule": "build.context", "title": "raspberry 4b \u6811\u8393\u6d3e4B docker\u4e0b\u7f16\u8bd1\u51fa\u9519", "excerpt": "moving intermediate container c8fafac96d1f\r\n ---> 1d4ac76be9ef\r\nstep 6/71 : env with_avx=${with_avx:-on}\r\n ---> [warning] the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested\r\n ---> running in 1e9182cbb019\r\nremoving intermediate container 1e9182cbb019\r\n ---> e2add42a6d84\r\nstep 7/71 : env home /root\r\n ---> [warning] the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested\r\n ---> running in eeea6d370e01\r\nremoving intermediate container eeea6d370e01\r\n ---> 7c42f998b26f\r\nstep 8/71 : copy tools/dockerfile/scripts/root/ /root/\r\ncopy failed: file not found in build context or excluded by .dockerignore: stat tools/dockerfile/scripts/root/: file does not exist\r\n`\r\n\u8bf7\u95ee\u5982\u4f55\u7ee7\u7eed\u6784\u5efadocker\u955c\u50cf\u5462\uff1f\n\nmessage that will be displayed on users' first issue\n\n$ sudo docker build -f dockerfile.devel -t paddle-serving.armv7-pi4:latest .\r\nsending build context to docker daemon 11.78kb\r\nstep 1/71 : from hub.baidubce.com/ctr/cuda:9.0-cudnn7-devel-ubuntu16.04\r\n ---> 5978609a60c5\r\nstep 2/71 : maintainer paddlepaddle authors \r\n ---> using cache\r\n ---> fa640de9e332\r\nstep 3/71 : arg with_gpu\r\n ---> using cache\r\n ---> 7110618d9a45\r\nstep 4/71 : arg with_avx\r\n ---> using cache\r\n ---> 9cdb4b048a19\r\nstep 5/71 : env with_gpu=${with_g"} +{"url": "https://github.com/cupcakearmy/cryptgeon/issues/4", "category": "build: COPY failed legacy", "rule": "build.context", "title": "arm64 compatible docker", "excerpt": "rom rust:1.51-alpine as rust\r\n\r\nenv cgo_enabled=0\r\nworkdir /tmp\r\nrun apk add libc-dev openssl-dev alpine-sdk\r\ncopy ./cargo* ./\r\ncopy ./src ./src\r\n\r\nrun cargo build --release\r\n\r\nfrom scratch\r\n\r\nworkdir /app\r\ncopy --from=rust /tmp/target/release/cryptgeon .\r\ncopy --from=client /tmp/build ./client/build\r\n\r\nenv memcache=memcached:11211\r\n\r\nexpose 5000\r\n\r\nentrypoint [ \"/app/cryptgeon\" ]\r\n```\r\n\n\ni created dockerfile but i can't build it.\r\n`docker build -t cryptgeon .`\r\n```\r\nstep 1/21 : from node:16-alpine as client\r\n ---> 8074a83d0ba9\r\nstep 2/21 : env cgo_enabled=0\r\n ---> using cache\r\n ---> 2b6a1ef23e2a\r\nstep 3/21 : workdir /tmp\r\n ---> using cache\r\n ---> dee5505ad804\r\nstep 4/21 : copy ./client ./\r\ncopy failed: file not found in build context or excluded by .dockerignore: stat client: file does not exist\r\n```\n\nare you sure you are in the right context? step 4 cannot fail really\n\notherwise try the following steps:\r\n\r\n1. clone a fresh instance of the repo\r\n2. change `from scratch` to `from alpine` in the dockerfile and try to build\n\nyou where right. i was in wrong directory. but issue is still there.\r\n```\r\ndocker run -it cryptgeon\r\nstandard_init_linux.go:228: exec user process caused: no such file or directory\r\n```\n\ncan you try with the comment before? https://github.com/cupcakearmy/cryptgeon/issues/4#issuecomment-1000215238\n\nyou mean docker-compose up? i'll try it later. \n\nyeah with alp"} +{"url": "https://github.com/IntersectMBO/cardano-addresses/issues/116", "category": "build: COPY failed legacy", "rule": "build.context", "title": "Error when attempting to build Docker image on Linux", "excerpt": "error when attempting to build docker image on linux\n### description\r\nfollowing the steps in the readme, when running attempting to build docker image i'm hitting an error blocking me from proceeding.\r\n\r\n### steps:\r\n1. checkout this repo\r\n2. `$ docker build -t cardano-address .`\r\n### result:\r\n`step 5/21 : copy stack.yaml .`\r\n`copy failed: file not found in build context or excluded by .dockerignore: stat stack.yaml: file does not exist`\r\n\r\n### environment\r\nlinux mint 20 (ulyana)\r\ndocker version 20.10.5, build 55c4c88\r\ncardano-addresses commit 55f174b\n\n### full logs\r\n> $ docker build -t cardano-address .\r\nsending build context to docker daemon 753.2kb\r\nstep 1/21 : from haskell:8.6.5 as build\r\n ---> 933dea80169e\r\nstep 2/21 : workdir /build\r\n ---> running in 9625b79002d3\r\nremoving intermediate container 9625b79002d3\r\n ---> f8cf4b4342a5\r\nstep 3/21 : run apt-get update && apt-get install --no-install-recommends -y build-essential=12.3 git=1:2.11.*\r\n ---> running in 0c51ef802a3c\r\nign:1 http://deb.debian.org/debian"} +{"url": "https://github.com/nabaztag2018/pynab/issues/282", "category": "build: outside build context", "rule": "build.context", "title": "Error setting up the Docker-based environment on ARMv7 platform", "excerpt": "images, there's something in the arm environment or debian image that is missing, to do with rust apparently. maybe there are pre-compiled packages for nlu parsers on x86, but not for arm, so it tries to compile them but fail due to a missing dependency? i don't have a rp4 so i can't easily check unfortunately.\r\n\r\nfor the `requirements.txt`, symlinks are not supported by docker i believe (it will still see the file is \"outside\" of the build context:\r\n\r\n```\r\n$ ls -la nab/requirements.txt \r\nlrwxrwxrwx 1 nicolas users 22 jun 27 11:41 nab/requirements.txt -> ../../requirements.txt\r\n$ docker-compose build\r\n...\r\nstep 17/24 : copy requirements.txt /tmp/requirements.txt\r\ncopy failed: forbidden path outside the build context: requirements.txt ()\r\nerror: service 'migrate' failed to build : build failed\r\n```\r\n\r\nplus it wouldn't work on windows...\n\nthanks a lot for your answer.\r\nit might be useful to mention in the `docker/readme.md` file that is works only on x86.\r\n\r\n> for the requirements.txt, symlinks are not supported by docker i believe (it will still see the file is \"outside\" of the build context)\r\n\r\nindeed. then care should be taken to keep `docker/nab/requirements.txt` up to date wrt `requirements.txt`.\r\n\n\nmy understanding is the docker file should not be limited to x86. it makes most sense for platforms where binaries packages are available. it also makes most sense on desktop pla"} +{"url": "https://github.com/Tencent/CodeAnalysis/issues/57", "category": "build: outside build context", "rule": "build.context", "title": "\u5b89\u88c5\u6210\u529f\u540e\u4e00\u76f4\u5361\u5728\u6b63\u5728\u52a0\u8f7d\u4e2d", "excerpt": "ub.com/tencent/codeanalysis/blob/main/doc/deploy.md\r\ndocker\u90e8\u7f72\u6587\u6863\uff1ahttps://github.com/tencent/codeanalysis/blob/main/doc/deploy_dc.md\n\n\u5982\u679c\u662fdocker\u90e8\u7f72\uff0c\u9ebb\u70e6\u67e5\u770b\u4e0b\u662f\u5426\u5df2\u6267\u884c`./compose_init.sh`\r\n![image](https://user-images.githubusercontent.com/18720809/148935010-82fadb7b-d412-4b2e-a5de-3b61335a9381.png)\r\n\n\n\u5c31\u662f\u53c2\u7167\u672c\u5730\u90e8\u7f72\u6587\u6863\u90e8\u7f72\u7684\r\n\n\n![image](https://user-images.githubusercontent.com/59357339/148939152-2be7b203-49a3-4c8f-af2e-6b95e98e1590.png)\r\n\u5e0c\u671b\u8fd9\u90e8\u5206\u53ef\u4ee5\u5b8c\u5584\n\n@m0re-work \u8bf7\u95ee\u76ee\u524d\u662f\u5426\u8fd8\u672a\u89e3\u51b3\uff1f\n\n\u672a\u89e3\u51b3\r\n\n\n[root@vm-8-12-centos codeanalysis-main]# ./compose_init.sh\r\nrecreating codeanalysismain_redis_1 ... \r\nrecreating codeanalysismain_mysql_1 ... done\r\nwait dbenter password: \r\n.enter password: \r\n\r\nbuilding file-server\r\nerror: forbidden path outside the build context: ../../dockerconfs/dockerfile-common ()\r\nerror: no container found for file-server_1\r\nbuilding login-server\r\nerror: forbidden path outside the build context: ../../dockerconfs/dockerfile-common ()\r\nerror: no container found for login-server_1\r\nbuilding analysis-server\r\nerror: forbidden path outside the build context: ../../dockerconfs/dockerfile-common ()\r\nerror: no container found for analysis-server_1\r\nbuilding main-server\r\nerror: forbidden path outside the build context: ../../dockerconfs/dockerfile-common ()\r\nerror: no container found for main-server_1\r\nbuilding main-server\r\nerror: forbidden path outside the build context: ../../dockerconfs/dockerfile-common ()\r"} +{"url": "https://github.com/mediacloud/story-indexer/issues/62", "category": "build: outside build context", "rule": "build.context", "title": "docker/README.md needs enhancement?", "excerpt": "me on ifill using the instructions in docker/readme.md\r\n\r\nbut `docker compose build` give me:\r\n`docker: 'compose' is not a docker command.`\r\n\r\nso it seems that docker/readme.md needs a prequel on getting compose working?\r\nif it's complicated, maybe make a shell script (in the docker directory?)??\n\nis this a [version](https://docs.docker.com/compose/migrate/) issue @thepsalmist? if yes, then the docs need to specify which is the minimum version of docker engine supported.\n\n> version\r\n\r\nyes this is a `compose version` issue, for older versions of compose `docker-compose` should work\r\n\n\ninstalled docker-compose, but get:\r\n```\r\nstep 6/20 : copy ../requirements.txt .\r\ncopy failed: forbidden path outside the build context: ../requirements.txt ()\r\nerror: service 'common_worker' failed to build : build failed\r\n```\n\ni see in pr#65:\r\n> 1. docker: docker must be installed on the host where you plan to set up the swarm. you can download and install docker from docker's official website.\r\n> 2. docker compose: make sure you have docker compose installed, as it's essential for managing multi-container applications. you can install docker compose by following the instructions in the official documentation.\r\n\r\nthat's helpful to know! a url for the \"official documentation\" would be nice!\r\n\r\nmy development server (ifill), which also runs the rss-fetcher staging environment (under dokku) is runni"} +{"url": "https://github.com/CarnegieLearningWeb/UpGrade/issues/274", "category": "build: outside build context", "rule": "build.context", "title": "Local Docker setup build context failing on Linux", "excerpt": "driver \"bridge\"\r\ncreating volume \"upgrade_upgradedbdata\" with default driver\r\nbuilding frontend\r\nsending build context to docker daemon 1.017gb\r\nstep 1/8 : from node:12.22.10-alpine\r\n12.22.10-alpine: pulling from library/node\r\n59bf1c3509f3: pull complete \r\n8769eb813ad5: pull complete \r\n7025e9ac362e: pull complete \r\n1efe07d207fa: pull complete \r\ndigest: sha256:dfa564312367b1a8fca8db7ae4bae102b28e68b39ebcb7b17022c938f105846b\r\nstatus: downloaded newer image for node:12.22.10-alpine\r\n ---> 1b156b4c3ee8\r\nstep 2/8 : workdir /usr/src/app\r\n ---> running in 7aeebc5e4718\r\nremoving intermediate container 7aeebc5e4718\r\n ---> 856dc7e5a1be\r\nstep 3/8 : copy ./../types ./types\r\ncopy failed: forbidden path outside the build context: ../types ()\r\nerror: service 'frontend' failed to build : build failed\r\nmake: *** [makefile:18: default] error 1\r\n```\r\n\r\n_originally posted by @jerith666 in https://github.com/carnegielearningweb/upgrade/issues/266#issuecomment-1049239156_"} +{"url": "https://github.com/moby/buildkit/issues/2671", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "Execs on Merges/Diffs require unlazying non-base inputs with Stargz", "excerpt": "hat `diffapply` can't hardlink between snapshots due to the use of separate fuse mounts for each stargz snapshot and the use of non-fuse mounts for newly created (non-lazy) snapshots. this means it falls back to doing file copies, which works but results in the non-base merge inputs being unlazied.\r\n\r\ntwo options:\r\na. update stargz to more directly support `merge`, with it internally handling the merge implementation.\r\nb. update buildkit's `merge` implementation to use \"overlay merges\" where the merge is implemented by just joining `lowerdir`s together.\r\n\r\n`a.` should be possible but is unfortunate in that it requires major changes to external code.\r\n\r\n`b.` is more appealing because it only requires buildkit updates and may also benefit other snapshotters that could selectively use the same optimization.\r\n\r\nthe main issue with `b.` is that there are several annoying corner cases that can introduce a ton of complication (which is why this approach was originally abandoned and replaced with the hardlink implementation). to explain, the rule with `mergeop` is that the merged snapshot must look the same as if you had exported each of the merge inputs as layers and then unpacked those layers on top of each other in the same order as the merge. `diffop` has a similar rule when `lower` is a snapshot in `upper`'s history. corner cases that arise from this:\r\n\r\n---\r\n\r\n1. [the oci image s"} +{"url": "https://github.com/fenollp/reMarkable-tools/issues/23", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "`docker-compose up --build` fails.", "excerpt": " match \"^[a-za-z0-9_-]+$\": invalid argument, code: 1\r\n * status: failed to parse platform : \"\" is an invalid component of \"\": platform specifier component must match \"^[a-za-z0-9_-]+$\": invalid argument, code: 1\r\n\r\n\r\n```\r\n\n\nseems like $buildplatform is null and likely hasn't been passed in properly. maybe try running `docker_buildkit=1 docker-compose up --build --abort-on-contianer-exit` as that seems to make it work for me.\n\n@eeems thanks, i don't know what that does but the docker container does build and run after that. \n\nfor more information on docker buildkit: https://docs.docker.com/develop/develop-images/build_enhancements/\n\nsorry i just now noticed this issue.\r\n\r\nindeed this requires buildkit. see the root makefile for a complete docker-compose call."} +{"url": "https://github.com/mr-smithers-excellent/docker-build-push/issues/81", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "add buildkit support?", "excerpt": "add buildkit support?\nawesome action all around! just missing one thing and thats buildkit?\r\n\r\nas an example of an everyday docker command not supported by the action currently:\r\n\r\n```\r\ncopy --chown=someuser --chmod=755 somebinary /usr/local/bin/\r\nthe --chmod option requires buildkit. refer to https://docs.docker.com/go/buildkit/ to learn how to build images with buildkit enabled\r\nerror: command failed: docker build -f dockerfile -t someimage:sometag\r\n```\r\n\r\nthen we can have lean and mean dockerfiles that likely can be relied on to build with the action as well as locally?\n\nhi @erzz - thanks for the kind words and enhancement request. i have to admit i have not yet kicked the tires with buildkits yet. it looks like to enable them you must set an environment variable `docker_buildkit=1`. if that's the case, are you thinking this should be a workflow input that defaults to `false`?\n\nsorry for the slow response - my notifications were trimmed a little heav"} +{"url": "https://github.com/aboutcode-org/scancode.io/issues/350", "category": "build: BuildKit required", "rule": "build.buildkit", "title": "Optimize Dockerfiles for faster and smaller builds", "excerpt": "optimize dockerfiles for faster and smaller builds\ncurrent sizes:\r\n- uncompressed: `scancodeio-images-v30.0.1.tar` - 5.15 gb\r\n- compressed: `scancodeio-images-v30.0.1.tar.gz` - 1.76 gb\r\n\r\nsome ideas at https://testdriven.io/blog/docker-best-practices/ and https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/\n\nfrom 1.76 gb to 713m for the compressed tarball with current changes in the https://github.com/nexb/scancode.io/tree/350-docker-optimizations branch\r\nalso, the build is much faster and leverage caching.\n\n```\r\nstep 8/9 : run --mount=type=cache,target=/root/.cache/pip pip install .\r\nerror: service 'web' failed to build : the --mount option requires buildkit. refer to https://docs.docker.com/go/buildkit/ to learn how to build images with buildkit enabled\r\n```\r\n\r\nthe following requires buildkit which is not always enabled depending on the docker version\r\n```\r\n# cache python packages on the local machine\r\nrun --mount=type=cache,target=/root/.cache/pip pip install .\r\n```"} +{"url": "https://github.com/docker/compose/issues/10293", "category": "compose: required variable", "rule": "compose.env", "title": "[BUG] Extra \"invalid interpolation format\" error when specifying mandatory variables", "excerpt": "[bug] extra \"invalid interpolation format\" error when specifying mandatory variables\n### description\r\n\r\nif we use a mandatory variable in a docker-compose.yml file \r\n`mysql_root_password: ${npm_db_root_password:?error message}`\r\nand try to start it up without an .env file we got this message:\r\n```\r\ninvalid interpolation format for services.npm_db.environment.mysql_root_password.\r\nyou may need to escape any $ with another $.\r\nrequired variable npm_db_root_password is missing a value: error message\r\n```\r\n\r\nwe expected just this message:\r\n```\r\nrequired variable npm_db_root_password is missing a value: error message\r\n```\r\n\r\n### steps to reproduce\r\n\r\nour _docker-compose.yml_:\r\n```\r\nversion: \"3\"\r\n\r\nservices:\r\n npm_db:\r\n image: ${npm_db_image:-mariadb:10.5}\r\n restart: unless-stopped\r\n\r\n environment:\r\n mysql_root_password: ${npm_db_root_password:?error message}\r\n\r\n volumes:\r\n - ./volumes/npm_db_data:/var/lib/mysql\r\n\r\n```\r\n\r\nstart file:\r\n```\r\ndocker compose up\r\n```\r\n\r\n### compose version\r\n\r\n```text\r\n# docker compose version\r\ndocker compose version v2.16.0\r\n\r\n# docker-compose version\r\ndocker compose version v2.11.1\r\n```\r\n\r\n\r\n### docker e"} +{"url": "https://github.com/docker/compose/issues/10011", "category": "compose: required variable", "rule": "compose.env", "title": "[BUG] Mandatory variables not throwing errors when not used last", "excerpt": "warning: no blkio throttle.read_iops_device support\r\nwarning: no blkio throttle.write_iops_device support\n```\n\n\n### anything else?\n\nusing docker for windows with wsl2 backend.\n\ni tried to reproduce the issue on a macos aarch64, but it works fine and the env variable is set correctly. i think someone with windows and wsl2 backend, can do a better investigation of the issue.\n\ntried to reproduce with latest release (v2.17.3) and get the expected error:\r\n```\r\n$ docker compose config\r\nwarn[0000] the \"other_path\" variable is not set. defaulting to a blank string. \r\nparsing /users/nicolas/truc/bidule/compose.yaml: error while interpolating services.data.environment.[]: required variable variable_a is missing a value: required variable\r\n```\r\n\r\nsame passing optional variable:\r\n```\r\n$ other_path=foo docker compose config\r\nparsing /users/nicolas/truc/bidule/compose.yaml: error while interpolating services.data.environment.[]: required variable variable_a is missing a value: required variable\r\n```\r\n\r\nso i guess this issue was fixed in the meantime, feel free to comment or create a new issue if we missed something here"} +{"url": "https://github.com/microsoft/vscode-docker/issues/3437", "category": "compose: required variable", "rule": "compose.env", "title": "The options.env property on VS Code tasks seems to be ignored by Docker tasks", "excerpt": "ith the dedicated `docker-compose` task type, the environment variable is not resolving in the `docker-compose.yaml` file:\r\n\r\n```json\r\n{\r\n \"label\": \"compose up: product 1\",\r\n \"type\": \"docker-compose\",\r\n \"dockercompose\": {\r\n \"up\": {\r\n \"detached\": true,\r\n \"build\": true\r\n },\r\n \"files\": [\r\n \"${workspacefolder}/docker-compose.yaml\"\r\n ],\r\n \"envfile\": \"${workspacefolder}/.env\"\r\n },\r\n \"options\": {\r\n \"env\": {\r\n \"user_email\": \"${input:useremail}\"\r\n }\r\n }\r\n}\r\n```\r\n\r\nrunning this gives:\r\n\r\n```none\r\ninvalid interpolation format for services.product1.environment.[]: \"required variable user_email is missing a value: admin user email is missing or empty\".\r\n```\n\nthanks for the detailed report! we should get this fixed. i don't expect it will be _too_ difficult. i'd like to also fix it for `docker-build` (although `buildargs` is kinda similar) and `docker-run` tasks.\n\n@alexr00 the `options` field on the task is not coming through with the `resolveddefinition` in the `customexecution`. do you know why?\n\ni will let @alexr00 chime in, but i noticed that, unlike `processexecution` and `shellexecution`, `customexecution` class definition does not have `options` property...\n\nthe `taskdefinition` that's passed into the `customexecution` callback is only composed of the properties that are part"} +{"url": "https://github.com/open-condo-software/open-condo-platform/issues/2", "category": "compose: required variable", "rule": "compose.env", "title": "invalid interpolation with the command \"docker-compose up -d postgresdb\"", "excerpt": "invalid interpolation with the command \"docker-compose up -d postgresdb\"\nit returns:\r\n\"invalid interpolation format for services.app.environment.worker_redis_url: \"required variable docker_compose_worker_redis_url is missing a value: environment docker_compose_worker_redis_url needs to be set (check [reademe.md](https://reademe.md/))!\". you may need to escape any $ with another $.\".\r\n\r\ni'm trying to add the graphql layer in the app. i'm following the \"get starter\" path, but i can't overcome this problem "} +{"url": "https://github.com/SolRacht/WritingComDownloader/issues/3", "category": "compose: variable not set", "rule": "compose.env", "title": "Total newbie here, experiencing problems...", "excerpt": "total newbie here, experiencing problems...\ni can get as far as creating a \"docker-compose build\" , but after that things get hazy. \r\n\r\nthis is the log from my cmd window, can you tell me where i'm going wrong when trying to scrape? apologies in advance if this is a dumb question or if this is the completely wrong way to get in contact with you.\r\n\r\n\"c:\\windows\\system32>cd c:\\users\\a****\\downloads\\writingcomdownloader-master\\writingcomdownloader-master\\db\r\n\r\nc:\\users\\a****\\downloads\\writingcomdownloader-master\\writingcomdownloader-master\\db>docker-compose build\r\nwarning: the db variable is not set. defaulting to a blank string.\r\nwarning: the render variable is not set. defaulting to a blank string.\r\nbuilding scrape\r\nstep 1/6 : from openjdk:16-jdk-alpine3.12\r\n ---> c74f5761e8f8\r\nstep 2/6 : env scala_version=2.13.4 scala_home=/usr/share/scala sbt_version=1.4.5 path=\"/usr/local/sbt/bin/:$path\"\r\n ---> using cache\r\n ---> 2bf8b8d7cb74\r\nstep 3/6 : run apk add --no-cache --virtual=.build-dependencies wget ca-certificates && apk add --no-cache bash && cd \"/tmp\" && wget --no-verbose \"https://downloads.typesafe.com/scala/${scala_version}/scala-${scala_version}.tgz\" && tar xzf \"scala-${scala_version}.tgz\" && mkdir \"${scala_home}\" && rm \"/tmp"} +{"url": "https://github.com/actions/runner-images/issues/2609", "category": "compose: variable not set", "rule": "compose.env", "title": "Correct Node.js build failed after re-running. Docker compose environment variables error", "excerpt": "correct node.js build failed after re-running. docker compose environment variables error\n**description** \r\ni have a trivial github actions script where i install yarn and run docker compose files with docker compose --env-file command.\r\ni've restarted already successful build and got an error like:\r\n`\r\nthe node_env variable is not set. defaulting to a blank string. \r\n...\r\nthe workerpool_max_thread variable is not set. defaulting to a blank string.\r\nthe compose file '././deploy/containers/development/docker-compose.yml' is invalid because:\r\nservices.mongodb.ports contains an invalid type, it should be a number, or an object\r\nservices.node-app.ports contains an invalid type, it should be a number, or an object\r\nservices.redis.ports contains an invalid type, it should be a number, or an object\r\nerror command failed with exit code 1.\r\n...\r\n`\r\ndocker compose port section is working locally and as i said worked on actions before:\r\n`\r\n...\r\n ports:\r\n - ${node_port}:3000\r\n depends_on:\r\n...\r\n`\r\ni alre"} +{"url": "https://github.com/naim94a/lumen/issues/19", "category": "compose: variable not set", "rule": "compose.env", "title": "thread 'main' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', lumen/src/main.rs:297:9", "excerpt": "30a436877/library/core/src/panicking.rs:92:14\r\n 15: 0x5569287a2192 - core::option::expect_failed::h8be1ca96ca0d69ca\r\n at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/core/src/option.rs:1292:5\r\n 16: 0x556928899363 - lumen::main::ha4258b6c1e83748c\r\n 17: 0x55692880a946 - std::sys_common::backtrace::__rust_begin_short_backtrace::h567c94c8ce62918a\r\n 18: 0x55692888e538 - main\r\n 19: 0x7f231411f2e1 - __libc_start_main\r\n 20: 0x55692870d93a - _start\r\n 21: 0x0 - \r\naborted\r\nroot@user123:~/lumen/lumen/bin/release# \r\n```\n\n\r\n- docker \r\n```\r\nroot@user123:~/lumen2/lumen# docker-compose up\r\nwarning: the pkcspasswd variable is not set. defaulting to a blank string.\r\nbuilding with native build. learn about native build in compose here: https://docs.docker.com/go/compose-native-build/\r\nrecreating lumina-postgres ... done\r\nrecreating lumen_lumina_1 ... done\r\nattaching to lumina-postgres, lumen_lumina_1\r\nlumina_1 | connection to db 5432 port [tcp/*] succeeded!\r\nlumina_1 | no custom config.toml found, creating secure default.\r\nlumina_1 | no custom tls key with p12/pfx extension in the custom mount directory.\r\nlumina_1 | generating a rsa private key\r\nlumina-postgres | \r\nlumina-postgres | postgresql database directory appears to contain a database; skipping initialization\r\nlumina-postgres | \r\nlumina-post"} +{"url": "https://github.com/skalenetwork/skale-node/issues/184", "category": "compose: variable not set", "rule": "compose.env", "title": "Getting docker-compose.yml invalid error", "excerpt": "getting docker-compose.yml invalid error\nsome validators getting this error during the node update. \n\n`2021-01-21 13:56:56,596 - tools.helper - info - running: ['bash', '/tmp/_meigfwedu/data/datafiles/update.sh']\n2021-01-21 13:56:57,502 - tools.helper - info - removing node containers ...\nremoving api, sla, bounty, admin containers ...\n2021-01-21 13:56:57,503 - tools.helper - error - error during shell execution:\n2021-01-21 13:56:57,503 - tools.helper - error - the backup_run variable is not set. defaulting to a blank string.\nthe compose file '/root/.skale/config/docker-compose.yml' is invalid because:\nunsupported config option for services.advisor: 'cpu_shares'\nunsupported config option for services.skale-admin: 'cpu_shares'\n2021-01-21 13:56:57,504 - core.node - error - update script process errored\ntraceback (most recent call last):\n file \"core/node.py\", line 188, in update\n file \"tools/helper.py\", line 59, in run_cmd\n file \"subprocess.py\", line 444, in check_returncode\nsubprocess.calledprocesserror: command '['bash', '/tmp/_meigfwedu/data/datafiles/update.sh']' returned non-zero exit status 1.`\n\n\n\n\u2506issue is synchronized with this [jira task](https://skalela"} +{"url": "https://github.com/marcelo-ochoa/docker-volume-plugins/issues/3", "category": "compose: unsupported property", "rule": "compose.version", "title": "Additional property name is not allowed", "excerpt": "additional property name is not allowed\n**describe the bug**\r\ni'm simply trying to use this plugin to mount a glusterfs volume. i configured my compose file exactly as described in the documentation\r\n```\r\nvolumes:\r\n jellyfin-data:\r\n driver: glusterfs\r\n name: \"swarm-volumes/jellyfin-beta_jellyfin-data\"\r\n```\r\nafter running docker stack deploy it throws this error:\r\n`volumes.jellyfin-data additional property name is not allowed`\r\n\r\n\r\n**to reproduce**\r\nsteps to reproduce the behavior:\r\n1. install plugin\r\n2. add volume to compose file\r\n3. docker stack deploy\r\n4. see error\r\n\r\n**expected behavior**\r\nthe stack should be deployed and volume mounted without error.\r\n\r\n**server (please complete t"} +{"url": "https://github.com/lyst/lightfm/issues/612", "category": "compose: unsupported property", "rule": "compose.version", "title": "LightFM fails to build Docker Container on Apple M1 ", "excerpt": "lightfm fails to build docker container on apple m1 \nwhile running\r\n\r\ndocker-compose build lightfm \r\n\r\nthe following is returned\r\n(root) additional property lightfm is not allowed\r\n\r\ninitially i thought it was a mis-configuration of the docker-compose.yml file . \r\nhowever the same config works fine on apple intel . \r\n \r\n\n\nthis is what i did.\r\n\r\n1) edit _docker-compose.yml_ by inserting at the top of the file \r\n `services:`\r\nindent by one everything underneath it \r\n\r\n2) edit the first line of _dockerfile_ like so\r\n`from --platform=linux/amd64 ubuntu:16.04`\r\n\r\n3) run\r\n_docker-compose build lightfm_\r\n\r\nit worked on my m1. hope it does on yours. \r\n\r\n\r\n"} +{"url": "https://github.com/grpc-ecosystem/grpc-spring/issues/588", "category": "compose: unsupported property", "rule": "compose.version", "title": "Grpc server started but cannot connect", "excerpt": "eeter/sayhello\". it was \"error\": \"14 unavailable: failed to connect to all addresses\" instead.\r\n\r\n![image](https://user-images.githubusercontent.com/20805843/135182669-85cece53-19d0-422e-a9c6-a7463ec0aadf.png)\r\n\n\nwould be appreciated that if you don't mind help me to check through my app. it locates at https://github.com/jeffreychu-org/kotlin_example_app in grpc-issue branch. \r\n\r\nit may tested simply be \r\n1. cd /rdbms_service\r\n2. docker-compose up -d to start the postgresql and redis\r\n3. simple start the spring boot app and it will trigger the other project grpc_lib to generate the grpc stub for use\r\n\r\nthis issue struggle me a few days. many thanks. cheers. \n\n> $ docker compose up\r\n> (root) additional property postgres is not allowed\r\n\r\ni have trouble starting the docker compose on my computer (i haven't used it here before).\r\nmaybe windows doesn't like docker compose?\r\n\r\ni still managed to start the application by stripping it of the other components.\r\nffr: please reference only minimal workign examples not a project that showcases all.\r\n\r\n````txt\r\n2021-09-29 21:38:40.805 info 2888 --- [ main] n.d.b.g.s.s.abstractgrpcserverfactory : registered grpc service: grpc.health.v1.health, bean: grpchealthservice, class: io.grpc.services.healthserviceimpl\r\n2021-09-29 21:38:40.805 info 2888 --- [ main] n.d.b.g.s.s.abstractgrpcserverfactory : registered grpc se"} +{"url": "https://github.com/fastapi/full-stack-fastapi-template/issues/336", "category": "compose: unsupported property", "rule": "compose.version", "title": "Deploy script adds disallowed property name to network in docker-stack.yml", "excerpt": "deploy script adds disallowed property name to network in docker-stack.yml\nwhen running the _deploy.sh_ script `docker stack deploy -c ...` fails with:\r\n> networks.traefik-public additional property name is not allowed\r\n\r\nthe following gets added to the docker-stack.yml by `docker-compose -f docker-compose.yml config > docker-stack.yml`\r\n\r\n`networks:\r\ntraefik-public:\r\n external: true\r\n name: traefik-public`\r\n\r\nthis goes for docker-compose file version 3.3 and 3.6.\r\n\r\nif i remove the `name: traefik-public` line everything works fine. i am not that experienced with docker networks but why is config adding a property that docker stack deploy does not allow?\r\n\r\n----------------------------------------------\r\nubuntu 20.04\r\ndocker version 20.10.2, build 2291f61\r\ndocker-compose version 1.27.4, build 40524192\r\ndocker-py version: 4.3.1\r\ncpython version: 3.7.7\r\nopenssl v"} +{"url": "https://github.com/freeCodeCamp/chapter/issues/471", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "Docs: Add Troubleshooting for CONTRIBUTING.md Steps", "excerpt": "t-a-time, like _npm run db:drop_ then _npm run db:sync_ and then _npm run db:seed_. alternatively, a paid plan on elephantsql would avoid this issue. - via https://github.com/freecodecamp/chapter/issues/762\r\n\r\n## general docker troubleshooting\r\n- [linux](https://docs.docker.com/engine/install/linux-postinstall/)\r\n- [windows](https://docs.docker.com/docker-for-windows/troubleshoot/)\r\n- [mac](https://docs.docker.com/docker-for-mac/troubleshoot/)\r\n- [ ] make sure docker isn't already running and bound to port 54320 - error: for chapter-npx-test_db_1 cannot start service db: driver failed programming external connectivity on endpoint chapter-npx-test_db_1 (....): bind for 0.0.0.0:54320 failed: port is already allocated. error: for db cannot start service db: driver failed programming external connectivity on endpoint chapter-npx-test_db_1\r\n- [ ] to shut down docker on linux, press ctrl + c in the terminal where it was started.\r\n- [ ] to purge old images, which can sometimes be the source of errors, run `docker-compose rm && docker image prune -a`\r\n\r\n\r\n### wsl\r\n- [ ] [general wsl troubleshooting](https://docs.microsoft.com/en-us/windows/wsl/install-win10#troubleshooting-installation)\r\n- [ ] \"wsl2 installation is incomplete\" - follow the steps to install the missing component\r\n- [ ] wslregisterdistribution failed with error: 0x80070057 - this is common on older cpus which does not "} +{"url": "https://github.com/dosvath/kerberos-containers/issues/1", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "error while starting the continer ", "excerpt": " not already exist. to rebuild this image you must use `docker-compose build` or `docker-compose up --build`.\r\ncreating ssh-container_ssh-server_1 ...\r\ncreating ssh-container_ssh-server_1 ... error\r\nwarning: host is already in use by another container\r\n\r\nerror: for ssh-container_ssh-server_1 cannot start service ssh-server: driver failed programming external connectivity on endpoint ssh-container_ssh-servercreating ssh-container_ssh-client_1 ... done\r\n\r\nerror: for ssh-server cannot start service ssh-server: driver failed programming external connectivity on endpoint ssh-container_ssh-server_1 (47f168bceef310f45d41f5e686ba297c32bfbd814d3da52a6b703c2c05a5de77): bind for 0.0.0.0:2222 failed: port is already allocated\r\nerror: encountered errors while bringing up the project.\r\n\r\nerberos-containers/kdc-ssh-server# docker-compose up -d\r\nrecreating kdc-ssh-server_kdc-ssh-server_1 ...\r\nrecreating kdc-ssh-server_kdc-ssh-server_1 ... error\r\n\r\nerror: for kdc-ssh-server_kdc-ssh-server_1 cannot start service kdc-ssh-server: driver failed programming external connectivity on endpoint kdc-ssh-server_kdc-ssh-server_1 (69c76baa1cae192eb21606588aad5c8d97abf9242ae3883236f52c31a6f1a55f): bind for 0.0.0.0:88 failed: port is already allocated\r\n\r\nerror: for kdc-ssh-server cannot start service kdc-ssh-server: driver failed programming external connectivity on endpoint kdc-ssh-server_kdc-ssh-server_"} +{"url": "https://github.com/PrefectHQ/prefect/issues/4147", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "\"prefect server start --detach\" not terminate process, when server port other, than 4200", "excerpt": " ... done\r\npulling ui ... done\r\ncreating network \"prefect-server\" with the default driver\r\ncreating t_postgres_1 ... done\r\ncreating t_hasura_1 ... done\r\ncreating t_graphql_1 ... done\r\ncreating t_apollo_1 ...\r\ncreating t_apollo_1 ... error\r\nwarning: host is already in use by another container\r\n\r\nerror: for t_apollo_1 cannot start service apollo: driver failed programming external connectivity on endpoint t_apollo_1 (cda92d3d43e\r\ncreating t_towel_1 ... done\r\n\r\nerror: for apollo cannot start service apollo: driver failed programming external connectivity on endpoint t_apollo_1 (cda92d3d43ef8ab920138f6e9f74bd678f34f62d54df41b3ac11905787ea56a3): \r\nbind for 0.0.0.0:4201 failed: port is already allocated\r\n....\r\n```\r\n\r\n```\r\n$ docker ps | grep 4201\r\nb1aed8ae85c7 prefecthq/server:core-0.14.9 \"bash -c 'prefect-se\u2026\" 5 minutes ago up 5 minutes (healthy) 0.0.0.0:4201->4201/tcp t_graphql_1\r\n```\r\n\n\ni have the same issue, did someone managed to find a solution ?\r\n\r\n\n\nhey @jeremysrgt \r\n\r\n4201 is in use by the graphql container. setting the `--server-port` to something else (like 4202) works fine.\n\nhi @madkinsz, thanks for your quick reply\r\ni\u2019m setting the server port to 9000 but the problem is that the -d flag doesn\u2019t work if the server port is set to something else that the default one \n\nah alright, the scope of this issue is a little unclear as the original user"} +{"url": "https://github.com/prisma/orm/issues/5304", "category": "port already allocated", "rule": "ports.conflict,ports.host", "title": "Prisma CLI installation hangs indefinitely inside of docker (Kernel 5.10)", "excerpt": "exus@1.0.0\" has unmet peer dependency \"graphql@^14.5.8 || 15.x\".\r\nwarning \" > nexus-plugin-prisma@0.28.0\" has incorrect peer dependency \"@prisma/client@2.14.x\".\r\nwarning \" > nexus-plugin-prisma@0.28.0\" has unmet peer dependency \"graphql@^15.3.0\".\r\n[4/4] building fresh packages...\r\ndone in 69.98s.\r\necho \"up\"\r\nup\r\ndocker-compose up -d\r\ncreating prismapoc-db ... \r\ncreating prismapoc-db ... error\r\nwarning: host is already in use by another container\r\n\r\ncreating prismapoc-api ... done\r\n\r\nerror: for db cannot start service db: driver failed programming external connectivity on endpoint prismapoc-db (38c4f78d4294d638f65c7f83cd364386a45c3a92d81625b678a5626bafb7b011): bind for 0.0.0.0:5432 failed: port is already allocated\r\nerror: encountered errors while bringing up the project.\r\n```\r\nit also works if i do `docker-compose down -v --rmi all --remove-orphans` before.\r\n\r\nnotes:\r\n- it took 69.98s for the build steps for me where dependencies are downloaded / installed.\r\n- the db errors because i already have a postgres instance locally but that seems irrelevant to this issue\r\n- nexus-plugin-prisma doesn't support 2.17.0 at the moment, only 2.16.0, see https://github.com/graphql-nexus/nexus-plugin-prisma/releases i tried having those versions in sync here, and it works as well https://github.com/jolg42/prisma-poc/commit/704741aea1afa5d427f955ec1bc600ecb287ecd3\r\n\r\nmaybe @pantharshit00 can "} +{"url": "https://github.com/k0sproject/k0s/issues/635", "category": "address already in use", "rule": "ports.host", "title": "k0s running on Fedora 33 with containerd crashing", "excerpt": "failedscheduling 32m (x10 over 40m) default-scheduler 0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate.\r\n```\r\n\r\n**additional context**\r\n\r\nthis is the ourput i collected over 1min grepping for `error`.\r\n\r\n```bash\r\n\u279c downloads sudo ./k0s-v0.9.1-amd64 server -c \"${home}/.k0s/k0s.yaml\" --enable-worker --debug | grep -i error\r\n[sudo] password for filbot: \r\ntime=\"2021-01-18 18:24:08\" level=info msg=\"error: failed to run the master server: failed to get uds listener: failed to listen(unix) name /var/lib/k0s/run/konnectivity-server/konnectivity-server.sock: listen unix /var/lib/k0s/run/konnectivity-server/konnectivity-server.sock: bind: address already in use\" component=konnectivity\r\ntime=\"2021-01-18 18:24:08\" level=info msg=\" --alsologtostderr log to standard error as well as files\" component=konnectivity\r\ntime=\"2021-01-18 18:24:08\" level=info msg=\" --logtostderr log to standard error instead of files (default true)\" component=konnectivity\r\ntime=\"2021-01-18 18:24:08\" level=info msg=\"e0118 18:24:08.391051 23336 main.go:69] error: failed to run the master server: failed to get uds listener: failed to listen(unix) name /var/lib/k0s/run/konnectivity-server/konnectivity-server.sock: listen unix /var/lib/k0s/run/konnectivity-server/konnectivity-server.sock: bind: address already "} +{"url": "https://github.com/diyhue/diyHue/issues/561", "category": "address already in use", "rule": "ports.host", "title": "Light problem", "excerpt": "you through this issue, please consider submitting\r\na pull request to our documentation to help other! https://github.com/diyhue/readthedocs\r\n\r\nbasic github comment tutorial:\r\n1. logs\r\nwhen pasting logs or code, type logs like so with ``` on either side.\r\n```\r\nsudo ./hueemulator3.py\r\nexception in thread thread-6:\r\ntraceback (most recent call last):\r\n file \"/usr/lib/python3.7/threading.py\", line 917, in _bootstrap_inner\r\n self.run()\r\n file \"/usr/lib/python3.7/threading.py\", line 865, in run\r\n self._target(*self._args, **self._kwargs)\r\n file \"/opt/hue-emulator/functions/entertainment.py\", line 9, in entertainmentservice\r\n serversocket.bind(('127.0.0.1', 2101))\r\noserror: [errno 98] address already in use\r\n\r\nexception in thread thread-8:\r\ntraceback (most recent call last):\r\n file \"/usr/lib/python3.7/threading.py\", line 917, in _bootstrap_inner\r\n self.run()\r\n file \"/usr/lib/python3.7/threading.py\", line 865, in run\r\n self._target(*self._args, **self._kwargs)\r\n file \"./hueemulator3.py\", line 1932, in run\r\n httpd = server_class(server_address, handler_class)\r\n file \"/usr/lib/python3.7/socketserver.py\", line 452, in __init__\r\n self.server_bind()\r\n file \"/usr/lib/python3.7/http/server.py\", line 137, in server_bind\r\n socketserver.tcpserver.server_bind(self)\r\n file \"/usr/lib/python3.7/socketserver.py\", line 466, in server_bind\r\n self.socket.bind(self.se"} +{"url": "https://github.com/snsinfu/reverse-tunnel/issues/9", "category": "address already in use", "rule": "ports.host", "title": "Docker Image Version", "excerpt": "79a4c3ae4ecd33b7c078631d3424137ff332d7897ecd6e9ddee28df138a0064\" \\\r\n-e rtun_forward=\"10022/tcp:127.0.0.1:22\" \\\r\nsnsinfu/rtun\r\n```\n\nhi @snsinfu .\r\n\r\ni tested this with --net=host argument, the agent manage to connect to gateway,create tunnel and i can shh to the device via the new port forwrd ip and port.\r\n\r\nhowever, if i exit it (ctrl+z) from that agent docker, and reconnect back. i cant connect back with the port forward ip and port. the error at agent was \" agent error \"websocket: close 1000 (normal)\" - recovering...\" and the error ate gateway was \"{\"time\":\"2021-02-04t15:02:38.022768508z\",\"level\":\"error\",\"prefix\":\"echo\",\"file\":\"responder.go\",\"line\":\"42\",\"message\":\"listen tcp :10022: bind: address already in use\"}\"\r\n\r\nany idea why this thing occured? \r\n\r\nthanks for your feedback @snsinfu \n\nyeah, i see similar errors. in my case, the agent fails two times and eventually recovers in 20 seconds or so.\r\n\r\n```\r\n$ docker run --net=host -e rtun_gateway='ws://localhost:9000' -e rtun_key='sample' -e rtun_forward='8080/tcp:localhost:22' snsinfu/rtun\r\n2021/02/04 17:07:24 listening on remote port: 8080/tcp\r\n2021/02/04 17:07:24 agent error \"websocket: close 1000 (normal)\" - recovering...\r\n2021/02/04 17:07:34 listening on remote port: 8080/tcp\r\n2021/02/04 17:07:34 agent error \"websocket: close 1000 (normal)\" - recovering...\r\n2021/02/04 17:07:44 listening on remote port: 8080/tcp\r\n2021/02/04"} +{"url": "https://github.com/mpgirro/docker-pihole-unbound/issues/13", "category": "address already in use", "rule": "ports.host", "title": "(network.c.313) can't bind to socket: 192.168.1.2:80 Address already in use ", "excerpt": "(network.c.313) can't bind to socket: 192.168.1.2:80 address already in use \nhi,\r\n\r\ni tried your new \"one-container\" version. the container is starting, but i run into the following loop:\r\n\r\nstarting lighttpd\r\n(network.c.313) can't bind to socket: 192.168.1.2:80 address already in use \r\nstopping lighttpd\r\nlighttpd: no process found\r\n\r\nmy .env file looks like this (serverip=synology ip; rev_server_target=fritzbox)\r\n\r\nserverip=192.168.1.2\r\ntz=europe/berlin\r\nwebpassword=12345678\r\nrev_server=true\r\nrev_server_domain=local\r\nrev_server_target=192.168.1.1\r\nrev_server_cidr=192.168.0.0/16\r\n\r\ni don't know, what to do and hope you can help me.\r\n\r\nregards\n\nthis means your host system is already exposing a service on port 80, so it\u2019s conflicting with the co"} +{"url": "https://github.com/EMMC-ASBL/oteapi-services/issues/14", "category": "rootless privileged port", "rule": "ports.host", "title": "Maybe use podman instead of Docker", "excerpt": "man: https://podman.io/\r\n\r\ndocker desktop and docker hub are becoming costly options.\r\npodman might be the solution for replacing docker desktop as a docker engine diy drop-in alternative. while some ease-of-use might be lost, it should be a secure and powerful alternative to the standard docker engine.\r\ngithub packages or gitlab container registry or other might be the best alternative for docker hub.\n\ni think it is a good idea. but i would prefer if we can come up with a solution that allow to run podman rootless. \r\n\r\nhowever, when i try to run `port=8080 podman-compose up`, i get the following error:\r\n```\r\nerro[0003] error starting some container dependencies \r\nerro[0003] \"rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied\" \r\n```\r\nnot sure why it uses port 80 when i explicitly asks for 8080. but it looks like a solvable problem.\n\n> not sure why it uses port 80 when i explicitly asks for 8080. but it looks like a solvable problem.\r\n\r\nindeed. just as a reminder here - this particular thing was \"solved\" in #15, where the default port is now 8080 (instead of 80).\n\nwill close this for now as we will continue to use docker internally and will not focus on support for podman or similar. also, docker-compose"} +{"url": "https://github.com/podman-container-tools/podman/issues/13426", "category": "rootless privileged port", "rule": "ports.host", "title": "Rootless podman and authbind", "excerpt": "rt_start (i just need to exposed few ports) to or firewall rules (i use firewalld and local processes dont follow firewalld port forwarding without adding iptables/nft rules in parrallel, no process attached to port with netstat)\r\nis it podman internals which refuse to bind before trying it or some podman specificity ?\r\n\r\n**steps to reproduce the issue:**\r\n1. ```touch /etc/authbind/byport/80```\r\n2. ```chown debian /etc/authbind/byport/80```\r\n3. ```chmod 700 /etc/authbind/byport/80```\r\n4. ```authbind podman run -d -p 80:80 docker.io/traefik/whoami```\r\nor\r\n5. ```authbind --deep podman run -d -p 80:80 docker.io/traefik/whoami```\r\n\r\n**describe the results you received:**\r\n```error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied```\r\n\r\n**describe the results you expected:**\r\nrun this container on port 80 as expected\r\n\r\n**additional information you deem important (e.g. issue happens only occasionally):**\r\nit works well with others softwares like python's http.server\r\n```authbind python3 -m http.server 80```\r\n\r\n**output of `podman version`:**\r\ndebian 11 podman by apt\r\n```\r\nversion: 3.0.1\r\napi version: 3.0.0\r\ngo version: go1.15.9\r\nbuilt: thu jan 1 01:00:00 1970\r\nos/arch: linux/amd64\r\n```\r\n"} +{"url": "https://github.com/podman-container-tools/podman/issues/18205", "category": "rootless privileged port", "rule": "ports.host", "title": "network resources are leaked when error happens during setup", "excerpt": "network resources are leaked when error happens during setup\n### issue description\r\n\r\nthe network resources are leaked when there is a error during the initial container setup process.\r\nthis effects both netavark and cni.\r\n\r\n### steps to reproduce the issue\r\n\r\n\r\nmake sure to not have containers running and try this as rootless\r\n1. `podman network create test1`\r\n2. `podman run -p 80:80 --network podman1 alpine ip a`\r\nwhich correctly fails with:\r\n```\r\nerror: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied\r\n```\r\n3. `ps aux`\r\n\r\n\r\n### describe the results you received\r\n\r\nsee that aardvark-dns is still running, or dnsmasq when using cni.\r\n\r\n\r\n\r\n\r\n### describe the results you expected\r\n\r\npodman should teardown the network correctly on errors.\r\n\r\n### podman info output\r\n\r\n```yaml\r\nlatest main branch\r\n```\r\n\r\n\r\n### podman in a container\r\n\r\nno\r\n\r\n### privileged or rootless\r\n\r\nnone\r\n\r\n### upstream latest release\r\n\r\nyes\r\n\r\n### additional environment details\r\n\r\n_no response_\r\n\r\n### additional i"} +{"url": "https://github.com/podman-container-tools/podman/issues/17028", "category": "rootless privileged port", "rule": "ports.host", "title": "[Bug]: Disable automatic publishing of all ports for kube play", "excerpt": " in the name of sec. (edit: that means before 5.0)\n\nwe make the port available when the user didn't ask for it, so yes this very much is a security problem if the user is not aware of the behaviour. \n\nok, i am in favor of changing the behavior before 5.0.\r\n@containers/podman-maintainers please speak up if you disagree.\n\ni agree change the behavior now.\n\nso the flag should be `false` by default, but the defalt behaviour of this flag can be changed in the `containers.conf` right?\n\nsgtm\n\ni also just got bit by this issue after upgrading from el `9.1` -> `9.2` with podman being upgraded from version `4.2` to `4.4`, with the result, that all web containers refused to start with\r\n\r\n`rootlessport cannot expose privileged port 80`\r\n\r\nfrom my point of view that was already a breaking change which should be reverted sooner then later.\r\n\r\nalso comparing it with the behavior of docker compose, where the ports also must be explicitly defined, users migrating from compose to podman will most likely also run into this issue.\r\n\r\nin my testing setup here all pods are using a bridge network, where the pods should listen to and external access is only possible through an ingress pod communicating over the bridge network.\r\n\r\nrunning rootless without adjusting the `net.ipv4.ip_unprivileged_port_start` setting luckily saved me here, otherwise the services (ignoring the port conflicts), would have b"} +{"url": "https://github.com/sensepost/routopsy/issues/1", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "Mounting Errors in Toolkit and Playground", "excerpt": "/python3/dist-packages/docker/errors.py\", line 31, in create_api_error_from_http_exception\r\n raise cls(e, response=response, explanation=explanation)\r\ndocker.errors.apierror: 400 client error: bad request (\"oci runtime create failed: container_linux.go:349: starting container process caused \"process_linux.go:449: container init caused \\\"rootfs_linux.go:58: mounting \\\\\\\"/tmp/config/daemons\\\\\\\" to rootfs \\\\\\\"/var/lib/docker/overlay2/55fe5be46f48ba8faaa5bd20ec3c0081f8b4a9eca2006d2d84b0617744e91b9c/merged\\\\\\\" at \\\\\\\"/var/lib/docker/overlay2/55fe5be46f48ba8faaa5bd20ec3c0081f8b4a9eca2006d2d84b0617744e91b9c/merged/etc/frr/daemons\\\\\\\" caused \\\\\\\"not a directory\\\\\\\"\\\"\": unknown: are you trying to mount a directory onto a file (or vice-versa)? check if the specified host path exists and is the expected type\")\r\n\r\nthe error is basicaly the same i had with the compose files.\r\ni assume the issues is within the container creation. sorry if this is something obvious im missing but i am new to docker. thanks!\r\n\r\n\n\nhi, thanks for notifying us about the issue. we have pushed the fixes and its working our side. let us know if its working your side too?\n\nyes the version-fix resolved the issue, thanks! "} +{"url": "https://github.com/docker/compose/issues/8305", "category": "bind: dir onto file", "rule": "mounts.bind", "title": "Windows: missing secrets file creates file-named directory", "excerpt": "llo-world: invalid mount config for type \"bind\": bind source path does not exist: /run/desktop/mnt/host/c/.../my_secret.txt\r\n\t ```\r\n* deleting the folder and then creating a text file in its place results in the following failure:\r\n \t```bash\r\n\t > docker-compose up\r\n\t starting temp_hello-world_1 ... error\r\n\t \r\n\t error: for temp_hello-world_1 cannot start service hello-world: oci runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting \"/run/desktop/mnt/host/c/.../my_secret.txt\" to rootfs at \"/run/secrets/my_secret\" caused: mount through procfd: not a directory: unknown: are you trying to mount a directory onto a file (or vice-versa)? check if the specified host path exists and is the expected type\r\n\t ```\r\n* restarting docker reverts behavior back to initial behavior.\r\n* behavior is the same when run from a wsl terminal with docker client installed (connected up to docker for windows).\n\n@stale not stale.\n\nthe above replicated on:\r\ndocker desktop: 4.4.4 (73704\r\ndocker engine: 20.10.12\r\ndocker compose: 1.29.2\n\nfyi docker compose v1, the python version, reached end-of-life, please use compose v2 instead and let us know if you still have the problem with this version.\r\nyou can simply switch to compose v2 by checking the checkbox in docker desktop preferences\r\n\r\n\r\n**description**\r\n\r\nafter installing patches, we couldn't start some containers:\r\n\r\n```\r\n[root@ibmd13awx01 awx]# docker start awx_redis\r\nerror response from daemon: oci runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:59: mounting \"/tmp/awxcompose/redis.conf\" to rootfs at \"/var/lib/docker/overlay2/8b87878234d9f806633c4e714fea086459ba04f3ea43d297613107fcb23cc7ee/merged/usr/local/etc/redis/redis.conf\" caused: not a directory: unknown: are you trying to mount a directory onto a file (or vice-versa)? check if the specified host path exists and is the expected type\r\nerror: failed to start containers: awx_redis\r\n```\r\n\r\n\r\n\r\n**steps to reproduce the issue:**\r\n1.\r\n2.\r\n3.\r\n\r\n```\r\n[root@ibmd13awx01 awx]# docker start awx_redis\r\nerror response from daemon: oci runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:59: mounting \"/tmp/awxcompose/redis.conf\" to rootfs at \"/var/lib/docker/overlay2/8b87878234d9f806633c4e714fea086459ba04f3ea43d297613107fcb23cc7ee/merged/usr/local/etc/redis/redis"} +{"url": "https://github.com/docker-archive/compose-cli/issues/1543", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "invalid mount config for type \"bind\": bind source path does not exist: ", "excerpt": "invalid mount config for type \"bind\": bind source path does not exist: \n\r\n**description**\r\n\r\nwhen running with docker compose: trying to mount a folder into a container throws an error if the folder does not already exist in the host.\r\nwhen running with docker-compose: trying to mount a folder into a container automatically creates the folder if the folder does not already exist\r\n\r\nthe expectation would be that both commands work the same way\r\n\r\n**steps to reproduce the issue:**\r\n1. add a valid volume to a service in your docker-compose file but do not create the folder in the host file system\r\n2. `docker compose up`\r\n3. error is displayed\r\n4. `docker-compose up`\r\n5. application comes up normally\r\n\r\n**describe the results you r"} +{"url": "https://github.com/kubernetes/kubernetes/issues/98492", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "in-tree storage driver for Windows has issues when create container: mount point does not exist", "excerpt": "in-tree storage driver for windows has issues when create container: mount point does not exist\nstarting from v1.20, many storage tests with in-tree driver start to flake. checking the log, it shows that volume attach/mount all succeeded, but when creating container, get the error message\r\n\r\nfailed: error: error response from daemon: invalid volume specification: 'c:\\var\\lib\\kubelet\\pods\\7173f517-76c4-48e7-894d-bd9e6d92ca51\\volumes\\kubernetes.io~azure-disk\\pvc-6ece396b-2beb-4fc2-8265-5deed43d9e90:c:/mnt/test-1': invalid mount config for type \"bind\": bind source path does not exist: c:\\var\\lib\\kubelet\\pods\\7173f517-76c4-48e7-894d-bd9e6d92ca51\\volumes\\kubernetes.io~azure-disk\\pvc-6ece396b-2beb-4fc2-8265-5deed43d9e90\r\n\r\njan 23 23:54:59.151: info: at 2021-01-23 23:49:10 +0000 utc - event for azuredisk-volume-tester-6597z-0: {kubelet 6312k8s000} sandboxchanged: pod sandbox changed, it will be killed and re-created.\r\n\r\nthis error appeared for both gce pd and azure disk drivers.\r\n\r\ntestgrid\r\nhttps://testgrid.k8s.io/sig-windows-azure#aks-engine-azure-windows-azure-disk\r\nhttps://testgrid.k8s.io/sig-windows-gce#gce-windows-2019-containerd-master\n\n/sig storage\r\n/sig windows\n\njust had this fail in a pr: https://prow.k8s.io/view/gs/kubernetes-jenkin"} +{"url": "https://github.com/docker/for-win/issues/10422", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "[WSL2] bind mount (`--mount`) with a directory does not exist does not generate errors", "excerpt": "953ab520a6ca34e3a1eba238d1d1f50d2887a3\r\n[sarisia@marine test]$ ls -al\r\ntotal 12\r\ndrwxr-xr-x 3 sarisia sarisia 4096 feb 19 13:20 .\r\ndrwxr-xr-x 7 sarisia sarisia 4096 feb 19 13:20 ..\r\ndrwxr-xr-x 2 root root 4096 feb 19 13:20 bindtest\r\n```\r\n\r\n### expected behavior\r\n\r\n`docker run` should generate errors, as described in [the docs](https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior)\r\n\r\ntested the same command with the ubuntu vm (vmware workstation player):\r\n\r\n```\r\nsarisia@ubuntu:~/run$ sudo docker run --mount \"type=bind,src=$(pwd)/bindtest,dst=/bindtest\" --name bindtest -d nginx\r\ndocker: error response from daemon: invalid mount config for type \"bind\": bind source path does not exist: /home/sarisia/run/bindtest.\r\nsee 'docker run --help'.\r\n```\r\n\r\n
\r\n`docker version` in ubuntu vm\r\n\r\n```\r\nsarisia@ubuntu:~/run$ sudo docker version\r\nclient: docker engine - community\r\n version: 20.10.3\r\n api version: 1.41\r\n go version: go1.13.15\r\n git commit: 48d30b5\r\n built: fri jan 29 14:33:21 2021\r\n os/arch: linux/amd64\r\n context: default\r\n experimental: true\r\n\r\nserver: docker engine - community\r\n engine:\r\n version: 20.10.3\r\n api version: 1.41 (minimum version 1.12)\r\n go version: go1.13.15\r\n git commit: 46229ca\r\n built: fri j"} +{"url": "https://github.com/portainer/portainer/issues/5037", "category": "bind: source does not exist", "rule": "mounts.bind", "title": "swarm secrets from docker compose", "excerpt": " now it seems to setup the stack as services as expected!\r\ni do remember that when i first tried to deploy the stack i had some issues and \"half\" the stack was deployed \"outside\" of portainers control. (same as if i ran docker-compose up).\r\n\r\nso something is a bit unstable, but i don't really know how to reproduce at this time :sweat: \n\nthis is known behaviour when one or more services in a stack fail to deploy. also happens when you have invalid characters or caps in the name.\n\njust a followup: it seems like the portainer server is not making the /data/compose/ folder as intended for the new stack.. so some of the services are failing :thinking: \r\n`invalid mount config for type \"bind\": bind source path does not exist: /data/compose/29/tmp/data`\r\n\r\n\r\n\n\nshare the stack file if you can\n\nhere you go!\r\n\r\n\r\n```\r\nversion: \"3.8\"\r\nservices:\r\n app:\r\n image: signatures:latest\r\n env_file:\r\n - \".docker.development.env\"\r\n environment:\r\n container_name: webserver\r\n test: docker-secret->oauth_secret\r\n env_secrets_debug: \"1\"\r\n depends_on:\r\n - mysql\r\n - redis\r\n volumes:\r\n - ./tmp/data/:/data\r\n - bundle:/bundle\r\n secrets:\r\n - oauth_secret\r\n ports:\r\n - \"3000:3000\"\r\n healthcheck:\r\n test: [\"cmd\", \"curl\", \"-f\", \"http://127.0.0.1:3000/graphql\"]\r\n interval: 5s\r\n timeout: 10s\r\n retries: 6\r\n start_per"} +{"url": "https://github.com/ThePorgs/Exegol/issues/104", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "Exegol Image fails to start on Mac", "excerpt": "u try to create a container sharing the `/tmp/.x11-unix` folder ?\r\nhere is an example:\r\n`docker run --rm -it -v /tmp/.x11-unix:/tmp/.x11-unix debian ls -lhar /tmp/`\r\n\r\n@shutdownrepo can you try to reproduce (maybe a bug with a brew installation) ?\r\n\n\nthat failed but i think i found the issue as it gave me a hint:\r\n```\r\n[7/07/22 19:53:19]\u279c ~ docker run --rm -it -v /tmp/.x11-unix:/tmp/.x11-unix debian ls -lhar /tmp/\r\nunable to find image 'debian:latest' locally\r\nlatest: pulling from library/debian\r\n1339eaac5b67: pull complete \r\ndigest: sha256:859ea45db307402ee024b153c7a63ad4888eb4751921abbef68679fc73c4c739\r\nstatus: downloaded newer image for debian:latest\r\ndocker: error response from daemon: mounts denied: \r\nthe path /tmp/.x11-unix is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee https://docs.docker.com/desktop/mac for more info.\r\nerro[0026] error waiting for container: context canceled\r\n```\r\napparently docker shares these folders [by default](https://docs.docker.com/desktop/mac/#file-sharing) with the host which allows the container to bind the /tmp/ directory. however, they weren't shared on my system for some reason (not sure if it was a borked installation or if someone/me removed them at some point).\r\n\r\nregardless, when i had those folders to the resources and restart doc"} +{"url": "https://github.com/Kong/kong-pongo/issues/139", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "Gitlab CI", "excerpt": "estion is: is it possible to run kong-pongo in gitlab runner with docker socket binding configuration (as described [here](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-socket-binding))\r\n\r\nci job which i want to run `kong-pongo` script is docker container executed by docker runner with following arguments:\r\n\r\n```\r\ndocker run -v /var/run/docker.sock:/var/run/docker.sock -it docker:compose\r\n```\r\n\r\nthere is problem because checkouted plugin repository is inside docker container and docker engine is running in host (gitlab runner). then i get following error message:\r\n\r\n``` sh\r\n/kong-plugin # pongo run\r\ncreating kong-pongo_kong_run ... done\r\nerror response from daemon: mounts denied: \r\nthe path /kong-plugin is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee https://docs.docker.com/docker-for-mac for more info.\r\n```\r\n\r\nregards,\r\n\r\njan\r\n\r\n\r\n\n\nthe solution si probably to use dind runner https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-the-docker-executor-with-the-docker-image-docker-in-docker\n\nhave you tried the docker-in-docker instructions? see https://github.com/kong/kong-pongo#running-pongo-in-docker\n\nsorry i missed that section the documentation. thank you.\n\nwhat were you looking for? can we improve the docs by changing the header?\n\nmaybe"} +{"url": "https://github.com/kiwicampus/Turtlebot-Gazebo-Navigator/issues/1", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "Can't running Dev-Container", "excerpt": " ms] start: run: docker-compose --project-name turtlebot-gazebo-navigator_devcontainer -f /home/juan/turtlebot-gazebo-navigator/.devcontainer/docker-compose.yml -f /home/juan/.config/code/user/globalstorage/ms-vscode-remote.remote-containers/data/docker-compose/docker-compose.devcontainer.build-1674523773585.yml -f /home/juan/.config/code/user/globalstorage/ms-vscode-remote.remote-containers/data/docker-compose/docker-compose.devcontainer.containerfeatures-1674523777359.yml up -d --no-recreate\r\nstarting turtlebot-gazebo-navigator_devcontainer_turtlebot-navigator_1 ... error\r\n\r\nerror: for turtlebot-gazebo-navigator_devcontainer_turtlebot-navigator_1 cannot start service turtlebot-navigator: mounts denied: \r\nthe path /tmp/.x11-unix is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee https://docs.docker.com/ for more info.\r\n\r\nerror: for turtlebot-navigator cannot start service turtlebot-navigator: mounts denied: \r\nthe path /tmp/.x11-unix is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee https://docs.docker.com/ for more info.\r\nerror: encountered errors while bringing up the project.\r\n[19290 ms] error: command failed: docker-compose --project-name turtlebot-gazebo-navigator_devco"} +{"url": "https://github.com/mingwiki/anki-sync-server/issues/1", "category": "desktop: mounts denied", "rule": "mounts.sharing", "title": "\u5982\u4f55\u5728\u672c\u5730\u90e8\u7f72\u8be5\u670d\u52a1\u5668", "excerpt": "\u5982\u4f55\u5728\u672c\u5730\u90e8\u7f72\u8be5\u670d\u52a1\u5668\n\u8bf7\u6559\u4e00\u4e0b\u5982\u4f55\u5728\u672c\u5730\u90e8\u7f72\u670d\u52a1\u5668\uff08mac\u73af\u5883\uff09\u4f9b\u81ea\u5df1\u4f7f\u7528\uff1f\u53ea\u6709\u7535\u8111\u548c\u624b\u673a\u6709\u4f7f\u7528anki\u8fd9\u4e2a\u9700\u6c42\u3002nginx\u914d\u7f6e\u6587\u4ef6\u5e94\u8be5\u600e\u4e48\u6539\u5462\uff1f\u5176\u4ed6\u8fd8\u6709\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u5417\u3002\u8c22\u8c22\u3002\n\n\u56e0\u4e3a\u7528\u7684\u662fdocker\u6240\u4ee5mac\u8ddflinux\u6ca1\u4ec0\u4e48\u533a\u522b\uff0c\u7b2c\u4e00\u6b65\uff0cbrew install docker nginx\uff0c \u7b2c\u4e8c\u6b65\u4e0b\u8f7d\u90a3\u4e2ashell\u6587\u4ef6\uff0c \u7b2c\u4e09\u6b65\u8fd0\u884cshell\u3002\u8fd9\u4e2a\u65f6\u5019\u672c\u5730\u768427701\u7aef\u53e3\u5df2\u7ecf\u8dd1\u8d77\u6765\u4e86\uff0c\u7535\u8111\u5df2\u7ecf\u53ef\u4ee5\u4f7f\u7528\uff0c\u5b89\u5353\u9700\u8981https\u6240\u4ee5\u9ebb\u70e6\u4e00\u70b9\uff0c\u4f60\u5b89\u88c5\u4e00\u4e2amkcert\uff0cmac\u4f7f\u7528\u56fa\u5b9a\u5c40\u57df\u7f51ip\uff0c\u6bd4\u598210.10.10.10\uff0c \u7136\u540e\u7528mkcert\u751f\u6210\u8fd9\u4e2aip\u7684\u8bc1\u4e66\uff0c\u4e0b\u8f7d\u8bc1\u4e66cer\u540e\u7f00\u7684\u5230\u5b89\u5353\u4e0a\uff0c\u8bbe\u7f6e \u5b89\u5168\u91cc\u9762\u627e \u6709\u4e00\u4e2a\u5b89\u88c5\u8bc1\u4e66\u7684\u88c5\u4e0a\uff0cnginx\u7684\u914d\u7f6e\u6587\u4ef6\u5c31\u7528\u6211\u90a3\u4e2a\u5c31\u884c\u4e86\uff0cssl\u8bc1\u4e66\u6539\u4e00\u6539\uff0c\u57df\u540d\u6539\u621010.10.10.10. brew \u5b89\u88c5\u7684\u8bdd\u4e00\u822c\u4f4d\u7f6e\u5728 /usr/local/etc/nginx/servers\u76ee\u5f55\u4e0b\u7684\uff0c \u914d\u7f6e\u6587\u4ef6\u4fee\u6539\u597d\u4e4b\u540ebrew services restart nginx\u5c31\u597d\u4e86\u3002\u6b64\u65f6\u5b89\u5353\u4e5f\u80fd\u7528\u4e86\u3002\n\n\u7535\u8111\u5355\u6307windows\uff0c\u4f7f\u7528\u9700\u8981\u5b89\u88c5\u4e00\u4e2aankisyncd\u7684\u63d2\u4ef6\uff0c\u4f60\u7f51\u4e0a\u627e\u4e00\u627e\uff0cmkcert\u7f51\u4e0a\u4e5f\u6709\u6559\u7a0b\u4f7f\u7528\u5f88\u7b80\u5355\uff0c\u5982\u679c\u8fd8\u641e\u4e0d\u5b9a\u518d\u622a\u56fe\u53d1\u90ae\u4ef6\u95ee\u6211\u3002\n\nmac\u548cios\u7684anki\u4e0d\u652f\u6301\u7b2c\u4e09\u65b9\u540c\u6b65\uff0c\u53ea\u6709\u5b89\u5353\u548cwin\u652f\u6301\u3002\n\n\u6211\u91cd\u5199\u4e86\u4e00\u904dreadme\uff0c\u4f60\u518d\u770b\u770b\uff0c\u5e94\u8be5\u5f88\u6e05\u695a\u4e86\u3002\n\n\u811a\u672c\u542f\u52a8\u62a5\u5982\u4e0b\u9519\u8bef\uff1a\r\ndocker: error response from daemon: mounts denied:\r\nthe path /data/anki is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee https://docs.docker.com/desktop/mac for more info.\r\n\u5df2\u7ecf\u63d0\u524d\u5c06\u8be5\u6587\u4ef6\u5939\u52a0\u5165\u6587\u4ef6\u5171\u4eab\u91cc\u9762\u4e86\n\n\u7528sudo\u8bd5\u8bd5\n\n\u5176\u5b9e\u8fd9\u4e2a\u5730\u5740\u662f\u5b58anki\u6570\u636e\u7684\uff0c\u4f60\u653e\u4efb\u4f55\u5730\u65b9\u90fd\u884c\uff0c\u6bd4\u5982\u4f60\u60f3\u653e\u5728\u5bb6\u76ee\u5f55\u5c31\u628a\u90a3\u4e2aanki.sh\u91cc\u9762\u7684/data/anki\u66ff\u6362\u6210/users/xxx/ankidata\n\n\u8d85\u7ba1\u6743\u9650\u8fd8\u662f\u62a5\u4e00\u6837\u7684\u9519\uff0c\u6211\u662f\u5728\u5bb6\u76ee\u5f55\u521b\u5efa\u7684\u6587\u4ef6\u5939\r\n\u279c anki sudo sh ./anki.sh\r\n74ff5f4d84c423b857bac6a85d4538bcd11b81d8c2c32da67c940608da38cc6d\r\ndocker: error response from daemon: mounts denied:\r\nthe path /data/anki is not shared from the host and is not known to docker.\r\nyou can configure shared paths from docker -> preferences... -> resources -> file sharing.\r\nsee http"} +{"url": "https://github.com/justin2004/mssql_server_tiny/issues/4", "category": "memory: mssql minimum", "rule": "resources.memory", "title": "Will it work with SQL Server 2019?", "excerpt": " gcc\r\n\r\nadd https://raw.githubusercontent.com/justin2004/mssql_server_tiny/master/wrapper.c /root/\r\nrun gcc -shared -ldl -fpic -o wrapper.so wrapper.c\r\n\r\n\r\n\r\nfrom mcr.microsoft.com/mssql/server:2019-latest\r\ncopy --from=build0 /root/wrapper.so /root/\r\n\r\n\r\ncmd ld_preload=/root/wrapper.so /opt/mssql/bin/sqlservr\r\n```\r\n\r\nmy commands:\r\n```\r\nsudo docker build -t sql2019 .\r\nsudo docker run -e 'accept_eula=y' -e 'sa_password=yourstrong(!)password' -p 1433:1433 -t sql2019\r\n```\r\n\r\nresult:\r\n```\r\nsql server 2019 will run as non-root by default.\r\nthis container is running as user mssql.\r\nto learn more visit https://go.microsoft.com/fwlink/?linkid=2099216.\r\nsqlservr: this program requires a machine with at least 2000 megabytes of memory.\r\n/opt/mssql/bin/sqlservr: this program requires a machine with at least 2000 megabytes of memory.\r\n```\r\n\r\nthe **wrapper.c** file is correcly downloaded compiled and copied in the image\r\n\r\nno problem if i use 2017 image, i,m trying with a docker host with 1gb of ram\n\ni got the same result.\r\n\r\nhmm. that probably means they've changed how they look for physical memory...\r\nlet the arms race begin.\n\nhttps://www.dbi-services.com/blog/running-sql-server-on-the-oracle-free-tier/\r\n```dockerfile\r\nfrom oraclelinux:7-slim as build0\r\nworkdir /root\r\nrun yum update -y && yum install -y binutils gcc\r\nadd wrapper.c /root/\r\nrun gcc -shared -ldl -fpic -o wrapper.so wrapper.c"} +{"url": "https://github.com/rapidsai/cloud-ml-examples/issues/60", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "CloudML image with cuDF and cuML", "excerpt": "6\r\nrapidsai/rapidsai-cloud-ml:0.18-cuda11.0-base-ubuntu18.04-py3.8 | 12min 56sec | 15.7gb | 27min 8sec | 6895.85\r\nrapidsai/rapidsai-cloud-ml:0.18-cuda10.2-base-ubuntu18.04-py3.8 | 7min 51sec | 13gb | 24min 26sec | 5682.91\r\nrapidsai/rapidsai:cuda10.2-base-ubuntu18.04-py3.8 | 4min 51sec | 10.3gb | 22min 31sec | 4029.21\r\n\r\nrapidsai/rapidsai-cloud-ml:0.18-cuda11.0-base-ubuntu18.04-py3.8 is still too large for the hpo demo, during the docker pull extraction phase the following error occurs since the docker default volume is full:\r\n\r\n> failed to register layer: error processing tar file(exit status 1): write /root/.cache/pip/http/4/3/7/e/7/437e787c9e19e9665f5a9dead6abeae241b406062ce908cccee5a73d: no space left on device\n\nwhat size is the base+aws dependencies that you've successfully run on sagemaker?\n\nthe 0.16-cuda11.0-base-ubuntu18.04-py3.7 is an example of a passing cuda 11.0 based image. it is 4.16gb compressed, 10.7gb uncompressed, and 11.2gb with the additional packages (e.g. sagemaker-training-toolkit, flask, etc)\r\n\r\n\r\nto reiterate the issue: when a new sagemaker notebook instance is launched the docker default volume (dev/xvda1) has 111gb total space of which 81% is occupied by the various conda kernels offered by sagemaker (see df output below).\r\n\r\n!df -h\r\n```\r\nfilesystem size used avail use% mounted on\r\ndevtmpfs 2.1g 66k 2.1g 1% /dev\r\ntmpfs 2.1g "} +{"url": "https://github.com/guysoft/CustomPiOS/issues/126", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "Using the docker module causes build to fail", "excerpt": "using the docker module causes build to fail\ni'm building on a pi 4b running ubuntu and have followed these [build instructions](https://github.com/guysoft/custompios/wiki/building#build-a-distro-from-within-raspbian--debian--ubuntu--custompios-distros) very closely. i'm just simply trying to implement the docker module in an otherwise stock build, and the build fails.\r\n\r\ni can build a stock image by following the linked instructions, but once i edit the config file to add the docker module, the build fails. i do not have any custom start/end chroot scripts.\r\n\r\ni have attached the build log to this issue, but the specific failure message is `no space left on device: '/tmp/pip-wheel-4ppioxub'` after installing the python `cryptography` package. \r\n\r\nhere's what i'm using to create a fresh distro environment:\r\n\r\n```\r\ncd ~/custompios/src\r\n./make_custom_pi_os -g ~/new_distro\r\ncd ~/new_distro/src\r\nsudo modprobe loop\r\nsudo bash -x ./build_dist\r\n```\r\n\r\nthis works just fine with no customizations to any of the files in `~/new_distro/`. however, when i add the docker module to the `~/new_distro/src/config` file, and try to build again, it fails. here is the `config` with the docker module included:\r\n\r\n```\r\nexport dist_name=new_distro\r\nexport dist_version=0.1.0\r\nexport modules=\"base(network,docker(new_distro))\"\r\n```\r\n\r\ni can't imagine my "} +{"url": "https://github.com/Reed-CompBio/spras/issues/37", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "Support Singularity in addition to Docker", "excerpt": "ity. omics integrator uses a temporary file to pass data to the msgsteiner executable: https://github.com/fraenkel-lab/omicsintegrator/blob/0a57ede6beeef6e63b86d19898e560d62015e85d/scripts/forest.py#l560-l577\r\n\r\non our server, `/tmp` did not support creating large temporary files leading to\r\n```python\r\ntraceback (most recent call last):\r\n file \"/omicsintegrator/scripts/forest.py\", line 1464, in \r\n main()\r\n file \"/omicsintegrator/scripts/forest.py\", line 1424, in main\r\n (edgelist, info) = inputobj.runpcsf(options.msgpath, options.seed)\r\n file \"/omicsintegrator/scripts/forest.py\", line 576, in runpcsf\r\n 1-float(self.undiredges[edgenode1][edgenode2])))\r\nioerror: [errno 28] no space left on device\r\n```\r\n\r\nsetting the `tmpdir` environment variable so that the working directory is used as the temporary directory appears to resolve this issue (4909395df09e0dad3016b15378f9dcd2beb6cbc0). that may be a good general practice when we are using singularity.\n\nmore resources on running conda within singularity\r\n- https://stackoverflow.com/questions/57416579/activate-conda-environment-in-singularity-container-from-dockerfile\r\n- `https://github.com/apptainer/singularity/issues/5075`"} +{"url": "https://github.com/NVIDIA/pyxis/issues/46", "category": "disk: no space left", "rule": "resources.disk,host.disk", "title": "pyxis doesn't use environment variables defined in enroot .env files", "excerpt": "nt variable, there's no problem when `enroot` is called directly, but `pyxis` can't resolve that variable and fails to run the container:\r\n\r\n```\r\n$ grep enroot_data_path /etc/enroot/enroot.conf\r\nenroot_data_path ${scratch}/.enroot/data\r\n\r\n$ srun --container-image=debian --pty bash\r\npyxis: importing docker image ...\r\nslurmstepd: error: pyxis: container start failed with error code: 1\r\nslurmstepd: error: pyxis: printing contents of log file ...\r\nslurmstepd: error: pyxis: /usr/bin/enroot: line 44: scratch: unbound variable\r\nslurmstepd: error: pyxis: /usr/bin/enroot: line 44: scratch: unbound variable\r\nslurmstepd: error: pyxis: /usr/lib/enroot/runtime.sh: line 206: _lock: no space left on device\r\nslurmstepd: error: pyxis: couldn't start container\r\nslurmstepd: error: pyxis: if the image has an unusual entrypoint, try using --no-container-entrypoint\r\nslurmstepd: error: spank: required plugin spank_pyxis.so: task_init() failed with rc=-1\r\nslurmstepd: error: failed to invoke spank plugin stack\r\nsrun: error: sh02-01n60: task 0: exited with exit code 1\r\nsrun: launch/slurm: _step_signal: terminating stepid=24250082.1\r\n```\r\n\r\nthe failure is actually more about `no space left on device`, but it's because it must be falling back to `$xdg_data_home` (which doesn't have enough free space) instead of using the `$enroot_data_path` defined in `enroot.conf`.\r\n\r\nmaybe there c"} +{"url": "https://github.com/NVIDIA/dcgm-exporter/issues/33", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "could not select device driver with capabilities \"gpu\"", "excerpt": "could not select device driver with capabilities \"gpu\"\nhi,\r\n\r\ni am getting:\r\n\r\n`docker: error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].`\r\n\r\n\n\ni had the same problem. i fixed it by installing the nvidia-container-toolkit (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#setting-up-nvidia-container-toolkit)."} +{"url": "https://github.com/cvat-ai/cvat/issues/3593", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "could not select device driver \"\" with capabilities: [[gpu]] when deploying serverless function", "excerpt": "could not select device driver \"\" with capabilities: [[gpu]] when deploying serverless function\ni am trying to deploy a gpu serverless function that you put in the repo (pytorch), using to following command:\r\n`serverless/deploy_gpu.sh serverless/pytorch/facebookresearch/detectron2/retinanet/\r\n`\r\n\r\ni get the following error:\r\n`docker: error response from daemon: could not select device driver \"\" with capabilities: [[gpu]]`\r\n\r\nwhat can i do?\n\ndoes this command work for you?\r\n\r\n```sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi```\n\nit shows the same error. however, when i run nvidia-smi, it shows that there are drivers installed in my computer.\n\n@amitn1212 \r\n\r\nprobably you need"} +{"url": "https://github.com/replicate/cog/issues/280", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "No CUDA runtime is found / Found no NVIDIA driver on your system.", "excerpt": "ry: 11016 mbytes (11551440896 bytes)\r\n (68) multiprocessors, ( 64) cuda cores/mp: 4352 cuda cores\r\n...\r\nresult = pass\r\n```\r\n\r\n\n\nhi @bwhitman! \ud83d\udc4b \r\n\r\ndoes it work if you run the model with docker directly?\r\n\r\n```\r\n$ docker run -d -p 5000:5000 --gpus all r8.im/allenhung1025/looptest@sha256:f5cd715e99046e0513fe2b4034e8f7d8c102525b02f49efb52b05f46fcb9ea83\r\n\r\n$ curl http://localhost:5000/predict -x post -f seed=-1\r\n```\n\nhm, no: \r\n\r\n```\r\n$ docker run -d -p 5000:5000 --gpus all r8.im/allenhung1025/looptest@sha256:f5cd715e99046e0513fe2b4034e8f7d8c102525b02f49efb52b05f46fcb9ea83\r\nf189dd7fdffa728fc77f7c8976a3b9e4e4619cb670ed411774689439bd9e302c\r\ndocker: error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].\r\n```\r\n\r\ni'll dig in, doesn't seem like a cog issue\n\nit's certainly my system's issue but i have fixed this by using [`nvidia-docker`](https://github.com/nvidia/nvidia-docker) instead of docker. does cog allow overriding which docker command to call? \n\ncog doesn't support that, at the moment at least. i'm curious though, did you [install the nvidia-docker toolkit](https://stackoverflow.com/a/58432877/135797) and then `docker run --gpus all` still didn't work? we should catch that and give the user guidance on how to work around that.\n\ni did install the toolkit, and `docker run --gpus all` does work (same as nvidia-docker, but not w"} +{"url": "https://github.com/carlini/audio_adversarial_examples/issues/40", "category": "gpu: no device driver", "rule": "resources.gpu", "title": "Attack.py error", "excerpt": "ing arguments are required: --target\r\n\r\n\r\nalso \r\n\r\ndocker: got permission denied while trying to connect to the docker daemon socket at unix:///var/run/docker.sock: post http://%2fvar%2frun%2fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied.\r\nsee 'docker run --help'.\r\n\r\ncould you please assist me further\n\ncould you try to run the `docker` command with `sudo`, i.e. `sudo docker ` ...?\r\nhow did you try to run `attack.py`?\n\nsudo docker run --gpus all -it --mount src=$(pwd),target=/audio_adversarial_examples,type=bind -w /audio_adversarial_examples tomdoerr/aae_deepspeech_041_gpu\r\n[sudo] password for ren-admin: \r\ndocker: error response from daemon: could not select device driver \"\" with capabilities: [[gpu]].\r\nerro[0000] error waiting for container: context canceled \r\n\r\nattack.py:\r\npython3 attack.py --in sample-000000.wav --restore_path deepspeech-0.4.1-checkpoint/model.v0.4.1\r\nusage: attack.py [-h] --in input [input ...] --target target\r\n [--out out [out ...]] [--outprefix outprefix]\r\n [--finetune finetune [finetune ...]] [--lr lr]\r\n [--iterations iterations] [--l2penalty l2penalty] [--mp3]\r\n --restore_path restore_path\r\nattack.py: error: the following arguments are required: --target\r\n\n\n>> docker: error response from daemon: could not select device driver \"\" with capabil"} +{"url": "https://github.com/oppia/oppia/issues/11868", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Failed to start localhost", "excerpt": "] using discovery type [zen] and seed hosts providers [settings]\r\n[2021-02-18t12:37:58,439][warn ][o.e.g.danglingindicesstate] [computer] gateway.auto_import_dangling_indices is disabled, dangling indices will not be automatically detected or imported and must be managed manually\r\n[2021-02-18t12:37:58,786][info ][o.e.n.node ] [computer] initialized\r\n[2021-02-18t12:37:58,786][info ][o.e.n.node ] [computer] starting ...\r\n[2021-02-18t12:37:58,896][info ][o.e.t.transportservice ] [computer] publish_address {127.0.0.1:9300}, bound_addresses {[::1]:9300}, {127.0.0.1:9300}\r\n[2021-02-18t12:37:59,146][warn ][o.e.b.bootstrapchecks ] [computer] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]\r\n[2021-02-18t12:37:59,146][warn ][o.e.b.bootstrapchecks ] [computer] the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured\r\n[2021-02-18t12:37:59,147][info ][o.e.c.c.coordinator ] [computer] cluster uuid [60haxgnnqgygo90jco_yhw]\r\n[2021-02-18t12:37:59,156][info ][o.e.c.c.clusterbootstrapservice] [computer] no discovery configuration found, will perform best-effort cluster bootstrapping after [3s] unless existing master is discovered\r\n[2021-02-18t12:37:59,285][info ][o.e.c.s.masterservice ] [co"} +{"url": "https://github.com/opensearch-project/OpenSearch/issues/978", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Improve \"OpenSearch exited with code 137\" OOM error message on OSX", "excerpt": "\r\nhttps://opensearch.org/downloads.html \r\n\r\nhere is the terminal output on running the \"docker-compose up\" command as mentioned in the documented steps:\r\n[terminaloutput.txt](https://github.com/opensearch-project/opensearch/files/6832677/terminaloutput.txt)\r\n\r\noperating system: amazon linux 2 x86_64\r\n\r\n\r\n\n\nthe opensearch dashboard doesn't connect and gives this error on following the documentation instructions (https://opensearch.org/downloads.html): \r\n`opensearch-dashboards | {\"type\":\"log\",\"@timestamp\":\"2021-07-16t18:22:29z\",\"tags\":[\"error\",\"opensearch\",\"data\"],\"pid\":1,\"message\":\"[connectionerror]: getaddrinfo enotfound opensearch-node1 opensearch-node1:9200\"}` \r\n\r\nhowever, if you set: \r\n`vm.max_map_count=262144`\r\nin the /etc/sysctl.conf file and use `sudo sysctl -p` to reload, the opensearch dashboard should work now and you will see the below message instead: \r\n`opensearch-dashboards | {\"type\":\"log\",\"@timestamp\":\"2021-07-16t19:56:41z\",\"tags\":[\"listening\",\"info\"],\"pid\":1,\"message\":\"server running at http://0:5601\"}\r\nopensearch-dashboards | {\"type\":\"log\",\"@timestamp\":\"2021-07-16t19:56:41z\",\"tags\":[\"info\",\"http\",\"server\",\"opensearchdashboards\"],\"pid\":1,\"message\":\"http server running at http://0:5601\"}` \n\ndashboard returns connection error with opensearch because the opensearch process exited on bootstrap check failures. \r\n```\r\nopensearch-node2 | [2021-07-16t22:11:19,"} +{"url": "https://github.com/opendistro-for-elasticsearch/sample-code/issues/253", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "vm.max_map_count", "excerpt": "vm.max_map_count\ni try to run opendistro via docker-compose with docker-compose.yml provided in https://opendistro.github.io/for-elasticsearch-docs/docs/install/docker/\r\nbut opendicsto not running because of \r\n`max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]`\r\nthen i try to increase max vm.max_map_count inside host:\r\nsysctl -w vm.max_map_count=262144\r\nbut getting error:\r\n`sysctl: setting key \"vm.max_map_count\": read-only file system`\r\nis there any way to run opendicsto via docker-compose\n\nhi @anwarsky,\r\n\r\nthanks for reaching out. you can get a response by posting to this forum: https://discuss.opendistrocommunity.dev/c/general-elasticsearch/10. you"} +{"url": "https://github.com/noirscape/e621-docker/issues/4", "category": "kernel: vm.max_map_count", "rule": "kernel.sysctl", "title": "Something broke on first startup", "excerpt": "265z\", \"level\": \"info\", \"component\": \"o.e.n.node\", \"cluster.name\": \"docker-cluster\", \"node.name\": \"a3f70f97f4db\", \"message\": \"starting ...\" }\r\nes_1 | {\"type\": \"server\", \"timestamp\": \"2021-08-13t23:17:22,423z\", \"level\": \"info\", \"component\": \"o.e.t.transportservice\", \"cluster.name\": \"docker-cluster\", \"node.name\": \"a3f70f97f4db\", \"message\": \"publish_address {172.18.0.5:9300}, bound_addresses {0.0.0.0:9300}\" }\r\ncore_1 | host es:9200 not yet available...\r\nes_1 | {\"type\": \"server\", \"timestamp\": \"2021-08-13t23:17:23,006z\", \"level\": \"warn\", \"component\": \"o.e.b.bootstrapchecks\", \"cluster.name\": \"docker-cluster\", \"node.name\": \"a3f70f97f4db\", \"message\": \"max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]\" }\r\nes_1 | {\"type\": \"server\", \"timestamp\": \"2021-08-13t23:17:23,009z\", \"level\": \"info\", \"component\": \"o.e.c.c.coordinator\", \"cluster.name\": \"docker-cluster\", \"node.name\": \"a3f70f97f4db\", \"message\": \"cluster uuid [9prjop9qq5sqaqgswmgbaa]\" }\r\nes_1 | {\"type\": \"server\", \"timestamp\": \"2021-08-13t23:17:23,166z\", \"level\": \"info\", \"component\": \"o.e.c.s.masterservice\", \"cluster.name\": \"docker-cluster\", \"node.name\": \"a3f70f97f4db\", \"message\": \"elected-as-master ([1] nodes joined)[{a3f70f97f4db}{lmhsyqqgqnyhuhx_9rx61w}{fhs-m-udrm69mdt-hpg9ng}{172.18.0.5}{172.18.0.5:9300}{dilm}{ml.machine_memory=8275533824, xpack.installe"} +{"url": "https://github.com/rcdailey/nextcloud-cronjob/issues/9", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "Can't find docker container", "excerpt": "can't find docker container\ni am trying to get this running but getting into the error that it can't find the docker container.\r\n\r\n`docker ps`\r\n```\r\ncb2c6a9f3af2 nextcloud:latest \"/entrypoint.sh apac\u2026\" 8 days ago up 8 days 0.0.0.0:8080->80/tcp nextcloud\r\n```\r\n\r\n`docker ps --format '{{.names}},{{.id}}' | egrep \"nextcloud,\" | awk '{split($0,a,\",\"); print a[2]}'`\r\n```\r\ncb2c6a9f3af2\r\n``` \r\n\r\nresult in portainer:\r\n```\r\ncontainer name: nextcloud,\r\ncannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?,\r\nerror: unable to find the nextcloud container,\r\n``` \r\n\r\nmaybe add debug information on this line when debub is enabled?\r\nhttps://github.com/rcdailey/nextcloud-cronjob/blob/f2ce54653b6f8092da1e3abfd25179a4c7c68e0b/scripts/find-container.sh#l10\n\nplease share your `docker-compose.yml`. you are likely not mounting the docker unix socket which is required.\n\ni am not using docker-compose; i'v set up a stand alone instance of nextcloud.\n\nthe point of my request was that i need to see your configuration in order to help you. please provide a `docker-compose.yml` generated by [docker-autocompose](https"} +{"url": "https://github.com/jenkinsci/helm-charts/issues/221", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "Issues using docker on agent", "excerpt": "template(containers: [\r\n containertemplate(\r\n name: 'docker-in-docker',\r\n image: 'docker-in-docker:latest',\r\n alwayspullimage: true,\r\n command: 'cat', // fix worker infinite recursion\r\n ttyenabled: true\r\n )\r\n]) {\r\n node(pod_label) {\r\n stage('deploy') {\r\n container(\"docker-in-docker\") {\r\n checkout scm\r\n sh \"\"\"\r\n docker build -t derp:latest .\r\n docker rmi derp:latest\r\n \"\"\"\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\napplication source dockerfile:\r\n\r\n```docker\r\nfrom ubuntu\r\n```\r\n\r\ntrace:\r\n\r\n```console\r\n[pipeline] sh\r\n\r\n+ docker build -t derp:latest .\r\ncannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?\r\ntime=\"2021-06-01t15:30:32z\" level=error msg=\"failed to dial grpc: cannot connect to the docker daemon. is 'docker daemon' running on this host?: dial unix /var/run/docker.sock: connect: no such file or directory\"\r\n[pipeline] }\r\n[pipeline] // container\r\n[pipeline] }\r\n[pipeline] // stage\r\n[pipeline] }\r\n[pipeline] // node\r\n[pipeline] }\r\n[pipeline] // podtemplate\r\n[pipeline] end of pipeline\r\nerror: script returned exit code 1\r\nfinished: failure\r\n```\r\n\r\ni also tried adding `usermod -ag docker jenkins` to the worker image, just before the `user jenkins` directive. but no luck.\r\n\r\nin fact, when i `kub"} +{"url": "https://github.com/dockhero/heroku-buildpack-docker-compose/issues/7", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "How to start deamon docker", "excerpt": "how to start deamon docker\nhello im actually using this buildpack to have docker on heroku cli but its not working well\r\nim getting this error\r\n\r\nwarning: failed to get default registry endpoint from daemon (cannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?). using system default: https://index.docker.io/v1/\r\ncannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?\r\n"} +{"url": "https://github.com/docker/for-win/issues/10247", "category": "daemon: cannot connect", "rule": "(root cause)", "title": "\"load metadata for\" during docker pull hangs for about 10-20 seconds", "excerpt": "p to date for mongo:latest\r\ndocker.io/library/mongo:latest\r\n\r\nreal 0m0.426s\r\nuser 0m0.024s\r\nsys 0m0.000s\r\n```\r\n\r\n# caveats\r\n\r\n## automatic start at boot\r\n\r\nnormally, i'd follow the post installation setup steps (https://docs.docker.com/engine/install/linux-postinstall/) to add myself to the `docker` group so that i don't need to use `sudo` and to enable the systemd services so that it starts automatically at boot. adding my user to the group works fine. but even after running the commands to enable the services:\r\n\r\n```\r\nsudo systemctl enable docker.service\r\nsudo systemctl enable containerd.service\r\n```\r\n\r\n...and then restarting to test it out, it doesn't work:\r\n\r\n```\r\n> docker ps\r\ncannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?\r\n```\r\n\r\ni have to manually run a command to start the service. and it isn't a `systemctl` command:\r\n\r\n```\r\n> sudo systemctl start docker\r\nsystem has not been booted with systemd as init system (pid 1). can't operate.\r\nfailed to connect to bus: host is down\r\n```\r\n\r\nit's a `service` command:\r\n\r\n```\r\n> sudo service docker start\r\n * starting docker: docker [ ok ]\r\n```\r\n\r\nthen, until i shut my computer down, i can use docker:\r\n\r\n```\r\n> docker ps -a\r\ncontainer id image command created "} +{"url": "https://github.com/dockware/dockware/issues/36", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Notice: iconv(): Wrong charset, conversion from `utf-32le' to `utf-8' is not allowed ", "excerpt": "\n\n\ni also tried a quick fix insight the sabberworm css-parser which i found on the internet but than a running out of memory exception appears.\r\ni replaced the line 91 with `return mb_convert_encoding($sutf32 , 'utf-8' , 'utf-16le');`\n\nnot sure if that helps, but i had this issue during an update to current sw6.3.5.2 on a prod system not inside dockware!\r\n\r\nthe solution was like @thomasdcodes wrote to change to `return mb_convert_encoding($sutf32 , 'utf-8' , 'utf-16le');` \r\nline 91 in \u201cvendor/sabberworm/php-css-parser/lib/sabberworm/css/parsing\u201d\n\nyes - the only issue i am getting then is a \r\n\r\n```\r\nmmap() failed: [12] cannot allocate memory\r\n....\r\nmmap() failed: [12] cannot allocate memory\r\nqemu: uncaught target signal 11 (segmentation fault) - core dumped\r\nsegmentation fault\r\n```\r\n\r\nbtw: it seems that the issue has something to do with the bootstrap theme / scss files , maybe the icons or anything like that because of the encoding. seems to be an issue with the storefront scss php compiler.\r\n\r\nbecause if you remove the storefront / bootstrap theme from the styles within the `theme.json` it's compiling.\r\n\r\nhowever - it's strange because with docker 3.1 it was working.\n\nif i replace the part in line 91 with `return iconv('utf-32le', $this->scharset, hex2bin(\"14200000\"));` i got the error named above.\r\nif i run the php interactive shell insight the machine (both commands are runn"} +{"url": "https://github.com/apache/superset/issues/12697", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Installing Mac M1 with Docker Preview version 7", "excerpt": ", caching is effectively disabled.**\r\nsuperset_tests_worker | \"flask-caching: cache_type is set to null, \"\r\n**superset_tests_worker | error:flask_appbuilder.security.sqla.manager:db creation and initialization failed: (psycopg2.operationalerror) fatal: database \"test\" does not exist**\r\nsuperset_tests_worker | \r\nsuperset_tests_worker | (background on this error at: http://sqlalche.me/e/13/e3q8)\r\nsuperset_tests_worker | loaded your local configuration at [/app/docker/pythonpath_dev/superset_config.py]\r\nsuperset_worker | info:superset.utils.logging_configurator:logging was configured successfully\r\n**superset_tests_worker exited with code 1\r\nsuperset_worker | qemu: uncaught target signal 4 (illegal instruction) - core dumped**\r\nsuperset_db | 2021-01-22 19:51:25.820 utc [33] log: unexpected eof on client connection with an open transaction\r\nsuperset_worker | /app/docker/docker-bootstrap.sh: line 45: 10 illegal instruction celery worker --app=superset.tasks.celery_app:app -ofair -l info\r\nsuperset_app | info:superset.utils.logging_configurator:logging was configured successfully\r\nsuperset_worker | skipping local overrides\r\nsuperset_worker | starting celery worker...\r\nsuperset_init | info:superset.utils.logging_configurator:logging was configured successfully\r\nsuperset_app "} +{"url": "https://github.com/docker/for-mac/issues/5232", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Docker preview version for apple silicon is fail to run 'apache/airflow' image", "excerpt": "-word statement or a diagnostics id.\r\n\r\nissues unrelated to docker desktop will be closed. in particular, see\r\n - https://github.com/docker/compose/issues for docker-compose\r\n - https://github.com/docker/machine/issues for docker-machine\r\n - https://github.com/moby/moby/issues for docker daemon\r\n - https://github.com/docker/docker.github.io/issues for the documentation\r\n-->\r\n\r\n\r\n\r\n\r\n### issue:\r\ni tried to run the 'apache/airflow' image (https://hub.docker.com/r/apache/airflow) with docker-compose. \r\nthe container is able to start, but after running some airflow commends, the container is terminated with an error 'qemu: uncaught target signal 4 (illegal instruction) - core dumped'\r\n\r\n### actual behavior\r\nfollowing is my docker-compose.yml file\r\n```\r\nversion: '3.8'\r\nservices:\r\n webserver:\r\n image: apache/airflow\r\n command: bash -c\r\n \"airflow db init \r\n && airflow users create -u admin -f peter -l parker -r admin -e spiderman@superhero.org -p ****\r\n && airflow webserver\"\r\n volumes:\r\n - ./dags:/opt/airflow/dags\r\n environment:\r\n - airflow__core__sql_alchemy_conn=mysql+mysqldb://airflow:airflow@192.168.64.1:3306/airflow\r\n - airflow__core__executor=localexecutor\r\n ports:\r\n - \"8080:8080\"\r\n```\r\na"} +{"url": "https://github.com/XQuartz/XQuartz/issues/31", "category": "emulation: qemu crash", "rule": "image.platform", "title": "Apple Silicon black background", "excerpt": ".x11-unix:/tmp/.x11-unix \\\r\n -v ~/.idea:/home/developer/.idea \\\r\n -v ~/.idea.java:/home/developer/.java \\\r\n -v ~/.idea.maven:/home/developer/.m2 \\\r\n -v ~/.idea.gradle:/home/developer/.gradle \\\r\n -v ~/.idea.share:/home/developer/.local/share/jetbrains \\\r\n -v ~/project:/home/developer/project \\\r\n --name idea-$(head -c 4 /dev/urandom | xxd -p)-$(date +'%y%m%d-%h%m%s') \\\r\nrycus86/intellij-idea:latest\r\nwarning: the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\r\nopenjdk 64-bit server vm warning: option useconcmarksweepgc was deprecated in version 9.0 and will likely be removed in a future release.\r\nqemu: uncaught target signal 11 (segmentation fault) - core dumped\r\nsegmentation fault\r\n```\r\n\r\ni also tried using :0 rather than $display, but that also failed.\n\ni was able to reproduce with my ubuntu vm using https://github.com/toxiudev/simple-gui/releases/download/1.0/gui.jar \r\n\r\n\r\n```\r\njeremy@tair-ubuntu:~$ java -version\r\nopenjdk version \"14.0.2\" 2020-07-14\r\nopenjdk runtime environment (build 14.0.2+12-ubuntu-120.04)\r\nopenjdk 64-bit server vm (build 14.0.2+12-ubuntu-120.04, mixed mode, sharing)\r\njeremy@tair-ubuntu:~$ java -jar gui.jar \r\n```\r\n\r\nso this is a start...\n\ni've also filed an internal radar to track this: rdar://77000665\n\n@jeremyhu yeah, running x86_64 container on m1 docker is p"} +{"url": "https://github.com/podman-container-tools/podman/issues/9006", "category": "volume permission denied", "rule": "", "title": "\"lstat: invalid argument\" when using 'overlay' storage driver with fuse-overlayfs", "excerpt": "and-arg --storage-driver --exit-command-arg overlay --exit-command-arg --storage-opt --exit-command-arg overlay.ignore_chown_errors=true --exit-command-arg --storage-opt --exit-command-arg overlay.mount_program=/usr/bin/fuse-overlayfs --exit-command-arg --storage-opt --exit-command-arg overlay.mountopt=nodev --exit-command-arg --events-backend --exit-command-arg journald --exit-command-arg --syslog --exit-command-arg container --exit-command-arg cleanup --exit-command-arg --rm --exit-command-arg 7d6030b9b2fdb857aa49e3311ddbf7cf07c89480b10f164a9a7910ba2860bedb]\"\r\nwarn[0001] failed to add conmon to cgroupfs sandbox cgroup: error creating cgroup for cpu: mkdir /sys/fs/cgroup/cpu/libpod_parent: permission denied \r\ndebu[0001] received: 2181470 \r\ninfo[0001] got conmon pid as 2181459 \r\ndebu[0001] created container 7d6030b9b2fdb857aa49e3311ddbf7cf07c89480b10f164a9a7910ba2860bedb in oci runtime \r\ndebu[0001] attaching to container 7d6030b9b2fdb857aa49e3311ddbf7cf07c89480b10f164a9a7910ba2860bedb \r\ndebu[0001] connecting to socket /run/user/1015/libpod/tmp/socket/7d6030b9b2fdb857aa49e3311ddbf7cf07c89480b10f164a9a7910ba2860bedb/attach \r\ndebu[0001] received a resize event: {width:227 height:62} \r\ndebu[0001] starting container 7d6030b9b2fdb857aa49e3311ddbf7cf07c89480b10f164a9a7910ba2860bedb with command [/hello] \r\ndebu[0001] started container 7d603"} +{"url": "https://github.com/alerque/libertinus/issues/418", "category": "volume permission denied", "rule": "", "title": "InvalidInput error when building with Fontship, missing rules?", "excerpt": ", but i just noticed that your alias for running the fontship docker container includes `sudo docker`. this means you are running the container as root, something your *really* should not be doing. i don't think anything in fontship is going to infiltrate your system, but just as a general practice that is a big no-no. also it's likely to create all sorts of side effects such as the temporary build directories and resulting files being owned by root instead of your user. nothing about the fontship docker build requires elevated system privileges to run, it should be run just as your regular user.\n\nthanks for the heads up @alerque! when i try building as non-root i get the error `docker: got permission denied while trying to connect to the docker daemon socket at unix:///var/run/docker.sock: post http://%2fvar%2frun%2fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied.\r\nsee 'docker run --help'.`. after looking at https://stackoverflow.com/questions/48957195/how-to-fix-docker-got-permission-denied-issue i found that running docker as root fixed the issue but i didn't realize it could be a security risk (as you can probably tell, i need to get better at this). that page also suggests making a unix group for running docker. i am not sure how that really works, but https://docs.docker.com/engine/install/linux-postinstall/ seems to suggest"} +{"url": "https://github.com/otherguy/docker-dropbox/issues/16", "category": "volume permission denied", "rule": "", "title": "Feature Request - include dropbox.py script and unzip util", "excerpt": "issue if you'd like, i just was trying to save the issues from being flooded, since we already had talked about synology here.*\r\n\r\n---\r\n\r\non a related synology question, when i try to start the container via cli as my user `winston` it doesn't work, so i have to `sudo su` and then run the command again and it'll work just fine going forward without any further errors:\r\n\r\n```shell\r\nwinston@synology-vm-01:/$ docker run --privileged --detach -it --restart=always --name=dropbox --net=\"host\" -e \"tz=america/los_angeles\" -e \"dropbox_uid=0\" -e \"dropbox_gid=100\" -v \"/volume1/docker/dropbox-settings:/opt/dropbox/.dropbox\" -v \"/volume1/dropbox:/opt/dropbox/dropbox\" otherguy/dropbox:latest\r\ndocker: got permission denied while trying to connect to the docker daemon socket at unix:///var/run/docker.sock: post http://%2fvar%2frun%2fdocker.sock/v1.39/containers/create?name=dropbox: dial unix /var/run/docker.sock: connect: permission denied.\r\nsee 'docker run --help'.\r\nwinston@synology-vm-01:/$ sudo su\r\npassword: \r\nash-4.3# docker run --privileged --detach -it --restart=always --name=dropbox --net=\"host\" -e \"tz=america/los_angeles\" -e \"dropbox_uid=0\" -e \"dropbox_gid=100\" -v \"/volume1/docker/dropbox-settings:/opt/dropbox/.dropbox\" -v \"/volume1/dropbox:/opt/dropbox/dropbox\" otherguy/dropbox:latest\r\n4e9e1637219da87333eee08d5601b9ffe9b81a1f864a85b029199a3a0a5cc589\r\nash-4.3# \r\n```\r\n\r\ni'm using `dropb"} +{"url": "https://github.com/pi-hole/docker-pi-hole/issues/751", "category": "volume permission denied", "rule": "", "title": "Error when whitelisting domain: While executing INSERT OT IGNORE: attempt to write a readonly database Added 0 out of 1 domains ", "excerpt": "e 644 /etc/pihole/pihole-ftl.db\r\nroot:root 644 /etc/pihole/setupvars.conf\r\n```\r\n\r\ni run it again after the fix, and no change found even in permissions\r\n\r\ni thought this might help\n\nnot running on docker though, but still it might help someone\n\nfor those having issues: i ran the below and got it going. \r\n`sudo chown 999:999 /etc/pihole -r`\r\n\n\ni resolved this by running `chmod 777 /etc/pihole/` inside the container (i'm sure there's a more secure way of fixing this).\r\n\r\nit seems that the php process is unable to write journal files in the directory.\r\nstrace showed this:\r\n\r\n```\r\nopenat(at_fdcwd, \"/etc/pihole/gravity.db-journal\", o_rdwr|o_creat|o_largefile|o_cloexec, 0666) = -1 eacces (permission denied)\r\n```\r\n\n\nsame issue. using this workaround in my container startup script:\r\n`docker exec pihole chown -r www-data:pihole /etc/pihole`\r\n\r\ni'm updating from v4.1.1 using a fresh install to new server folders. no permission issues on previous version. \r\n\r\nand no idea what root cause is since i can run pihole without any mounted volumes and everything works fine but when i mount volumes it has the permission issues. even though /etc/pihole/* looks identical from an ownership/group/permission perspective with or without mounted volumes.\n\n> same issue. using this workaround in my container startup script: `docker exec pihole chown -r www-data:pihole /etc/pihole`\r\n> \r\n> i'm updati"} +{"url": "https://github.com/ArchiveBox/ArchiveBox/issues/667", "category": "DNS resolution in container", "rule": "", "title": "Bug: Fresh Ubuntu 20.04 Install, Error: [X] The search backend threw an exception=[Errno -3] Temporary failure in name resolution:", "excerpt": "bug: fresh ubuntu 20.04 install, error: [x] the search backend threw an exception=[errno -3] temporary failure in name resolution:\n#### describe the bug\r\nclean docker-compose install on ubuntu 20.04, running\r\n\r\n`docker-compose run archivebox add 'https://example.com'`\r\n\r\nresults in the following error:\r\n\r\n`[x] the search backend threw an exception=[errno -3] temporary failure in name resolution:`\r\n\r\ndns works fine and no errors are reported in 'archivebox --version'. error occurs on all url's; there is nothing 'temporary' about it.\r\n\r\n#### screenshots or log output\r\n\r\nhttps://imgur.com/a/haaclbv\r\n\r\n#### archivebox version\r\n\r\nlatest v0.5.6\r\n\r\n\r\nany ideas on what could be causing this? thank you!\r\n\n\nplease post the full verbatim output of `docker-compose run --rm archivebox --versio"} +{"url": "https://github.com/microsoft/WSL/issues/6427", "category": "DNS resolution in container", "rule": "", "title": "wsl2 no internet access (unable to resolve host address) on windows 1909 build 18363.1139", "excerpt": "0.547 ms\r\n64 bytes from 172.18.49.1: icmp_seq=13 ttl=128 time=0.580 ms\r\n64 bytes from 172.18.49.1: icmp_seq=14 ttl=128 time=0.579 ms\r\n64 bytes from 172.18.49.1: icmp_seq=15 ttl=128 time=0.703 ms\r\n^c\r\n--- 172.18.49.1 ping statistics ---\r\n15 packets transmitted, 15 received, 0% packet loss, time 14531ms\r\nrtt min/avg/max/mdev = 0.476/0.618/0.822/0.101 ms\r\nmanukyae@gneltcg8424mzx:~$\r\n```\n\njust to be helpful in case this is dns issue, the `wget` output that was supposed to download the file:\r\n\r\n```\r\nmanukyae@gneltcg8424mzx:/mnt/c/users/manukyae$ wget http://wordpress.org/latest.tar.gz\r\n--2021-01-14 21:35:52-- http://wordpress.org/latest.tar.gz\r\nresolving wordpress.org (wordpress.org)... failed: temporary failure in name resolution.\r\nwget: unable to resolve host address \u2018wordpress.org\u2019\r\nmanukyae@gneltcg8424mzx:/mnt/c/users/manukyae$\r\n```\n\n@armenic: yes, something is clearly wrong with dns.\r\n\r\ncan you share the output of `cat /etc/resolv.conf`, and then try to replace 'nameserver x.x.x.x' by 'nameserver 1.1.1.1' in that file and check if the wget command succeeds after doing that ? \n\nhere we go my friend (@oneblue), anything you say:\r\n\r\noriginal state\r\n```\r\nmanukyae@gneltcg8424mzx:~$ cat /etc/resolv.conf\r\n# this file was automatically generated by wsl. to stop automatic generation of this file, add the following entry to /etc/wsl.conf:\r\n# [network]\r\n# generateresolvconf = false\r\nname"} +{"url": "https://github.com/GoogleCloudPlatform/cloud-code-vscode/issues/376", "category": "DNS resolution in container", "rule": "", "title": "parsing skaffold config: unknown api version: \"skaffold/v2beta11\"", "excerpt": "pdate alpha'.\r\nmin supported version check failed for cloud sdk beta component. min supported version 2019.05.17. current version . err: the argument 'file' cannot be empty. received ''. please update the component using 'gcloud components update beta'.\r\n```\r\n\r\nso now i have tried to copy my `kubectl` bin from `/usr/local/bin/kubectl` to `~/.cache/cloud-code/installer/google-cloud-sdk/bin` but it didn't work as well\r\n\r\nso as last thing i have tried to remove `~/.cache` and i reinstalled the cloud code plugin with `cloudcode.autodependencies: true` but now i have got the error\r\n\r\n```\r\n,error: (gcloud.components.install) the component [kubectl] failed to download.\r\n\r\n\r\n\r\n\tat /home/user/.vscode/extensions/googlecloudtools.cloudcode-1.8.0/dist/extension.js:787:20690\r\n\tat processticksandrejections (internal/process/task_queues.js:94:5)\r\n[04/02/2021, 10:55:36] 'gcloud config config-helper --format json --quiet' exited with code 1 took 56232ms (managed)\r\n```\r\n\r\ni'm not sure if this is helping but if i will try to summarize it \r\n* fresh installed i have got skaffold in version `v1.17.2`\r\n* i couldn't override that path of the binaries skaffold, kubectl and minikube\r\n\r\n\r\n\r\n\n\nthanks for the detailed report here! that's really helped us explore the issue.\r\n\r\nit looks like the gcloud update somehow got corrupted at first which "} +{"url": "https://github.com/osixia/container-openldap/issues/514", "category": "DNS resolution in container", "rule": "", "title": "LDAP Container fails with missing FQDN", "excerpt": "ory variables should be set.\r\n\r\n```\r\n---\r\n\r\nversion: \"2\"\r\n\r\nservices:\r\n\r\n ldap_container:\r\n container_name: \"ldap_container\"\r\n repository: \"osixia/openldap:latest\"\r\n ports:\r\n - \"127.0.0.1:389:389\"\r\n command: \"--copy-service --loglevel trace\"\r\n env:\r\n ldap_domain: \"example.org\"\r\n ldap_organisation: \"organisation\"\r\n ldap_admin_password: \"abc\"\r\n ldap_config_password: \"def\"\r\n ldap_base_dn: \"ou=people,dc=example,dc=org\"\r\n domainname: \"example.org\"\r\n hostname: \"ldap-master\"\r\n\r\n...\r\n```\r\n\r\n`/etc/hosts` seem not to contain the hostname\r\n\r\nthe error with `--loglevel trace` is:\r\n\r\n```\r\n++ /bin/hostname --fqdn\r\nhostname: temporary failure in name resolution\r\n+ fqdn=\r\n*** /container/run/startup/slapd failed with status 1\r\n\r\n*** run commands before finish...\r\n*** killing all processes...\r\n```\n\nthat error occurs on every restart.\r\n\r\nthe first installation can be successful by executing that command while the setup task is running:\r\n\r\n```\r\ndocker exec -it ldap_container bash -c 'echo \"127.0.0.1 $(cat /etc/hostname)\" >> /etc/hosts'\r\n```\n\ndoes this work for you? (to figure out if it's a general docker issue, or an issue with this image.)\r\ni get this output: `ldap-master.example.org`\r\n\r\n```\r\n$ docker run --hostname ldap-master --domainname example.org --entrypoint hostname osixia/openldap --fqdn\r\n```\r\n\r\nand even th"} +{"url": "https://github.com/pezzolabs/pezzo/issues/64", "category": "container healthcheck unhealthy", "rule": "", "title": "Unable to build docker image on MacOS docker desktop", "excerpt": "unable to build docker image on macos docker desktop\n### report\n\nrunning on macos i've been attempting to build the docker image provided in the install instructions and encountering an issue preventing it from starting correctly:\r\n\r\ndependency failed to start: container pezzo-bold_shtern-pezzo-server-1 is unhealthy\r\nexit status 1\r\n\r\n\n\n### expected behavior\n\nfor docker desktop to compile and build\n\n### steps to reproduce the problem\n\n1. download repository via macos terminal and git build\r\n2. docker-compose build the application\r\n\n\n### logs (if applicable)\n\n```\r\nontainer pezzo-bold_shtern-supertokens-1 created\r\n container pezzo-bold_shtern-postgres-1 created\r\n container pezzo-bold_shtern-pezzo-server-1 creating\r\n container pezzo-bold_shtern-pezzo-server-1 created\r\n container pezzo-bold_shtern-pezzo-console-1 creating\r\n container pezzo-bold_shtern-pezzo-console-1 created\r\n container pezzo-bold_shtern-supertokens-1 starting\r\n container pezzo-bold_shtern-app-1 starting\r\n container pezz"} +{"url": "https://github.com/bitnami/containers/issues/33325", "category": "container healthcheck unhealthy", "rule": "", "title": "[bitnami/kafka] health check fails when running in kraft", "excerpt": "3\r\n - allow_plaintext_listener=yes\r\n - kafka_cfg_auto_create_topics_enable=true\r\n - bitnami_debug=true\r\n\r\n producer:\r\n build:\r\n context: ./producer\r\n dockerfile: dockerfile\r\n container_name: python-producer\r\n depends_on: \r\n kafka:\r\n condition: service_healthy\r\n ports:\r\n - 8001:8001\r\n networks:\r\n - kafka-pipeline\r\n environment:\r\n - kafka_topic_name=topic\r\n - kafka_server=kafka\r\n - kafka_port=9092\r\n``` \r\n\r\n### what is the expected behavior?\r\n\r\npython producer to run when docker-compose health check dependency returns service_healthy\r\n\r\n### what do you see instead?\r\n```\r\ndependency failed to start: container kafka is unhealthy\r\n```\r\n### additional information\r\n\r\ndoes not appear that the health check runs at all\r\nprobably an issue with configuration?\n\nhi @justjooste,\r\n\r\nthe `bitnami/kafka` image does not have the netcat package installed. that is why the healthcheck will fail:\r\n```\r\ni have no name!@cc9e95cdd14d:/$ nc -z localhost 9092\r\nbash: nc: command not found\r\n```\r\n\r\nin case it helps, maybe the following command helps you perform a healthcheck, although it is more complex than checking the port is open:\r\n```\r\nkafka-topics.sh --bootstrap-server kafka:9092 --topic hc --create --if-not-exists && kafka-topics\r\n.sh --bootstrap-server kafka:9092 --topic hc --describe\r\n```\r\n\n\ni have used something similar"} +{"url": "https://github.com/reportportal/reportportal/issues/1995", "category": "container healthcheck unhealthy", "rule": "", "title": "Macbook M1 platform is not supported", "excerpt": ".0s\r\n ! jobs the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s\r\n ! api the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s\r\n ! analyzer the requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s\r\ndependency failed to start: container reportportal-postgres-1 is unhealthy\r\n```\n\n```\r\n % docker ps\r\ncontainer id image command created status ports names\r\na3c2356624c9 reportportal/service-auto-analyzer:5.7.4 \"/venv/bin/uwsgi --h\u2026\" 29 minutes ago up 28 minutes (unhealthy) 5001/tcp reportportal-analyzer-1\r\nab3ffe834df1 reportportal/service-auto-analyzer:5.7.4 \"/venv/bin/uwsgi --h\u2026\" 29 minutes ago up 28 minutes (unhealthy) 5001/tcp "} +{"url": "https://github.com/LAION-AI/Open-Assistant/issues/1119", "category": "container healthcheck unhealthy", "rule": "", "title": "dependency failed to start: container for service \"webdb\" is unhealthy", "excerpt": "dependency failed to start: container for service \"webdb\" is unhealthy\ngetting this error after the after a long time of booting. \r\n\r\nrunning on ubuntu 20.04 python version 3.8. intel i3 8gb ram.\n\nthis might not be your issue, but in general you need python 3.10.\n\nif it's just timing out while starting the services due to ram or cpu contention, try increasing the timeout and retry values here:\r\n\r\nhttps://github.com/laion-ai/open-assistant/blob/dcb9dfe952fb0fa6fc11c719c6fc2881de19b29b/docker-compose.yaml#l34\r\n\r\nif that's the issue and you find sensible defaults that work on your hardware please submit them as a pull request :)"} +{"url": "https://github.com/youtous/docker-mailserver-traefik/issues/4", "category": "network not found", "rule": "", "title": "Dovecot not using proper certificate, but Postfix does", "excerpt": "********'\r\nmail | setting up dkim\r\nmail | * dkim keys added for: \r\nmail | * changing permissions on /etc/opendkim\r\nmail | * nameservers added to /etc/opendkim.conf\r\nmail | setting up ssl\r\nmail | * tls configured with 'modern' ciphers\r\nmail | * configuring certificates using cert /var/mail-state/manual-ssl/cert and key /var/mail-state/manual-ssl/key\r\nmail | * ssl configured with 'manual' certificates\r\nmail | setting up permit_docker option\r\nmail | * adding container ip in my networks\r\nmail | setting up mailname\r\nmail | * creating /etc/mailname\r\nmail | setting up amavis\r\nmail | * applying hostname to /etc/amavis/conf.d/05-node_id\r\nmail | setting up dmarc\r\nmail | * applying hostname to /etc/opendmarc.conf\r\nmail | applying hostname and domainname to postfix\r\nmail | * applying hostname to /etc/postfix/main.cf\r\nmail | applying hostname to dovecot\r\nmail | * applying hostname to /etc/dovecot/conf.d/15-lda.conf\r\nmail | * configuring postfix sm"} +{"url": "https://github.com/sethuiyer/Image-to-Image-Search/issues/19", "category": "network not found", "rule": "", "title": "ERROR: repository docker.io/image_search not found: does not exist or no pull access", "excerpt": "manually, after executing `docker_install.sh`, check `docker ps -a`,`${repository}:${tag}`\r\n\r\n```bash\r\n$ docker images\r\nrepository tag image id created size\r\nimage_to_image_search version2 7a10bc3d08cb 12 minutes ago 1.54 gb\r\n\r\n# website.image = image_to_image_search:version2\r\n```\r\n\r\n```\r\nversion: '2'\r\nservices:\r\n elasticsearch:\r\n image: docker.elastic.co/elasticsearch/elasticsearch:6.6.0\r\n container_name: elasticsearch\r\n ports:\r\n - \"9200:9200\"\r\n - \"9300:9300\"\r\n environment:\r\n es_java_opts: '-xms256m -xmx256m'\r\n network.bind_host: 0.0.0.0\r\n network.host: 0.0.0.0\r\n discovery.type: single-node\r\n website:\r\n image: image_to_image_search:version2\r\n volumes:\r\n - ~/.keras:/root/.keras\r\n ports:\r\n - \"5000:5000\"\r\n depends_on:\r\n - elasticsearch\r\n working_dir: /image_search\r\n command: python3 server.py\r\n```\r\n\n\n### maybe docker_image has not been maintained\r\n\r\n```bash\r\nwebsite_1 | get http://localhost:9200/desearch/_search [status:n/a request:0.001s]\r\nwebsite_1 | traceback (most recent call last):\r\nwebsite_1 | file \"/usr/local/lib/python3.5/dist-packages/urllib3/connection.py\", line 159, in _new_conn\r\nwebsite_1 | (self._dns_host, self."} +{"url": "https://github.com/raiden-network/raiden-service-bundle/issues/226", "category": "network not found", "rule": "", "title": " inclusion in the list of known servers", "excerpt": "o you need help in troubleshooting the problem?\r\nthe last 100 or so lines of your synapse logs as well as pfs logs would be helpful.\n\ni will check on it. thank you finally getting back to me.\n\non tue, feb 2, 2021, 1:48 am max langenfeld \nwrote:\n\n> @mossimokim , we noticed that your pfs is\n> still returning a 404, although we included you in the matrix federation.\n> do you need help in troubleshooting the problem?\n> the last 100 or so lines of your synapse logs as well as pfs logs would be\n> helpful.\n>\n> \u2014\n> you are receiving this because you were mentioned.\n> reply to this email directly, view it on github\n> ,\n> or unsubscribe\n> \n> .\n>\n\n\nhaving issue getting pfs up! need help!\r\n\r\n1. raijin1.raiden.ninja is pointed to 159.89.220.153\r\n2. .env file is [here](https://gist.github.com/mossimokim/565b172e1228b3ccc7607a978d79ac61)\r\n3. registered in the registry [here](https://etherscan.io/tx/0x59653c1f3c2da8130e4fd9cda81f48c03ea04bed82475bc47c7838e073791536)\r\n4. matrix endpoint gives http status 200 [here](https://transport.raijin1.raiden.ninja/_matrix/client/versions)\r\n5. pfs is down\r\n6. latest_confirmed_block is increasing regularly\r\n7. msrc & "} +{"url": "https://github.com/traefik/traefik/issues/7738", "category": "network not found", "rule": "", "title": "Router defined multiple times with different configurations error", "excerpt": "ro\"\r\n - \"./acme.json:/acme.json\"\r\n restart: unless-stopped\r\n labels:\r\n - \"com.ouroboros.enable=true\"\r\n - \"traefik.enable=true\"\r\n - \"traefik.http.routers.api.rule=host(`traefik.domain.com`)\"\r\n - \"traefik.http.routers.api.service=api@internal\"\r\n - \"traefik.http.routers.api.entrypoints=web-secure\"\r\n - \"traefik.http.routers.api.tls.certresolver=primary\"\r\n - \"traefik.http.middlewares.trauth.forwardauth.address=http://trauth.web:8080/\"\r\n - \"traefik.http.routers.api.middlewares=trauth\"\r\n # wildcard certs\r\n - \"traefik.http.routers.api.tls.domains[0].main=domain.com\"\r\n - \"traefik.http.routers.api.tls.domains[0].sans=*.domain.com\"\r\n networks:\r\n - web\r\n\r\n trauth:\r\n build:\r\n context: https://github.com/leonjza/trauth.git\r\n dockerfile: dockerfile\r\n image: trauth:local\r\n container_name: trauth\r\n environment:\r\n - trauth_domain=domain.com\r\n - trauth_password_file_location=/htpass/htpass\r\n volumes:\r\n - \"./htpass:/htpass\"\r\n restart: unless-stopped\r\n networks:\r\n - web\r\n\r\n\r\nnetworks:\r\n web:\r\n external: true\r\n```\r\n\r\n**pihole docker-compose.yml**\r\n```\r\nversion: \"3\"\r\n\r\n# more info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/\r\nservices:\r\n pihole:\r\n container_name: pihole\r\n image: pihole/pihole:latest\r\n environment:\r\n tz: europe/"} +{"url": "https://github.com/kubernauts/jmeter-operator/issues/26", "category": "OCI runtime exec failed", "rule": "", "title": "Automation to create InfluxDB fails", "excerpt": "db fails\nthe `$ curl ` not found at grafana pod.\r\n```\r\nbash-5.0$ curl 'http://admin:admin@127.0.0.1:3000/api/datasources' -x post -h 'content-type: application/json;charset=utf-8' --data-binary '{\"name\":\"jmeterdb\",\"type\":\"influxdb\",\"url\":\"http://'$influxdb_svc':8086\",\"access\":\"proxy\",\"isdefault\":true,\"database\":\"jmeter\",\"user\":\"admin\",\"password\":\"admin\"}'\r\nbash: curl: command not found\r\nbash-5.0$ cat /etc/issue \r\nwelcome to alpine linux 3.12\r\nkernel \\r on an \\m (\\l)\r\n```\r\nwhen you try execute the script `initialize_cluster.sh` return a generic error:\r\n```\r\n./initialize_cluster.sh \r\nenter the jmeter namespace: mynamespace\r\ncreating influxdb jmeter database\r\ncreating the influxdb data source\r\noci runtime exec failed: exec failed: container_linux.go:370: starting container process caused: exec: \"curl\": executable file not found in $path: unknown\r\ncommand terminated with exit code 126\r\n```\r\n"} +{"url": "https://github.com/fabric8io/kubernetes-client/issues/2704", "category": "OCI runtime exec failed", "rule": "", "title": "How to repleace System.out in ExecWatch", "excerpt": "system.err)\r\n .withtty()\r\n .usinglistener(new simplelistener())\r\n .exec();\r\n return outputstream.tostring();\r\n\r\n\r\nbut i cant get the data of outputstream,it will be ok if i use system.out\r\n\r\n\r\n\n\n@yangjinlogic : hi, could you please check this example which uses `writingoutput` and `writingerror` with `bytearrayoutputstream`:\r\n\r\nhttps://github.com/fabric8io/kubernetes-client/blob/6a7a7e406b5405bae2bb8219bda1bffe7ff5d7c8/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/executecommandonpodexample.java#l69-l75\n\n@rohankanojia i use the example code,i can run the command such as \"ls\"\u3001\u201cdf -h\u201d, but i run command \"cd\",show this \r\noci runtime exec failed: exec failed: container_linux.go:349: starting container process caused \"exec: \\\"cd\\\": executable file not found in $path\": unknown\n\n@rohankanojia whether the example code can ensure the command is successive?\n\ni can run perfect in my example,and it look like a real terminal,i only can't get the data of outputstream,i am confused\n\nfor cd commands and such, you'll need to run those within a shell:\r\n```\r\ncommand(\"sh\", \"-c\", \"cd $dir && ls \")\r\n```\n\n@manusa i can run cd command successful use the code: execwatch watch = kubernetesclientcontainer.getclient().pods().innamespace(namespace).withname(podname).readinginput(system.in)\r\n .writingoutput(system.ou"} +{"url": "https://github.com/lando/lando/issues/2834", "category": "OCI runtime exec failed", "rule": "", "title": "BUG: Lando drush error : OCI runtime exec failed: exec failed ", "excerpt": "bug: lando drush error : oci runtime exec failed: exec failed \nhi, i am new to lando, my drupal 8 project was running fine with the initial set up. lando drush failed after i tried to upgrade to the newest version of lando. uninstall/reinstall everything couldn't resolve this problem. i having been stuck on this lando drush problem for a week. please help if you can. \r\n\r\nos: windows 10\r\nlando v3.0.14 (still need to use this version as our drupal project is still on composer 1)\r\ndocker desktop: 2.3.0.5 (comes with lando installation)\r\n\r\n> lando.yml \r\nname: testportal3\r\nrecipe: drupal8\r\nconfig:\r\n webroot: ./docroot\r\n php: 7.4\r\n drush: ^8.4.5 \r\n mysql: 5.7\r\ntooling:\r\n drush:\r\n service: appserver\r\n cmd: 'd"} +{"url": "https://github.com/cplee/github-actions-demo/issues/5", "category": "OCI runtime exec failed", "rule": "", "title": "starting container process caused: exec: \"bash\": executable file not found in $PATH: unknown", "excerpt": "ux-x64\r\n[ci/test] \ud83d\udcac ::debug::destination /opt/hostedtoolcache/node/10.23.1/x64\r\n[ci/test] \ud83d\udcac ::debug::finished caching tool\r\n[ci/test] \u2699 ::add-path:: /opt/hostedtoolcache/node/10.23.1/x64/bin\r\n| [command]/opt/hostedtoolcache/node/10.23.1/x64/bin/node --version\r\n| v10.23.1\r\n| [command]/opt/hostedtoolcache/node/10.23.1/x64/bin/npm --version\r\n| 6.14.10\r\n[ci/test] \u2753 ##[add-matcher]/actions/actions-setup-node@v1/.github/tsc.json\r\n[ci/test] \u2753 ##[add-matcher]/actions/actions-setup-node@v1/.github/eslint-stylish.json\r\n[ci/test] \u2753 ##[add-matcher]/actions/actions-setup-node@v1/.github/eslint-compact.json\r\n[ci/test] \u2705 success - actions/setup-node@v1\r\n[ci/test] \u2b50 run npm install\r\n| oci runtime exec failed: exec failed: container_linux.go:370: starting container process caused: exec: \"bash\": executable file not found in $path: unknown\r\n[ci/test] \u274c failure - npm install\r\nerror: exit with `failure`: 126\r\n```\n\n\r\n[temporary workaround](https://github.com/nektos/act/issues/451#issuecomment-754307431)"} +{"url": "https://github.com/farend/redmine_message_customize/issues/40", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Fix .circleci/config.yml", "excerpt": "fix .circleci/config.yml\nrecent tests have failed with the following error:\r\n\r\n```\r\nerror: database is uninitialized and superuser password is not specified.\r\n you must specify postgres_password to a non-empty value for the\r\n superuser. for example, \"-e postgres_password=password\" on \"docker run\".\r\n\r\n you may also use \"postgres_host_auth_method=trust\" to allow all\r\n connections without a password. this is *not* recommended.\r\n\r\n see postgresql documentation about \"trust\":\r\n https://www.postgresql.org/docs/current/auth-trust.html\r\n```\n\ni will try update orb\r\nhttps://circleci.com/developer/orbs/orb/agileware-jp/redmine-plugin\n\nmerged: #41"} +{"url": "https://github.com/OpenVAA/voting-advice-application/issues/114", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Investigate \"Error: Database is uninitialized and superuser password is not specified.\" error in Postgres container", "excerpt": "investigate \"error: database is uninitialized and superuser password is not specified.\" error in postgres container\nwhen setting up the app in @jayabidari 's computer, we encountered \"error: database is uninitialized and superuser password is not specified.\" error from postgres container, and the container was stuck in a restart loop. running npm run again solved the issue, but should be checked if that is something to consider for future setup instructions."} +{"url": "https://github.com/docker/for-mac/issues/5239", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Apple Silicon: Automatic detection of the CPU-architecture of the pull/run image", "excerpt": " preview already automatically uses the arm64 images from multi-arch images. \r\ni did a quick check on one of our m1 machines and it works fine for me:\r\n\r\n```\r\n$ docker run postgres:13-alpine\r\nunable to find image 'postgres:13-alpine' locally\r\n13-alpine: pulling from library/postgres\r\n159e5727ea61: already exists \r\nd20223af9aac: pull complete \r\n2482f57ac4ab: pull complete \r\nc8812dbcb6a5: pull complete \r\nafb4f04eea5c: pull complete \r\n3f725905c09b: pull complete \r\n8bbfc23e7ec3: pull complete \r\n469ca852de68: pull complete \r\ndigest: sha256:0b6f8681377407396a54512812789bd311afd40b2b4e2bd66e9d98da6632bd8e\r\nstatus: downloaded newer image for postgres:13-alpine\r\nerror: database is uninitialized and superuser password is not specified.\r\n you must specify postgres_password to a non-empty value for the\r\n superuser. for example, \"-e postgres_password=password\" on \"docker run\".\r\n\r\n you may also use \"postgres_host_auth_method=trust\" to allow all\r\n connections without a password. this is *not* recommended.\r\n\r\n see postgresql documentation about \"trust\":\r\n https://www.postgresql.org/docs/current/auth-trust.html\r\n\r\n$ docker inspect --format \"{{ .architecture }}\" postgres:13-alpine\r\narm64\r\n\r\n$ docker pull postgres:13-alpine\r\n13-alpine: pulling from library/postgres\r\ndigest: sha256:0b6f8681377407396a54512812789bd311afd40b2b4e2bd66e9d98da6632bd8e\r\nstatus: image "} +{"url": "https://github.com/TandoorRecipes/recipes/issues/444", "category": "app config/env missing at runtime", "rule": "(learned)", "title": "Lost data after upgrade", "excerpt": "21-02-21 17:51:48 +0000] [1] [info] starting gunicorn 20.0.4,\r\n[2021-02-21 17:51:48 +0000] [1] [info] listening at: http://0.0.0.0:8080 (1),\r\n[2021-02-21 17:51:48 +0000] [1] [info] using worker: sync,\r\n[2021-02-21 17:51:48 +0000] [15] [info] booting worker with pid: 15,\r\n```\r\n\r\nwhen i stop `web_recipes_1` and start `recipe`, the web front end loads (on port 8099 rather than 8090, which is specified for this nginx container in my compose file), but all of my old data is gone. i had to set up a new account.\r\n\r\n\r\nlooking at the log for `docker_db_recipes`, there are repeated errors identical to this one. so the old database is... gone? misconfigured? \r\n```\r\nerror: database is uninitialized and superuser password is not specified.,\r\n you must specify postgres_password to a non-empty value for the,\r\n superuser. for example, \"-e postgres_password=password\" on \"docker run\".,\r\n,\r\n you may also use \"postgres_host_auth_method=trust\" to allow all,\r\n connections without a password. this is *not* recommended.,\r\n,\r\n see postgresql documentation about \"trust\":,\r\n https://www.postgresql.org/docs/current/auth-trust.html,\r\n```\r\n \r\ni unfortunately am stupid and had not gotten around to backing up data for this project yet. so i'd love to be able to reconnect at least temporarily to rescue the data, and then set this thing up properly, which i obviously did not "} diff --git a/bench/mine.py b/bench/mine.py new file mode 100644 index 0000000..5c2f63c --- /dev/null +++ b/bench/mine.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +"""Mine GitHub issues for container deployment failures. + +For each failure category, searches GitHub issues for the error message Docker +prints, records how many issues match (a prevalence proxy) and saves a sample +for manual labelling. Categories preflight does not cover are included on +purpose, so coverage is measured against all common failures, not only the +ones the tool was designed for. + +Requires the `gh` CLI, logged in. Usage: python3 bench/mine.py [--sample N] +""" +import argparse, csv, json, os, subprocess, sys, time, urllib.parse + +# category, preflight rule covering it ("" = not covered), search phrase +CATEGORIES = [ + ("platform: exec format error", "image.platform", '"exec format error" docker'), + ("platform: no matching manifest", "image.platform", '"no matching manifest for"'), + ("platform: requested platform mismatch", "image.platform", '"does not match the detected host platform"'), + ("image: tag/repo not found", "image.exists", '"manifest unknown" docker'), + ("image: pull access denied", "image.exists", '"pull access denied" "may require"'), + ("credentials helper missing", "registry.credentials",'"error getting credentials" "docker-credential"'), + ("build: COPY source not found", "build.context", '"failed to compute cache key" "not found"'), + ("build: COPY failed legacy", "build.context", '"COPY failed: file not found in build context"'), + ("build: outside build context", "build.context", '"forbidden path outside the build context"'), + ("build: BuildKit required", "build.buildkit", '"requires BuildKit"'), + ("compose: required variable", "compose.env", '"required variable" "is missing a value"'), + ("compose: variable not set", "compose.env", '"variable is not set. Defaulting to a blank string"'), + ("compose: unsupported property", "compose.version", '"additional property" "is not allowed" compose'), + ("port already allocated", "ports.conflict,ports.host", '"port is already allocated"'), + ("address already in use", "ports.host", '"address already in use" docker'), + ("rootless privileged port", "ports.host", '"cannot expose privileged port"'), + ("bind: dir onto file", "mounts.bind", '"Are you trying to mount a directory onto a file"'), + ("bind: source does not exist", "mounts.bind", '"bind source path does not exist"'), + ("desktop: mounts denied", "mounts.sharing", '"Mounts denied" "is not shared from the host"'), + ("memory: OOMKilled", "resources.memory", 'OOMKilled "exit code 137"'), + ("memory: mssql minimum", "resources.memory", '"requires a machine with at least 2000 megabytes"'), + ("disk: no space left", "resources.disk,host.disk", '"no space left on device" docker pull'), + ("gpu: no device driver", "resources.gpu", '"could not select device driver" "capabilities: [[gpu]]"'), + ("kernel: vm.max_map_count", "kernel.sysctl", '"vm.max_map_count" "is too low"'), + ("daemon: cannot connect", "(root cause)", '"Cannot connect to the Docker daemon"'), + ("emulation: qemu crash", "image.platform", '"qemu: uncaught target signal"'), + # Not covered by preflight: measured to keep coverage claims honest. + ("volume permission denied", "", 'docker volume "permission denied" container'), + ("DNS resolution in container", "", '"Temporary failure in name resolution" docker'), + ("container healthcheck unhealthy", "", '"is unhealthy" "dependency failed to start"'), + ("network not found", "", 'docker "network" "not found" compose'), + ("OCI runtime exec failed", "", '"OCI runtime exec failed"'), + ("app config/env missing at runtime", "(learned)", '"Database is uninitialized and superuser password is not specified"'), +] + +def gh_api(path): + for attempt in range(5): + r = subprocess.run(["gh", "api", "-H", "Accept: application/vnd.github+json", path], + capture_output=True, text=True) + if r.returncode == 0: + return json.loads(r.stdout) + if "rate limit" in r.stderr.lower() or "403" in r.stderr: + time.sleep(20 * (attempt + 1)) + continue + raise RuntimeError(r.stderr.strip()) + raise RuntimeError("rate limited") + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--sample", type=int, default=30) + ap.add_argument("--since", default="2021-01-01") + ap.add_argument("--out", default=os.path.join(os.path.dirname(__file__), "data")) + args = ap.parse_args() + os.makedirs(args.out, exist_ok=True) + + rows = [] + for cat, rule, phrase in CATEGORIES: + q = f"{phrase} is:issue created:>={args.since}" + res = gh_api("search/issues?per_page=%d&q=%s" % (args.sample, urllib.parse.quote(q))) + items = [{ + "url": i["html_url"], "title": i["title"], + "repo": i["repository_url"].split("/repos/")[1], + "created": i["created_at"], "state": i["state"], "comments": i["comments"], + } for i in res.get("items", [])] + slug = "".join(c if c.isalnum() else "-" for c in cat.lower()).strip("-") + with open(os.path.join(args.out, f"{slug}.json"), "w") as f: + json.dump({"category": cat, "rule": rule, "query": q, + "total": res["total_count"], "sample": items}, f, indent=1) + rows.append((cat, rule, res["total_count"])) + print(f"{res['total_count']:>7} {cat}", file=sys.stderr) + time.sleep(2.5) # search API: 30 requests/minute + + with open(os.path.join(args.out, "counts.csv"), "w", newline="") as f: + w = csv.writer(f) + w.writerow(["category", "preflight_rule", "github_issues_since_" + args.since]) + w.writerows(sorted(rows, key=lambda r: -r[2])) + +if __name__ == "__main__": + main() diff --git a/bench/precision.py b/bench/precision.py new file mode 100644 index 0000000..fb71d8d --- /dev/null +++ b/bench/precision.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +"""Estimate how many search hits really contain each category's error. + +GitHub issue search matches words loosely, so raw counts overstate +prevalence. For every sampled issue, this fetches the body and comments and +checks for the category's exact error text. precision = verified / sampled, +and adjusted = total × precision. +""" +import csv, glob, json, os, re, subprocess, sys + +# Exact text (lowercase) that must appear for an issue to count. +MUST = { + "platform: exec format error": ["exec format error"], + "platform: no matching manifest": ["no matching manifest for"], + "platform: requested platform mismatch": ["does not match the detected host platform"], + "image: tag/repo not found": ["manifest unknown"], + "image: pull access denied": ["pull access denied"], + "credentials helper missing": ["error getting credentials"], + "build: COPY source not found": ["failed to compute cache key"], + "build: COPY failed legacy": ["copy failed: file not found in build context"], + "build: outside build context": ["outside the build context"], + "build: BuildKit required": ["requires buildkit"], + "compose: required variable": ["is missing a value"], + "compose: variable not set": ["variable is not set. defaulting to a blank string"], + "compose: unsupported property": ["additional property", "not allowed"], + "port already allocated": ["port is already allocated"], + "address already in use": ["address already in use"], + "rootless privileged port": ["cannot expose privileged port"], + "bind: dir onto file": ["mount a directory onto a file"], + "bind: source does not exist": ["bind source path does not exist"], + "desktop: mounts denied": ["mounts denied"], + "memory: OOMKilled": ["oomkilled"], + "memory: mssql minimum": ["at least 2000 megabytes"], + "disk: no space left": ["no space left on device"], + "gpu: no device driver": ["could not select device driver"], + "kernel: vm.max_map_count": ["vm.max_map_count", "too low"], + "daemon: cannot connect": ["cannot connect to the docker daemon"], + "emulation: qemu crash": ["qemu: uncaught target signal"], + "volume permission denied": ["permission denied"], + "DNS resolution in container": ["temporary failure in name resolution"], + "container healthcheck unhealthy": ["is unhealthy"], + "network not found": [re.compile(r"network \S+ (not found|declared as external, but could not be found)")], + "OCI runtime exec failed": ["oci runtime exec failed"], + "app config/env missing at runtime": ["superuser password is not specified"], +} + +def text_of(url): + path = url.replace("https://github.com/", "repos/").replace("/issues/", "/issues/", 1) + parts = [] + for p in (path, path + "/comments?per_page=50"): + r = subprocess.run(["gh", "api", p], capture_output=True, text=True) + if r.returncode != 0: + continue + data = json.loads(r.stdout) + items = data if isinstance(data, list) else [data] + for it in items: + parts.append((it.get("title") or "") + "\n" + (it.get("body") or "")) + return "\n".join(parts).lower() + +def main(): + here = os.path.join(os.path.dirname(__file__), "data") + rows = [] + for path in sorted(glob.glob(os.path.join(here, "*.json"))): + d = json.load(open(path)) + must = MUST[d["category"]] + verified = 0 + for item in d["sample"]: + if "verified" not in item: + t = text_of(item["url"]) + item["verified"] = all((m.search(t) is not None) if hasattr(m, "search") else (m in t) for m in must) + verified += item["verified"] + n = len(d["sample"]) + d["precision"] = verified / n if n else 0 + d["adjusted"] = round(d["total"] * d["precision"]) + json.dump(d, open(path, "w"), indent=1) + rows.append((d["category"], d["rule"], d["total"], n, verified, round(d["precision"], 2), d["adjusted"])) + print(f"{d['adjusted']:>7} adj {verified:>2}/{n:<2} {d['category']}", file=sys.stderr) + with open(os.path.join(here, "counts.csv"), "w", newline="") as f: + w = csv.writer(f) + w.writerow(["category", "preflight_rule", "raw_hits", "sampled", "verified", "precision", "adjusted_estimate"]) + w.writerows(sorted(rows, key=lambda r: -r[6])) + +if __name__ == "__main__": + main() diff --git a/bench/sample.py b/bench/sample.py new file mode 100644 index 0000000..22e8a88 --- /dev/null +++ b/bench/sample.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +"""Draw a stratified, seeded sample of verified issues for labelling. + +Takes N verified issues per category and saves a condensed excerpt of each +(title plus the text around the error) to labels/sample.jsonl. +""" +import glob, json, os, random, subprocess, sys + +sys.path.insert(0, os.path.dirname(__file__)) +from precision import MUST # noqa: E402 + +N, SEED, WINDOW = 4, 20260924, 700 + +def fetch(url): + path = url.replace("https://github.com/", "repos/") + out = [] + for p in (path, path + "/comments?per_page=30"): + r = subprocess.run(["gh", "api", p], capture_output=True, text=True) + if r.returncode == 0: + d = json.loads(r.stdout) + for it in (d if isinstance(d, list) else [d]): + out.append((it.get("body") or "")) + return "\n---\n".join(out) + +def excerpt(text, needle): + low = text.lower() + if hasattr(needle, "search"): + m = needle.search(low) + i = m.start() if m else -1 + else: + i = low.find(needle) + if i < 0: + return text[:WINDOW * 2] + return text[max(0, i - WINDOW):i + WINDOW] + +def main(): + here = os.path.dirname(__file__) + rng = random.Random(SEED) + out = open(os.path.join(here, "labels", "sample.jsonl"), "w") + for path in sorted(glob.glob(os.path.join(here, "data", "*.json"))): + d = json.load(open(path)) + pool = [i for i in d["sample"] if i.get("verified")] + for item in rng.sample(pool, min(N, len(pool))): + body = fetch(item["url"]) + out.write(json.dumps({ + "url": item["url"], "category": d["category"], "rule": d["rule"], + "title": item["title"], "excerpt": excerpt(body, MUST[d["category"]][0]), + }) + "\n") + print(d["category"], file=sys.stderr) + +if __name__ == "__main__": + main() diff --git a/bench/table.py b/bench/table.py new file mode 100644 index 0000000..011aa29 --- /dev/null +++ b/bench/table.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +"""Write the paper's category table from data/counts.csv.""" +import csv, os +here = os.path.dirname(__file__) +rows = list(csv.DictReader(open(os.path.join(here, "data", "counts.csv")))) +esc = lambda s: s.replace("_", r"\_").replace("&", r"\&").replace("%", r"\%") +out = [r"\begin{table}[t]", r"\centering\scriptsize", + r"\caption{Failure categories: GitHub issues since 2021 matching each error, precision of the search (share of 30 sampled issues containing the exact error text), and adjusted estimate. Rule ``--'' marks categories \tool{} does not target; $\dagger$ marks a rule added after mining.}", + r"\label{tab:categories}", + r"\begin{tabular}{@{}llrrr@{}}", r"\toprule", + r"Category & Rule & Hits & Precision & Adjusted \\", r"\midrule"] +for r in rows: + rule = r["preflight_rule"] or "--" + added = r["category"] == "volume permission denied" # rule added after mining + if added: + rule = "mounts.permissions" + rule = r"\texttt{" + esc(rule.split(",")[0]) + "}" if rule not in ("--", "(root cause)", "(learned)") else esc(rule) + if added: + rule += "$^\\dagger$" + out.append(f"{esc(r['category'])} & {rule} & {int(r['raw_hits']):,} & {float(r['precision']):.2f} & {int(r['adjusted_estimate']):,} \\\\") +out += [r"\bottomrule", r"\end{tabular}", r"\end{table}"] +open(os.path.join(here, "..", "paper", "categories.tex"), "w").write("\n".join(out) + "\n") diff --git a/cmd/check.go b/cmd/check.go index 27518a6..5ea0d47 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -1,6 +1,5 @@ /* Copyright © 2026 NAME HERE - */ package cmd @@ -10,29 +9,29 @@ import ( "github.com/spf13/cobra" - "github.com/raphgm/container-doctor/internal/engine" - "github.com/raphgm/container-doctor/internal/executor" - "github.com/raphgm/container-doctor/internal/renderer" - "github.com/raphgm/container-doctor/pkg/report" - "github.com/raphgm/container-doctor/providers/docker" - dockerChecks "github.com/raphgm/container-doctor/providers/docker/checks" - "github.com/raphgm/container-doctor/providers/compose" - composeChecks "github.com/raphgm/container-doctor/providers/compose/checks" - "github.com/raphgm/container-doctor/providers/buildx" - buildxChecks "github.com/raphgm/container-doctor/providers/buildx/checks" - "github.com/raphgm/container-doctor/providers/system" - systemChecks "github.com/raphgm/container-doctor/providers/system/checks" + "github.com/raphgm/container-preflight/internal/engine" + "github.com/raphgm/container-preflight/internal/executor" + "github.com/raphgm/container-preflight/internal/renderer" + "github.com/raphgm/container-preflight/pkg/report" + "github.com/raphgm/container-preflight/providers/buildx" + buildxChecks "github.com/raphgm/container-preflight/providers/buildx/checks" + "github.com/raphgm/container-preflight/providers/compose" + composeChecks "github.com/raphgm/container-preflight/providers/compose/checks" + "github.com/raphgm/container-preflight/providers/docker" + dockerChecks "github.com/raphgm/container-preflight/providers/docker/checks" + "github.com/raphgm/container-preflight/providers/system" + systemChecks "github.com/raphgm/container-preflight/providers/system/checks" ) // checkCmd represents the check command var checkCmd = &cobra.Command{ - Use: "check", - Short: "Run all registered diagnostic checks", + Use: "host", + Short: "Check this machine's Docker installation and resources", Long: `Run all diagnostic checks to determine the health of your environment. This will query all providers (Docker, Kubernetes, etc.) and generate a report.`, Run: func(cmd *cobra.Command, args []string) { exec := executor.New() - + reg := engine.NewRegistry() reg.Register(system.New( @@ -49,7 +48,7 @@ This will query all providers (Docker, Kubernetes, etc.) and generate a report.` dockerChecks.NewVersion(exec), dockerChecks.NewSocket(exec), )) - + reg.Register(compose.New( composeChecks.NewInstalled(exec), )) @@ -57,10 +56,10 @@ This will query all providers (Docker, Kubernetes, etc.) and generate a report.` reg.Register(buildx.New( buildxChecks.NewInstalled(exec), )) - + eng := engine.New(reg) rep := eng.Run(cmd.Context()) - + var rnd renderer.Renderer switch format { case "json": @@ -74,12 +73,12 @@ This will query all providers (Docker, Kubernetes, etc.) and generate a report.` default: rnd = renderer.NewTerminal() } - + if err := rnd.Render(rep); err != nil { fmt.Printf("Error rendering report: %v\n", err) os.Exit(1) } - + for _, p := range rep.Providers { for _, r := range p.Results { if r.Status == report.Fail { diff --git a/cmd/learn.go b/cmd/learn.go new file mode 100644 index 0000000..a0796dd --- /dev/null +++ b/cmd/learn.go @@ -0,0 +1,247 @@ +package cmd + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + osexec "os/exec" + "regexp" + "sort" + "strings" + "time" + + "github.com/spf13/cobra" + + "github.com/raphgm/container-preflight/pkg/preflight" + "github.com/raphgm/container-preflight/pkg/preflight/learn" + "github.com/raphgm/container-preflight/pkg/preflight/project" + "github.com/raphgm/container-preflight/pkg/preflight/rules" +) + +var ( + learnDir string + learnService string + learnFix string + learnLog string + learnSuccess bool + learnForce bool +) + +var learnCmd = &cobra.Command{ + Use: "learn [flags] -- ", + Short: "Turn a real failure into a preflight rule", + Long: `Learn runs a command (usually ` + "`docker compose up`" + `), and if it fails, extracts +the decisive error line and records the project and host conditions at the +time as a rule in ` + learn.File + `. Preflight then predicts that failure +wherever the same conditions hold. Commit the file to share it. + +A second failure with the same error generalizes the rule (conditions that +differ are dropped). Recording a working run with --success refines rules it +contradicts. + + container-preflight learn -- docker compose up db + container-preflight learn --log build.log --service web + container-preflight learn --success -- docker compose up -d`, + RunE: func(cmd *cobra.Command, args []string) error { + output, failed, err := learnInput(args) + if err != nil { + return err + } + + env, err := preflight.Prepare(cmd.Context(), preflight.Options{Dir: learnDir}) + if err != nil { + return err + } + store, err := learn.Load(env.Project.Dir) + if err != nil { + return err + } + hostName, _ := os.Hostname() + + if !failed || learnSuccess { + return recordSuccess(env, store, hostName) + } + + f, ok := learn.Extract(output) + if !ok { + return errors.New("the command failed, but no line in its output explains why; pass the log with --log and --service") + } + if learnService != "" { + f.Service = learnService + } + svc := findService(env.Project, f.Service) + if svc == nil { + return fmt.Errorf("cannot tell which service failed (saw %q); pass --service", f.Service) + } + + fmt.Printf("\nFailure in %s: %s\n", svc.Name, f.Line) + + if !learnForce { + if rule, ok := alreadyPredicted(cmd, env, svc.Name, f.Line); ok { + fmt.Printf("✓ Already predicted by built-in rule %s. Nothing new to learn.\n", rule) + return nil + } + } + + out := store.ObserveFailure(f, rules.Features(env, svc), hostName) + if learnFix != "" { + out.Rule.Fix = learnFix + } + if err := store.Save(); err != nil { + return err + } + + if out.Created { + fmt.Printf("✓ Learned new rule %s\n", out.Rule.ID) + } else { + fmt.Printf("✓ Rule %s seen again (%d failures)\n", out.Rule.ID, len(out.Rule.Failures)) + if len(out.Dropped) > 0 { + fmt.Printf(" generalized: dropped %s\n", strings.Join(out.Dropped, ", ")) + } + } + fmt.Printf(" signature: %s\n", out.Rule.Signature) + fmt.Printf(" predicts it when: %s\n", conditions(out.Rule.When)) + fmt.Printf(" saved to %s — commit it to share with your team\n\n", store.Path()) + return nil + }, +} + +func init() { + rootCmd.AddCommand(learnCmd) + learnCmd.Flags().StringVarP(&learnDir, "dir", "C", ".", "Project directory") + learnCmd.Flags().StringVarP(&learnService, "service", "s", "", "Service that failed (detected from Compose output when omitted)") + learnCmd.Flags().StringVar(&learnFix, "fix", "", "Fix to show when the rule predicts this failure") + learnCmd.Flags().StringVar(&learnLog, "log", "", "Learn from a saved log file (- for stdin) instead of running a command") + learnCmd.Flags().BoolVar(&learnSuccess, "success", false, "Record a working run to refine learned rules") + learnCmd.Flags().BoolVar(&learnForce, "force", false, "Learn even if a built-in rule already predicts the failure") +} + +// learnInput runs the command (echoing its output) or reads the log. +func learnInput(args []string) (string, bool, error) { + if learnLog != "" { + var r io.Reader = os.Stdin + if learnLog != "-" { + f, err := os.Open(learnLog) + if err != nil { + return "", false, err + } + defer f.Close() + r = f + } + b, err := io.ReadAll(r) + return string(b), true, err + } + if len(args) == 0 { + if learnSuccess { + return "", false, nil + } + return "", false, errors.New("give a command after --, or --log") + } + + var buf bytes.Buffer + c := osexec.Command(args[0], args[1:]...) + c.Dir = learnDir + c.Stdin = os.Stdin + c.Stdout = io.MultiWriter(os.Stdout, &buf) + c.Stderr = io.MultiWriter(os.Stderr, &buf) + err := c.Run() + var exit *osexec.ExitError + if err != nil && !errors.As(err, &exit) { + return "", false, err + } + // `docker compose up` exits 0 even when a container crashes. + failed := err != nil || containerExited.MatchString(buf.String()) + return buf.String(), failed, nil +} + +var containerExited = regexp.MustCompile(`exited with code [1-9]\d*`) + +func recordSuccess(env *rules.Env, store *learn.Store, hostName string) error { + targets := env.Project.Services + if learnService != "" { + svc := findService(env.Project, learnService) + if svc == nil { + return fmt.Errorf("no service %q", learnService) + } + targets = []*project.Service{svc} + } + var touched []*learn.Learned + for _, svc := range targets { + touched = append(touched, store.ObserveSuccess(svc.Name, rules.Features(env, svc), hostName)...) + } + if len(touched) == 0 { + fmt.Println("\n✓ Run succeeded; no learned rule predicted a failure here.") + return nil + } + if err := store.Save(); err != nil { + return err + } + fmt.Println("\n✓ Run succeeded where learned rules predicted failure; refined:") + for _, r := range touched { + fmt.Printf(" %s → %s (when: %s)\n", r.ID, r.Status, conditions(r.When)) + } + return nil +} + +func findService(p *project.Project, name string) *project.Service { + for _, s := range p.Services { + if s.Name == name { + return s + } + } + if name == "" && len(p.Services) == 1 { + return p.Services[0] + } + return nil +} + +// alreadyPredicted reports a built-in rule whose predicted error is the +// failure that happened. +func alreadyPredicted(cmd *cobra.Command, env *rules.Env, service, line string) (string, bool) { + rep := preflight.Evaluate(cmd.Context(), env, rules.All(), nil, time.Now()) + for _, f := range rep.Findings { + if f.Predicts == "" || (f.Service != "" && f.Service != service) { + continue + } + if similar(f.Predicts, line) { + return f.Rule, true + } + } + return "", false +} + +var word = regexp.MustCompile(`[a-zA-Z]{3,}`) + +// similar is true when most words of the predicted message occur in the +// observed line. +func similar(predicted, observed string) bool { + have := map[string]bool{} + for _, w := range word.FindAllString(strings.ToLower(observed), -1) { + have[w] = true + } + words := word.FindAllString(strings.ToLower(predicted), -1) + if len(words) == 0 { + return false + } + hit := 0 + for _, w := range words { + if have[w] { + hit++ + } + } + return hit*10 >= len(words)*6 +} + +func conditions(when map[string]string) string { + if len(when) == 0 { + return "(always — record a --success run to refine)" + } + var out []string + for k, v := range when { + out = append(out, k+"="+v) + } + sort.Strings(out) + return strings.Join(out, ", ") +} diff --git a/cmd/preflight.go b/cmd/preflight.go new file mode 100644 index 0000000..ca146a8 --- /dev/null +++ b/cmd/preflight.go @@ -0,0 +1,197 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "github.com/spf13/cobra" + + "github.com/raphgm/container-preflight/pkg/preflight" + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/host" +) + +var ( + preflightFormat string + preflightOffline bool + preflightHost string + preflightRun string +) + +var preflightCmd = &cobra.Command{ + Use: "check [path]", + Aliases: []string{"preflight"}, + Short: "Predict whether a project will build and run on this machine", + Long: `Preflight reads the project's Compose file and Dockerfiles, profiles this +host (the Docker daemon, its VM, tooling, ports, kernel settings) and queries +registries for image platforms and sizes. It then predicts the failures +` + "`docker compose up`" + ` would hit, before anything runs. + +Checks that cannot run because something upstream is broken are grouped +under that root cause instead of being reported as separate failures.`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + dir := "." + if len(args) > 0 { + dir = args[0] + } + opts := preflight.Options{Dir: dir, Offline: preflightOffline, Command: preflightRun} + if preflightHost != "" { + snap, err := host.LoadSnapshot(preflightHost) + if err != nil { + return err + } + opts.Host = snap + } + rep, err := preflight.Run(cmd.Context(), opts) + if err != nil { + return err + } + switch preflightFormat { + case "json": + enc := json.NewEncoder(os.Stdout) + enc.SetIndent("", " ") + if err := enc.Encode(rep); err != nil { + return err + } + default: + renderPreflight(os.Stdout, rep, useColor()) + } + if rep.Errors() > 0 { + os.Exit(1) + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(preflightCmd) + preflightCmd.Flags().StringVarP(&preflightFormat, "format", "f", "term", "Output format (term, json)") + preflightCmd.Flags().BoolVar(&preflightOffline, "offline", false, "Skip registry lookups") + preflightCmd.Flags().StringVar(&preflightRun, "run", "", "Check a `docker run`, `docker create` or `docker pull` command instead of a Compose project") + preflightCmd.Flags().StringVar(&preflightHost, "host", "", "Predict for the machine in this snapshot file instead of this one (see `snapshot`)") +} + +type palette struct{ red, yellow, green, dim, bold, reset string } + +func useColor() bool { + if os.Getenv("NO_COLOR") != "" { + return false + } + st, err := os.Stdout.Stat() + return err == nil && st.Mode()&os.ModeCharDevice != 0 +} + +func renderPreflight(w io.Writer, rep *preflight.Report, color bool) { + c := palette{} + if color { + c = palette{"\033[31m", "\033[33m", "\033[32m", "\033[2m", "\033[1m", "\033[0m"} + } + icon := func(s fact.Severity) string { + switch s { + case fact.Error: + return c.red + "✗" + c.reset + case fact.Warning: + return c.yellow + "!" + c.reset + } + return c.dim + "i" + c.reset + } + + h := rep.Host + fmt.Fprintf(w, "\n%sContainer Preflight · preflight%s %s%s%s\n", c.bold, c.reset, c.dim, rep.Dir, c.reset) + if rep.HostName != "" { + fmt.Fprintf(w, "%sPredicting for snapshot of %s%s\n", c.yellow, rep.HostName, c.reset) + } + var hostBits []string + if h.OperatingSystem != "" { + hostBits = append(hostBits, h.OperatingSystem, h.Platform, humanSize(h.MemTotal)+" RAM for containers") + } + if h.ComposeVersion != "" { + hostBits = append(hostBits, "Compose "+h.ComposeVersion) + } + if h.BuildxInstalled { + hostBits = append(hostBits, "buildx "+h.BuildxVersion) + } + if len(hostBits) > 0 { + fmt.Fprintf(w, "%sHost: %s%s\n", c.dim, strings.Join(hostBits, " · "), c.reset) + } + + if len(rep.Roots) > 0 { + fmt.Fprintf(w, "\n%sROOT CAUSES%s\n", c.bold, c.reset) + for _, rc := range rep.Roots { + fmt.Fprintf(w, " %s %s\n", icon(rc.Severity), rc.Summary) + if rc.Detail != "" { + fmt.Fprintf(w, " %s%s%s\n", c.dim, rc.Detail, c.reset) + } + if rc.Fix != "" { + fmt.Fprintf(w, " fix: %s\n", rc.Fix) + } + if len(rc.Blocks) > 0 { + fmt.Fprintf(w, " %sblocks %d check(s): %s%s\n", c.dim, len(rc.Blocks), strings.Join(rc.Blocks, ", "), c.reset) + } + } + } + + var errs, warns int + for _, f := range rep.Findings { + switch f.Severity { + case fact.Error: + errs++ + case fact.Warning: + warns++ + } + } + if len(rep.Findings) > 0 { + fmt.Fprintf(w, "\n%sPREDICTED PROBLEMS%s %d error(s), %d warning(s)\n", c.bold, c.reset, errs, warns) + for _, f := range rep.Findings { + where := "" + if f.Service != "" { + where = "[" + f.Service + "] " + } + fmt.Fprintf(w, " %s %s%s", icon(f.Severity), where, f.Title) + if f.Location != "" { + fmt.Fprintf(w, " %s%s%s", c.dim, f.Location, c.reset) + } + fmt.Fprintln(w) + for _, e := range f.Evidence { + fmt.Fprintf(w, " %s%s%s\n", c.dim, e, c.reset) + } + if f.Predicts != "" { + fmt.Fprintf(w, " %swould fail with:%s %q\n", c.dim, c.reset, f.Predicts) + } + if f.Fix != "" { + fmt.Fprintf(w, " fix: %s\n", f.Fix) + } + } + } + + if len(rep.Passed) > 0 { + fmt.Fprintf(w, "\n%s✓ passed:%s %s%s%s\n", c.green, c.reset, c.dim, strings.Join(rep.Passed, ", "), c.reset) + } + + total := rep.Errors() + fmt.Fprintln(w) + if total > 0 { + fmt.Fprintf(w, "%s%s✗ Will fail:%s %d blocking problem(s) predicted %s(%s)%s\n\n", c.bold, c.red, c.reset, total, c.dim, rep.Duration.Round(1e6), c.reset) + } else if warns > 0 { + fmt.Fprintf(w, "%s%s! Should run%s, with %d warning(s) %s(%s)%s\n\n", c.bold, c.yellow, c.reset, warns, c.dim, rep.Duration.Round(1e6), c.reset) + } else { + fmt.Fprintf(w, "%s%s✓ Ready to run%s %s(%s)%s\n\n", c.bold, c.green, c.reset, c.dim, rep.Duration.Round(1e6), c.reset) + } +} + +func humanSize(n int64) string { + const unit = 1024 + if n < unit { + return fmt.Sprintf("%d B", n) + } + div, exp := int64(unit), 0 + for m := n / unit; m >= unit; m /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %ciB", float64(n)/float64(div), "KMGTPE"[exp]) +} diff --git a/cmd/report.go b/cmd/report.go deleted file mode 100644 index 2bd1660..0000000 --- a/cmd/report.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright © 2026 NAME HERE - -*/ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -// reportCmd represents the report command -var reportCmd = &cobra.Command{ - Use: "report", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("report called") - }, -} - -func init() { - rootCmd.AddCommand(reportCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // reportCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // reportCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} diff --git a/cmd/root.go b/cmd/root.go index 6add7cd..9942511 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,5 @@ /* Copyright © 2026 NAME HERE - */ package cmd @@ -10,18 +9,14 @@ import ( "github.com/spf13/cobra" ) - - // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "container-doctor", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Use: "container-preflight", + Short: "Predict container failures before you run, and diagnose them at the root cause", + Long: `container-preflight checks whether a container project will build and run +on a given machine. ` + "`check`" + ` joins what the project needs (from its +Compose file and Dockerfiles) with what the host offers and what registries +publish, and reports each predicted failure once, at its root cause.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, @@ -41,11 +36,8 @@ func init() { // Cobra supports persistent flags, which, if defined here, // will be global for your application. - // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.container-doctor.yaml)") + // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.container-preflight.yaml)") // Cobra also supports local flags, which will only run // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } - - diff --git a/cmd/snapshot.go b/cmd/snapshot.go new file mode 100644 index 0000000..1fa9706 --- /dev/null +++ b/cmd/snapshot.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "encoding/json" + "os" + + "github.com/spf13/cobra" + + "github.com/raphgm/container-preflight/internal/executor" + "github.com/raphgm/container-preflight/pkg/preflight/host" +) + +var snapshotOut string + +var snapshotCmd = &cobra.Command{ + Use: "snapshot", + Short: "Save this machine's container capabilities to a file", + Long: `Snapshot records what this machine offers containers: Docker daemon +platform and memory, emulation, tooling versions, kernel settings, local +images and listening ports. Share the file, then run + + container-preflight preflight --host snapshot.json + +on any machine to predict whether a project will work on this one.`, + RunE: func(cmd *cobra.Command, args []string) error { + snap := host.Capture(cmd.Context(), executor.New()) + out := os.Stdout + if snapshotOut != "" && snapshotOut != "-" { + f, err := os.Create(snapshotOut) + if err != nil { + return err + } + defer f.Close() + out = f + } + enc := json.NewEncoder(out) + enc.SetIndent("", " ") + return enc.Encode(snap) + }, +} + +func init() { + rootCmd.AddCommand(snapshotCmd) + snapshotCmd.Flags().StringVarP(&snapshotOut, "output", "o", "", "Write to this file instead of stdout") +} diff --git a/cmd/version.go b/cmd/version.go index 435b4c7..69755dc 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,6 +1,5 @@ /* Copyright © 2026 NAME HERE - */ package cmd @@ -11,17 +10,14 @@ import ( ) // versionCmd represents the version command +// Version is set at build time with -ldflags "-X github.com/raphgm/container-preflight/cmd.Version=v1.0.0". +var Version = "dev" + var versionCmd = &cobra.Command{ Use: "version", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Short: "Print the container-preflight version", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("version called") + fmt.Println("container-preflight", Version) }, } diff --git a/docs/design/kubernetes.md b/docs/design/kubernetes.md new file mode 100644 index 0000000..52106a0 --- /dev/null +++ b/docs/design/kubernetes.md @@ -0,0 +1,65 @@ +# Preflight for Kubernetes: design sketch + +Status: proposal. Nothing here is implemented. + +## Idea + +Apply the same three-view join to Kubernetes. Predict whether a set of manifests (plain YAML, +Kustomize output or a rendered Helm chart) will schedule and start on a **specific cluster**, +before `kubectl apply`: + +| View | Docker today | Kubernetes | +|---|---|---| +| Requirements | Compose, Dockerfiles, `docker run` | Pods (from Deployments, StatefulSets, Jobs…), requests/limits, node selectors, affinity, tolerations, PVCs, Services, Ingress, ServiceAccounts | +| Capabilities | daemon, VM, ports, kernel | nodes (arch, OS, allocatable, taints, labels), quotas and LimitRanges, StorageClasses, IngressClasses, CRDs, admission policies, API versions | +| Registry | platforms, size, user | same, per container image, including image pull secrets | + +The cluster profile comes from read-only API calls (`get`/`list` only) or from a saved snapshot, +so the check can run from CI against a cluster it cannot reach, just as `snapshot` works for +Docker hosts. + +## Candidate rules + +Each rule predicts a concrete event or status that Kubernetes would report. + +| Rule | Predicts | +|---|---| +| `k8s.platform` | image has no variant for any schedulable node's arch → `exec format error`, `CrashLoopBackOff`, or no node can run it | +| `k8s.schedulable` | no node satisfies selectors, affinity, tolerations and requests together → `FailedScheduling: 0/N nodes are available` (with the per-reason breakdown the scheduler would give) | +| `k8s.capacity` | requests exceed allocatable, or sum exceeds free capacity → `Insufficient cpu/memory` | +| `k8s.quota` | requests exceed ResourceQuota or violate LimitRange → `exceeded quota` / `forbidden` | +| `k8s.storage` | PVC names a StorageClass that doesn't exist, access mode the class can't provide, or zone-bound volume vs node zones → PVC `Pending` | +| `k8s.api` | manifest uses an API version the cluster doesn't serve, or a CRD that isn't installed → `no matches for kind` | +| `k8s.image` | tag missing, private image without an `imagePullSecret` → `ErrImagePull` / `ImagePullBackOff` | +| `k8s.gpu` | `nvidia.com/gpu` requested but no node advertises it → `FailedScheduling … Insufficient nvidia.com/gpu` | +| `k8s.security` | Pod Security Admission level rejects `runAsRoot`, `hostPath`, privileged, etc. → `violates PodSecurity` | +| `k8s.memory-floor` | image with a known memory floor (SQL Server, Elasticsearch) under a limit below it → `OOMKilled` | +| `k8s.ports` | Service NodePort already used, `hostPort` conflicts on every eligible node | + +## What carries over + +- **Root-cause grouping.** Unreachable cluster, missing RBAC to list nodes, or an unknown CRD + becomes one root cause that blocks the rules that depend on it. It does not show up as a + dozen failures. +- **Learned rules.** `learn -- kubectl rollout status …` captures the failing event, for example + a `FailedScheduling` message or container exit reason, and records it with the pod's features. + Generalization and specialization work unchanged. +- **Registry metadata.** Reused as-is. + +## Related tools to position against + +- Manifest validators and linters (kubeconform, kube-score, Polaris) check manifests mostly in + isolation from a specific cluster. +- Replicated's troubleshoot.sh ships *preflight* checks that an application author writes by + hand for their own app. This proposal derives checks from the manifests themselves. The + name overlap needs a decision before any public release. +- openshift-preflight certifies operators and images for OpenShift. That is certification, + not deployment-failure prediction. + +## Evaluation plan + +Reuse the mining pipeline with Kubernetes error texts: `FailedScheduling`, `ImagePullBackOff`, +`no matches for kind`, `exceeded quota`, `violates PodSecurity`, `OOMKilled`, PVC `Pending`. +Stratify by category, freeze the rules before drawing a held-out sample, and validate in the +field on kind or minikube plus one managed cluster with mixed architectures (for example EKS +with Graviton and x86 node groups). diff --git a/docs/validation/2026-09-23-colima-m-series.md b/docs/validation/2026-09-23-colima-m-series.md new file mode 100644 index 0000000..8e53d0f --- /dev/null +++ b/docs/validation/2026-09-23-colima-m-series.md @@ -0,0 +1,111 @@ +# Validation run: Apple silicon Mac, Colima + +Date: 2026-09-23 +Host: MacBook (arm64, 8 GiB), macOS, Colima 0.10 (vz driver, no Rosetta), VM Ubuntu 24.04.4, 2 CPUs, 1.9 GiB memory. +Tooling: Docker CLI 29.8.1, docker-compose 5.5.1 (standalone), no buildx plugin. +Project: `examples/broken-shop`. + +Each preflight prediction was checked by running the real Docker command. Where the real error was +worded differently from the predicted text, the rule was corrected and the corrected text is shown. + +## Predictions vs. reality + +| # | Rule | Prediction | Real outcome | Verdict | +|---|------|-----------|--------------|---------| +| 1 | `registry.credentials` | `error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH` | identical | ✅ exact | +| 2 | `image.exists` | `redis:7.9.99-alpine` missing | `failed to resolve reference "docker.io/library/redis:7.9.99-alpine": … not found` | ✅ (wording corrected) | +| 3 | `build.buildkit` | `the --mount option requires BuildKit` | identical | ✅ exact | +| 4 | `build.context` | `package-lock.json` missing | `COPY failed: file not found in build context or excluded by .dockerignore: stat package-lock.json: file does not exist` | ✅ (legacy-builder wording added) | +| 5 | `compose.env` | `required variable DB_PASSWORD is missing a value` | identical | ✅ exact | +| 6 | `ports.conflict` | two services on 8080 | `Bind for 0.0.0.0:18080 failed: port is already allocated` | ✅ exact | +| 7 | `ports.conflict` | 2 replicas on one host port | `Bind for 0.0.0.0:18081 failed: port is already allocated` | ✅ exact | +| 8 | `mounts.bind` | missing `nginx.conf` becomes a directory | `not a directory: Are you trying to mount a directory onto a file (or vice-versa)?` | ✅ exact | +| 9 | `image.platform` | first version: mssql "no emulation → exec format error" | amd64 runs via QEMU (`uname -m` → `x86_64`) | ❌ false positive, fixed: kernel binfmt is now read inside the VM | +| 10 | `image.platform` + `resources.memory` | mssql needs ≥2000 MB, VM has 1.9 GiB | crashed earlier under QEMU: `Invalid mapping of address … in reserved address space` | ⚠️ memory finding true but masked; new QEMU-crash knowledge added, now predicted exactly | +| 11 | `kernel.sysctl` | first version: "passed" without data | VM `vm.max_map_count` = 1048576 | ⚠️ silent pass fixed: value now read from VM; unknown → warning | + +## Root-cause diagnosis (before Colima was started) + +The daemon failure was first reported generically. On this machine the actual cause was a Docker +context (`desktop-linux`) still pointing at the socket of an uninstalled Docker Desktop, with Colima +installed but stopped. Preflight now reports: + +``` +✗ Docker context "desktop-linux" still points to Docker Desktop, which is not installed + /Users/…/.docker/run/docker.sock is left over from it; nothing is listening there + fix: Start Colima: `colima start`, then `docker context use colima` + blocks 3 check(s): image.platform, resources.memory, resources.gpu +``` + +Following the fix started a working daemon. The first `colima start` failed because the Mac's disk had +118 MiB free; that is a host condition preflight does not yet diagnose. + +## Observations for the evaluation + +- Docker stops at the first failure: pulling surfaced only the credential error, not the missing tag; + the build surfaced only the missing `COPY` source, not `RUN --mount`. Preflight reported all of them + in one 4-second run. +- Of 11 predictions, 8 identified the real problem (6 word-for-word, 2 with different wording), 1 was a false + positive, and 2 were imprecise. All three were caused by facts inside the VM that the first version + could not see; reading the VM kernel fixed them. + +## Learning from failures (`learn`) + +1. `mongo:7` forced to `linux/amd64` under QEMU was expected to crash for lack of AVX. It ran, + because this QEMU emulates AVX. Preflight had only warned about emulation, which was the + right severity. +2. `postgres:16-alpine` without `POSTGRES_PASSWORD`. Preflight predicted nothing, because no + rule knew this failure. + - `learn -- docker-compose up` extracted + `Error: Database is uninitialized and superuser password is not specified.` and created + `learned.postgres` with conditions `image=postgres, memory=<2GiB`. + - After a password was added, `learn --success -- docker-compose up -d` observed the working + run. It added the distinguishing condition `env.POSTGRES_PASSWORD=unset`. + - Preflight then reported nothing when the password was set. It predicted the failure when + the password was removed on another tag (`postgres:17`). + - `memory=<2GiB` remains a spurious condition until a failure on a larger VM generalizes it + away. This bias of single-example learning should be discussed in the paper. + +## Same Mac on Docker Desktop (2026-09-24) + +Host: Docker Desktop, engine 29.8.0, VM 3.8 GiB, Rosetta enabled, buildx 0.37.1, Compose 5.5.1. +The same project (`broken-shop`) got different predictions than it did on Colima, and each +difference was confirmed: + +| Check | Colima prediction | Desktop prediction | Real on Desktop | +|---|---|---|---| +| credential helper | error | passes (helper installed) | pulls work | +| `RUN --mount` | error (no buildx) | passes | builds | +| mssql | error: crashes under QEMU | warning: Rosetta emulation | `SQL Server is now ready for client connections` ✅ | +| bind outside shared paths | n/a | error (shared paths read from the VM) | `mounts denied: The path /opt/homebrew/etc is not shared from the host` ✅ exact | +| missing COPY source | legacy wording | BuildKit wording | `failed to compute cache key: failed to calculate checksum of ref …: "/missing.txt": not found` (text corrected) | + +A new failure was found during setup and is now diagnosed. Docker Desktop had been started from +its installer disk image. That copy kept the socket and hung every command, while the copy in +/Applications attached to it. Preflight first reported only "accepts connections but does not +answer". It now names the installer copy as the root cause and adds a `host.installer` warning. +Probe commands also time out after 20s, where before they hung. + +## Host disk pressure makes Docker Desktop's filesystem read-only (2026-09-24) + +This failure happened on the author's machine and was not staged. Free space on the Mac's home +volume fell from about 7 GB to 3.6 GB while Docker Desktop ran a minikube cluster. Docker +Desktop keeps its VM disk as a sparse file on that volume (`Docker.raw`), so the VM's disk can +only grow as far as the host allows. After that: + +1. `minikube stop` failed: `GUEST_STOP_TIMEOUT: Unable to stop VM ... Maximum number of retries (60) exceeded`. +2. `docker stop` / `docker kill minikube` failed. `docker inspect` reported `status=dead pid=0` + while `docker ps` still listed the container as `Up`. +3. `minikube delete` and `docker rm -f minikube` failed with + `write /var/lib/desktop-containerd/daemon/io.containerd.metadata.v1.bolt/meta.db: read-only file system`. + +A failed write inside the VM had made its filesystem read-only. Restarting Docker Desktop +remounted it, after which the container, image (1.8 GB) and volume (790 MB) could be removed. +Host free space rose from 5.4 GB to 8.4 GB while the VM was stopped. + +**Relevance.** None of the three error messages mentions disk space. Each one points at a +symptom: the VM, the container, the metadata database. The `host.disk` rule targets the +precondition, a VM-based engine with less than 10 GB free on the host volume, and warns before +the chain starts. Preflight reported `only 6.7 GiB free on this machine; Docker's VM disk grows +here` on this machine shortly before the incident. The rule predicts the precondition, not this +specific chain, so it counts as supporting evidence rather than a confirmed prediction. diff --git a/examples/broken-shop/compose.yaml b/examples/broken-shop/compose.yaml new file mode 100644 index 0000000..f683fc5 --- /dev/null +++ b/examples/broken-shop/compose.yaml @@ -0,0 +1,35 @@ +# A realistic project with problems that only show up on some machines. +services: + web: + build: + context: ./web + ports: + - "8080:80" + deploy: + replicas: 2 + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + environment: + API_URL: ${API_URL} + develop: + watch: + - path: ./web + action: rebuild + + api: + image: node:20-alpine + ports: + - "8080:3000" + environment: + DB_PASSWORD: ${DB_PASSWORD:?set DB_PASSWORD in .env} + + db: + image: mcr.microsoft.com/mssql/server:2022-latest + environment: + ACCEPT_EULA: "Y" + + search: + image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0 + + cache: + image: redis:7.9.99-alpine diff --git a/examples/broken-shop/web/.dockerignore b/examples/broken-shop/web/.dockerignore new file mode 100644 index 0000000..6a0d87e --- /dev/null +++ b/examples/broken-shop/web/.dockerignore @@ -0,0 +1,2 @@ +node_modules +.env* diff --git a/examples/broken-shop/web/.env.production b/examples/broken-shop/web/.env.production new file mode 100644 index 0000000..e69de29 diff --git a/examples/broken-shop/web/Dockerfile b/examples/broken-shop/web/Dockerfile new file mode 100644 index 0000000..8ed0493 --- /dev/null +++ b/examples/broken-shop/web/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +FROM node:20-alpine AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN --mount=type=cache,target=/root/.npm npm ci +COPY src ./src +RUN npm run build + +FROM nginx:1.27-alpine +COPY --from=build /app/dist /usr/share/nginx/html +COPY .env.production /etc/app.env diff --git a/examples/broken-shop/web/package.json b/examples/broken-shop/web/package.json new file mode 100644 index 0000000..200614f --- /dev/null +++ b/examples/broken-shop/web/package.json @@ -0,0 +1 @@ +{"name":"web"} diff --git a/examples/broken-shop/web/src/index.js b/examples/broken-shop/web/src/index.js new file mode 100644 index 0000000..e14c4f2 --- /dev/null +++ b/examples/broken-shop/web/src/index.js @@ -0,0 +1 @@ +console.log(1) diff --git a/examples/hosts/macbook-m2-desktop.json b/examples/hosts/macbook-m2-desktop.json new file mode 100644 index 0000000..444fac6 --- /dev/null +++ b/examples/hosts/macbook-m2-desktop.json @@ -0,0 +1,28 @@ +{ + "version": 1, + "capturedAt": "2026-09-23T00:00:00Z", + "hostname": "example: MacBook Air M2, Docker Desktop defaults", + "profile": { + "ClientOS": "darwin", + "ClientArch": "arm64", + "ClientMem": 17179869184, + "Platform": "linux/arm64", + "OperatingSystem": "Docker Desktop", + "ServerVersion": "27.2.0", + "KernelVersion": "6.10.4-linuxkit", + "MemTotal": 4108189696, + "NCPU": 8, + "Runtimes": ["io.containerd.runc.v2", "runc"], + "CgroupVersion": "2", + "DockerRootDir": "/var/lib/docker", + "Endpoint": "unix:///Users/me/.docker/run/docker.sock", + "DiskFree": 48318382080, + "ComposeVersion": "2.20.2-desktop.1", + "BuildxInstalled": true, + "BuildxVersion": "0.12.1-desktop.4", + "Emulated": ["linux/amd64"], + "Sysctls": {"vm.max_map_count": 262144}, + "Local": true + }, + "listeningPorts": ["5000/tcp", "7000/tcp"] +} diff --git a/examples/hosts/ubuntu-legacy-server.json b/examples/hosts/ubuntu-legacy-server.json new file mode 100644 index 0000000..d9aaf00 --- /dev/null +++ b/examples/hosts/ubuntu-legacy-server.json @@ -0,0 +1,27 @@ +{ + "version": 1, + "capturedAt": "2026-09-23T00:00:00Z", + "hostname": "example: Ubuntu 20.04 server, distro Docker packages", + "profile": { + "ClientOS": "linux", + "ClientArch": "amd64", + "ClientMem": 8335405056, + "Platform": "linux/amd64", + "OperatingSystem": "Ubuntu 20.04.6 LTS", + "ServerVersion": "20.10.21", + "KernelVersion": "5.4.0-196-generic", + "MemTotal": 8335405056, + "NCPU": 4, + "Runtimes": ["io.containerd.runc.v2", "runc"], + "CgroupVersion": "1", + "DockerRootDir": "/var/lib/docker", + "Endpoint": "unix:///var/run/docker.sock", + "DiskFree": 3221225472, + "DiskExact": true, + "ComposeVersion": "1.29.2", + "BuildxInstalled": false, + "Sysctls": {"vm.max_map_count": 65530, "net.ipv4.ip_unprivileged_port_start": 1024}, + "Local": true + }, + "listeningPorts": ["22/tcp", "8080/tcp"] +} diff --git a/go.mod b/go.mod index a682ca4..1d9ce72 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,48 @@ -module github.com/raphgm/container-doctor +module github.com/raphgm/container-preflight go 1.26.5 require ( + github.com/compose-spec/compose-go/v2 v2.15.0 + github.com/google/go-containerregistry v0.22.1 + github.com/moby/buildkit v0.33.0 + github.com/moby/patternmatcher v0.6.1 github.com/shirou/gopsutil/v3 v3.24.5 + github.com/sirupsen/logrus v1.10.1 github.com/spf13/cobra v1.10.2 + gopkg.in/yaml.v3 v3.0.1 ) require ( + github.com/agext/levenshtein v1.2.3 // indirect + github.com/containerd/typeurl/v2 v2.3.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/cli v29.7.2+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.8 // indirect + github.com/docker/go-connections v0.7.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/klauspost/compress v1.19.2 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mattn/go-shellwords v1.0.15 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/spf13/pflag v1.0.9 // indirect + github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect + github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - golang.org/x/sys v0.20.0 // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect + golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.41.0 // indirect + google.golang.org/protobuf v1.36.12 // indirect ) diff --git a/go.sum b/go.sum index b4e3de7..996d47f 100644 --- a/go.sum +++ b/go.sum @@ -1,42 +1,102 @@ +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/compose-spec/compose-go/v2 v2.15.0 h1:tdQw+eMyT+P6ZIb09JfcIVvbMmIa+PjST7cWezVLf00= +github.com/compose-spec/compose-go/v2 v2.15.0/go.mod h1:Q1+qtN4vhzEjGrnqRtzx1xa8raDZQlMUe3WJxndYNiQ= +github.com/containerd/typeurl/v2 v2.3.0 h1:HZHPhRWo5XMy3QGQoPrUzbW/2ckwjfweHmOwlkIrPAQ= +github.com/containerd/typeurl/v2 v2.3.0/go.mod h1:Qk+PAdUYArVj41TnGi6rJ+48RF0PkcTc4i/taoBcK0w= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/docker/cli v29.7.2+incompatible h1:dlkwallR8XqfeVnA2ELEhdwvb4lsSwuB4IgsG8Q9cLY= +github.com/docker/cli v29.7.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker-credential-helpers v0.9.8 h1:bIREROb7So6PRlq6KTtdS9MPEjC29OQRkFNlvK2OX8Q= +github.com/docker/docker-credential-helpers v0.9.8/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.22.1 h1:RZuuSYhTvlDvtsK+NkutoCZ//C0X2ebLK8X8l3ULs84= +github.com/google/go-containerregistry v0.22.1/go.mod h1:bJR35SK8XgisYmhg/FMQ/5RK0S/XrOAqLBV5/LR2XE0= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-shellwords v1.0.15 h1:rx0n8+ZdM9JWZMlr2BMPAjtLU0rfluLNtwMC2FJOTtY= +github.com/mattn/go-shellwords v1.0.15/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/moby/buildkit v0.33.0 h1:zBbt1FiMcTB/oFg1iCNcKa83k5Rn8MGcVjXFIcfYhuQ= +github.com/moby/buildkit v0.33.0/go.mod h1:uNKSZnfMk1aSa18JiCR5BT68M/3jIDGo6XuAByUK3ek= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U= +github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= +github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= +github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE= +github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= +go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= +go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +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= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= diff --git a/internal/engine/engine.go b/internal/engine/engine.go index 59829e5..d9cd0f7 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type Engine struct { diff --git a/internal/engine/engine_test.go b/internal/engine/engine_test.go index 83a4ca4..51de18e 100644 --- a/internal/engine/engine_test.go +++ b/internal/engine/engine_test.go @@ -4,8 +4,8 @@ import ( "context" "testing" - "github.com/raphgm/container-doctor/pkg/check" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/check" + "github.com/raphgm/container-preflight/pkg/report" ) // mockCheck implements check.Check diff --git a/internal/engine/registry.go b/internal/engine/registry.go index 94ad5ba..f2802ff 100644 --- a/internal/engine/registry.go +++ b/internal/engine/registry.go @@ -1,7 +1,7 @@ package engine import ( - "github.com/raphgm/container-doctor/pkg/provider" + "github.com/raphgm/container-preflight/pkg/provider" ) type Registry struct { diff --git a/internal/engine/registry_test.go b/internal/engine/registry_test.go index ee20593..0019996 100644 --- a/internal/engine/registry_test.go +++ b/internal/engine/registry_test.go @@ -3,7 +3,7 @@ package engine import ( "testing" - "github.com/raphgm/container-doctor/pkg/check" + "github.com/raphgm/container-preflight/pkg/check" ) // mockProvider implements the provider.Provider interface for testing diff --git a/internal/renderer/html.go b/internal/renderer/html.go index db51950..bfea0cc 100644 --- a/internal/renderer/html.go +++ b/internal/renderer/html.go @@ -5,7 +5,7 @@ import ( "io" "os" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type HTML struct { @@ -24,7 +24,7 @@ func (h *HTML) Render(rep report.Report) error { - Container Doctor Report + Container Preflight Report -

Container Doctor Diagnostic Report

+

Container Preflight Diagnostic Report

Generated at: ` + rep.Timestamp.Format("2006-01-02 15:04:05 UTC") + `
`) for _, provider := range rep.Providers { diff --git a/internal/renderer/json.go b/internal/renderer/json.go index eaa311c..287a51e 100644 --- a/internal/renderer/json.go +++ b/internal/renderer/json.go @@ -4,7 +4,7 @@ import ( "encoding/json" "os" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type JSON struct{} diff --git a/internal/renderer/markdown.go b/internal/renderer/markdown.go index 09579c3..1b437fa 100644 --- a/internal/renderer/markdown.go +++ b/internal/renderer/markdown.go @@ -5,7 +5,7 @@ import ( "io" "os" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type Markdown struct { @@ -19,7 +19,7 @@ func NewMarkdown() *Markdown { } func (m *Markdown) Render(rep report.Report) error { - fmt.Fprintln(m.out, "# Container Doctor Diagnostic Report") + fmt.Fprintln(m.out, "# Container Preflight Diagnostic Report") fmt.Fprintf(m.out, "\n**Timestamp:** %s\n", rep.Timestamp.Format("2006-01-02 15:04:05 UTC")) fmt.Fprintln(m.out, "\n---") diff --git a/internal/renderer/renderer.go b/internal/renderer/renderer.go index 10cbde5..e33cb65 100644 --- a/internal/renderer/renderer.go +++ b/internal/renderer/renderer.go @@ -1,6 +1,6 @@ package renderer -import "github.com/raphgm/container-doctor/pkg/report" +import "github.com/raphgm/container-preflight/pkg/report" type Renderer interface { Render(report.Report) error diff --git a/internal/renderer/terminal.go b/internal/renderer/terminal.go index 9411c7d..667a7cb 100644 --- a/internal/renderer/terminal.go +++ b/internal/renderer/terminal.go @@ -3,7 +3,7 @@ package renderer import ( "fmt" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type Terminal struct{} @@ -14,7 +14,7 @@ func NewTerminal() *Terminal { func (t *Terminal) Render(r report.Report) error { fmt.Println() - fmt.Println("Container Doctor") + fmt.Println("Container Preflight") fmt.Println() for _, provider := range r.Providers { diff --git a/main.go b/main.go index 01339aa..1081b46 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,7 @@ Copyright © 2026 NAME HERE */ package main -import "github.com/raphgm/container-doctor/cmd" +import "github.com/raphgm/container-preflight/cmd" func main() { cmd.Execute() diff --git a/paper/.gitignore b/paper/.gitignore new file mode 100644 index 0000000..20678e6 --- /dev/null +++ b/paper/.gitignore @@ -0,0 +1,7 @@ +*.aux +*.log +*.out +*.bbl +*.blg +*.spl +main.pdf diff --git a/paper/categories.tex b/paper/categories.tex new file mode 100644 index 0000000..289b07e --- /dev/null +++ b/paper/categories.tex @@ -0,0 +1,43 @@ +\begin{table}[t] +\centering\scriptsize +\caption{Failure categories: GitHub issues since 2021 matching each error, precision of the search (share of 30 sampled issues containing the exact error text), and adjusted estimate. Rule ``--'' marks categories \tool{} does not target; $\dagger$ marks a rule added after mining.} +\label{tab:categories} +\begin{tabular}{@{}llrrr@{}} +\toprule +Category & Rule & Hits & Precision & Adjusted \\ +\midrule +memory: OOMKilled & \texttt{resources.memory} & 97,607 & 0.37 & 35,789 \\ +image: tag/repo not found & \texttt{image.exists} & 7,405 & 0.93 & 6,911 \\ +network not found & -- & 18,407 & 0.33 & 6,136 \\ +volume permission denied & \texttt{mounts.permissions}$^\dagger$ & 6,073 & 1.00 & 6,073 \\ +platform: exec format error & \texttt{image.platform} & 5,372 & 0.97 & 5,193 \\ +address already in use & \texttt{ports.host} & 3,792 & 1.00 & 3,792 \\ +image: pull access denied & \texttt{image.exists} & 3,730 & 1.00 & 3,730 \\ +platform: requested platform mismatch & \texttt{image.platform} & 3,717 & 1.00 & 3,717 \\ +OCI runtime exec failed & -- & 3,479 & 1.00 & 3,479 \\ +platform: no matching manifest & \texttt{image.platform} & 2,760 & 1.00 & 2,760 \\ +daemon: cannot connect & (root cause) & 2,712 & 1.00 & 2,712 \\ +compose: variable not set & \texttt{compose.env} & 2,390 & 0.97 & 2,310 \\ +DNS resolution in container & -- & 2,021 & 1.00 & 2,021 \\ +build: COPY source not found & \texttt{build.context} & 1,421 & 1.00 & 1,421 \\ +emulation: qemu crash & \texttt{image.platform} & 1,301 & 1.00 & 1,301 \\ +disk: no space left & \texttt{resources.disk} & 1,241 & 1.00 & 1,241 \\ +port already allocated & \texttt{ports.conflict} & 1,239 & 1.00 & 1,239 \\ +container healthcheck unhealthy & -- & 1,155 & 1.00 & 1,155 \\ +bind: dir onto file & \texttt{mounts.bind} & 707 & 1.00 & 707 \\ +bind: source does not exist & \texttt{mounts.bind} & 544 & 1.00 & 544 \\ +compose: unsupported property & \texttt{compose.version} & 486 & 1.00 & 486 \\ +gpu: no device driver & \texttt{resources.gpu} & 457 & 1.00 & 457 \\ +build: BuildKit required & \texttt{build.buildkit} & 443 & 0.97 & 428 \\ +build: COPY failed legacy & \texttt{build.context} & 417 & 1.00 & 417 \\ +compose: required variable & \texttt{compose.env} & 475 & 0.83 & 396 \\ +kernel: vm.max\_map\_count & \texttt{kernel.sysctl} & 369 & 1.00 & 369 \\ +credentials helper missing & \texttt{registry.credentials} & 260 & 1.00 & 260 \\ +desktop: mounts denied & \texttt{mounts.sharing} & 153 & 1.00 & 153 \\ +app config/env missing at runtime & (learned) & 118 & 1.00 & 118 \\ +build: outside build context & \texttt{build.context} & 65 & 1.00 & 65 \\ +rootless privileged port & \texttt{ports.host} & 39 & 0.87 & 34 \\ +memory: mssql minimum & \texttt{resources.memory} & 4,653 & 0.00 & 0 \\ +\bottomrule +\end{tabular} +\end{table} diff --git a/paper/main.tex b/paper/main.tex new file mode 100644 index 0000000..8411170 --- /dev/null +++ b/paper/main.tex @@ -0,0 +1,261 @@ +%% Draft for the Journal of Systems and Software (Elsevier). +%% Compile with the elsarticle class (bundled with TeX Live / Overleaf): +%% latexmk -pdf main.tex +\documentclass[preprint,12pt]{elsarticle} + +\usepackage{amsmath} +\usepackage{booktabs} +\usepackage{graphicx} +\usepackage{xcolor} +\usepackage{listings} +\usepackage{tikz} +\usetikzlibrary{positioning,arrows.meta,fit,backgrounds} +\usepackage[hidelinks]{hyperref} + +\newcommand{\todo}[1]{\textcolor{red}{[TODO: #1]}} +\newcommand{\tool}{\textsc{Container Preflight}} +\lstset{basicstyle=\ttfamily\footnotesize,breaklines=true,frame=single,columns=fullflexible} + +\journal{Journal of Systems and Software} + +\begin{document} + +\begin{frontmatter} + +\title{Predicting Container Deployment Failures Before Execution by Jointly Analyzing Container Artifacts and Host Environments} + +\author[1]{Raphael Gab-Momoh\corref{cor1}} +\ead{rdgabmomoh@gmail.com} +\cortext[cor1]{Corresponding author} +\affiliation[1]{organization={Paynautik Limited},city={Lagos},country={Nigeria}} + +\begin{abstract} +Containerized projects that work on one machine routinely fail on another: an image lacks the host's CPU architecture, a Compose file needs more memory than the Docker virtual machine has, a \texttt{COPY} source is excluded by \texttt{.dockerignore}, a port is already taken. Existing tools inspect either the artifacts (Dockerfile linters) or the host (daemon diagnostics), never both, and Docker itself reports only the first failure it reaches. We present \tool{}, an approach and tool that predicts deployment failures before anything runs by joining three views: requirements extracted from Compose files and Dockerfiles with Docker's own parsers, a capability profile of the host (including the virtual machine that Docker Desktop and Colima run on macOS), and image metadata read directly from registries. Checks that depend on facts that cannot be established are grouped under a single root cause through an explicit causal graph, and a learning component turns observed failures into shareable rules that are generalized by later failures and specialized by successful runs. We estimated 95k GitHub issues across 32 failure categories, correcting search counts by verified precision, and labeled two stratified samples. On a held-out sample drawn after the rules were frozen, \tool{} fully predicted 33\% of local Docker failures and at least partially predicted 58\% (58\% weighted by category prevalence); categories it does not target are dominated by runtime behavior such as DNS resolution and health checks. On two real engines (Colima and Docker Desktop) on the same machine, 8 of 11 initial predictions matched the actual failure, 6 word for word, and the same project received different, confirmed predictions per engine. \todo{Inter-rater agreement (Cohen's $\kappa$) on 40 held-out issues.} +\end{abstract} + +\begin{keyword} +containers \sep Docker \sep Docker Compose \sep configuration errors \sep failure prediction \sep root cause analysis +\end{keyword} + +\end{frontmatter} + +%% --------------------------------------------------------------------- +\section{Introduction} +\label{sec:intro} + +Containers promised that software runs the same everywhere. In practice a container project is the product of its artifacts \emph{and} the machine it runs on. The same \texttt{compose.yaml} may start on a developer's Intel laptop and fail on a colleague's Apple silicon machine because an image ships only \texttt{linux/amd64}; it may start on Docker Desktop and fail on a Linux server because \texttt{vm.max\_map\_count} is too low for Elasticsearch; it may build on one machine and fail on another that lacks the BuildKit plugin required by \texttt{RUN --mount}. + +These failures share three properties that make them costly. First, they are \emph{relational}: neither the artifact nor the host is wrong in isolation. Second, they are \emph{sequential}: Docker stops at the first failure, so a project with five problems is fixed through five failed runs. Third, their error messages point at symptoms: ``Cannot connect to the Docker daemon'' says nothing about the stale context that caused it, and ``exec format error'' says nothing about which image lacks which architecture. + +Existing tools address one side. Dockerfile linters such as Hadolint~\cite{hadolint} and research systems such as Binnacle~\cite{henkel2020binnacle} check artifacts against best-practice rules; repair tools such as Shipwright~\cite{henkel2021shipwright} fix broken builds after they fail. Host diagnostics (\texttt{docker info}, Docker Desktop's troubleshooter) report the machine's state without reference to what a project needs. Early detection of configuration errors has been studied for server software~\cite{xu2016pcheck}, but not for the joint space of container artifacts and container hosts. + +This paper makes the following contributions: +\begin{enumerate} + \item \textbf{Joint analysis.} An approach that predicts container build and start-up failures before execution by matching requirements extracted from Compose files, Dockerfiles or \texttt{docker run} commands against a capability profile of the host and image metadata read from registries without pulling (\S\ref{sec:approach}). + \item \textbf{Root-cause grouping.} A causal fact graph under which a check that needs an unknown fact is reported once under the fact's root cause, including specific diagnoses of why a Docker daemon is unreachable (\S\ref{sec:causal}). + \item \textbf{Learning from failures.} A rule learner that turns an observed failure into a shareable rule, generalizes it with further failures and specializes it with successful runs (\S\ref{sec:learn}). + \item \textbf{Evaluation.} A failure taxonomy from 95k verified GitHub issues, a labeled development sample and a held-out test sample, and field validation on two Docker engines (\S\ref{sec:eval}). All data and scripts are released. +\end{enumerate} + +%% --------------------------------------------------------------------- +\section{Motivating example} +\label{sec:motivation} + +Listing~\ref{lst:shop} shows an excerpt of a Compose project. On an Apple silicon Mac running Colima with default settings, \texttt{docker compose up} fails first with \texttt{error getting credentials} (the Docker configuration still names Docker Desktop's credential helper, which was uninstalled). After fixing that, it fails with \texttt{the --mount option requires BuildKit}. After installing buildx, it fails on a missing \texttt{COPY} source, then on a port clash, then on a missing bind-mounted file, and finally SQL Server crashes under QEMU emulation. + +\begin{lstlisting}[caption={Excerpt of the example project.},label={lst:shop}] +services: + web: + build: ./web # RUN --mount=type=cache ... + ports: ["8080:80"] + deploy: {replicas: 2} + volumes: ["./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"] + api: + image: node:20-alpine + ports: ["8080:3000"] + db: + image: mcr.microsoft.com/mssql/server:2022-latest +\end{lstlisting} + +\tool{} reports all of these in one run of about four seconds, each with the evidence from both sides and the error Docker would print. On Docker Desktop on the same machine it reports a different set: the credential helper and BuildKit checks pass, and SQL Server is only a warning because Desktop runs amd64 under Rosetta, where it starts successfully (\S\ref{sec:field}). + +%% --------------------------------------------------------------------- +\section{Approach} +\label{sec:approach} + +\tool{} builds three views and evaluates rules over their join (Figure~\ref{fig:arch}). + +\begin{figure}[t] +\centering +\begin{tikzpicture}[ + font=\footnotesize, + box/.style={draw, rounded corners=2pt, align=center, minimum height=9mm, text width=27mm, fill=white}, + src/.style={box, fill=gray!8}, + arr/.style={-{Stealth[length=2mm]}, thick}, + node distance=5mm and 9mm] +\node[src] (proj) {Compose file, Dockerfiles,\\ or \texttt{docker run}}; +\node[src, below=of proj] (hostsrc) {Docker CLI and daemon,\\ VM kernel, ports, disk}; +\node[src, below=of hostsrc] (reg) {Container registries}; +\node[box, right=of proj] (req) {Requirements\\ \scriptsize (Docker's own parsers)}; +\node[box, right=of hostsrc] (cap) {Host profile\\ \scriptsize (or snapshot)}; +\node[box, right=of reg] (meta) {Image metadata\\ \scriptsize (no pull)}; +\node[box, right=14mm of cap, text width=30mm, minimum height=24mm, fill=blue!6] (rules) {\textbf{Rules}\\[2pt] 18 built-in\\ + learned rules}; +\node[box, above=of rules, text width=30mm, fill=orange!10] (graph) {Causal fact graph\\ \scriptsize unknown facts $\Rightarrow$ root causes}; +\node[box, right=of rules, text width=27mm, fill=green!8] (rep) {Report\\ \scriptsize root causes, predicted\\ errors with evidence}; +\node[box, below=of rep, text width=27mm, fill=gray!8] (learn) {\texttt{learn}\\ \scriptsize observed failures\\ and successes}; +\draw[arr] (proj) -- (req); \draw[arr] (hostsrc) -- (cap); \draw[arr] (reg) -- (meta); +\draw[arr] (req.east) -- (rules.155); +\draw[arr] (cap) -- (rules); +\draw[arr] (meta.east) -- (rules.205); +\draw[arr] (cap.north east) -- (graph.south west); +\draw[arr] (graph) -- (rules); +\draw[arr] (rules) -- (rep); +\draw[arr] (learn.west) -| (rules.south); +\end{tikzpicture} +\caption{Overview. Requirements, host capabilities and registry metadata are extracted independently and joined by rules. Facts that cannot be established become root causes that block dependent rules. \texttt{learn} adds rules from observed runs.} +\label{fig:arch} +\end{figure} + +\subsection{Project requirements} +Compose files are loaded with \texttt{compose-go}, the library Docker Compose uses, so interpolation, \texttt{.env} files, profiles and path resolution behave as in Compose. Dockerfiles are parsed with BuildKit's Dockerfile frontend. For each build, \tool{} computes the set of stages BuildKit will actually build for the requested target (following \texttt{FROM}, \texttt{COPY --from} and \texttt{RUN --mount from=} edges), because problems in unreachable stages do not break builds. From these it extracts: images to pull and the platform each will be requested for; base images of reachable stages; memory limits and reservations times replicas; published ports; bind mounts and their options; \texttt{COPY}/\texttt{ADD} sources, resolved against the build context and \texttt{.dockerignore} with BuildKit's pattern matcher; BuildKit-only syntax; Compose features with minimum versions; interpolated variables; GPU requests; and the container user. Raw YAML is walked separately to keep line numbers for every requirement. Commands such as \texttt{docker run} are parsed into the same model. + +\subsection{Host capabilities} +The host profile records the daemon's platform, memory, runtimes and security options from \texttt{docker info}; Compose and buildx versions; emulated platforms and the emulation mechanism (QEMU or Rosetta); kernel settings; free disk where images are stored; images already present; ports held by processes and containers; and credential helpers. On macOS the daemon runs in a virtual machine, so memory and kernel settings of the \emph{VM} matter, not the laptop's. \tool{} reads them inside the VM (for Colima, through \texttt{colima ssh}; for Docker Desktop, from the VM's command line, which also reveals the folders actually shared with the VM). Profiles can be saved as \emph{snapshots} and checked against from another machine, so a developer can predict failures on a CI runner or server without access to it. + +\subsection{Registry metadata} +For each image to be pulled, \tool{} reads the manifest or manifest list from the registry, recording available platforms, the compressed size for the requested platform, and the configured user. Whether a reference is a single-platform image or a manifest list matters: a list without the host's platform makes \texttt{docker pull} fail, whereas a single foreign-platform image is pulled and needs emulation to run. + +\subsection{Rules} +Each rule joins a requirement with a capability and emits a finding with severity, evidence from both sides, a fix, a source location, and the error Docker would print. Table~\ref{tab:rules} lists the 18 built-in rules. A small knowledge base records host requirements invisible in manifests, each tied to the error the image prints (e.g., SQL Server's 2000~MB minimum and its crash under QEMU; Elasticsearch's \texttt{vm.max\_map\_count}, skipped in single-node mode where its bootstrap checks do not apply). + +\begin{table}[t] +\centering\footnotesize +\caption{Built-in rules.} +\label{tab:rules} +\begin{tabular}{@{}lp{0.62\linewidth}@{}} +\toprule +Rule & Predicts \\ +\midrule +\texttt{image.exists} & tag or repository missing, or private \\ +\texttt{image.platform} & no variant for the host platform; emulation unavailable; known crashes under QEMU \\ +\texttt{registry.credentials} & configured credential helper not installed \\ +\texttt{build.context} & \texttt{COPY}/\texttt{ADD} source missing, excluded by \texttt{.dockerignore}, or outside the context \\ +\texttt{build.buildkit} & BuildKit-only syntax with the legacy builder \\ +\texttt{compose.version} & Compose features newer than the installed Compose \\ +\texttt{compose.env} & unset or required variables \\ +\texttt{resources.memory} & known image minimums and total limits vs.\ Docker's memory \\ +\texttt{resources.disk} & image size vs.\ free space (VM and host volume) \\ +\texttt{host.disk} & too little host space for a VM-based engine \\ +\texttt{host.installer} & Docker Desktop running from its installer image \\ +\texttt{resources.gpu} & GPU requests without an NVIDIA runtime \\ +\texttt{kernel.sysctl} & \texttt{vm.max\_map\_count} below image requirement \\ +\texttt{ports.conflict} & services or replicas publishing one host port \\ +\texttt{ports.host} & host port held by a process or another project's container; rootless privileged ports \\ +\texttt{mounts.bind} & missing bind sources that become directories \\ +\texttt{mounts.permissions} & non-root writes to root-owned or foreign-owned binds; SELinux labels \\ +\texttt{mounts.sharing} & paths outside Docker Desktop's shared folders \\ +\bottomrule +\end{tabular} +\end{table} + +%% --------------------------------------------------------------------- +\section{Root-cause grouping} +\label{sec:causal} + +Facts form a directed graph: the Docker CLI must exist before the daemon can be queried; the daemon must answer before its platform or memory are known; whether the daemon is \emph{local} is derived from the CLI context, not from the daemon, so port and bind-mount checks still run while the daemon is down. Each rule declares the facts it needs. When a fact cannot be established, the engine walks to the top-most failed ancestor and reports every dependent rule once under that root. Unknown is never reported as pass: when \tool{} cannot read a kernel setting or the emulation mechanism, it emits a warning rather than silently passing, a distinction that the field validation showed to matter (\S\ref{sec:field}). + +A daemon that cannot be reached is further diagnosed from local evidence: whether the context's socket exists and which engine owns it, which engines are installed or running, whether commands time out (a starting or memory-starved VM), whether Docker Desktop runs from its installer image, and free host disk. On the author's machine this turned ``Cannot connect to the Docker daemon'' into ``Docker context \texttt{desktop-linux} still points to Docker Desktop, which is not installed'' with the fix \texttt{colima start}, which worked. + +%% --------------------------------------------------------------------- +\section{Learning rules from failures} +\label{sec:learn} + +Built-in rules cannot anticipate application-specific failures. \texttt{learn} wraps a command (typically \texttt{docker compose up}), and on failure extracts the decisive log line with a keyword-weighted score that down-weights generic wrappers. The line is generalized into a signature by replacing addresses, identifiers, paths and numbers. The service's features at the time (image repository, platform, emulation mechanism, memory bucket, builder, and which environment variables are set, never their values) become the rule's conditions, starting from features that are unusual or plausibly causal. + +Rules are refined in the manner of version-space learning~\cite{mitchell1982generalization}. A later failure with the same signature drops conditions the observations disagree on (generalization). A successful run that satisfies every condition adds a feature on which all failures agree and the success differs (specialization); if none exists, the rule is marked unreliable and no longer reported. Rules live in the project repository, so one developer's failure becomes a prediction for everyone. + +In a real run, Postgres started without a password failed; \texttt{learn} created a rule conditioned on the image. After a password was added, the successful run specialized the rule to \texttt{env.POSTGRES\_PASSWORD=unset}, and \tool{} then flagged a different project using \texttt{postgres:17} without a password. + +%% --------------------------------------------------------------------- +\section{Evaluation} +\label{sec:eval} + +We ask: +\textbf{RQ1} How common are the failures \tool{} targets? +\textbf{RQ2} What share of real local Docker failures would \tool{} have predicted? +\textbf{RQ3} Do predictions match reality on real engines? + +\subsection{RQ1: Failure landscape} +We defined 32 failure categories by the error text Docker or the image prints, including 7 categories \tool{} does not target, and counted GitHub issues created since 2021 per category. Because issue search matches loosely, we fetched 30 sampled issues per category with their comments and checked for the exact error text, giving a precision estimate and an adjusted count. Precision was at least 0.83 for all but three categories: OOMKilled (0.37, largely Kubernetes), ``network not found'' (0.33) and the SQL Server memory message (0.0). For ``network not found'' the check requires Docker's own phrasing (\texttt{network not found} or \texttt{declared as external, but could not be found}); an earlier, looser check that only required both words had reported 0.97. The labeled samples for this category (8 of 245 issues) were drawn under the looser check. + +Of the 95k adjusted issues, 80\% fall in targeted categories; excluding OOMKilled, which is dominated by Kubernetes, 68\%. The largest targeted categories are platform mismatches (11.7k), missing images (10.6k) and port conflicts (5.1k); the largest untargeted are Docker networks not found (6.1k), volume permissions (6.1k, subsequently addressed by \texttt{mounts.permissions}), OCI runtime exec errors (3.5k) and DNS resolution (2.0k). Table~\ref{tab:categories} lists all categories. + +\input{categories} + +\subsection{RQ2: Predictive coverage} +\paragraph{Protocol} We drew a development sample of 4 verified issues per category (124 issues) and labeled each: whether it is a local Docker failure (not Kubernetes, Podman, application bugs or feature requests), and whether \tool{} would have predicted it before execution given the project files and the host (\emph{yes}), would have addressed its cause only partially (\emph{partial}: a warning where an error resulted, a different input form, a different OS, or only after learning), or not (\emph{no}). We then added rules for misses and froze them (tag \texttt{eval-frozen}). Finally we drew a held-out test sample of 121 issues with a different search ordering, excluding every issue seen before, and labeled it against the frozen rules. + +\begin{table}[t] +\centering\footnotesize +\caption{Predictive coverage on local Docker failures.} +\label{tab:coverage} +\begin{tabular}{@{}lrrrrr@{}} +\toprule +Sample & $n$ & Yes & Partial & No & Yes (weighted) \\ +\midrule +Development, initial rules & 98 & 42\% & 26\% & 33\% & 31\% \\ +Development, after fixes & 98 & 51\% & 18\% & 31\% & 46\% \\ +\textbf{Held-out test} & \textbf{72} & \textbf{33\%} & \textbf{25\%} & \textbf{42\%} & \textbf{30\%} \\ +\bottomrule +\end{tabular} +\end{table} + +Table~\ref{tab:coverage} reports results; ``weighted'' reweights categories by their adjusted prevalence. The drop from development to test (51\% to 33\%) shows the development figure was optimistic, as expected for rules written after seeing its misses; the held-out figure is the one we claim. Yes-or-partial remained stable (69\% vs.\ 58\%; 60\% vs.\ 58\% weighted). Misses concentrate on runtime behavior (unhealthy containers, DNS, application errors, OCI exec), which configuration analysis cannot observe. + +\paragraph{Agreement} \todo{A second rater, blind to our labels, labeled 40 held-out issues. Report Cohen's $\kappa$~\cite{cohen1960kappa} for scope and for prediction.} + +\subsection{RQ3: Field validation} +\label{sec:field} +We ran \tool{} on the example project on an Apple silicon Mac, first with Colima (Ubuntu VM, 1.9~GiB, QEMU, no buildx) and then with Docker Desktop (3.8~GiB VM, Rosetta, buildx), and checked every prediction by executing the corresponding Docker command. + +On Colima, 8 of 11 initial predictions identified the real failure, 6 with Docker's exact wording (credential helper, BuildKit, required variable, two port conflicts, bind mount of a missing file) and 2 with different wording, since corrected. One was a false positive: \tool{} predicted that amd64 could not run, but the VM had QEMU registered, which the first version could not see; two were imprecise (a memory prediction masked by an earlier QEMU crash, and a kernel check that passed without data). All three stemmed from facts inside the VM, and reading the VM's kernel fixed them. + +On Docker Desktop, the same project received different predictions, each confirmed: SQL Server ran under Rosetta (``ready for client connections'') where it had crashed under QEMU; a bind mount outside the shared folders failed with the predicted \texttt{mounts denied} message. Setting up Docker Desktop also produced a new failure---Desktop launched from its installer image held the socket and hung every command---which \tool{} now diagnoses. + +%% --------------------------------------------------------------------- +\section{Discussion and threats to validity} +\label{sec:threats} + +\paragraph{Construct} ``Would have predicted'' is a judgment about a counterfactual run; we mitigate it with a written rubric and a blind second rater. Category membership is defined by error text, which excludes failures reported without logs. + +\paragraph{Internal} The first author built the tool and labeled both samples. The development sample was used to add rules; we therefore froze rules before drawing the test sample and report the test result. Some predicted error texts and minimum versions were written from documentation and were corrected only where verified. + +\paragraph{External} GitHub issues over-represent open-source projects and under-represent failures resolved silently. Field validation covers two engines on one machine; Linux servers, Windows and remote daemons were exercised only through tests and snapshots. + +\paragraph{Scope} \tool{} targets configuration and environment mismatches. It does not predict runtime behavior, and learned rules can only predict failures someone has already hit. + +%% --------------------------------------------------------------------- +\section{Related work} +\label{sec:related} + +\paragraph{Container ``preflight'' tools} Red Hat's \texttt{preflight}~\cite{openshiftpreflight} checks operator bundles and container images against OpenShift certification requirements, and \texttt{kubeadm} runs preflight checks on a machine before creating a Kubernetes cluster. Both validate an artifact or a host against fixed policy; neither predicts whether a given project will build and run on a given host. + +\paragraph{Dockerfile analysis and repair} Cito et al.~\cite{cito2017docker} characterized the Docker ecosystem on GitHub and its quality issues. Hadolint~\cite{hadolint} and Binnacle~\cite{henkel2020binnacle} check Dockerfiles against rules; Shipwright~\cite{henkel2021shipwright} repairs broken builds; Wu et al.~\cite{wu2020buildfailures} studied Docker build failures. Recent work repairs Dockerfile drift using project context~\cite{drift2026}. All operate on artifacts; none model the host. + +\paragraph{Compose} Ibrahim et al.~\cite{ibrahim2021compose} studied how Docker Compose is used to compose multi-component systems; linters validate Compose syntax. They do not relate files to host capabilities. + +\paragraph{Configuration errors} Xu et al.~\cite{xu2016pcheck} detect latent configuration errors early by checking configuration values at initialization. \tool{} applies the early-detection idea across the artifact--host boundary of containers and adds learning from observed failures. + +%% --------------------------------------------------------------------- +\section{Conclusion} +\label{sec:conclusion} + +Container failures that ``work on my machine'' are relational: they arise between a project and a host. By analyzing both together, grouping unknowns under root causes and learning from observed failures, \tool{} predicted a third of held-out local Docker failures fully and more than half at least partially, before anything ran, and its predictions held up on two real engines. The same join applies to Kubernetes: manifests against a specific cluster's node architectures, allocatable resources, quotas, storage classes, served APIs and admission policies, predicting events such as \texttt{FailedScheduling}, \texttt{ImagePullBackOff} and \texttt{no matches for kind} before deployment, with root-cause grouping and learned rules unchanged. Other future work: runtime-oriented checks such as health checks and container DNS, and a study with developers measuring time to a working setup. + +\section*{Data availability} +The tool, rules, mined data, samples, labels and scripts are available at \url{https://github.com/raphgm/container-preflight} \todo{archive with a DOI on Zenodo}. + +\bibliographystyle{elsarticle-num} +\bibliography{refs} + +\end{document} diff --git a/paper/refs.bib b/paper/refs.bib new file mode 100644 index 0000000..ba9effb --- /dev/null +++ b/paper/refs.bib @@ -0,0 +1,90 @@ +% Every entry below must be checked against the publisher's page before +% submission (authors, pages, DOI). Entries were written from memory. + +@misc{hadolint, + title = {Hadolint: Haskell Dockerfile Linter}, + howpublished = {\url{https://github.com/hadolint/hadolint}}, + note = {Accessed 2026-09-24} +} + +@inproceedings{cito2017docker, + author = {Cito, J{\"u}rgen and Schermann, Gerald and Wittern, John Erik and Leitner, Philipp and Zumberi, Sali and Gall, Harald C.}, + title = {An Empirical Analysis of the {Docker} Container Ecosystem on {GitHub}}, + booktitle = {Proceedings of the 14th International Conference on Mining Software Repositories (MSR)}, + year = {2017}, + pages = {323--333} +} + +@inproceedings{henkel2020binnacle, + author = {Henkel, Jordan and Bird, Christian and Lahiri, Shuvendu K. and Reps, Thomas}, + title = {Learning from, Understanding, and Supporting {DevOps} Artifacts for {Docker}}, + booktitle = {Proceedings of the 42nd International Conference on Software Engineering (ICSE)}, + year = {2020}, + pages = {38--49} +} + +@inproceedings{henkel2021shipwright, + author = {Henkel, Jordan and Silva, Denini and Teixeira, Leopoldo and d'Amorim, Marcelo and Reps, Thomas}, + title = {Shipwright: A Human-in-the-Loop System for {Dockerfile} Repair}, + booktitle = {Proceedings of the 43rd International Conference on Software Engineering (ICSE)}, + year = {2021}, + pages = {1148--1160} +} + +@inproceedings{wu2020buildfailures, + author = {Wu, Yiwen and Zhang, Yang and Wang, Tao and Wang, Huaimin}, + title = {An Empirical Study of Build Failures in the {Docker} Context}, + booktitle = {Proceedings of the 17th International Conference on Mining Software Repositories (MSR)}, + year = {2020}, + pages = {76--80} +} + +@article{ibrahim2021compose, + author = {Ibrahim, Md Hasan and Sayagh, Mohammed and Hassan, Ahmed E.}, + title = {A Study of How {Docker Compose} Is Used to Compose Multi-Component Systems}, + journal = {Empirical Software Engineering}, + year = {2021}, + volume = {26}, + number = {6} +} + +@misc{drift2026, + title = {Taming the Drift: Context-aware Repair of {Dockerfile} Drift during Software Evolution}, + howpublished = {arXiv:2607.12541}, + year = {2026}, + note = {Authors to be filled in from the arXiv page} +} + +@inproceedings{xu2016pcheck, + author = {Xu, Tianyin and Jin, Xinxin and Huang, Peng and Zhou, Yuanyuan and Lu, Shan and Jin, Long and Pasupathy, Shankar}, + title = {Early Detection of Configuration Errors to Reduce Failure Damage}, + booktitle = {Proceedings of the 12th USENIX Symposium on Operating Systems Design and Implementation (OSDI)}, + year = {2016}, + pages = {619--634} +} + +@article{mitchell1982generalization, + author = {Mitchell, Tom M.}, + title = {Generalization as Search}, + journal = {Artificial Intelligence}, + year = {1982}, + volume = {18}, + number = {2}, + pages = {203--226} +} + +@article{cohen1960kappa, + author = {Cohen, Jacob}, + title = {A Coefficient of Agreement for Nominal Scales}, + journal = {Educational and Psychological Measurement}, + year = {1960}, + volume = {20}, + number = {1}, + pages = {37--46} +} + +@misc{openshiftpreflight, + title = {openshift-preflight: Operator and container preflight certification tests}, + howpublished = {\url{https://github.com/redhat-openshift-ecosystem/openshift-preflight}}, + note = {Accessed 2026-09-24} +} diff --git a/pkg/check/check.go b/pkg/check/check.go index a5f36eb..67a92cf 100644 --- a/pkg/check/check.go +++ b/pkg/check/check.go @@ -3,7 +3,7 @@ package check import ( "context" - "github.com/raphgm/container-doctor/pkg/report" + "github.com/raphgm/container-preflight/pkg/report" ) type Check interface { diff --git a/pkg/preflight/fact/fact.go b/pkg/preflight/fact/fact.go new file mode 100644 index 0000000..089da3d --- /dev/null +++ b/pkg/preflight/fact/fact.go @@ -0,0 +1,111 @@ +// Package fact defines the facts preflight depends on and the causal graph +// between them. A fact "fails" when it cannot be determined; every rule that +// needs a failed fact is reported as blocked by that fact's root cause instead +// of producing its own, misleading, failure. +package fact + +import "sort" + +type ID string + +const ( + DockerCLI ID = "docker.cli" + Daemon ID = "docker.daemon" + LocalDaemon ID = "docker.local" + Compose ID = "docker.compose" + Buildx ID = "docker.buildx" + Registry ID = "registry.network" + ComposeFile ID = "project.compose" + Dockerfile ID = "project.dockerfile" +) + +// parents encodes the causal edges: a fact cannot be known unless its parent +// is known. LocalDaemon ("the daemon endpoint is on this machine") comes +// from the CLI context, so host-side checks still run when the daemon is +// down. +var parents = map[ID]ID{ + Daemon: DockerCLI, + LocalDaemon: DockerCLI, + Compose: DockerCLI, + Buildx: DockerCLI, +} + +// Parent returns the direct causal parent of id, if any. +func Parent(id ID) (ID, bool) { + p, ok := parents[id] + return p, ok +} + +type Severity string + +const ( + Error Severity = "ERROR" + Warning Severity = "WARN" + Info Severity = "INFO" +) + +// Failure explains why a fact could not be determined. +type Failure struct { + Fact ID + Severity Severity + Summary string + Detail string + Fix string +} + +// Set records which facts failed. +type Set struct { + failed map[ID]Failure +} + +func NewSet() *Set { + return &Set{failed: map[ID]Failure{}} +} + +func (s *Set) Fail(f Failure) { + if _, exists := s.failed[f.Fact]; !exists { + s.failed[f.Fact] = f + } +} + +// Failed reports whether id is unknown, either directly or because an +// ancestor failed. +func (s *Set) Failed(id ID) bool { + _, ok := s.Root(id) + return ok +} + +// Root returns the top-most failed fact on id's ancestor chain. Fixing the +// root is what unblocks id. +func (s *Set) Root(id ID) (Failure, bool) { + var root Failure + found := false + for cur, ok := id, true; ok; cur, ok = Parent(cur) { + if f, failed := s.failed[cur]; failed { + root, found = f, true + } + } + return root, found +} + +// All returns every recorded failure. +func (s *Set) All() []Failure { + var out []Failure + for _, f := range s.failed { + out = append(out, f) + } + sort.Slice(out, func(i, j int) bool { return out[i].Fact < out[j].Fact }) + return out +} + +// Roots returns every failed fact whose ancestors are all known. +func (s *Set) Roots() []Failure { + var out []Failure + for id, f := range s.failed { + if r, _ := s.Root(id); r.Fact == id { + out = append(out, f) + } + } + sort.Slice(out, func(i, j int) bool { return out[i].Fact < out[j].Fact }) + return out +} diff --git a/pkg/preflight/fact/fact_test.go b/pkg/preflight/fact/fact_test.go new file mode 100644 index 0000000..1464505 --- /dev/null +++ b/pkg/preflight/fact/fact_test.go @@ -0,0 +1,39 @@ +package fact + +import "testing" + +func TestRootWalksToTopMostFailure(t *testing.T) { + s := NewSet() + s.Fail(Failure{Fact: DockerCLI, Summary: "no docker"}) + s.Fail(Failure{Fact: Daemon, Summary: "daemon down"}) + + r, ok := s.Root(Daemon) + if !ok || r.Fact != DockerCLI { + t.Fatalf("root of Daemon = %v, %v; want DockerCLI", r.Fact, ok) + } + roots := s.Roots() + if len(roots) != 1 || roots[0].Fact != DockerCLI { + t.Fatalf("roots = %+v; want only DockerCLI", roots) + } +} + +func TestDaemonDownLeavesHostFactsKnown(t *testing.T) { + s := NewSet() + s.Fail(Failure{Fact: Daemon, Summary: "daemon down"}) + if s.Failed(LocalDaemon) || s.Failed(Compose) { + t.Fatal("endpoint locality and Compose do not depend on the daemon") + } +} + +func TestCLIFailureBlocksEverythingDockerSide(t *testing.T) { + s := NewSet() + s.Fail(Failure{Fact: DockerCLI}) + for _, id := range []ID{Daemon, LocalDaemon, Compose, Buildx} { + if r, _ := s.Root(id); r.Fact != DockerCLI { + t.Errorf("root of %s = %s; want %s", id, r.Fact, DockerCLI) + } + } + if s.Failed(Registry) { + t.Error("registry reachability does not depend on the docker CLI") + } +} diff --git a/pkg/preflight/host/diagnose.go b/pkg/preflight/host/diagnose.go new file mode 100644 index 0000000..1b7f95d --- /dev/null +++ b/pkg/preflight/host/diagnose.go @@ -0,0 +1,191 @@ +package host + +import ( + "fmt" + "os" + osexec "os/exec" + "path/filepath" + "runtime" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +// engine is a local Docker engine this machine could use. +type engine struct { + Name string + Socket string // socket path when the engine is running + Start string // command or action that starts it + Context string // docker context it registers +} + +// daemonClues is what diagnoseDaemon reasons over. It is gathered by +// gatherClues and kept separate so the reasoning can be tested. +type daemonClues struct { + Context string + Endpoint string + Err string + Installed []engine + Running []engine + + // FromInstaller is true when Docker Desktop processes run from a + // mounted installer disk image. + FromInstaller bool + + // DiskFree is free space on this machine; VM engines cannot start + // without room for their disk image. + DiskFree int64 +} + +// diagnoseDaemon turns "cannot connect" into the specific reason: the +// context points at an engine that is gone, an installed engine is stopped, +// another engine is running under a different context, or permissions. +func diagnoseDaemon(c daemonClues) fact.Failure { + f := fact.Failure{ + Fact: fact.Daemon, + Severity: fact.Error, + Summary: "Docker daemon is not reachable", + Detail: c.Err, + } + socket := strings.TrimPrefix(c.Endpoint, "unix://") + ctxName := c.Context + if ctxName == "" { + ctxName = "default" + } + + switch { + case c.FromInstaller: + f.Summary = "Docker Desktop is running from its installer disk image and holds the socket" + f.Fix = "Quit it, stop leftover processes (`pkill -f /Volumes/Docker/Docker.app`), eject the Docker disk, then start Docker from Applications." + return f + + case strings.Contains(c.Err, "did not answer within"): + f.Summary = "Docker daemon accepts connections but does not answer" + fix := "Wait for it to finish starting; if it stays stuck, restart it." + if len(c.Running) > 1 { + var names []string + for _, r := range c.Running { + names = append(names, r.Name) + } + fix = "Several Docker VMs are running (" + strings.Join(names, ", ") + ") and compete for memory. Stop all but one, e.g. `colima stop`." + } + f.Fix = fix + return f + + case strings.Contains(c.Err, "permission denied"): + f.Summary = "No permission to use the Docker socket " + socket + f.Fix = "Add yourself to the docker group (`sudo usermod -aG docker $USER`, then log in again), or use rootless Docker." + return f + + case len(c.Running) > 0 && !strings.EqualFold(c.Running[0].Socket, socket): + r := c.Running[0] + f.Summary = fmt.Sprintf("%s is running, but the Docker context %q points elsewhere (%s)", r.Name, ctxName, socket) + f.Fix = "`docker context use " + r.Context + "`" + return f + + case strings.HasPrefix(c.Endpoint, "unix://"): + owner := socketOwner(socket) + ownerInstalled := false + for _, e := range c.Installed { + if e.Name == owner { + ownerInstalled = true + } + } + switch { + case owner != "" && !ownerInstalled: + f.Summary = fmt.Sprintf("Docker context %q still points to %s, which is not installed", ctxName, owner) + f.Detail = socket + " is left over from it; nothing is listening there" + case !fileExists(socket): + f.Summary = fmt.Sprintf("Docker context %q points to %s, which does not exist", ctxName, socket) + case owner != "": + f.Summary = owner + " is installed but not running" + } + } + + switch len(c.Installed) { + case 0: + f.Fix = "Install a Docker engine (Docker Desktop, OrbStack or Colima) and start it." + default: + e := c.Installed[0] + f.Fix = fmt.Sprintf("Start %s: `%s`", e.Name, e.Start) + if e.Context != "" && e.Context != ctxName { + f.Fix += fmt.Sprintf(", then `docker context use %s`", e.Context) + } + if c.DiskFree > 0 && c.DiskFree < 2<<30 && e.Name != "Docker Engine" { + f.Fix = fmt.Sprintf("Free disk space first: only %d MiB free, and %s needs a few GiB for its VM. Then: %s", + c.DiskFree>>20, e.Name, strings.TrimPrefix(f.Fix, "Start "+e.Name+": ")) + } + if len(c.Installed) > 1 { + var others []string + for _, o := range c.Installed[1:] { + others = append(others, o.Name) + } + f.Fix += " (also installed: " + strings.Join(others, ", ") + ")" + } + } + return f +} + +func socketOwner(socket string) string { + switch { + case strings.Contains(socket, "/.docker/run/"), strings.Contains(socket, "docker-desktop"): + return "Docker Desktop" + case strings.Contains(socket, "/.colima/"): + return "Colima" + case strings.Contains(socket, "/.orbstack/"): + return "OrbStack" + case strings.Contains(socket, "podman"): + return "Podman" + } + return "" +} + +// gatherClues looks for local engines: installed apps and binaries, and the +// sockets of those that are running. +func gatherClues(ctxName, endpoint, errText string, diskFree int64) daemonClues { + c := daemonClues{Context: ctxName, Endpoint: endpoint, Err: errText, DiskFree: diskFree} + home, _ := os.UserHomeDir() + + candidates := []struct { + engine + installed func() bool + }{ + {engine{"Colima", filepath.Join(home, ".colima/default/docker.sock"), "colima start", "colima"}, func() bool { return onPath("colima") }}, + {engine{"OrbStack", filepath.Join(home, ".orbstack/run/docker.sock"), "open -a OrbStack", "orbstack"}, func() bool { + return fileExists("/Applications/OrbStack.app") || onPath("orb") + }}, + {engine{"Docker Desktop", filepath.Join(home, ".docker/run/docker.sock"), "open -a Docker", "desktop-linux"}, func() bool { + return fileExists("/Applications/Docker.app") + }}, + } + if runtime.GOOS == "linux" { + candidates = append(candidates, struct { + engine + installed func() bool + }{engine{"Docker Engine", "/var/run/docker.sock", "sudo systemctl start docker", "default"}, func() bool { return onPath("dockerd") }}) + } + + if out, err := osexec.Command("pgrep", "-f", "/Volumes/.*/Docker.app/").Output(); err == nil && len(strings.TrimSpace(string(out))) > 0 { + c.FromInstaller = true + } + + for _, cand := range candidates { + if fileExists(cand.Socket) { + c.Running = append(c.Running, cand.engine) + } + if cand.installed() { + c.Installed = append(c.Installed, cand.engine) + } + } + return c +} + +func onPath(bin string) bool { + _, err := osexec.LookPath(bin) + return err == nil +} + +func fileExists(p string) bool { + _, err := os.Stat(p) + return err == nil +} diff --git a/pkg/preflight/host/diagnose_test.go b/pkg/preflight/host/diagnose_test.go new file mode 100644 index 0000000..b6006c5 --- /dev/null +++ b/pkg/preflight/host/diagnose_test.go @@ -0,0 +1,94 @@ +package host + +import ( + "strings" + "testing" +) + +var colima = engine{"Colima", "/h/.colima/default/docker.sock", "colima start", "colima"} + +func TestDiagnoseStaleDesktopContext(t *testing.T) { + f := diagnoseDaemon(daemonClues{ + Context: "desktop-linux", + Endpoint: "unix:///nonexistent/.docker/run/docker.sock", + Err: "Cannot connect to the Docker daemon", + Installed: []engine{colima}, + }) + if f.Summary != `Docker context "desktop-linux" still points to Docker Desktop, which is not installed` { + t.Errorf("summary = %q", f.Summary) + } + if f.Fix != "Start Colima: `colima start`, then `docker context use colima`" { + t.Errorf("fix = %q", f.Fix) + } +} + +func TestDiagnoseRunningEngineUnderOtherContext(t *testing.T) { + f := diagnoseDaemon(daemonClues{ + Context: "desktop-linux", + Endpoint: "unix:///nonexistent/.docker/run/docker.sock", + Installed: []engine{colima}, + Running: []engine{colima}, + }) + if !strings.Contains(f.Summary, "Colima is running") || f.Fix != "`docker context use colima`" { + t.Errorf("got %q / %q", f.Summary, f.Fix) + } +} + +func TestDiagnosePermission(t *testing.T) { + f := diagnoseDaemon(daemonClues{Endpoint: "unix:///var/run/docker.sock", Err: "dial unix /var/run/docker.sock: connect: permission denied"}) + if !strings.Contains(f.Fix, "usermod -aG docker") { + t.Errorf("fix = %q", f.Fix) + } +} + +func TestDiagnoseNothingInstalled(t *testing.T) { + f := diagnoseDaemon(daemonClues{Endpoint: "unix:///nonexistent.sock"}) + if !strings.Contains(f.Fix, "Install a Docker engine") { + t.Errorf("fix = %q", f.Fix) + } +} + +func TestDiagnoseInstalledButStopped(t *testing.T) { + f := diagnoseDaemon(daemonClues{ + Context: "colima", + Endpoint: "unix:///nonexistent/.colima/default/docker.sock", + Installed: []engine{colima}, + }) + if f.Summary != "Colima is installed but not running" && !strings.Contains(f.Summary, "does not exist") { + t.Errorf("summary = %q", f.Summary) + } + if f.Fix != "Start Colima: `colima start`" { + t.Errorf("fix = %q", f.Fix) + } +} + +func TestDiagnoseFullDiskBlocksVMStart(t *testing.T) { + f := diagnoseDaemon(daemonClues{ + Context: "desktop-linux", + Endpoint: "unix:///nonexistent/.docker/run/docker.sock", + Installed: []engine{colima}, + DiskFree: 118 << 20, + }) + if !strings.HasPrefix(f.Fix, "Free disk space first: only 118 MiB free") || !strings.Contains(f.Fix, "colima start") { + t.Errorf("fix = %q", f.Fix) + } +} + +func TestDiagnoseHungDaemonWithTwoVMs(t *testing.T) { + desktop := engine{"Docker Desktop", "/h/.docker/run/docker.sock", "open -a Docker", "desktop-linux"} + f := diagnoseDaemon(daemonClues{ + Endpoint: "unix:///h/.docker/run/docker.sock", + Err: "`docker info --format {{json .}}` did not answer within 20s (the daemon may still be starting, or be out of memory)", + Running: []engine{colima, desktop}, + }) + if f.Summary != "Docker daemon accepts connections but does not answer" || !strings.Contains(f.Fix, "colima stop") { + t.Errorf("got %q / %q", f.Summary, f.Fix) + } +} + +func TestDiagnoseInstallerCopy(t *testing.T) { + f := diagnoseDaemon(daemonClues{Endpoint: "unix:///h/.docker/run/docker.sock", Err: "did not answer within 20s", FromInstaller: true}) + if !strings.Contains(f.Summary, "installer disk image") || !strings.Contains(f.Fix, "eject") { + t.Errorf("got %q / %q", f.Summary, f.Fix) + } +} diff --git a/pkg/preflight/host/host.go b/pkg/preflight/host/host.go new file mode 100644 index 0000000..3bf133f --- /dev/null +++ b/pkg/preflight/host/host.go @@ -0,0 +1,646 @@ +// Package host builds a capability profile of the machine that will run the +// project: the Docker daemon's platform and resources (which on macOS and +// Windows are the VM's, not the laptop's), installed tooling, emulation, and +// live port usage. +package host + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net" + "os" + osexec "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "time" + + "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v3/mem" + + "github.com/raphgm/container-preflight/internal/executor" + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +type Profile struct { + // ClientOS/ClientArch describe the machine preflight runs on. + ClientOS string + ClientArch string + ClientMem int64 + + // ClientDiskFree is free space on this machine's home volume, where + // Docker Desktop, Colima and OrbStack keep their VM disks. + ClientDiskFree int64 + + // Platform is the daemon's native platform, e.g. linux/arm64. + Platform string + OperatingSystem string + ServerVersion string + KernelVersion string + MemTotal int64 + NCPU int + Runtimes []string + Rootless bool + SELinux bool + CgroupVersion string + DockerRootDir string + Endpoint string + + // DiskFree is the free space where images are stored. DiskExact is + // false when only an upper bound is known (Docker Desktop's VM disk + // cannot be measured from the host). + DiskFree int64 + DiskExact bool + + ComposeVersion string + BuildxInstalled bool + BuildxVersion string + BuildKitDisabled bool + + // Emulated lists foreign platforms the host can run or build. + // EmulationKnown is false when the daemon's kernel could not be + // inspected, so an empty Emulated list proves nothing. + Emulated []string + EmulationKnown bool + + // Emulators maps an emulated platform to the mechanism: "qemu" or + // "rosetta". Some software runs under Rosetta but crashes under QEMU. + Emulators map[string]string + + // SharedPaths are the host folders Docker Desktop shares with its VM, + // read from the running VM. Empty when unknown. + SharedPaths []string + + // Sysctls holds kernel settings read on a local Linux daemon host. + Sysctls map[string]int64 + + // LocalImages holds canonical references already present in the + // daemon; Compose does not pull these. + LocalImages map[string]bool + + // PublishedPorts maps "port/proto" to containers already publishing it. + PublishedPorts map[string][]Container + + // PortProbe and Lsof are nil on remote daemons. + PortProbe func(ip string, port int, proto string) bool `json:"-"` + Lsof func(port int, proto string) string `json:"-"` + + // RunningFromInstaller is true when Docker Desktop runs from its + // mounted installer disk image instead of /Applications. + RunningFromInstaller bool + + // Local is true when the daemon endpoint is on this machine. + Local bool + + // MissingCredentialHelper names a credsStore/credHelpers program that + // ~/.docker/config.json configures but that is not installed. + MissingCredentialHelper string +} + +type Container struct { + Name string + ComposeProject string +} + +// UsesVM reports whether the daemon runs in a VM whose disk image lives on +// this machine and grows as images are pulled. +func (p *Profile) UsesVM() bool { + return p.Local && (p.ClientOS == "darwin" || p.ClientOS == "windows" || p.IsDesktop() || strings.Contains(p.Endpoint, "/.colima/")) +} + +// MapsOwnership reports whether bind-mounted files appear owned by the +// container user regardless of host ownership: true for the file sharing of +// Docker Desktop, Colima and OrbStack on macOS and Windows. +func (p *Profile) MapsOwnership() bool { + return p.ClientOS == "darwin" || p.ClientOS == "windows" +} + +// IsDesktop reports whether the daemon runs inside Docker Desktop's VM. +func (p *Profile) IsDesktop() bool { + return strings.Contains(p.OperatingSystem, "Docker Desktop") +} + +// CanRun reports whether platform runs natively or under emulation. +func (p *Profile) CanRun(platform string) (native, emulated bool) { + if registry.Compatible(platform, p.Platform) { + return true, false + } + for _, e := range p.Emulated { + if registry.Compatible(platform, e) { + return false, true + } + } + return false, false +} + +// PortHolder reports what already holds a host port: a container, a local +// process, or "" when the port is free. +func (p *Profile) PortHolder(ip string, port int, proto string) (holder string, container *Container) { + if cs := p.PublishedPorts[fmt.Sprintf("%d/%s", port, proto)]; len(cs) > 0 { + return "container " + cs[0].Name, &cs[0] + } + if p.PortProbe != nil && p.PortProbe(ip, port, proto) { + if p.Lsof != nil { + if name := p.Lsof(port, proto); name != "" { + return "process " + name, nil + } + } + return "another process", nil + } + return "", nil +} + +// Probe inspects the host. Anything it cannot determine is recorded in +// facts with the reason, so dependent rules report the true root cause. +func Probe(ctx context.Context, run executor.Runner, facts *fact.Set) *Profile { + run = timeoutRunner{run} + p := &Profile{ + ClientOS: runtime.GOOS, + ClientArch: runtime.GOARCH, + Sysctls: map[string]int64{}, + PublishedPorts: map[string][]Container{}, + LocalImages: map[string]bool{}, + } + if vm, err := mem.VirtualMemoryWithContext(ctx); err == nil { + p.ClientMem = int64(vm.Total) + } + if home, err := os.UserHomeDir(); err == nil { + if u, err := disk.UsageWithContext(ctx, home); err == nil { + p.ClientDiskFree = int64(u.Free) + } + } + p.BuildKitDisabled = os.Getenv("DOCKER_BUILDKIT") == "0" + + if _, err := run.Run(ctx, "docker", "--version"); err != nil { + facts.Fail(fact.Failure{ + Fact: fact.DockerCLI, + Severity: fact.Error, + Summary: "Docker CLI not found", + Detail: errText(err), + Fix: "Install Docker Desktop, OrbStack, Colima or Docker Engine, and make sure `docker` is on PATH.", + }) + return p + } + + p.MissingCredentialHelper = missingCredentialHelper() + p.probeEndpoint(ctx, run, facts) + p.probeDaemon(ctx, run, facts) + p.probeCompose(ctx, run, facts) + p.probeBuildx(ctx, run) + return p +} + +func (p *Profile) probeDaemon(ctx context.Context, run executor.Runner, facts *fact.Set) { + out, err := run.Run(ctx, "docker", "info", "--format", "{{json .}}") + var info dockerInfo + if err == nil { + err = json.Unmarshal([]byte(out), &info) + } + if err == nil && len(info.ServerErrors) > 0 { + err = errors.New(strings.Join(info.ServerErrors, "; ")) + } + if err == nil && info.ServerVersion == "" { + err = errors.New("docker info returned no server details") + } + if err != nil { + ctxName, _ := run.Run(ctx, "docker", "context", "show") + facts.Fail(diagnoseDaemon(gatherClues(ctxName, p.Endpoint, errText(err), p.ClientDiskFree))) + return + } + + p.Platform = registry.Normalize(info.OSType + "/" + info.Architecture) + p.OperatingSystem = info.OperatingSystem + p.ServerVersion = info.ServerVersion + p.KernelVersion = info.KernelVersion + p.MemTotal = info.MemTotal + p.NCPU = info.NCPU + p.CgroupVersion = info.CgroupVersion + p.DockerRootDir = info.DockerRootDir + for name := range info.Runtimes { + p.Runtimes = append(p.Runtimes, name) + } + for _, opt := range info.SecurityOptions { + if strings.Contains(opt, "name=rootless") { + p.Rootless = true + } + if strings.Contains(opt, "name=selinux") { + p.SELinux = true + } + } + + if p.IsDesktop() { + // Docker Desktop's VM supports amd64 on Apple silicon (Rosetta or + // QEMU) and ships its own sysctl defaults. + if p.Platform == "linux/arm64" { + p.Emulated = append(p.Emulated, "linux/amd64") + } else if p.Platform == "linux/amd64" { + p.Emulated = append(p.Emulated, "linux/arm64", "linux/arm/v7") + } + p.Sysctls = map[string]int64{"vm.max_map_count": 262144} + p.EmulationKnown = true + p.DiskExact = false + p.readDesktopVM(ctx, run) + } else if shell := p.kernelShell(); shell != nil { + p.readKernel(ctx, run, shell) + } + + if out, err := run.Run(ctx, "docker", "image", "ls", "--format", "{{.Repository}}:{{.Tag}}"); err == nil { + for _, ref := range strings.Split(out, "\n") { + if ref != "" && !strings.Contains(ref, "") { + p.LocalImages[registry.Canonical(ref)] = true + } + } + } + + if out, err := run.Run(ctx, "docker", "ps", "--format", "{{.Names}}\t{{.Label \"com.docker.compose.project\"}}\t{{.Ports}}"); err == nil { + p.PublishedPorts = parsePS(out) + } +} + +// probeEndpoint decides from the CLI context whether the daemon runs on +// this machine. Only then do local ports, paths and kernel settings apply. +func (p *Profile) probeEndpoint(ctx context.Context, run executor.Runner, facts *fact.Set) { + p.Endpoint = os.Getenv("DOCKER_HOST") + if p.Endpoint == "" { + p.Endpoint, _ = run.Run(ctx, "docker", "context", "inspect", "--format", "{{.Endpoints.docker.Host}}") + } + p.Local = p.Endpoint == "" || strings.HasPrefix(p.Endpoint, "unix://") || strings.HasPrefix(p.Endpoint, "npipe://") + if !p.Local { + facts.Fail(fact.Failure{ + Fact: fact.LocalDaemon, + Severity: fact.Info, + Summary: "Docker daemon is remote (" + p.Endpoint + ")", + Detail: "Ports, bind-mount paths and kernel settings live on the remote host and cannot be checked from here.", + Fix: "Run container-preflight on the daemon host for full coverage.", + }) + return + } + + p.PortProbe = portInUse + p.Lsof = lsofHolder + if home, err := os.UserHomeDir(); err == nil { + if usage, err := disk.UsageWithContext(ctx, home); err == nil { + p.DiskFree = int64(usage.Free) + } + } +} + +// readDesktopVM reads Docker Desktop's VM command line on macOS: it shows +// whether amd64 runs under Rosetta or QEMU and which folders are shared. +func (p *Profile) readDesktopVM(ctx context.Context, run executor.Runner) { + if p.ClientOS != "darwin" { + return + } + pid, err := run.Run(ctx, "pgrep", "-f", "com.docker.virtualization") + if err != nil || pid == "" { + return + } + args, err := run.Run(ctx, "ps", "-o", "args=", "-p", strings.Fields(pid)[0]) + if err != nil { + return + } + fields := strings.Fields(args) + emulator := "qemu" + for i, f := range fields { + switch f { + case "--rosetta": + emulator = "rosetta" + case "--virtiofs": + if i+1 < len(fields) { + p.SharedPaths = append(p.SharedPaths, fields[i+1]) + } + } + } + for _, e := range p.Emulated { + if p.Emulators == nil { + p.Emulators = map[string]string{} + } + if e == "linux/amd64" { + p.Emulators[e] = emulator + } else { + p.Emulators[e] = "qemu" + } + } + if strings.Contains(args, "/Volumes/") && strings.Contains(args, "Docker.app") { + p.RunningFromInstaller = true + } +} + +// kernelShell returns the command prefix that runs a shell where the +// daemon's kernel lives: this machine for a local Linux daemon, or the VM +// for Colima. It returns nil when there is no way in. +func (p *Profile) kernelShell() []string { + if !p.Local { + return nil + } + sock := strings.TrimPrefix(p.Endpoint, "unix://") + if i := strings.Index(sock, "/.colima/"); i >= 0 { + profile := strings.SplitN(sock[i+len("/.colima/"):], "/", 2)[0] + if profile == "" || profile == "_lima" { + profile = "default" + } + return []string{"colima", "ssh", "-p", profile, "--"} + } + if runtime.GOOS == "linux" { + return []string{} + } + return nil +} + +// kernelScript prints the kernel facts preflight needs, one per line. +const kernelScript = `echo max_map_count=$(cat /proc/sys/vm/max_map_count 2>/dev/null) +echo unpriv_port_start=$(cat /proc/sys/net/ipv4/ip_unprivileged_port_start 2>/dev/null) +echo binfmt=$(ls /proc/sys/fs/binfmt_misc 2>/dev/null | tr '\n' ' ') +echo disk_free=$(df -B1 --output=avail "$0" 2>/dev/null | tail -1)` + +func (p *Profile) readKernel(ctx context.Context, run executor.Runner, shell []string) { + root := p.DockerRootDir + if root == "" { + root = "/var/lib/docker" + } + args := append(append([]string{}, shell...), "sh", "-c", kernelScript, root) + out, err := run.Run(ctx, args[0], args[1:]...) + if err != nil { + return + } + native := p.Platform + for _, line := range strings.Split(out, "\n") { + key, val, ok := strings.Cut(strings.TrimSpace(line), "=") + if !ok || val == "" { + continue + } + switch key { + case "max_map_count": + if v, err := strconv.ParseInt(val, 10, 64); err == nil { + p.Sysctls["vm.max_map_count"] = v + } + case "unpriv_port_start": + if v, err := strconv.ParseInt(val, 10, 64); err == nil { + p.Sysctls["net.ipv4.ip_unprivileged_port_start"] = v + } + case "binfmt": + p.EmulationKnown = true + for _, h := range strings.Fields(val) { + arch, ok := binfmtPlatforms[h] + if !ok || arch == native { + continue + } + if !containsStr(p.Emulated, arch) { + p.Emulated = append(p.Emulated, arch) + } + if p.Emulators == nil { + p.Emulators = map[string]string{} + } + // Rosetta wins when both are registered: the kernel + // prefers it on Apple virtualization. + if h == "rosetta" || p.Emulators[arch] == "" { + p.Emulators[arch] = strings.SplitN(h, "-", 2)[0] + } + } + case "disk_free": + if v, err := strconv.ParseInt(val, 10, 64); err == nil { + p.DiskFree, p.DiskExact = v, true + } + } + } +} + +// binfmtPlatforms maps binfmt_misc handler names (QEMU and Rosetta) to the +// platforms they run. +var binfmtPlatforms = map[string]string{ + "qemu-x86_64": "linux/amd64", + "rosetta": "linux/amd64", + "qemu-aarch64": "linux/arm64", + "qemu-arm": "linux/arm/v7", + "qemu-riscv64": "linux/riscv64", + "qemu-ppc64le": "linux/ppc64le", + "qemu-s390x": "linux/s390x", +} + +func (p *Profile) probeCompose(ctx context.Context, run executor.Runner, facts *fact.Set) { + if v, err := run.Run(ctx, "docker", "compose", "version", "--short"); err == nil { + p.ComposeVersion = strings.TrimPrefix(v, "v") + return + } + if v, err := run.Run(ctx, "docker-compose", "version", "--short"); err == nil { + p.ComposeVersion = strings.TrimPrefix(v, "v") + return + } + facts.Fail(fact.Failure{ + Fact: fact.Compose, + Severity: fact.Error, + Summary: "Docker Compose is not installed", + Fix: "Install the Compose v2 plugin (bundled with Docker Desktop; `docker-compose-plugin` package on Linux).", + }) +} + +func (p *Profile) probeBuildx(ctx context.Context, run executor.Runner) { + v, err := run.Run(ctx, "docker", "buildx", "version") + if err != nil { + return + } + p.BuildxInstalled = true + if f := strings.Fields(v); len(f) >= 2 { + p.BuildxVersion = strings.TrimPrefix(f[1], "v") + } + if out, err := run.Run(ctx, "docker", "buildx", "inspect"); err == nil { + for _, line := range strings.Split(out, "\n") { + if rest, ok := strings.CutPrefix(strings.TrimSpace(line), "Platforms:"); ok { + p.EmulationKnown = true + for _, pl := range strings.Split(rest, ",") { + pl = registry.Normalize(strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(pl), "*"))) + if pl != "" && pl != p.Platform && !containsStr(p.Emulated, pl) { + p.Emulated = append(p.Emulated, pl) + } + } + } + } + } +} + +type dockerInfo struct { + ServerVersion string + OSType string + Architecture string + OperatingSystem string + KernelVersion string + MemTotal int64 + NCPU int + CgroupVersion string + DockerRootDir string + Runtimes map[string]json.RawMessage + SecurityOptions []string + ServerErrors []string +} + +// parsePS reads `docker ps` rows: name, compose project, ports. +func parsePS(out string) map[string][]Container { + res := map[string][]Container{} + for _, line := range strings.Split(out, "\n") { + cols := strings.Split(line, "\t") + if len(cols) < 3 { + continue + } + c := Container{Name: cols[0], ComposeProject: cols[1]} + for _, mapping := range strings.Split(cols[2], ", ") { + // 0.0.0.0:8080->80/tcp, :::8080->80/tcp, 0.0.0.0:8000-8001->80-81/tcp + left, right, ok := strings.Cut(mapping, "->") + if !ok { + continue + } + _, proto, _ := strings.Cut(right, "/") + hostPorts := left[strings.LastIndex(left, ":")+1:] + lo, hi, _ := strings.Cut(hostPorts, "-") + start, err := strconv.Atoi(lo) + if err != nil { + continue + } + end := start + if hi != "" { + if e, err := strconv.Atoi(hi); err == nil { + end = e + } + } + for port := start; port <= end; port++ { + key := fmt.Sprintf("%d/%s", port, proto) + if !containsContainer(res[key], c.Name) { + res[key] = append(res[key], c) + } + } + } + } + return res +} + +func portInUse(ip string, port int, proto string) bool { + if ip == "" { + ip = "0.0.0.0" + } + addr := net.JoinHostPort(ip, strconv.Itoa(port)) + if proto == "udp" { + c, err := net.ListenPacket("udp", addr) + if err != nil { + return true + } + c.Close() + return false + } + // A listener on 127.0.0.1 alone still blocks Docker's 0.0.0.0 bind on + // Linux, and on macOS a bind can succeed despite it, so dial as well. + if c, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)), 300*time.Millisecond); err == nil { + c.Close() + return true + } + l, err := net.Listen("tcp", addr) + if err != nil { + return true + } + l.Close() + return false +} + +func lsofHolder(port int, proto string) string { + args := []string{"-nP", fmt.Sprintf("-i%s:%d", strings.ToUpper(proto), port), "-Fcp"} + if proto == "tcp" { + args = append(args, "-sTCP:LISTEN") + } + out, err := osexec.Command("lsof", args...).Output() + if err != nil { + return "" + } + var pid, cmd string + for _, line := range strings.Split(string(out), "\n") { + if strings.HasPrefix(line, "p") && pid == "" { + pid = line[1:] + } + if strings.HasPrefix(line, "c") && cmd == "" { + cmd = line[1:] + } + } + if cmd == "" { + return "" + } + return fmt.Sprintf("%s (pid %s)", cmd, pid) +} + +// missingCredentialHelper returns the first credential helper configured in +// the Docker CLI config that cannot be found on PATH. +func missingCredentialHelper() string { + dir := os.Getenv("DOCKER_CONFIG") + if dir == "" { + home, err := os.UserHomeDir() + if err != nil { + return "" + } + dir = filepath.Join(home, ".docker") + } + b, err := os.ReadFile(filepath.Join(dir, "config.json")) + if err != nil { + return "" + } + var cfg struct { + CredsStore string `json:"credsStore"` + CredHelpers map[string]string `json:"credHelpers"` + } + if json.Unmarshal(b, &cfg) != nil { + return "" + } + helpers := []string{cfg.CredsStore} + for _, h := range cfg.CredHelpers { + helpers = append(helpers, h) + } + for _, h := range helpers { + if h == "" { + continue + } + if _, err := osexec.LookPath("docker-credential-" + h); err != nil { + return "docker-credential-" + h + } + } + return "" +} + +// commandTimeout bounds each probe command: a daemon that is starting or +// starved of memory accepts connections but never answers. +const commandTimeout = 20 * time.Second + +type timeoutRunner struct{ executor.Runner } + +func (t timeoutRunner) Run(ctx context.Context, name string, args ...string) (string, error) { + cctx, cancel := context.WithTimeout(ctx, commandTimeout) + defer cancel() + out, err := t.Runner.Run(cctx, name, args...) + if err != nil && cctx.Err() == context.DeadlineExceeded { + return out, fmt.Errorf("`%s %s` did not answer within %s (the daemon may still be starting, or be out of memory)", name, strings.Join(args, " "), commandTimeout) + } + return out, err +} + +func errText(err error) string { + if errors.Is(err, osexec.ErrNotFound) { + return "`docker` executable not found on PATH" + } + return strings.TrimPrefix(strings.TrimSpace(err.Error()), "exit status 1: ") +} + +func containsStr(xs []string, s string) bool { + for _, x := range xs { + if x == s { + return true + } + } + return false +} + +func containsContainer(cs []Container, name string) bool { + for _, c := range cs { + if c.Name == name { + return true + } + } + return false +} diff --git a/pkg/preflight/host/host_test.go b/pkg/preflight/host/host_test.go new file mode 100644 index 0000000..23f5e53 --- /dev/null +++ b/pkg/preflight/host/host_test.go @@ -0,0 +1,127 @@ +package host + +import ( + "context" + "errors" + "fmt" + "os/exec" + "strings" + "testing" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +type fakeRunner map[string]string + +func (f fakeRunner) Run(_ context.Context, name string, args ...string) (string, error) { + key := strings.TrimSpace(name + " " + strings.Join(args, " ")) + for prefix, out := range f { + if strings.HasPrefix(key, prefix) { + if strings.HasPrefix(out, "ERR:") { + return "", errors.New(strings.TrimPrefix(out, "ERR:")) + } + return out, nil + } + } + return "", fmt.Errorf("unexpected command %q", key) +} + +type missingDocker struct{} + +func (missingDocker) Run(context.Context, string, ...string) (string, error) { + return "", fmt.Errorf("%w", exec.ErrNotFound) +} + +func TestNoDockerCLIIsTheOnlyRootCause(t *testing.T) { + facts := fact.NewSet() + Probe(context.Background(), missingDocker{}, facts) + roots := facts.Roots() + if len(roots) != 1 || roots[0].Fact != fact.DockerCLI { + t.Fatalf("roots = %+v", roots) + } + for _, id := range []fact.ID{fact.Daemon, fact.Compose, fact.Buildx, fact.LocalDaemon} { + if !facts.Failed(id) { + t.Errorf("%s should be unknown without the CLI", id) + } + } +} + +func TestDaemonDown(t *testing.T) { + facts := fact.NewSet() + p := Probe(context.Background(), fakeRunner{ + "docker --version": "Docker version 27.0.3", + "docker info": "ERR:Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?", + "docker compose": "2.29.1", + "docker buildx version": "github.com/docker/buildx v0.16.1 abc", + "docker buildx inspect": "Platforms: linux/arm64", + "docker ps": "ERR:cannot connect", + }, facts) + r, ok := facts.Root(fact.Daemon) + if !ok || r.Fact != fact.Daemon || !strings.Contains(r.Detail, "Cannot connect") { + t.Fatalf("root = %+v", r) + } + if facts.Failed(fact.LocalDaemon) || p.PortProbe == nil { + t.Error("a local endpoint stays checkable while the daemon is down") + } + if facts.Failed(fact.Compose) || p.ComposeVersion != "2.29.1" || !p.BuildxInstalled { + t.Errorf("compose/buildx do not need the daemon: %+v", p) + } +} + +func TestDesktopProfile(t *testing.T) { + facts := fact.NewSet() + info := `{"ServerVersion":"27.0.3","OSType":"linux","Architecture":"aarch64","OperatingSystem":"Docker Desktop","MemTotal":4102033408,"NCPU":4,"Runtimes":{"runc":{}},"SecurityOptions":["name=seccomp,profile=builtin","name=cgroupns"]}` + p := Probe(context.Background(), fakeRunner{ + "docker --version": "Docker version 27.0.3", + "docker info": info, + "docker context inspect": "unix:///Users/me/.docker/run/docker.sock", + "docker ps": "db-1\tshop\t0.0.0.0:5432->5432/tcp, :::5432->5432/tcp\nweb\t\t0.0.0.0:8000-8001->80-81/tcp", + "docker compose": "v2.29.1-desktop.1", + "docker buildx version": "github.com/docker/buildx v0.16.1 abc", + "docker buildx inspect": "Name: desktop-linux\nPlatforms: linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64", + }, facts) + if len(facts.Roots()) != 0 { + t.Fatalf("unexpected failures: %+v", facts.Roots()) + } + if p.Platform != "linux/arm64" || !p.IsDesktop() || p.MemTotal != 4102033408 { + t.Errorf("profile = %+v", p) + } + if native, emu := p.CanRun("linux/amd64"); native || !emu { + t.Error("desktop on arm64 should emulate amd64") + } + if native, emu := p.CanRun("linux/s390x"); native || emu { + t.Error("s390x is not available") + } + if holder, c := p.PortHolder("", 5432, "tcp"); c == nil || c.ComposeProject != "shop" { + t.Errorf("5432 holder = %q %+v", holder, c) + } + if _, c := p.PortHolder("", 8001, "tcp"); c == nil || c.Name != "web" { + t.Error("range ports not parsed") + } + if p.ComposeVersion != "2.29.1-desktop.1" { + t.Errorf("compose version = %q", p.ComposeVersion) + } +} + +func TestColimaKernelProbe(t *testing.T) { + facts := fact.NewSet() + info := `{"ServerVersion":"29.1.3","OSType":"linux","Architecture":"aarch64","OperatingSystem":"Ubuntu 24.04.4 LTS","MemTotal":2053578752,"NCPU":2,"DockerRootDir":"/var/lib/docker"}` + p := Probe(context.Background(), fakeRunner{ + "docker --version": "Docker version 29.8.1", + "docker context inspect": "unix:///Users/me/.colima/default/docker.sock", + "docker info": info, + "colima ssh -p default -- sh -c": "max_map_count=1048576\nunpriv_port_start=1024\nbinfmt=python3.12 qemu-i386 qemu-x86_64 register status\ndisk_free=95000000000", + "docker-compose": "5.5.1", + "docker compose": "ERR:unknown command", + "docker buildx": "ERR:unknown command", + }, facts) + if !p.EmulationKnown || len(p.Emulated) != 1 || p.Emulated[0] != "linux/amd64" || p.Emulators["linux/amd64"] != "qemu" { + t.Errorf("emulation = %v known=%v", p.Emulated, p.EmulationKnown) + } + if p.Sysctls["vm.max_map_count"] != 1048576 || !p.DiskExact || p.DiskFree != 95000000000 { + t.Errorf("kernel facts = %v disk=%d exact=%v", p.Sysctls, p.DiskFree, p.DiskExact) + } + if p.ComposeVersion != "5.5.1" || p.BuildxInstalled { + t.Errorf("compose=%q buildx=%v", p.ComposeVersion, p.BuildxInstalled) + } +} diff --git a/pkg/preflight/host/snapshot.go b/pkg/preflight/host/snapshot.go new file mode 100644 index 0000000..13f49f1 --- /dev/null +++ b/pkg/preflight/host/snapshot.go @@ -0,0 +1,123 @@ +package host + +import ( + "context" + "encoding/json" + "fmt" + "os" + osexec "os/exec" + "strconv" + "strings" + "time" + + "github.com/raphgm/container-preflight/internal/executor" + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +const snapshotVersion = 1 + +// Snapshot is a portable host profile. Preflight can run against a snapshot +// from another machine (a teammate's laptop, a CI runner, a server) to +// predict failures there without access to it. +type Snapshot struct { + Version int `json:"version"` + CapturedAt time.Time `json:"capturedAt"` + Hostname string `json:"hostname"` + Profile *Profile `json:"profile"` + Failures []fact.Failure `json:"failures,omitempty"` + ListeningPorts []string `json:"listeningPorts,omitempty"` +} + +// Capture probes this host and records it as a snapshot. +func Capture(ctx context.Context, run executor.Runner) *Snapshot { + facts := fact.NewSet() + p := Probe(ctx, run, facts) + name, _ := os.Hostname() + s := &Snapshot{ + Version: snapshotVersion, + CapturedAt: time.Now().UTC(), + Hostname: name, + Profile: p, + Failures: facts.All(), + } + if p.Local { + s.ListeningPorts = listeningPorts() + } + return s +} + +// Restore turns a snapshot back into a profile and fact set. Port checks use +// the ports that were listening when the snapshot was taken. +func (s *Snapshot) Restore() (*Profile, *fact.Set) { + facts := fact.NewSet() + for _, f := range s.Failures { + facts.Fail(f) + } + p := s.Profile + if p.Sysctls == nil { + p.Sysctls = map[string]int64{} + } + if p.LocalImages == nil { + p.LocalImages = map[string]bool{} + } + if p.PublishedPorts == nil { + p.PublishedPorts = map[string][]Container{} + } + if p.Local { + listening := map[string]bool{} + for _, lp := range s.ListeningPorts { + listening[lp] = true + } + p.PortProbe = func(_ string, port int, proto string) bool { + return listening[fmt.Sprintf("%d/%s", port, proto)] + } + p.Lsof = nil + } + return p, facts +} + +func LoadSnapshot(path string) (*Snapshot, error) { + b, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var s Snapshot + if err := json.Unmarshal(b, &s); err != nil { + return nil, fmt.Errorf("%s: %w", path, err) + } + if s.Profile == nil { + return nil, fmt.Errorf("%s: not a container-preflight snapshot", path) + } + if s.Version > snapshotVersion { + return nil, fmt.Errorf("%s: snapshot version %d is newer than this container-preflight supports", path, s.Version) + } + return &s, nil +} + +// listeningPorts lists TCP ports with a listener on this machine. +func listeningPorts() []string { + out, err := osexec.Command("lsof", "-nP", "-iTCP", "-sTCP:LISTEN", "-Fn").Output() + if err != nil { + return nil + } + seen := map[string]bool{} + var ports []string + for _, line := range strings.Split(string(out), "\n") { + if !strings.HasPrefix(line, "n") { + continue + } + i := strings.LastIndex(line, ":") + if i < 0 { + continue + } + if _, err := strconv.Atoi(line[i+1:]); err != nil { + continue + } + key := line[i+1:] + "/tcp" + if !seen[key] { + seen[key] = true + ports = append(ports, key) + } + } + return ports +} diff --git a/pkg/preflight/learn/learn_test.go b/pkg/preflight/learn/learn_test.go new file mode 100644 index 0000000..f05f85c --- /dev/null +++ b/pkg/preflight/learn/learn_test.go @@ -0,0 +1,115 @@ +package learn + +import ( + "regexp" + "testing" +) + +func TestExtractPicksSpecificCauseFromComposeOutput(t *testing.T) { + out := "Attaching to db-1\n" + + "db-1 | SQL Server 2022 will run as non-root by default.\n" + + "db-1 | /opt/mssql/bin/sqlservr: Invalid mapping of address 0x4005353000 in reserved address space below 0x400000000000. Possible causes:\n" + + "db-1 | 1) the process (itself, or via a wrapper) starts-up its own running environment\n" + + "db-1 exited with code 1\n" + f, ok := Extract(out) + if !ok || f.Service != "db" || f.ExitCode != 1 { + t.Fatalf("got %+v", f) + } + if want := "/opt/mssql/bin/sqlservr: Invalid mapping"; f.Line[:len(want)] != want { + t.Errorf("line = %q", f.Line) + } +} + +func TestExtractIgnoresGenericWrappers(t *testing.T) { + f, ok := Extract("Error response from daemon:\nERROR: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]\nsearch-1 exited with code 78\n") + if !ok || f.Service != "search" || f.ExitCode != 78 { + t.Fatalf("got %+v", f) + } +} + +func TestSignatureGeneralizesVolatileParts(t *testing.T) { + a := "/opt/mssql/bin/sqlservr: Invalid mapping of address 0x4005353000 in reserved address space below 0x400000000000. Possible causes:" + b := "/usr/bin/sqlservr: Invalid mapping of address 0x7f00aa in reserved address space below 0x400000000000. Possible causes:" + re := regexp.MustCompile(Signature(a)) + if !re.MatchString(a) || !re.MatchString(b) { + t.Errorf("signature %q should match both", Signature(a)) + } + if re.MatchString("exec format error") { + t.Error("signature too loose") + } +} + +func features(kv ...string) map[string]string { + m := map[string]string{} + for i := 0; i+1 < len(kv); i += 2 { + m[kv[i]] = kv[i+1] + } + return m +} + +func TestLearnGeneralizeAndRefine(t *testing.T) { + s := &Store{path: t.TempDir() + "/learned.yaml"} + crash := Failure{Line: "WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!", Service: "db"} + + // First failure: colima, QEMU, small VM. + out := s.ObserveFailure(crash, features("image", "docker.io/library/mongo", "run.platform", "linux/amd64", "host.platform", "linux/arm64", "emulation", "qemu", "memory", "<2GiB", "engine", "colima", "build", "yes", "buildkit", "no"), "mac-1") + r := out.Rule + if !out.Created || r.When["emulation"] != "qemu" || r.When["memory"] != "<2GiB" || r.When["image"] != "docker.io/library/mongo" { + t.Fatalf("new rule when = %v", r.When) + } + if _, ok := r.When["engine"]; ok { + t.Error("engine is recorded but not a starting condition") + } + if r.When["run.platform"] != "linux/amd64" || r.When["buildkit"] != "no" { + t.Errorf("foreign platform and builder of a built service are conditions: %v", r.When) + } + image := s.ObserveFailure(Failure{Line: "other failure xyz"}, features("image", "x", "run.platform", "linux/arm64", "host.platform", "linux/arm64", "build", "no", "buildkit", "no"), "m").Rule + if len(image.When) != 1 { + t.Errorf("native platform and unused builder must not be conditions: %v", image.When) + } + + // Same failure on a bigger VM: memory was not the cause. + out = s.ObserveFailure(crash, features("image", "docker.io/library/mongo", "run.platform", "linux/amd64", "host.platform", "linux/arm64", "emulation", "qemu", "memory", "<8GiB", "build", "yes", "buildkit", "yes"), "mac-2") + if out.Created || len(out.Dropped) != 2 || r.When["memory"] != "" || r.When["buildkit"] != "" { + t.Fatalf("generalization: dropped=%v when=%v", out.Dropped, r.When) + } + + // Mongo under Rosetta works: rule does not hold, untouched. + if n := len(s.ObserveSuccess("db", features("image", "docker.io/library/mongo", "run.platform", "linux/amd64", "emulation", "rosetta"), "mac-3")); n != 0 { + t.Errorf("rosetta success should not touch the rule") + } + if r.Status != Active { + t.Errorf("status = %s", r.Status) + } + + // A success that satisfies every condition but differs on a feature + // all failures share specializes the rule. + r.When = map[string]string{"image": "docker.io/library/mongo"} + touched := s.ObserveSuccess("db", features("image", "docker.io/library/mongo", "run.platform", "linux/arm64", "emulation", "none"), "linux-arm") + if len(touched) != 1 || r.When["run.platform"] != "linux/amd64" || r.Status != Active { + t.Errorf("specialize: when=%v status=%s", r.When, r.Status) + } + + if err := s.Save(); err != nil { + t.Fatal(err) + } +} + +func TestSuccessLearnsMissingVariable(t *testing.T) { + s := &Store{path: t.TempDir() + "/learned.yaml"} + fail := Failure{Line: "Error: Database is uninitialized and superuser password is not specified.", Service: "db"} + r := s.ObserveFailure(fail, features("image", "docker.io/library/postgres", "emulation", "none"), "mac").Rule + if len(r.When) != 1 { + t.Fatalf("when = %v", r.When) + } + s.ObserveSuccess("db", features("image", "docker.io/library/postgres", "emulation", "none", "env.POSTGRES_PASSWORD", "set"), "mac") + if r.When["env.POSTGRES_PASSWORD"] != unset || r.Status != Active { + t.Errorf("when = %v status = %s", r.When, r.Status) + } + if r.holds(features("image", "docker.io/library/postgres", "env.POSTGRES_PASSWORD", "set")) { + t.Error("rule must not fire once the password is set") + } + if !r.holds(features("image", "docker.io/library/postgres")) { + t.Error("rule must fire when the password is missing") + } +} diff --git a/pkg/preflight/learn/signature.go b/pkg/preflight/learn/signature.go new file mode 100644 index 0000000..93f673c --- /dev/null +++ b/pkg/preflight/learn/signature.go @@ -0,0 +1,150 @@ +// Package learn turns observed container failures into preflight rules. A +// failure's decisive log line becomes a signature; the project and host +// features at the time become the rule's conditions. Later failures with the +// same signature generalize the conditions, and successful runs that match +// them mark the rule unreliable. +package learn + +import ( + "regexp" + "strconv" + "strings" +) + +// Failure is what was extracted from a failed run's output. +type Failure struct { + Line string + Service string + ExitCode int +} + +// composePrefix matches Compose's log prefix, e.g. "db-1 | ". +var composePrefix = regexp.MustCompile(`^([a-zA-Z0-9][a-zA-Z0-9_.-]*?)(?:-\d+)?\s+\|\s?(.*)$`) + +// exitedLine matches Compose's container exit report. +var exitedLine = regexp.MustCompile(`^([a-zA-Z0-9][a-zA-Z0-9_.-]*?)(?:-\d+)? exited with code (\d+)`) + +var ansi = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`) + +// Keywords that make a line decisive, with weights. Generic wrappers such as +// "exited with code" or "Error response from daemon" score low so the +// specific cause wins. +var cues = []struct { + re *regexp.Regexp + weight int +}{ + {regexp.MustCompile(`(?i)\b(fatal|panic|segmentation fault|illegal instruction|core dumped)\b`), 5}, + {regexp.MustCompile(`(?i)\b(requires?|required|not supported|unsupported|incompatible|too low|at least)\b`), 4}, + {regexp.MustCompile(`(?i)\b(error|failed|failure|invalid|cannot|can't|unable|denied|refused|not found|no such|no space|oom|killed)\b`), 3}, + {regexp.MustCompile(`(?i)\bwarn(ing)?\b`), 1}, +} + +var generic = regexp.MustCompile(`(?i)(exited with code|error response from daemon:?\s*$|^error:?\s*$|attaching to|gracefully stopping|aborting on container exit)`) + +// Extract picks the line that best explains why a run failed. +func Extract(output string) (Failure, bool) { + var best Failure + bestScore := 0 + exitCodes := map[string]int{} + for _, raw := range strings.Split(ansi.ReplaceAllString(output, ""), "\n") { + line := strings.TrimSpace(raw) + if line == "" { + continue + } + if m := exitedLine.FindStringSubmatch(line); m != nil { + if code, _ := strconv.Atoi(m[2]); code != 0 { + exitCodes[m[1]] = code + } + continue + } + service := "" + if m := composePrefix.FindStringSubmatch(line); m != nil { + service, line = m[1], strings.TrimSpace(m[2]) + } + score := 0 + for _, c := range cues { + if c.re.MatchString(line) { + score += c.weight + } + } + if generic.MatchString(line) { + score -= 3 + } + // Later lines win ties: the cause is usually printed last. + if score > 0 && score >= bestScore { + best, bestScore = Failure{Line: line, Service: service}, score + } + } + if bestScore == 0 { + return Failure{}, false + } + if best.Service == "" && len(exitCodes) == 1 { + for s := range exitCodes { + best.Service = s + } + } + best.ExitCode = exitCodes[best.Service] + if len(best.Line) > 300 { + best.Line = best.Line[:300] + } + return best, true +} + +var ( + hexAddr = regexp.MustCompile(`0x[0-9a-fA-F]+`) + hexID = regexp.MustCompile(`\b[0-9a-f]{12,64}\b`) + absPath = regexp.MustCompile(`(?:/[^\s"':,]+)+`) + number = regexp.MustCompile(`\d+`) + stampish = regexp.MustCompile(`^\S*\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}\S*\s*`) +) + +// Signature turns a log line into a regular expression that matches the same +// failure on another machine: addresses, IDs, paths and numbers vary. +func Signature(line string) string { + line = stampish.ReplaceAllString(line, "") + type span struct { + start, end int + repl string + } + var spans []span + taken := make([]bool, len(line)) + mark := func(re *regexp.Regexp, repl string) { + for _, loc := range re.FindAllStringIndex(line, -1) { + free := true + for i := loc[0]; i < loc[1]; i++ { + if taken[i] { + free = false + break + } + } + if !free { + continue + } + for i := loc[0]; i < loc[1]; i++ { + taken[i] = true + } + spans = append(spans, span{loc[0], loc[1], repl}) + } + } + mark(hexAddr, `0x[0-9a-fA-F]+`) + mark(hexID, `[0-9a-f]+`) + mark(absPath, `\S+`) + mark(number, `\d+`) + + var b strings.Builder + for i := 0; i < len(line); { + matched := false + for _, sp := range spans { + if sp.start == i { + b.WriteString(sp.repl) + i, matched = sp.end, true + break + } + } + if !matched { + b.WriteString(regexp.QuoteMeta(line[i : i+1])) + i++ + } + } + return b.String() +} diff --git a/pkg/preflight/learn/store.go b/pkg/preflight/learn/store.go new file mode 100644 index 0000000..d033a75 --- /dev/null +++ b/pkg/preflight/learn/store.go @@ -0,0 +1,338 @@ +package learn + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + "time" + + "gopkg.in/yaml.v3" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/rules" +) + +// File is where a project's learned rules live. It is meant to be committed, +// so a failure one teammate hits is predicted for everyone. +const File = ".container-preflight/learned.yaml" + +// relevant lists the features a new rule starts with. Host details that +// rarely cause failures (engine, Compose version) are recorded but not used +// as conditions until evidence requires them. +var relevant = []string{"image", "run.platform", "emulation", "memory", "buildkit"} + +// applies drops starting conditions that cannot be the cause: the builder +// for a service that is not built, or the platform when it is native. +func applies(k, v string, features map[string]string) bool { + switch k { + case "buildkit": + return features["build"] == "yes" + case "run.platform": + return v != features["host.platform"] + } + return true +} + +// normal values are the unremarkable state of a feature; a single failure +// does not make them part of a rule. +var normal = map[string]string{"emulation": "none", "buildkit": "yes", "memory": ">=8GiB"} + +type Store struct { + path string + Rules []*Learned `yaml:"rules"` +} + +type Learned struct { + ID string `yaml:"id"` + Signature string `yaml:"signature"` + Example string `yaml:"example"` + When map[string]string `yaml:"when"` + Fix string `yaml:"fix,omitempty"` + Status string `yaml:"status"` + Failures []Observation `yaml:"failures"` + Successes []Observation `yaml:"successes,omitempty"` +} + +type Observation struct { + At time.Time `yaml:"at"` + Host string `yaml:"host"` + Service string `yaml:"service,omitempty"` + ExitCode int `yaml:"exitCode,omitempty"` + Features map[string]string `yaml:"features"` +} + +const ( + Active = "active" + Unreliable = "unreliable" +) + +func Load(dir string) (*Store, error) { + s := &Store{path: filepath.Join(dir, File)} + b, err := os.ReadFile(s.path) + if errors.Is(err, os.ErrNotExist) { + return s, nil + } + if err != nil { + return nil, err + } + if err := yaml.Unmarshal(b, s); err != nil { + return nil, fmt.Errorf("%s: %w", s.path, err) + } + return s, nil +} + +func (s *Store) Save() error { + if err := os.MkdirAll(filepath.Dir(s.path), 0o755); err != nil { + return err + } + b, err := yaml.Marshal(s) + if err != nil { + return err + } + header := "# Rules learned from real failures by `container-preflight learn`.\n# Commit this file so preflight predicts these failures for everyone.\n" + return os.WriteFile(s.path, append([]byte(header), b...), 0o644) +} + +func (s *Store) Path() string { return s.path } + +// Outcome says what an observation did to the store. +type Outcome struct { + Rule *Learned + Created bool + // Dropped lists conditions removed because a new failure did not share + // them (the rule became more general). + Dropped []string +} + +// ObserveFailure records a failure. A failure whose signature matches an +// existing rule generalizes it: conditions the two failures disagree on are +// dropped. Otherwise a new rule is created. +func (s *Store) ObserveFailure(f Failure, features map[string]string, hostName string) Outcome { + obs := Observation{At: time.Now().UTC(), Host: hostName, Service: f.Service, ExitCode: f.ExitCode, Features: features} + + for _, r := range s.Rules { + if !r.matchesLine(f.Line) { + continue + } + r.Failures = append(r.Failures, obs) + var dropped []string + for k, v := range r.When { + if value(features, k) != v { + delete(r.When, k) + dropped = append(dropped, k+"="+v) + } + } + sort.Strings(dropped) + r.Status = r.recomputeStatus() + return Outcome{Rule: r, Dropped: dropped} + } + + when := map[string]string{} + for _, k := range relevant { + v, ok := features[k] + if !ok || v == "" || v == "unknown" || normal[k] == v || !applies(k, v, features) { + continue + } + when[k] = v + } + r := &Learned{ + ID: s.nextID(features["image"]), + Signature: Signature(f.Line), + Example: f.Line, + When: when, + Status: Active, + Failures: []Observation{obs}, + } + s.Rules = append(s.Rules, r) + return Outcome{Rule: r, Created: true} +} + +// ObserveSuccess records a run that worked. Any active rule whose conditions +// all hold for it is contradicted: its conditions are too general. If the +// failures agree on a feature where the success differs, that feature is +// added as a condition (the rule is specialized); otherwise the rule is +// marked unreliable. +func (s *Store) ObserveSuccess(service string, features map[string]string, hostName string) []*Learned { + var touched []*Learned + for _, r := range s.Rules { + if !r.holds(features) { + continue + } + r.Successes = append(r.Successes, Observation{At: time.Now().UTC(), Host: hostName, Service: service, Features: features}) + if k, v, ok := r.distinguishing(features); ok { + r.When[k] = v + } + r.Status = r.recomputeStatus() + touched = append(touched, r) + } + return touched +} + +// distinguishing finds a feature on which every recorded failure agrees and +// the success differs. +func (r *Learned) distinguishing(success map[string]string) (string, string, bool) { + // Candidates include features only the success has: a variable the + // failures lacked is a condition "unset". + keys := map[string]bool{} + for k := range r.Failures[0].Features { + keys[k] = true + } + for k := range success { + keys[k] = true + } + var sorted []string + for k := range keys { + sorted = append(sorted, k) + } + // Prefer the curated features, then the rest alphabetically. + sort.SliceStable(sorted, func(i, j int) bool { + return rank(sorted[i]) < rank(sorted[j]) || (rank(sorted[i]) == rank(sorted[j]) && sorted[i] < sorted[j]) + }) + for _, k := range sorted { + if _, already := r.When[k]; already { + continue + } + v := value(r.Failures[0].Features, k) + agree := true + for _, f := range r.Failures[1:] { + if value(f.Features, k) != v { + agree = false + } + } + if agree && value(success, k) != v { + return k, v, true + } + } + return "", "", false +} + +func rank(k string) int { + for i, r := range relevant { + if r == k { + return i + } + } + return len(relevant) +} + +// recomputeStatus is unreliable while some success still satisfies every +// condition. +func (r *Learned) recomputeStatus() string { + for _, s := range r.Successes { + if r.holds(s.Features) { + return Unreliable + } + } + return Active +} + +func (r *Learned) holds(features map[string]string) bool { + for k, v := range r.When { + if value(features, k) != v { + return false + } + } + return true +} + +// unset is the value of a feature that was not observed, e.g. an +// environment variable the service does not define. +const unset = "unset" + +func value(features map[string]string, k string) string { + if v, ok := features[k]; ok && v != "" { + return v + } + return unset +} + +func (r *Learned) matchesLine(line string) bool { + re, err := regexp.Compile(r.Signature) + return err == nil && re.MatchString(line) +} + +// Matches reports whether line is this rule's failure. +func (r *Learned) Matches(line string) bool { return r.matchesLine(line) } + +func (s *Store) nextID(image string) string { + base := "learned" + if image != "" { + base += "." + strings.ReplaceAll(filepath.Base(image), "_", "-") + } + id := base + for n := 2; s.byID(id) != nil; n++ { + id = fmt.Sprintf("%s-%d", base, n) + } + return id +} + +func (s *Store) byID(id string) *Learned { + for _, r := range s.Rules { + if r.ID == id { + return r + } + } + return nil +} + +// Rules exposes the active learned rules to the preflight engine. +func (s *Store) Active() []rules.Rule { + var out []rules.Rule + for _, r := range s.Rules { + if r.Status == Active { + out = append(out, learnedRule{r}) + } + } + return out +} + +type learnedRule struct{ l *Learned } + +func (r learnedRule) ID() string { return r.l.ID } +func (r learnedRule) Title() string { return "Learned: " + r.l.Example } +func (r learnedRule) Needs() []fact.ID { + return []fact.ID{fact.Daemon, fact.ComposeFile} +} + +func (r learnedRule) Check(_ context.Context, env *rules.Env) []rules.Finding { + var out []rules.Finding + for _, svc := range env.Project.Services { + features := rules.Features(env, svc) + if len(r.l.When) == 0 || !r.l.holds(features) { + continue + } + var conds []string + for k, v := range r.l.When { + conds = append(conds, k+"="+v) + } + sort.Strings(conds) + first := r.l.Failures[0] + evidence := []string{ + fmt.Sprintf("learned: failed %d time(s), first on %s (%s)", len(r.l.Failures), first.Host, first.At.Format("2006-01-02")), + "conditions now true here: " + strings.Join(conds, ", "), + } + if n := len(r.l.Successes); n > 0 { + evidence = append(evidence, fmt.Sprintf("refined by %d successful run(s)", n)) + } + fix := r.l.Fix + if fix == "" { + fix = "Seen before under the same conditions. Change one of them, or add a fix to " + File + "." + } + out = append(out, rules.Finding{ + Rule: r.l.ID, + Severity: fact.Error, + Service: svc.Name, + Title: "this failed before under the same conditions: " + r.l.Example, + Evidence: evidence, + Fix: fix, + Location: svc.Location.String(), + Predicts: r.l.Example, + }) + } + return out +} diff --git a/pkg/preflight/preflight.go b/pkg/preflight/preflight.go new file mode 100644 index 0000000..c3d2fa7 --- /dev/null +++ b/pkg/preflight/preflight.go @@ -0,0 +1,230 @@ +// Package preflight predicts whether a container project will build and run +// on this host before anything is executed. It joins requirements extracted +// from the project with a capability profile of the host and live registry +// metadata, and reports each predicted failure once, at its root cause. +package preflight + +import ( + "context" + "errors" + "sort" + "sync" + "time" + + "github.com/raphgm/container-preflight/internal/executor" + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/host" + "github.com/raphgm/container-preflight/pkg/preflight/learn" + "github.com/raphgm/container-preflight/pkg/preflight/project" + "github.com/raphgm/container-preflight/pkg/preflight/registry" + "github.com/raphgm/container-preflight/pkg/preflight/rules" +) + +type Options struct { + Dir string + Offline bool + + // Command, when set, is a `docker run`/`create`/`pull` command line to + // check instead of a Compose project in Dir. + Command string + + // Host, when set, replaces probing this machine: preflight predicts + // for the machine the snapshot was taken on. + Host *host.Snapshot + + Runner executor.Runner + Resolver registry.Resolver + Rules []rules.Rule +} + +// RootCause is a fact that could not be established, with every rule it +// blocked. Fixing it is what makes those rules checkable. +type RootCause struct { + fact.Failure + Blocks []string `json:"blocks"` +} + +type Report struct { + Project string `json:"project"` + Dir string `json:"dir"` + HostName string `json:"hostName,omitempty"` + Host *host.Profile `json:"host"` + Roots []RootCause `json:"rootCauses"` + Findings []rules.Finding `json:"findings"` + Passed []string `json:"passed"` + Duration time.Duration `json:"duration"` + Timestamp time.Time `json:"timestamp"` +} + +// Errors counts findings and root causes that will break the project. +func (r *Report) Errors() int { + n := 0 + for _, f := range r.Findings { + if f.Severity == fact.Error { + n++ + } + } + for _, rc := range r.Roots { + if rc.Severity == fact.Error { + n++ + } + } + return n +} + +// Prepare loads the project, profiles the host and resolves images: every +// input the rules read. +func Prepare(ctx context.Context, opts Options) (*rules.Env, error) { + if opts.Runner == nil { + opts.Runner = executor.New() + } + if opts.Resolver == nil { + opts.Resolver = registry.NewRemote() + } + var h *host.Profile + facts := fact.NewSet() + if opts.Host != nil { + h, facts = opts.Host.Restore() + } + var proj *project.Project + var err error + if opts.Command != "" { + proj, err = project.FromCommand(opts.Command, opts.Dir) + } else { + proj, err = project.Load(ctx, opts.Dir, facts) + } + if err != nil { + return nil, err + } + if h == nil { + h = host.Probe(ctx, opts.Runner, facts) + } + + env := &rules.Env{Project: proj, Host: h, Facts: facts} + if opts.Offline { + facts.Fail(fact.Failure{ + Fact: fact.Registry, + Severity: fact.Info, + Summary: "Registry checks skipped (--offline)", + }) + } else { + env.Images = resolveImages(ctx, opts.Resolver, rules.Pulls(proj, h), facts) + } + return env, nil +} + +// Run predicts the failures of the project in opts.Dir. +func Run(ctx context.Context, opts Options) (*Report, error) { + start := time.Now() + env, err := Prepare(ctx, opts) + if err != nil { + return nil, err + } + if opts.Rules == nil { + opts.Rules = rules.All() + learned, err := learn.Load(env.Project.Dir) + if err != nil { + return nil, err + } + opts.Rules = append(opts.Rules, learned.Active()...) + } + return Evaluate(ctx, env, opts.Rules, opts.Host, start), nil +} + +// Evaluate runs rules against a prepared environment. +func Evaluate(ctx context.Context, env *rules.Env, rs []rules.Rule, snap *host.Snapshot, start time.Time) *Report { + proj, h, facts := env.Project, env.Host, env.Facts + rep := &Report{Project: proj.Name, Dir: proj.Dir, Host: h, Timestamp: start} + if snap != nil { + rep.HostName = snap.Hostname + } + blocked := map[fact.ID][]string{} + for _, r := range rs { + if root, ok := blockingRoot(facts, r.Needs()); ok { + blocked[root.Fact] = append(blocked[root.Fact], r.ID()) + continue + } + found := r.Check(ctx, env) + if len(found) == 0 { + rep.Passed = append(rep.Passed, r.ID()) + } + rep.Findings = append(rep.Findings, found...) + } + + for _, root := range facts.Roots() { + rep.Roots = append(rep.Roots, RootCause{Failure: root, Blocks: blocked[root.Fact]}) + } + sort.SliceStable(rep.Findings, func(i, j int) bool { + return rank(rep.Findings[i].Severity) < rank(rep.Findings[j].Severity) + }) + rep.Duration = time.Since(start) + return rep +} + +func blockingRoot(facts *fact.Set, needs []fact.ID) (fact.Failure, bool) { + for _, id := range needs { + if root, ok := facts.Root(id); ok { + return root, true + } + } + return fact.Failure{}, false +} + +// resolveImages fetches registry metadata for all pulls in parallel. If the +// network is down, that becomes one root cause rather than one error per +// image. +func resolveImages(ctx context.Context, res registry.Resolver, pulls []rules.Pull, facts *fact.Set) map[string]rules.ImageResult { + out := map[string]rules.ImageResult{} + var mu sync.Mutex + var wg sync.WaitGroup + sem := make(chan struct{}, 8) + + for _, p := range pulls { + key := rules.ImageKey(p.Ref, p.Platform) + mu.Lock() + if _, dup := out[key]; dup { + mu.Unlock() + continue + } + out[key] = rules.ImageResult{} + mu.Unlock() + + wg.Add(1) + go func(p rules.Pull, key string) { + defer wg.Done() + sem <- struct{}{} + defer func() { <-sem }() + cctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + img, err := res.Resolve(cctx, p.Ref, p.Platform) + mu.Lock() + out[key] = rules.ImageResult{Image: img, Err: err} + mu.Unlock() + }(p, key) + } + wg.Wait() + + for _, r := range out { + if errors.Is(r.Err, registry.ErrNetwork) { + facts.Fail(fact.Failure{ + Fact: fact.Registry, + Severity: fact.Warning, + Summary: "Container registries are unreachable", + Detail: r.Err.Error(), + Fix: "Check network/proxy settings. Pulls will fail unless images are already cached locally.", + }) + break + } + } + return out +} + +func rank(s fact.Severity) int { + switch s { + case fact.Error: + return 0 + case fact.Warning: + return 1 + } + return 2 +} diff --git a/pkg/preflight/preflight_test.go b/pkg/preflight/preflight_test.go new file mode 100644 index 0000000..69ab2c1 --- /dev/null +++ b/pkg/preflight/preflight_test.go @@ -0,0 +1,128 @@ +package preflight + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/host" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +type daemonDown struct{} + +func (daemonDown) Run(_ context.Context, name string, args ...string) (string, error) { + cmd := name + " " + strings.Join(args, " ") + switch { + case strings.HasPrefix(cmd, "docker --version"): + return "Docker version 27.0.3", nil + case strings.HasPrefix(cmd, "docker context inspect"): + return "unix:///var/run/docker.sock", nil + case strings.HasPrefix(cmd, "docker compose version"): + return "2.29.1", nil + case strings.HasPrefix(cmd, "docker buildx version"): + return "github.com/docker/buildx v0.16.1 x", nil + } + return "", errors.New("Cannot connect to the Docker daemon at unix:///var/run/docker.sock") +} + +type offlineRegistry struct{} + +func (offlineRegistry) Resolve(context.Context, string, string) (*registry.Image, error) { + return nil, fmt.Errorf("%w: dial tcp: lookup registry-1.docker.io: no such host", registry.ErrNetwork) +} + +func sampleProject(t *testing.T) string { + dir := t.TempDir() + files := map[string]string{ + "compose.yaml": "services:\n web: {build: ., ports: [\"8080:80\"]}\n api: {image: node:20, ports: [\"8080:3000\"]}\n", + "Dockerfile": "FROM nginx\nCOPY dist /usr/share/nginx/html\n", + } + for name, content := range files { + if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o644); err != nil { + t.Fatal(err) + } + } + return dir +} + +func TestRootCausesBlockDependentsOnly(t *testing.T) { + rep, err := Run(context.Background(), Options{Dir: sampleProject(t), Runner: daemonDown{}, Resolver: offlineRegistry{}}) + if err != nil { + t.Fatal(err) + } + + roots := map[fact.ID][]string{} + for _, r := range rep.Roots { + roots[r.Fact] = r.Blocks + } + if len(roots) != 2 { + t.Fatalf("want 2 root causes (daemon, registry), got %+v", rep.Roots) + } + if !contains(roots[fact.Daemon], "resources.memory") || !contains(roots[fact.Daemon], "image.platform") { + t.Errorf("daemon should block memory and platform checks: %v", roots[fact.Daemon]) + } + if !contains(roots[fact.Registry], "image.exists") { + t.Errorf("registry should block image.exists: %v", roots[fact.Registry]) + } + + // Checks that need neither still run and find real problems. + var got []string + for _, f := range rep.Findings { + got = append(got, f.Rule) + } + for _, want := range []string{"build.context", "ports.conflict"} { + if !contains(got, want) { + t.Errorf("missing %s finding; got %v", want, got) + } + } + for _, blocked := range []string{"resources.memory", "image.platform", "image.exists"} { + if contains(got, blocked) || contains(rep.Passed, blocked) { + t.Errorf("%s ran although it is blocked", blocked) + } + } +} + +func TestSnapshotRoundTrip(t *testing.T) { + snap := host.Capture(context.Background(), daemonDown{}) + b, err := json.Marshal(snap) + if err != nil { + t.Fatal(err) + } + path := filepath.Join(t.TempDir(), "host.json") + if err := os.WriteFile(path, b, 0o644); err != nil { + t.Fatal(err) + } + loaded, err := host.LoadSnapshot(path) + if err != nil { + t.Fatal(err) + } + rep, err := Run(context.Background(), Options{Dir: sampleProject(t), Host: loaded, Offline: true}) + if err != nil { + t.Fatal(err) + } + found := false + for _, r := range rep.Roots { + if r.Fact == fact.Daemon { + found = true + } + } + if !found { + t.Errorf("daemon failure should survive the snapshot: %+v", rep.Roots) + } +} + +func contains(xs []string, x string) bool { + for _, v := range xs { + if v == x { + return true + } + } + return false +} diff --git a/pkg/preflight/project/context.go b/pkg/preflight/project/context.go new file mode 100644 index 0000000..d7230a2 --- /dev/null +++ b/pkg/preflight/project/context.go @@ -0,0 +1,104 @@ +package project + +import ( + "os" + "path/filepath" + "strings" + + "github.com/moby/patternmatcher" + "github.com/moby/patternmatcher/ignorefile" +) + +// BuildContext answers whether COPY/ADD sources will be visible to the +// builder, applying .dockerignore the way BuildKit does. +type BuildContext struct { + Dir string + IgnoreFile string + patterns []string +} + +// OpenContext loads the ignore rules for a build. A Dockerfile-specific +// ignore file (.dockerignore) takes precedence over the +// context's .dockerignore, as in BuildKit. +func OpenContext(dir, dockerfile string) (*BuildContext, error) { + bc := &BuildContext{Dir: dir} + candidates := []string{filepath.Join(dir, ".dockerignore")} + if dockerfile != "" { + candidates = append([]string{dockerfile + ".dockerignore"}, candidates...) + } + for _, c := range candidates { + f, err := os.Open(c) + if err != nil { + continue + } + patterns, err := ignorefile.ReadAll(f) + f.Close() + if err != nil { + return nil, err + } + bc.IgnoreFile, bc.patterns = c, patterns + break + } + return bc, nil +} + +type SourceStatus int + +const ( + SourceOK SourceStatus = iota + SourceSkipped + SourceMissing + SourceIgnored + SourceOutside +) + +// Check reports whether src resolves to at least one file the builder will +// receive. For SourceIgnored it also returns the pattern responsible. +func (bc *BuildContext) Check(src string) (SourceStatus, string) { + if strings.Contains(src, "$") || strings.Contains(src, "://") || strings.HasPrefix(src, "git@") { + return SourceSkipped, "" + } + rel := filepath.Clean(strings.TrimPrefix(src, "/")) + if rel == ".." || strings.HasPrefix(rel, "../") { + return SourceOutside, "" + } + + matches, err := filepath.Glob(filepath.Join(bc.Dir, rel)) + if err != nil || len(matches) == 0 { + return SourceMissing, "" + } + var blocker string + for _, m := range matches { + r, _ := filepath.Rel(bc.Dir, m) + pattern := bc.excludedBy(filepath.ToSlash(r)) + if pattern == "" { + return SourceOK, "" + } + blocker = pattern + } + return SourceIgnored, blocker +} + +// excludedBy returns the ignore pattern that excludes rel, or "" when rel is +// sent to the builder. The last matching pattern wins, and a `!` pattern +// re-includes. +func (bc *BuildContext) excludedBy(rel string) string { + if rel == "." { + return "" + } + var last string + excluded := false + for _, p := range bc.patterns { + neg := strings.HasPrefix(p, "!") + body := strings.TrimPrefix(p, "!") + ok, err := patternmatcher.MatchesOrParentMatches(rel, []string{body}) + if err != nil || !ok { + continue + } + excluded, last = !neg, p + } + if !excluded { + return "" + } + return last +} diff --git a/pkg/preflight/project/dockerfile.go b/pkg/preflight/project/dockerfile.go new file mode 100644 index 0000000..56a5f81 --- /dev/null +++ b/pkg/preflight/project/dockerfile.go @@ -0,0 +1,275 @@ +package project + +import ( + "bytes" + "fmt" + "os" + "regexp" + "strconv" + "strings" + + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/moby/buildkit/frontend/dockerfile/parser" +) + +// Dockerfile is the requirement view of a parsed Dockerfile. +type Dockerfile struct { + Path string + Syntax string + Stages []Stage + + // BuildKitFeatures lists syntax the legacy builder rejects. + BuildKitFeatures []Feature +} + +type Stage struct { + Name string + + // Base is the FROM reference after ARG expansion. + Base string + + // BaseStage is the index of the earlier stage Base refers to, or -1 when + // Base is an external image. + BaseStage int + + // Platform is the FROM --platform value after ARG expansion. It may + // still contain $BUILDPLATFORM or $TARGETPLATFORM. + Platform string + + Location Location + + // Copies are COPY/ADD instructions that read from the build context. + Copies []Copy + + // Deps are indices of other stages this stage reads from. + Deps []int +} + +type Copy struct { + Instruction string + Sources []string + Location Location +} + +// Unresolved reports whether Base still depends on an ARG with no value. +func (s Stage) Unresolved() bool { + return strings.Contains(s.Base, "$") +} + +// ParseDockerfile parses the file at path. args override ARG defaults, as +// `--build-arg` would. +func ParseDockerfile(path string, args map[string]string) (*Dockerfile, error) { + content, err := os.ReadFile(path) + if err != nil { + return nil, err + } + return parseDockerfile(path, content, args) +} + +func parseDockerfile(path string, content []byte, args map[string]string) (*Dockerfile, error) { + res, err := parser.Parse(bytes.NewReader(content)) + if err != nil { + return nil, err + } + stages, metaArgs, err := instructions.Parse(res.AST, nil) + if err != nil { + return nil, err + } + + df := &Dockerfile{Path: path} + df.Syntax, _, _, _ = parser.DetectSyntax(content) + + vars := map[string]string{} + for _, a := range metaArgs { + for _, kv := range a.Args { + if kv.Value != nil { + vars[kv.Key] = *kv.Value + } + } + } + for k, v := range args { + vars[k] = v + } + + for _, node := range res.AST.Children { + if len(node.Heredocs) > 0 { + df.BuildKitFeatures = append(df.BuildKitFeatures, Feature{ + Name: "heredoc (< 0 { + add("exclude") + } +} + +// Reachable returns the indices of stages BuildKit actually builds for +// target (the last stage when target is empty). Unreachable stages are +// skipped by BuildKit, so their problems do not break the build. +func (df *Dockerfile) Reachable(target string) ([]int, error) { + if len(df.Stages) == 0 { + return nil, nil + } + start := len(df.Stages) - 1 + if target != "" { + start = -1 + for i, s := range df.Stages { + if strings.EqualFold(s.Name, target) { + start = i + } + } + if start < 0 { + return nil, fmt.Errorf("target stage %q not found", target) + } + } + + seen := map[int]bool{} + var visit func(int) + visit = func(i int) { + if seen[i] { + return + } + seen[i] = true + for _, d := range df.Stages[i].Deps { + visit(d) + } + } + visit(start) + + var out []int + for i := range df.Stages { + if seen[i] { + out = append(out, i) + } + } + return out, nil +} + +func stageRef(ref string, byName map[string]int, current int) (int, bool) { + if idx, ok := byName[strings.ToLower(ref)]; ok { + return idx, true + } + if n, err := strconv.Atoi(ref); err == nil && n >= 0 && n < current { + return n, true + } + return 0, false +} + +func firstLine(r []parser.Range) int { + if len(r) == 0 { + return 0 + } + return r[0].Start.Line +} + +var varRef = regexp.MustCompile(`\$\{([A-Za-z_][A-Za-z0-9_]*)(?::?([-+])([^}]*))?\}|\$([A-Za-z_][A-Za-z0-9_]*)`) + +// expand substitutes ARG values the way the Dockerfile frontend does for +// FROM lines. Variables with no value are left in place so callers can tell +// the reference is unresolved. +func expand(s string, vars map[string]string) string { + return varRef.ReplaceAllStringFunc(s, func(m string) string { + sub := varRef.FindStringSubmatch(m) + name, op, word := sub[1], sub[2], sub[3] + if name == "" { + name = sub[4] + } + v, ok := vars[name] + switch op { + case "-": + if !ok || v == "" { + return word + } + case "+": + if ok && v != "" { + return word + } + return "" + } + if !ok { + return m + } + return v + }) +} + +// expandKeepUnknown is expand, but it never touches the automatic platform +// ARGs, which only the builder can fill in. +func expandKeepUnknown(s string, vars map[string]string) string { + filtered := map[string]string{} + for k, v := range vars { + if !strings.HasSuffix(k, "PLATFORM") { + filtered[k] = v + } + } + return expand(s, filtered) +} diff --git a/pkg/preflight/project/load.go b/pkg/preflight/project/load.go new file mode 100644 index 0000000..7818ba7 --- /dev/null +++ b/pkg/preflight/project/load.go @@ -0,0 +1,289 @@ +package project + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/dotenv" + "github.com/compose-spec/compose-go/v2/types" + "github.com/sirupsen/logrus" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +// composeFileNames is the lookup order Compose itself uses. +var composeFileNames = []string{"compose.yaml", "compose.yml", "docker-compose.yaml", "docker-compose.yml"} + +// Load extracts requirements from dir. A Compose file is used when present; +// otherwise a lone Dockerfile is treated as a single built service. Parse +// problems are returned as fact failures so rules depending on them are +// reported as blocked rather than silently skipped. +func Load(ctx context.Context, dir string, facts *fact.Set) (*Project, error) { + abs, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + if st, err := os.Stat(abs); err != nil || !st.IsDir() { + return nil, fmt.Errorf("%s is not a directory", dir) + } + + p := &Project{Dir: abs, Name: filepath.Base(abs), Env: environment(abs)} + + for _, name := range composeFileNames { + if _, err := os.Stat(filepath.Join(abs, name)); err == nil { + p.ComposeFile = filepath.Join(abs, name) + break + } + } + + if p.ComposeFile == "" { + dockerfile := filepath.Join(abs, "Dockerfile") + if _, err := os.Stat(dockerfile); err != nil { + return nil, fmt.Errorf("no compose file or Dockerfile found in %s", abs) + } + svc := &Service{ + Name: p.Name, + Replicas: 1, + Build: &Build{Context: abs, DockerfilePath: dockerfile}, + Location: Location{File: dockerfile}, + } + loadDockerfile(svc.Build, facts) + p.Services = append(p.Services, svc) + return p, nil + } + + raw, err := os.ReadFile(p.ComposeFile) + if err != nil { + return nil, err + } + p.EnvRefs = scanEnvRefs(p.ComposeFile, raw) + p.ComposeFeatures = scanComposeFeatures(p.ComposeFile, raw) + + cp, err := loadCompose(ctx, abs, p.ComposeFile, nil) + if err != nil { + // Missing ${VAR:?} values are reported precisely by the env rule; + // keep analysing the rest of the file instead of stopping here. + if placeholders := missingRequired(p); len(placeholders) > 0 { + cp, err = loadCompose(ctx, abs, p.ComposeFile, placeholders) + } + } + if err != nil { + facts.Fail(fact.Failure{ + Fact: fact.ComposeFile, + Severity: fact.Error, + Summary: "Compose file cannot be loaded", + Detail: err.Error(), + Fix: "Fix the error above; `docker compose config` shows the same message.", + }) + return p, nil + } + p.Name = cp.Name + + lines := serviceLines(raw) + for _, name := range cp.ServiceNames() { + sc := cp.Services[name] + svc := convertService(sc) + svc.Location = Location{File: p.ComposeFile, Line: lines[name]} + if svc.Build != nil { + loadDockerfile(svc.Build, facts) + } + for _, ef := range sc.EnvFiles { + p.EnvFiles = append(p.EnvFiles, EnvFile{Service: name, Path: ef.Path, Required: bool(ef.Required)}) + } + p.Services = append(p.Services, svc) + } + return p, nil +} + +func loadCompose(ctx context.Context, dir, file string, extraEnv map[string]string) (*types.Project, error) { + // compose-go logs interpolation warnings; preflight reports those itself. + logrus.SetOutput(io.Discard) + + fns := []cli.ProjectOptionsFn{ + cli.WithWorkingDirectory(dir), + cli.WithOsEnv, + cli.WithEnvFiles(), + cli.WithDotEnv, + } + if len(extraEnv) > 0 { + var kv []string + for k, v := range extraEnv { + kv = append(kv, k+"="+v) + } + fns = append(fns, cli.WithEnv(kv)) + } + opts, err := cli.NewProjectOptions([]string{file}, fns...) + if err != nil { + return nil, err + } + return cli.ProjectFromOptions(ctx, opts) +} + +// missingRequired returns placeholder values for ${VAR:?} references that +// have no value. +func missingRequired(p *Project) map[string]string { + out := map[string]string{} + for _, r := range p.EnvRefs { + if _, set := p.Env[r.Name]; r.Required && !set { + out[r.Name] = "preflight-placeholder" + } + } + return out +} + +func convertService(sc types.ServiceConfig) *Service { + svc := &Service{ + Name: sc.Name, + Platform: sc.Platform, + User: sc.User, + MemLimit: int64(sc.MemLimit), + Replicas: 1, + Environment: map[string]string{}, + } + if sc.Build == nil { + svc.Image = sc.Image + } else { + b := &Build{ + Context: sc.Build.Context, + Target: sc.Build.Target, + Platforms: sc.Build.Platforms, + Args: map[string]string{}, + } + for k, v := range sc.Build.Args { + if v != nil { + b.Args[k] = *v + } + } + switch { + case sc.Build.DockerfileInline != "": + b.DockerfilePath = "" + case filepath.IsAbs(sc.Build.Dockerfile): + b.DockerfilePath = sc.Build.Dockerfile + default: + df := sc.Build.Dockerfile + if df == "" { + df = "Dockerfile" + } + b.DockerfilePath = filepath.Join(sc.Build.Context, df) + } + svc.Build = b + } + + if sc.Scale != nil { + svc.Replicas = *sc.Scale + } + if d := sc.Deploy; d != nil { + if d.Replicas != nil { + svc.Replicas = *d.Replicas + } + if lim := d.Resources.Limits; lim != nil { + if l := int64(lim.MemoryBytes); l > 0 && (svc.MemLimit == 0 || l < svc.MemLimit) { + svc.MemLimit = l + } + } + if r := d.Resources.Reservations; r != nil { + svc.MemReservation = int64(r.MemoryBytes) + for _, dev := range r.Devices { + if hasGPU(dev.Capabilities) { + svc.GPU = true + } + } + } + } + if int64(sc.MemReservation) > svc.MemReservation { + svc.MemReservation = int64(sc.MemReservation) + } + if len(sc.Gpus) > 0 { + svc.GPU = true + } + + for k, v := range sc.Environment { + if v != nil { + svc.Environment[k] = *v + } + } + + for _, pc := range sc.Ports { + if pc.Published == "" { + continue + } + start, end, err := parseRange(pc.Published) + if err != nil { + continue + } + proto := pc.Protocol + if proto == "" { + proto = "tcp" + } + svc.Ports = append(svc.Ports, Port{HostIP: pc.HostIP, Start: start, End: end, Target: pc.Target, Protocol: proto}) + } + + for _, v := range sc.Volumes { + if v.Type != types.VolumeTypeBind { + continue + } + create, selinux := true, "" + if v.Bind != nil { + create, selinux = bool(v.Bind.CreateHostPath), v.Bind.SELinux + } + svc.Binds = append(svc.Binds, Bind{Source: v.Source, Target: v.Target, CreateHostPath: create, ReadOnly: v.ReadOnly, SELinux: selinux}) + } + return svc +} + +func hasGPU(caps []string) bool { + for _, c := range caps { + if c == "gpu" { + return true + } + } + return false +} + +func parseRange(s string) (int, int, error) { + lo, hi, found := strings.Cut(s, "-") + start, err := strconv.Atoi(lo) + if err != nil { + return 0, 0, err + } + if !found { + return start, start, nil + } + end, err := strconv.Atoi(hi) + return start, end, err +} + +func loadDockerfile(b *Build, facts *fact.Set) { + if b.DockerfilePath == "" { + return + } + df, err := ParseDockerfile(b.DockerfilePath, b.Args) + if err != nil { + b.ParseErr = err + return + } + b.Dockerfile = df +} + +// environment is what Compose interpolates with: the .env file, overridden +// by the process environment. +func environment(dir string) map[string]string { + env := map[string]string{} + if dot, err := dotenv.GetEnvFromFile(map[string]string{}, []string{filepath.Join(dir, ".env")}); err == nil { + for k, v := range dot { + env[k] = v + } + } + for _, kv := range os.Environ() { + if k, v, ok := strings.Cut(kv, "="); ok { + env[k] = v + } + } + return env +} diff --git a/pkg/preflight/project/project.go b/pkg/preflight/project/project.go new file mode 100644 index 0000000..4362957 --- /dev/null +++ b/pkg/preflight/project/project.go @@ -0,0 +1,134 @@ +// Package project extracts what a container project requires from the host: +// platforms, memory, ports, bind mounts, build inputs and tool features. It +// reads Compose files and Dockerfiles with the same parsers Docker uses. +package project + +import ( + "fmt" + "path/filepath" +) + +// Location points at the line in a project file that created a requirement. +type Location struct { + File string + Line int +} + +func (l Location) String() string { + if l.File == "" { + return "" + } + if l.Line == 0 { + return filepath.Base(l.File) + } + return fmt.Sprintf("%s:%d", filepath.Base(l.File), l.Line) +} + +// Project is the set of requirements extracted from one directory. +type Project struct { + Dir string + Name string + ComposeFile string + + Services []*Service + + // ComposeFeatures lists Compose-file syntax that needs a minimum + // Compose version. + ComposeFeatures []Feature + + // EnvRefs lists every variable interpolated in the Compose file. + EnvRefs []EnvRef + + // Env is the environment Compose would interpolate with (OS + .env). + Env map[string]string + + // EnvFiles lists env_file entries referenced by services. + EnvFiles []EnvFile +} + +type Service struct { + Name string + + // Image is the image Compose pulls. It is empty when the service is + // built and never pulled. + Image string + + Build *Build + + // Platform is the explicit `platform:` value, if any. + Platform string + + MemLimit int64 + MemReservation int64 + Replicas int + + Ports []Port + Binds []Bind + + GPU bool + + // User is the Compose `user:` value, if any. + User string + + Environment map[string]string + + Location Location +} + +type Port struct { + HostIP string + Start int + End int + Target uint32 + Protocol string +} + +func (p Port) String() string { + host := fmt.Sprint(p.Start) + if p.End != p.Start { + host = fmt.Sprintf("%d-%d", p.Start, p.End) + } + if p.HostIP != "" { + host = p.HostIP + ":" + host + } + return fmt.Sprintf("%s->%d/%s", host, p.Target, p.Protocol) +} + +type Bind struct { + Source string + Target string + CreateHostPath bool + ReadOnly bool + // SELinux is the relabel option: "z", "Z" or "". + SELinux string +} + +type Build struct { + Context string + DockerfilePath string + Dockerfile *Dockerfile + ParseErr error + Target string + Platforms []string + Args map[string]string +} + +// Feature is syntax that only works with a new enough tool. +type Feature struct { + Name string + MinVersion string + Location Location +} + +type EnvRef struct { + Name string + HasDefault bool + Required bool + Location Location +} + +type EnvFile struct { + Service string + Path string + Required bool +} diff --git a/pkg/preflight/project/project_test.go b/pkg/preflight/project/project_test.go new file mode 100644 index 0000000..0f3e59b --- /dev/null +++ b/pkg/preflight/project/project_test.go @@ -0,0 +1,272 @@ +package project + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +func write(t *testing.T, dir string, files map[string]string) { + t.Helper() + for name, content := range files { + p := filepath.Join(dir, name) + if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(p, []byte(content), 0o644); err != nil { + t.Fatal(err) + } + } +} + +func TestDockerfileStagesAndReachability(t *testing.T) { + dir := t.TempDir() + write(t, dir, map[string]string{"Dockerfile": `ARG NODE=20 +FROM node:${NODE}-alpine AS deps +COPY package.json ./ +RUN --mount=type=cache,target=/root/.npm npm ci + +FROM golang:1.22 AS unused +COPY missing.go ./ + +FROM --platform=$BUILDPLATFORM deps AS build +COPY --chmod=755 src ./src + +FROM gcr.io/distroless/nodejs20 +COPY --from=build /app /app +`}) + + df, err := ParseDockerfile(filepath.Join(dir, "Dockerfile"), nil) + if err != nil { + t.Fatal(err) + } + if got := df.Stages[0].Base; got != "node:20-alpine" { + t.Errorf("ARG not expanded: base = %q", got) + } + if df.Stages[2].BaseStage != 0 { + t.Errorf("stage 2 should derive from stage 0, got %d", df.Stages[2].BaseStage) + } + if df.Stages[2].Platform != "$BUILDPLATFORM" { + t.Errorf("platform ARG must be left for the builder, got %q", df.Stages[2].Platform) + } + + reach, _ := df.Reachable("") + if want := []int{0, 2, 3}; !equal(reach, want) { + t.Errorf("reachable = %v; want %v (stage 1 is never built)", reach, want) + } + + var names []string + for _, f := range df.BuildKitFeatures { + names = append(names, f.Name) + } + if !contains(names, "RUN --mount") || !contains(names, "COPY --chmod") { + t.Errorf("BuildKit features = %v", names) + } +} + +func TestBuildArgOverridesDefault(t *testing.T) { + dir := t.TempDir() + write(t, dir, map[string]string{"Dockerfile": "ARG TAG=1\nFROM alpine:${TAG}\n"}) + df, err := ParseDockerfile(filepath.Join(dir, "Dockerfile"), map[string]string{"TAG": "3.20"}) + if err != nil { + t.Fatal(err) + } + if df.Stages[0].Base != "alpine:3.20" { + t.Errorf("base = %q", df.Stages[0].Base) + } +} + +func TestLoadCompose(t *testing.T) { + dir := t.TempDir() + write(t, dir, map[string]string{ + "compose.yaml": `include: + - other.yaml +services: + db: + image: postgres:16 + mem_limit: 512m + ports: ["5432:5432"] + environment: + POSTGRES_PASSWORD: ${DB_PASSWORD:?set a password} + web: + build: . + platform: linux/amd64 + ports: ["8000-8001:80"] + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + - data:/data + deploy: + replicas: 2 + resources: + reservations: + devices: [{capabilities: [gpu]}] + develop: + watch: [{path: ., action: rebuild}] + depends_on: + db: {condition: service_started, required: false} + environment: + MODE: ${MODE:-dev} + TOKEN: $API_TOKEN +volumes: {data: {}} +`, + "other.yaml": "services: {}\n", + "Dockerfile": "FROM nginx:1.27\n", + ".env": "DB_PASSWORD=x\n", + }) + + facts := fact.NewSet() + p, err := Load(context.Background(), dir, facts) + if err != nil { + t.Fatal(err) + } + if facts.Failed(fact.ComposeFile) { + r, _ := facts.Root(fact.ComposeFile) + t.Fatalf("compose failed to load: %s", r.Detail) + } + if len(p.Services) != 2 { + t.Fatalf("services = %d", len(p.Services)) + } + db, web := p.Services[0], p.Services[1] + if db.Image != "postgres:16" || db.MemLimit != 512*1024*1024 { + t.Errorf("db = %+v", db) + } + if web.Image != "" || web.Build == nil || web.Build.Dockerfile == nil { + t.Fatalf("web build not parsed: %+v", web) + } + if web.Replicas != 2 || !web.GPU || web.Platform != "linux/amd64" { + t.Errorf("web = replicas %d gpu %v platform %q", web.Replicas, web.GPU, web.Platform) + } + if len(web.Ports) != 1 || web.Ports[0].Start != 8000 || web.Ports[0].End != 8001 { + t.Errorf("ports = %+v", web.Ports) + } + if len(web.Binds) != 1 || web.Binds[0].Source != filepath.Join(dir, "nginx.conf") { + t.Errorf("binds = %+v", web.Binds) + } + + var features []string + for _, f := range p.ComposeFeatures { + features = append(features, f.Name) + } + for _, want := range []string{"include", "services.web.develop", "services.web.depends_on.required"} { + if !contains(features, want) { + t.Errorf("missing compose feature %q in %v", want, features) + } + } + + refs := map[string]EnvRef{} + for _, r := range p.EnvRefs { + refs[r.Name] = r + } + if !refs["DB_PASSWORD"].Required || !refs["MODE"].HasDefault || refs["API_TOKEN"].HasDefault { + t.Errorf("env refs = %+v", refs) + } + if p.Env["DB_PASSWORD"] != "x" { + t.Error(".env not read") + } +} + +func TestBrokenComposeIsAFactFailure(t *testing.T) { + dir := t.TempDir() + write(t, dir, map[string]string{"compose.yaml": "services:\n a:\n image: [not, a, string]\n"}) + facts := fact.NewSet() + if _, err := Load(context.Background(), dir, facts); err != nil { + t.Fatal(err) + } + if !facts.Failed(fact.ComposeFile) { + t.Fatal("expected compose file failure") + } +} + +func equal(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +func contains(xs []string, x string) bool { + for _, v := range xs { + if v == x { + return true + } + } + return false +} + +func TestBuildContextCheck(t *testing.T) { + dir := t.TempDir() + write(t, dir, map[string]string{ + "Dockerfile": "FROM alpine\n", + ".dockerignore": "*.env\nsecrets/\nnode_modules\n!keep.env\n", + "app.py": "", + "prod.env": "", + "keep.env": "", + "secrets/key": "", + }) + bc, err := OpenContext(dir, filepath.Join(dir, "Dockerfile")) + if err != nil { + t.Fatal(err) + } + cases := map[string]SourceStatus{ + "app.py": SourceOK, + "./app.py": SourceOK, + "*.py": SourceOK, + "prod.env": SourceIgnored, + "keep.env": SourceOK, + "secrets/key": SourceIgnored, + "secrets": SourceIgnored, + "missing.txt": SourceMissing, + "../outside": SourceOutside, + "$APP_DIR": SourceSkipped, + "https://x.y/z": SourceSkipped, + ".": SourceOK, + } + for src, want := range cases { + if got, pattern := bc.Check(src); got != want { + t.Errorf("Check(%q) = %v (%q); want %v", src, got, pattern, want) + } + } + if _, pattern := bc.Check("prod.env"); pattern != "*.env" { + t.Errorf("blocking pattern = %q; want *.env", pattern) + } +} + +func TestFromCommand(t *testing.T) { + dir := t.TempDir() + p, err := FromCommand(`docker run -d --name web -p 127.0.0.1:8080:80 -p 9000-9001:9000/udp -v ./conf/nginx.conf:/etc/nginx/nginx.conf:ro,z -v data:/data --mount type=bind,source=/nope,target=/x --platform linux/amd64 -e A=1 -u 1000 -m 512m --gpus all --network host nginx:1.27 nginx -g "daemon off;"`, dir) + if err != nil { + t.Fatal(err) + } + s := p.Services[0] + if s.Name != "web" || s.Image != "nginx:1.27" || s.Platform != "linux/amd64" || s.User != "1000" || !s.GPU || s.MemLimit != 512<<20 { + t.Fatalf("service = %+v", s) + } + if len(s.Ports) != 2 || s.Ports[0].HostIP != "127.0.0.1" || s.Ports[1].End != 9001 || s.Ports[1].Protocol != "udp" { + t.Errorf("ports = %+v", s.Ports) + } + if len(s.Binds) != 2 || !s.Binds[0].ReadOnly || s.Binds[0].SELinux != "z" || s.Binds[0].Source != filepath.Join(dir, "conf/nginx.conf") { + t.Errorf("binds = %+v", s.Binds) + } + if s.Binds[1].CreateHostPath { + t.Error("--mount does not create missing sources") + } + if s.Environment["A"] != "1" { + t.Errorf("env = %v", s.Environment) + } + + p, err = FromCommand("docker pull kubernetes/pause", dir) + if err != nil || p.Services[0].Image != "kubernetes/pause" { + t.Errorf("pull: %v %+v", err, p) + } + if _, err := FromCommand("docker build .", dir); err == nil { + t.Error("build is not supported") + } +} diff --git a/pkg/preflight/project/run.go b/pkg/preflight/project/run.go new file mode 100644 index 0000000..91328c4 --- /dev/null +++ b/pkg/preflight/project/run.go @@ -0,0 +1,212 @@ +package project + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/docker/go-units" + "github.com/mattn/go-shellwords" +) + +// FromCommand builds a one-service project from a `docker run`, `docker +// create` or `docker pull` command line, so the same rules apply to +// containers started without Compose. Relative bind sources resolve +// against dir, as the shell would. +func FromCommand(cmdline, dir string) (*Project, error) { + args, err := shellwords.Parse(cmdline) + if err != nil { + return nil, fmt.Errorf("cannot parse command: %w", err) + } + if len(args) > 0 && (args[0] == "docker" || strings.HasSuffix(args[0], "/docker")) { + args = args[1:] + } + if len(args) > 0 && args[0] == "container" { + args = args[1:] + } + if len(args) == 0 { + return nil, fmt.Errorf("expected `docker run`, `docker create` or `docker pull`") + } + abs, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + p := &Project{Dir: abs, Name: filepath.Base(abs), Env: environment(abs)} + svc := &Service{Replicas: 1, Environment: map[string]string{}, Location: Location{File: "command line"}} + + verb, rest := args[0], args[1:] + switch verb { + case "run", "create", "pull": + default: + return nil, fmt.Errorf("unsupported command %q: use docker run, create or pull", verb) + } + + for i := 0; i < len(rest); i++ { + a := rest[i] + if !strings.HasPrefix(a, "-") || a == "-" { + svc.Image = a + break // the rest is the container's command + } + name, val, hasVal := strings.Cut(a, "=") + next := func() string { + if hasVal { + return val + } + if i+1 < len(rest) { + i++ + return rest[i] + } + return "" + } + switch name { + case "-p", "--publish": + if port, ok := parsePublish(next()); ok { + svc.Ports = append(svc.Ports, port) + } + case "-v", "--volume": + if b, ok := parseVolume(next(), abs); ok { + svc.Binds = append(svc.Binds, b) + } + case "--mount": + if b, ok := parseMount(next(), abs); ok { + svc.Binds = append(svc.Binds, b) + } + case "--platform": + svc.Platform = next() + case "-e", "--env": + k, v, ok := strings.Cut(next(), "=") + if !ok { + v = os.Getenv(k) + } + svc.Environment[k] = v + case "-u", "--user": + svc.User = next() + case "-m", "--memory": + if n, err := units.RAMInBytes(next()); err == nil { + svc.MemLimit = n + } + case "--memory-reservation": + if n, err := units.RAMInBytes(next()); err == nil { + svc.MemReservation = n + } + case "--gpus": + next() + svc.GPU = true + case "--name": + svc.Name = next() + default: + // Flags that take a value in the next argument; the rest are + // booleans. Only the common ones matter for skipping. + if !hasVal && takesValue[name] { + i++ + } + } + } + if svc.Image == "" { + return nil, fmt.Errorf("no image in command") + } + if svc.Name == "" { + svc.Name = strings.SplitN(filepath.Base(svc.Image), ":", 2)[0] + } + p.Services = []*Service{svc} + return p, nil +} + +var takesValue = map[string]bool{ + "-w": true, "--workdir": true, "--network": true, "--net": true, "-h": true, "--hostname": true, + "--entrypoint": true, "--restart": true, "-l": true, "--label": true, "--env-file": true, + "--add-host": true, "--device": true, "--cpus": true, "--shm-size": true, "--ulimit": true, + "--log-driver": true, "--log-opt": true, "--cap-add": true, "--cap-drop": true, "--dns": true, + "--security-opt": true, "--tmpfs": true, "--pull": true, "--ipc": true, "--pid": true, + "--stop-signal": true, "--health-cmd": true, "--expose": true, "--link": true, "--sysctl": true, + "--runtime": true, "--cgroupns": true, "--userns": true, "-a": true, "--attach": true, +} + +// parsePublish reads [ip:]hostPort[-end]:containerPort[/proto]. +func parsePublish(s string) (Port, bool) { + proto := "tcp" + if spec, pr, ok := strings.Cut(s, "/"); ok { + s, proto = spec, pr + } + parts := strings.Split(s, ":") + if len(parts) < 2 { + return Port{}, false // container port only: nothing published on a fixed host port + } + ip := "" + if len(parts) == 3 { + ip = parts[0] + } + start, end, err := parseRange(parts[len(parts)-2]) + if err != nil || parts[len(parts)-2] == "" { + return Port{}, false + } + target, _ := strconv.Atoi(strings.SplitN(parts[len(parts)-1], "-", 2)[0]) + return Port{HostIP: ip, Start: start, End: end, Target: uint32(target), Protocol: proto}, true +} + +// parseVolume reads source:target[:opts]; named volumes are not binds. +func parseVolume(s, dir string) (Bind, bool) { + parts := strings.Split(s, ":") + if len(parts) < 2 { + return Bind{}, false + } + src := parts[0] + if !strings.HasPrefix(src, "/") && !strings.HasPrefix(src, ".") && !strings.HasPrefix(src, "~") { + return Bind{}, false + } + b := Bind{Source: absPath(src, dir), Target: parts[1], CreateHostPath: true} + if len(parts) > 2 { + for _, o := range strings.Split(parts[2], ",") { + switch o { + case "ro": + b.ReadOnly = true + case "z", "Z": + b.SELinux = o + } + } + } + return b, true +} + +// parseMount reads --mount type=bind,source=…,target=…; unlike -v, a +// missing source is an error rather than created. +func parseMount(s, dir string) (Bind, bool) { + kv := map[string]string{} + for _, f := range strings.Split(s, ",") { + k, v, _ := strings.Cut(f, "=") + kv[k] = v + } + if kv["type"] != "bind" { + return Bind{}, false + } + src := kv["source"] + if src == "" { + src = kv["src"] + } + dst := kv["target"] + if dst == "" { + dst = kv["destination"] + } + if dst == "" { + dst = kv["dst"] + } + _, ro := kv["readonly"] + if _, r := kv["ro"]; r { + ro = true + } + return Bind{Source: absPath(src, dir), Target: dst, ReadOnly: ro}, src != "" +} + +func absPath(p, dir string) string { + if strings.HasPrefix(p, "~") { + if home, err := os.UserHomeDir(); err == nil { + p = filepath.Join(home, strings.TrimPrefix(p, "~")) + } + } + if !filepath.IsAbs(p) { + p = filepath.Join(dir, p) + } + return filepath.Clean(p) +} diff --git a/pkg/preflight/project/scan.go b/pkg/preflight/project/scan.go new file mode 100644 index 0000000..971e87c --- /dev/null +++ b/pkg/preflight/project/scan.go @@ -0,0 +1,143 @@ +package project + +import ( + "regexp" + "strings" + + "gopkg.in/yaml.v3" +) + +// composeMinVersions maps Compose-file syntax to the first Docker Compose v2 +// release that accepts it (from the docker/compose release notes). Older +// versions reject the file or silently ignore the key. +var composeMinVersions = struct { + topLevel map[string]string + service map[string]string + build map[string]string + dependsOn map[string]string +}{ + topLevel: map[string]string{ + "include": "2.20.0", + "name": "2.3.3", + "models": "2.38.0", + }, + service: map[string]string{ + "develop": "2.22.0", + "gpus": "2.30.0", + "post_start": "2.30.0", + "pre_stop": "2.30.0", + }, + build: map[string]string{ + "additional_contexts": "2.17.0", + }, + dependsOn: map[string]string{ + "restart": "2.17.0", + "required": "2.20.0", + }, +} + +// scanComposeFeatures walks the raw YAML, keeping line numbers that the typed +// loader discards. +func scanComposeFeatures(file string, raw []byte) []Feature { + var doc yaml.Node + if yaml.Unmarshal(raw, &doc) != nil || len(doc.Content) == 0 { + return nil + } + root := doc.Content[0] + var out []Feature + add := func(name, version string, n *yaml.Node) { + out = append(out, Feature{Name: name, MinVersion: version, Location: Location{File: file, Line: n.Line}}) + } + + for key, val := range mappingPairs(root) { + if v, ok := composeMinVersions.topLevel[key.Value]; ok { + add(key.Value, v, key) + } + if key.Value != "services" { + continue + } + for svcKey, svc := range mappingPairs(val) { + for k, v := range mappingPairs(svc) { + if ver, ok := composeMinVersions.service[k.Value]; ok { + add("services."+svcKey.Value+"."+k.Value, ver, k) + } + switch k.Value { + case "build": + for bk := range mappingPairs(v) { + if ver, ok := composeMinVersions.build[bk.Value]; ok { + add("services."+svcKey.Value+".build."+bk.Value, ver, bk) + } + } + case "depends_on": + for _, dep := range mappingPairs(v) { + for dk := range mappingPairs(dep) { + if ver, ok := composeMinVersions.dependsOn[dk.Value]; ok { + add("services."+svcKey.Value+".depends_on."+dk.Value, ver, dk) + } + } + } + } + } + } + } + return out +} + +// mappingPairs iterates key/value nodes of a YAML mapping in file order. +func mappingPairs(n *yaml.Node) func(func(*yaml.Node, *yaml.Node) bool) { + return func(yield func(*yaml.Node, *yaml.Node) bool) { + if n == nil || n.Kind != yaml.MappingNode { + return + } + for i := 0; i+1 < len(n.Content); i += 2 { + if !yield(n.Content[i], n.Content[i+1]) { + return + } + } + } +} + +// serviceLines maps each service name to the line defining it. +func serviceLines(raw []byte) map[string]int { + out := map[string]int{} + var doc yaml.Node + if yaml.Unmarshal(raw, &doc) != nil || len(doc.Content) == 0 { + return out + } + for key, val := range mappingPairs(doc.Content[0]) { + if key.Value == "services" { + for svc := range mappingPairs(val) { + out[svc.Value] = svc.Line + } + } + } + return out +} + +var interpolation = regexp.MustCompile(`\$\$|\$\{([A-Za-z_][A-Za-z0-9_]*)(:?[-?+])?[^}]*\}|\$([A-Za-z_][A-Za-z0-9_]*)`) + +// scanEnvRefs finds every ${VAR} Compose will interpolate. +func scanEnvRefs(file string, raw []byte) []EnvRef { + var out []EnvRef + for i, line := range strings.Split(string(raw), "\n") { + if strings.HasPrefix(strings.TrimSpace(line), "#") { + continue + } + for _, m := range interpolation.FindAllStringSubmatch(line, -1) { + if m[0] == "$$" { + continue + } + name, op := m[1], m[2] + if name == "" { + name = m[3] + } + out = append(out, EnvRef{ + Name: name, + HasDefault: strings.HasSuffix(op, "-") || strings.HasSuffix(op, "+"), + Required: strings.HasSuffix(op, "?"), + Location: Location{File: file, Line: i + 1}, + }) + } + } + return out +} diff --git a/pkg/preflight/registry/live_test.go b/pkg/preflight/registry/live_test.go new file mode 100644 index 0000000..fdd9643 --- /dev/null +++ b/pkg/preflight/registry/live_test.go @@ -0,0 +1,63 @@ +package registry + +import ( + "context" + "errors" + "os" + "testing" + "time" +) + +// Hits real registries; run with PREFLIGHT_LIVE=1. +func TestLiveResolve(t *testing.T) { + if os.Getenv("PREFLIGHT_LIVE") == "" { + t.Skip("set PREFLIGHT_LIVE=1 to query real registries") + } + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + r := NewRemote() + + img, err := r.Resolve(ctx, "postgres:16", "linux/arm64") + if err != nil { + t.Fatal(err) + } + t.Logf("postgres:16 index=%v platforms=%v size=%d", img.Index, img.Platforms, img.CompressedSize) + if !img.Index || img.CompressedSize == 0 { + t.Error("expected multi-arch index with arm64 size") + } + + img, err = r.Resolve(ctx, "mcr.microsoft.com/mssql/server:2022-latest", "linux/arm64") + if err != nil { + t.Fatal(err) + } + t.Logf("mssql index=%v platforms=%v size=%d", img.Index, img.Platforms, img.CompressedSize) + + _, err = r.Resolve(ctx, "postgres:this-tag-does-not-exist-123", "linux/arm64") + t.Logf("missing tag: %v", err) + if !errors.Is(err, ErrNotFound) { + t.Errorf("want ErrNotFound, got %v", err) + } + _, err = r.Resolve(ctx, "raphgm/definitely-not-a-repo-xyz:1", "linux/arm64") + t.Logf("missing repo: %v", err) +} + +func TestNormalize(t *testing.T) { + cases := map[string]string{ + "linux/arm64/v8": "linux/arm64", + "Linux/aarch64": "linux/arm64", + "linux/x86_64": "linux/amd64", + "linux/arm/v7": "linux/arm/v7", + "linux/amd64/": "linux/amd64", + } + for in, want := range cases { + if got := Normalize(in); got != want { + t.Errorf("Normalize(%q) = %q; want %q", in, got, want) + } + } + if Compatible("linux/amd64", "linux/arm64") { + t.Error("amd64 must not satisfy arm64") + } + if !Compatible("linux/arm/v7", "linux/arm") { + t.Error("variant-less want should accept v7") + } +} diff --git a/pkg/preflight/registry/registry.go b/pkg/preflight/registry/registry.go new file mode 100644 index 0000000..81ca37c --- /dev/null +++ b/pkg/preflight/registry/registry.go @@ -0,0 +1,263 @@ +// Package registry reads image metadata straight from registries, without +// pulling, so preflight can see which platforms an image ships and how big it +// is before Docker ever tries. +package registry + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "strings" + "sync" + + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/google/go-containerregistry/pkg/v1/remote/transport" +) + +// Image describes an image reference as the registry sees it. +type Image struct { + Ref string + + // Index is true for a multi-platform manifest list. A single-platform + // image is pulled regardless of host platform; an index without a + // matching entry makes `docker pull` fail. + Index bool + + // Platforms are normalized "os/arch[/variant]" strings. + Platforms []string + + // CompressedSize is the download size for the requested platform, or 0 + // when that platform is not available. + CompressedSize int64 + + // User is the image's configured USER for the requested platform. + User string +} + +var ( + ErrNotFound = errors.New("image not found in registry") + ErrUnauthorized = errors.New("registry denied access") + ErrNetwork = errors.New("registry unreachable") +) + +type Resolver interface { + Resolve(ctx context.Context, ref, platform string) (*Image, error) +} + +// Remote resolves against real registries using the user's Docker +// credentials. Results are cached per reference and platform. +type Remote struct { + mu sync.Mutex + cache map[string]result + + keychain *fallbackKeychain +} + +type result struct { + img *Image + err error +} + +func NewRemote() *Remote { + return &Remote{cache: map[string]result{}, keychain: &fallbackKeychain{}} +} + +// CredentialError returns the first error hit while reading Docker +// credentials, e.g. a credsStore helper that is configured but not +// installed. Docker itself fails pulls in that state. +func (r *Remote) CredentialError() error { + r.keychain.mu.Lock() + defer r.keychain.mu.Unlock() + return r.keychain.err +} + +// fallbackKeychain uses the Docker credentials when they can be read and +// falls back to anonymous access, remembering why. +type fallbackKeychain struct { + mu sync.Mutex + err error +} + +func (k *fallbackKeychain) Resolve(target authn.Resource) (authn.Authenticator, error) { + a, err := authn.DefaultKeychain.Resolve(target) + if err != nil { + k.mu.Lock() + if k.err == nil { + k.err = err + } + k.mu.Unlock() + return authn.Anonymous, nil + } + return a, nil +} + +func (r *Remote) Resolve(ctx context.Context, ref, platform string) (*Image, error) { + key := ref + "|" + platform + r.mu.Lock() + if c, ok := r.cache[key]; ok { + r.mu.Unlock() + return c.img, c.err + } + r.mu.Unlock() + + img, err := r.resolve(ctx, ref, platform) + + r.mu.Lock() + r.cache[key] = result{img, err} + r.mu.Unlock() + return img, err +} + +func (r *Remote) resolve(ctx context.Context, ref, platform string) (*Image, error) { + parsed, err := name.ParseReference(ref) + if err != nil { + return nil, fmt.Errorf("%w: invalid reference %q: %v", ErrNotFound, ref, err) + } + opts := []remote.Option{ + remote.WithContext(ctx), + remote.WithAuthFromKeychain(r.keychain), + } + desc, err := remote.Get(parsed, opts...) + if err != nil { + return nil, classify(err) + } + + out := &Image{Ref: ref} + want := Normalize(platform) + + if desc.MediaType.IsIndex() { + out.Index = true + idx, err := desc.ImageIndex() + if err != nil { + return nil, classify(err) + } + im, err := idx.IndexManifest() + if err != nil { + return nil, classify(err) + } + var match *v1.Descriptor + for i, m := range im.Manifests { + if m.Platform == nil || m.Platform.OS == "unknown" { + continue // attestation manifests + } + p := Normalize(m.Platform.String()) + out.Platforms = append(out.Platforms, p) + if match == nil && Compatible(p, want) { + match = &im.Manifests[i] + } + } + if match != nil { + if img, err := idx.Image(match.Digest); err == nil { + out.CompressedSize = layerSize(img) + if cfg, err := img.ConfigFile(); err == nil { + out.User = cfg.Config.User + } + } + } + return out, nil + } + + img, err := desc.Image() + if err != nil { + return nil, classify(err) + } + cfg, err := img.ConfigFile() + if err != nil { + return nil, classify(err) + } + p := Normalize(cfg.OS + "/" + cfg.Architecture + "/" + cfg.Variant) + out.Platforms = []string{p} + out.CompressedSize = layerSize(img) + out.User = cfg.Config.User + return out, nil +} + +func layerSize(img v1.Image) int64 { + m, err := img.Manifest() + if err != nil { + return 0 + } + var total int64 + for _, l := range m.Layers { + total += l.Size + } + return total +} + +func classify(err error) error { + var te *transport.Error + if errors.As(err, &te) { + switch te.StatusCode { + case http.StatusNotFound: + return fmt.Errorf("%w: %v", ErrNotFound, err) + case http.StatusUnauthorized, http.StatusForbidden: + // Docker Hub answers 401 for repositories that do not exist + // as well as for private ones. + return fmt.Errorf("%w: %v", ErrUnauthorized, err) + } + for _, d := range te.Errors { + if d.Code == transport.ManifestUnknownErrorCode || d.Code == transport.NameUnknownErrorCode { + return fmt.Errorf("%w: %v", ErrNotFound, err) + } + } + } + var ne net.Error + var dns *net.DNSError + if errors.As(err, &ne) || errors.As(err, &dns) || errors.Is(err, context.DeadlineExceeded) { + return fmt.Errorf("%w: %v", ErrNetwork, err) + } + return err +} + +// Canonical returns the fully qualified form of ref, so "postgres" and +// "docker.io/library/postgres:latest" compare equal. +func Canonical(ref string) string { + parsed, err := name.ParseReference(ref) + if err != nil { + return ref + } + return parsed.Name() +} + +// Normalize maps platform spellings to one canonical form. +func Normalize(p string) string { + p = strings.ToLower(strings.Trim(p, "/")) + parts := strings.Split(p, "/") + if len(parts) < 2 { + return p + } + arch := parts[1] + switch arch { + case "x86_64", "x86-64": + arch = "amd64" + case "aarch64": + arch = "arm64" + } + variant := "" + if len(parts) > 2 { + variant = parts[2] + } + if arch == "arm64" && variant == "v8" { + variant = "" + } + if variant == "" { + return parts[0] + "/" + arch + } + return parts[0] + "/" + arch + "/" + variant +} + +// Compatible reports whether an image built for have runs natively on want. +func Compatible(have, want string) bool { + have, want = Normalize(have), Normalize(want) + if have == want { + return true + } + // linux/arm/v7 and friends: accept a missing variant on either side. + hp, wp := strings.Split(have, "/"), strings.Split(want, "/") + return len(hp) >= 2 && len(wp) >= 2 && hp[0] == wp[0] && hp[1] == wp[1] && (len(hp) == 2 || len(wp) == 2) +} diff --git a/pkg/preflight/registry/user_live_test.go b/pkg/preflight/registry/user_live_test.go new file mode 100644 index 0000000..05b0029 --- /dev/null +++ b/pkg/preflight/registry/user_live_test.go @@ -0,0 +1,24 @@ +package registry + +import ( + "context" + "os" + "testing" + "time" +) + +func TestLiveImageUser(t *testing.T) { + if os.Getenv("PREFLIGHT_LIVE") == "" { + t.Skip("set PREFLIGHT_LIVE=1") + } + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + r := NewRemote() + for _, ref := range []string{"grafana/grafana:11.2.0", "postgres:16", "docker.elastic.co/elasticsearch/elasticsearch:8.15.0", "jenkins/jenkins:lts"} { + img, err := r.Resolve(ctx, ref, "linux/arm64") + if err != nil { + t.Fatal(err) + } + t.Logf("%-55s user=%q", ref, img.User) + } +} diff --git a/pkg/preflight/rules/build.go b/pkg/preflight/rules/build.go new file mode 100644 index 0000000..7d8dfd7 --- /dev/null +++ b/pkg/preflight/rules/build.go @@ -0,0 +1,250 @@ +package rules + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/project" +) + +var buildContextRule = rule{ + id: "build.context", + title: "Build inputs exist in the build context", + needs: []fact.ID{fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + for _, svc := range env.Project.Services { + b := svc.Build + if b == nil { + continue + } + f := func(sev fact.Severity, title, fix, loc, predicts string, evidence ...string) { + out = append(out, Finding{Rule: "build.context", Severity: sev, Service: svc.Name, Title: title, Fix: fix, Location: loc, Predicts: predicts, Evidence: evidence}) + } + if st, err := os.Stat(b.Context); err != nil || !st.IsDir() { + f(fact.Error, "build context "+rel(env, b.Context)+" does not exist", "Fix `build.context` in the Compose file.", svc.Location.String(), "unable to prepare context: path not found") + continue + } + if b.DockerfilePath == "" { + continue + } + if _, err := os.Stat(b.DockerfilePath); err != nil { + f(fact.Error, "Dockerfile "+rel(env, b.DockerfilePath)+" does not exist", "Fix `build.dockerfile`; it is relative to the build context.", svc.Location.String(), "failed to read dockerfile: open Dockerfile: no such file or directory") + continue + } + if b.ParseErr != nil { + f(fact.Error, "Dockerfile cannot be parsed", "Fix the syntax error.", rel(env, b.DockerfilePath), "dockerfile parse error", b.ParseErr.Error()) + continue + } + df := b.Dockerfile + reach, err := df.Reachable(b.Target) + if err != nil { + f(fact.Error, fmt.Sprintf("build target %q is not a stage in the Dockerfile", b.Target), "Fix `build.target`.", svc.Location.String(), "target stage \""+b.Target+"\" could not be found") + continue + } + + bc, err := project.OpenContext(b.Context, b.DockerfilePath) + if err != nil { + f(fact.Warning, ".dockerignore cannot be read", "", rel(env, b.Context), "", err.Error()) + continue + } + // The two builders word a missing COPY source differently. + notFound := func(src string) string { + if env.Host.BuildxInstalled && !env.Host.BuildKitDisabled { + return `failed to compute cache key: failed to calculate checksum of ref …: "/` + strings.TrimPrefix(src, "/") + `": not found` + } + return "COPY failed: file not found in build context or excluded by .dockerignore: stat " + strings.TrimPrefix(src, "/") + ": file does not exist" + } + for _, i := range reach { + st := df.Stages[i] + if st.Unresolved() { + f(fact.Error, "base image "+st.Base+" depends on an ARG with no value", "Give the ARG a default before the first FROM, or pass it in `build.args`.", st.Location.String(), "invalid reference format") + } + for _, cp := range st.Copies { + for _, src := range cp.Sources { + status, pattern := bc.Check(src) + switch status { + case project.SourceMissing: + f(fact.Error, fmt.Sprintf("%s source %q not found in build context", cp.Instruction, src), + "Create the file, fix the path (it is relative to "+rel(env, b.Context)+"), or run the step that generates it first.", + cp.Location.String(), notFound(src), + "context: "+rel(env, b.Context)) + case project.SourceIgnored: + f(fact.Error, fmt.Sprintf("%s source %q is excluded by .dockerignore", cp.Instruction, src), + fmt.Sprintf("Remove or negate the pattern %q in %s.", pattern, rel(env, bc.IgnoreFile)), + cp.Location.String(), notFound(src), + fmt.Sprintf("%s: pattern %q", rel(env, bc.IgnoreFile), pattern)) + case project.SourceOutside: + f(fact.Error, fmt.Sprintf("%s source %q is outside the build context", cp.Instruction, src), + "Move the file into the context, widen `build.context`, or use `build.additional_contexts`.", + cp.Location.String(), "forbidden path outside the build context") + } + } + } + } + } + return out + }, +} + +var buildKitRule = rule{ + id: "build.buildkit", + title: "Builder supports the Dockerfile syntax", + needs: []fact.ID{fact.DockerCLI, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + if h.BuildxInstalled && !h.BuildKitDisabled { + return nil + } + reason := "host: docker buildx plugin is not installed, so `docker build` falls back to the legacy builder" + fix := "Install the buildx plugin (`docker-buildx-plugin` on Linux; bundled with Docker Desktop)." + if h.BuildKitDisabled { + reason = "host: DOCKER_BUILDKIT=0 forces the legacy builder" + fix = "Unset DOCKER_BUILDKIT." + } + var out []Finding + for _, svc := range env.Project.Services { + if svc.Build == nil || svc.Build.Dockerfile == nil { + continue + } + for _, feat := range svc.Build.Dockerfile.BuildKitFeatures { + predicts := "" + if strings.Contains(feat.Name, "--") { + predicts = "the --" + lastWord(feat.Name) + " option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled" + } + out = append(out, Finding{ + Rule: "build.buildkit", + Severity: fact.Error, + Service: svc.Name, + Title: feat.Name + " requires BuildKit", + Evidence: []string{reason}, + Fix: fix, + Location: feat.Location.String(), + Predicts: predicts, + }) + } + } + return out + }, +} + +var composeFeaturesRule = rule{ + id: "compose.version", + title: "Installed Compose understands the Compose file", + needs: []fact.ID{fact.Compose}, + check: func(_ context.Context, env *Env) []Finding { + have := env.Host.ComposeVersion + var out []Finding + if strings.HasPrefix(have, "1.") { + out = append(out, Finding{ + Rule: "compose.version", + Severity: fact.Warning, + Title: "only legacy docker-compose " + have + " is installed", + Evidence: []string{"host: `docker compose` (v2) is missing; found docker-compose " + have}, + Fix: "Install the Compose v2 plugin; v1 has been end-of-life since 2023.", + }) + } + for _, feat := range env.Project.ComposeFeatures { + if versionLess(have, feat.MinVersion) { + out = append(out, Finding{ + Rule: "compose.version", + Severity: fact.Error, + Title: fmt.Sprintf("`%s` needs Compose %s or newer", feat.Name, feat.MinVersion), + Evidence: []string{"host: Compose " + have}, + Fix: "Upgrade Docker Compose (or Docker Desktop).", + Location: feat.Location.String(), + }) + } + } + return out + }, +} + +var envRule = rule{ + id: "compose.env", + title: "Interpolated variables have values", + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + seen := map[string]bool{} + for _, ref := range env.Project.EnvRefs { + if _, set := env.Project.Env[ref.Name]; set || ref.HasDefault || seen[ref.Name] { + continue + } + seen[ref.Name] = true + if ref.Required { + out = append(out, Finding{ + Rule: "compose.env", + Severity: fact.Error, + Title: "required variable " + ref.Name + " is not set", + Evidence: []string{"project: ${" + ref.Name + ":?…} has no value in the environment or .env"}, + Fix: "Set " + ref.Name + " in .env or the shell.", + Location: ref.Location.String(), + Predicts: "required variable " + ref.Name + " is missing a value", + }) + continue + } + out = append(out, Finding{ + Rule: "compose.env", + Severity: fact.Warning, + Title: "variable " + ref.Name + " is not set and defaults to an empty string", + Evidence: []string{"project: $" + ref.Name + " not found in the environment or .env"}, + Fix: "Set it in .env, or write ${" + ref.Name + ":-default}.", + Location: ref.Location.String(), + Predicts: `The "` + ref.Name + `" variable is not set. Defaulting to a blank string.`, + }) + } + for _, ef := range env.Project.EnvFiles { + if _, err := os.Stat(ef.Path); err != nil && !ef.Required { + out = append(out, Finding{ + Rule: "compose.env", + Severity: fact.Info, + Service: ef.Service, + Title: "optional env_file " + rel(env, ef.Path) + " is missing", + Fix: "Create it if the service needs those variables.", + }) + } + } + return out + }, +} + +func rel(env *Env, path string) string { + if r, err := filepath.Rel(env.Project.Dir, path); err == nil && !strings.HasPrefix(r, "..") { + return r + } + return path +} + +func lastWord(s string) string { + s = s[strings.LastIndex(s, " ")+1:] + return strings.TrimPrefix(s, "--") +} + +// versionLess compares dotted versions numerically, ignoring suffixes such +// as "-desktop.1". +func versionLess(a, b string) bool { + pa, pb := versionParts(a), versionParts(b) + for i := 0; i < 3; i++ { + if pa[i] != pb[i] { + return pa[i] < pb[i] + } + } + return false +} + +func versionParts(v string) [3]int { + var out [3]int + v = strings.TrimPrefix(v, "v") + if i := strings.IndexAny(v, "-+ "); i >= 0 { + v = v[:i] + } + for i, p := range strings.SplitN(v, ".", 3) { + out[i], _ = strconv.Atoi(p) + } + return out +} diff --git a/pkg/preflight/rules/features.go b/pkg/preflight/rules/features.go new file mode 100644 index 0000000..648de59 --- /dev/null +++ b/pkg/preflight/rules/features.go @@ -0,0 +1,154 @@ +package rules + +import ( + "sort" + "strings" + + "github.com/google/go-containerregistry/pkg/name" + + "github.com/raphgm/container-preflight/pkg/preflight/host" + "github.com/raphgm/container-preflight/pkg/preflight/project" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +// Features describes one service on one host as flat key/value pairs. +// Learned rules are conjunctions over these keys, so the vocabulary is kept +// small and host-independent where possible (buckets, not exact numbers). +func Features(env *Env, svc *project.Service) map[string]string { + h := env.Host + f := map[string]string{ + "host.platform": hostPlatform(h), + "engine": engineKind(h), + "memory": memoryBucket(h.MemTotal), + "buildkit": yesNo(h.BuildxInstalled && !h.BuildKitDisabled), + } + if v := h.ComposeVersion; v != "" { + f["compose.major"] = strings.SplitN(v, ".", 2)[0] + } + + f["build"] = yesNo(svc.Build != nil) + + // Environment variables are recorded as set/empty, never their values: + // learned rules are shared and must not leak secrets. A variable that is + // absent reads as "unset" (see learn). + for k, v := range svc.Environment { + if v == "" { + f["env."+k] = "empty" + } else { + f["env."+k] = "set" + } + } + + ref := serviceImage(svc) + if ref == "" { + return f + } + f["image"] = repository(ref) + + want := hostPlatform(h) + if svc.Platform != "" { + want = svc.Platform + } + runAs := registry.Normalize(want) + if res, ok := env.Images[ImageKey(ref, want)]; ok && res.Image != nil { + ps := append([]string(nil), res.Image.Platforms...) + sort.Strings(ps) + f["image.platforms"] = strings.Join(ps, ",") + available := false + for _, p := range ps { + if registry.Compatible(p, want) { + available = true + } + } + if !available && len(ps) == 1 { + runAs = ps[0] + } + } + f["run.platform"] = runAs + + switch native, emulated := h.CanRun(runAs); { + case native: + f["emulation"] = "none" + case emulated && h.Emulators[runAs] != "": + f["emulation"] = h.Emulators[runAs] + case emulated: + f["emulation"] = "yes" + case h.EmulationKnown: + f["emulation"] = "unavailable" + default: + f["emulation"] = "unknown" + } + return f +} + +// serviceImage is the image the service's containers run: its image, or the +// base of the final build stage. +func serviceImage(svc *project.Service) string { + if svc.Image != "" { + return svc.Image + } + if svc.Build == nil || svc.Build.Dockerfile == nil || len(svc.Build.Dockerfile.Stages) == 0 { + return "" + } + df := svc.Build.Dockerfile + reach, err := df.Reachable(svc.Build.Target) + if err != nil || len(reach) == 0 { + return "" + } + st := df.Stages[reach[len(reach)-1]] + for st.BaseStage >= 0 { + st = df.Stages[st.BaseStage] + } + if st.Unresolved() || strings.EqualFold(st.Base, "scratch") { + return "" + } + return st.Base +} + +// repository strips the tag or digest, so a rule learned on mongo:7 also +// covers mongo:7.0.14. +func repository(ref string) string { + parsed, err := name.ParseReference(ref) + if err != nil { + return ref + } + return parsed.Context().Name() +} + +func engineKind(h *host.Profile) string { + switch { + case h.OperatingSystem == "": + return "unknown" + case h.IsDesktop(): + return "docker-desktop" + case strings.Contains(h.Endpoint, "/.colima/"): + return "colima" + case strings.Contains(h.Endpoint, "/.orbstack/") || strings.Contains(h.OperatingSystem, "OrbStack"): + return "orbstack" + case !h.Local: + return "remote" + } + return "linux" +} + +func memoryBucket(n int64) string { + const gib = 1 << 30 + switch { + case n == 0: + return "unknown" + case n < 2*gib: + return "<2GiB" + case n < 4*gib: + return "<4GiB" + case n < 8*gib: + return "<8GiB" + } + return ">=8GiB" +} + +func yesNo(b bool) string { + if b { + return "yes" + } + return "no" +} diff --git a/pkg/preflight/rules/host_io.go b/pkg/preflight/rules/host_io.go new file mode 100644 index 0000000..1627103 --- /dev/null +++ b/pkg/preflight/rules/host_io.go @@ -0,0 +1,231 @@ +package rules + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" +) + +type portUse struct { + service string + loc string +} + +var portConflictRule = rule{ + id: "ports.conflict", + title: "Services do not publish the same host port", + needs: []fact.ID{fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + used := map[string]portUse{} + for _, svc := range env.Project.Services { + for _, p := range svc.Ports { + width := p.End - p.Start + 1 + if svc.Replicas > 1 && width < svc.Replicas { + out = append(out, Finding{ + Rule: "ports.conflict", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("%d replicas cannot all publish host port %s", svc.Replicas, p.String()), + Evidence: []string{"project: each replica binds the same host port"}, + Fix: fmt.Sprintf("Publish a range at least %d wide (e.g. \"%d-%d:%d\"), drop the host port, or put a proxy in front.", svc.Replicas, p.Start, p.Start+svc.Replicas-1, p.Target), + Location: svc.Location.String(), + Predicts: "Bind for 0.0.0.0:" + fmt.Sprint(p.Start) + " failed: port is already allocated", + }) + } + for port := p.Start; port <= p.End; port++ { + key := fmt.Sprintf("%s:%d/%s", p.HostIP, port, p.Protocol) + if prev, ok := used[key]; ok && prev.service != svc.Name { + out = append(out, Finding{ + Rule: "ports.conflict", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("host port %d/%s is published by both %s and %s", port, p.Protocol, prev.service, svc.Name), + Fix: "Give one of them a different host port.", + Location: svc.Location.String(), + Predicts: fmt.Sprintf("Bind for 0.0.0.0:%d failed: port is already allocated", port), + }) + break + } + used[key] = portUse{svc.Name, svc.Location.String()} + } + } + } + return out + }, +} + +var hostPortRule = rule{ + id: "ports.host", + title: "Published ports are free on the host", + needs: []fact.ID{fact.LocalDaemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + unprivStart := int64(1024) + if v, ok := h.Sysctls["net.ipv4.ip_unprivileged_port_start"]; ok { + unprivStart = v + } + var out []Finding + busy := map[string]int{} // port -> index in out + for _, svc := range env.Project.Services { + for _, p := range svc.Ports { + if h.Rootless && int64(p.Start) < unprivStart { + out = append(out, Finding{ + Rule: "ports.host", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("rootless Docker cannot publish privileged port %d", p.Start), + Evidence: []string{"host: daemon runs rootless", fmt.Sprintf("host: net.ipv4.ip_unprivileged_port_start = %d", unprivStart)}, + Fix: "Publish a port ≥ 1024, or `sudo sysctl net.ipv4.ip_unprivileged_port_start=0`.", + Location: svc.Location.String(), + Predicts: "cannot expose privileged port " + fmt.Sprint(p.Start), + }) + } + for port := p.Start; port <= p.End; port++ { + key := fmt.Sprintf("%d/%s", port, p.Protocol) + if i, ok := busy[key]; ok { + out[i].Service += ", " + svc.Name + break + } + holder, c := h.PortHolder(p.HostIP, port, p.Protocol) + if holder == "" { + continue + } + // Compose replaces its own containers on `up`. + if c != nil && c.ComposeProject == env.Project.Name { + continue + } + out = append(out, Finding{ + Rule: "ports.host", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("host port %d/%s is already in use by %s", port, p.Protocol, holder), + Evidence: []string{fmt.Sprintf("host: %s is listening on %d", holder, port)}, + Fix: "Stop it, or publish a different host port.", + Location: svc.Location.String(), + Predicts: fmt.Sprintf("Bind for 0.0.0.0:%d failed: port is already allocated / address already in use", port), + }) + busy[key] = len(out) - 1 + break + } + } + } + return out + }, +} + +var bindRule = rule{ + id: "mounts.bind", + title: "Bind-mount sources exist and have the right type", + needs: []fact.ID{fact.LocalDaemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + for _, svc := range env.Project.Services { + for _, b := range svc.Binds { + wantsFile := looksLikeFile(b.Target) + st, err := os.Stat(b.Source) + src := rel(env, b.Source) + switch { + case err != nil && !b.CreateHostPath: + out = append(out, Finding{ + Rule: "mounts.bind", Severity: fact.Error, Service: svc.Name, + Title: "bind source " + src + " does not exist", + Evidence: []string{"project: create_host_path: false"}, + Fix: "Create " + src + " before starting.", + Location: svc.Location.String(), + Predicts: "invalid mount config for type \"bind\": bind source path does not exist", + }) + case err != nil && wantsFile: + out = append(out, Finding{ + Rule: "mounts.bind", Severity: fact.Error, Service: svc.Name, + Title: fmt.Sprintf("bind source %s is missing; Docker will create a directory where %s expects a file", src, b.Target), + Evidence: []string{"host: " + src + " does not exist", "project: target " + b.Target + " looks like a file"}, + Fix: "Create the file " + src + " (check the path is relative to the Compose file).", + Location: svc.Location.String(), + Predicts: "Are you trying to mount a directory onto a file (or vice-versa)?", + }) + case err != nil: + out = append(out, Finding{ + Rule: "mounts.bind", Severity: fact.Warning, Service: svc.Name, + Title: "bind source " + src + " does not exist and will be created empty, owned by root", + Fix: "Create it yourself if the container expects content or write access.", + Location: svc.Location.String(), + }) + case st.IsDir() && wantsFile && isEmptyDir(b.Source): + out = append(out, Finding{ + Rule: "mounts.bind", Severity: fact.Error, Service: svc.Name, + Title: fmt.Sprintf("%s is an empty directory but %s expects a file", src, b.Target), + Evidence: []string{"host: " + src + " is an empty directory, typically left by an earlier run when the file was missing"}, + Fix: "Delete the empty directory " + src + " and create the file.", + Location: svc.Location.String(), + Predicts: "Are you trying to mount a directory onto a file (or vice-versa)?", + }) + } + } + } + return out + }, +} + +// Docker Desktop for Mac shares these host paths with its VM by default. +var desktopSharedPaths = []string{"/Users", "/Volumes", "/private", "/tmp", "/var/folders"} + +var fileSharingRule = rule{ + id: "mounts.sharing", + title: "Bind mounts are inside Docker Desktop's shared paths", + needs: []fact.ID{fact.LocalDaemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + if !h.IsDesktop() || (h.ClientOS != "darwin" && h.ClientOS != "linux") { + return nil + } + defaults := desktopSharedPaths + if h.ClientOS == "linux" { + // Docker Desktop for Linux shares only the home directory. + if home, err := os.UserHomeDir(); err == nil { + defaults = []string{home} + } + } + var out []Finding + for _, svc := range env.Project.Services { + for _, b := range svc.Binds { + paths, source := defaults, "shares "+strings.Join(defaults, ", ")+" by default" + if len(h.SharedPaths) > 0 { + paths, source = h.SharedPaths, "shares "+strings.Join(h.SharedPaths, ", ")+" (read from the running VM)" + } + shared := false + for _, p := range paths { + if b.Source == p || strings.HasPrefix(b.Source, p+"/") { + shared = true + } + } + if shared { + continue + } + out = append(out, Finding{ + Rule: "mounts.sharing", Severity: fact.Error, Service: svc.Name, + Title: "bind source " + b.Source + " is outside Docker Desktop's shared paths", + Evidence: []string{"host: Docker Desktop " + source}, + Fix: "Add the path in Docker Desktop → Settings → Resources → File sharing.", + Location: svc.Location.String(), + Predicts: "mounts denied: The path " + b.Source + " is not shared from the host and is not known to Docker.", + }) + } + } + return out + }, +} + +func looksLikeFile(target string) bool { + base := filepath.Base(target) + return strings.Contains(strings.TrimPrefix(base, "."), ".") && !strings.HasSuffix(target, "/") +} + +func isEmptyDir(path string) bool { + entries, err := os.ReadDir(path) + return err == nil && len(entries) == 0 +} diff --git a/pkg/preflight/rules/images.go b/pkg/preflight/rules/images.go new file mode 100644 index 0000000..6fceec7 --- /dev/null +++ b/pkg/preflight/rules/images.go @@ -0,0 +1,211 @@ +package rules + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +func pullKind(p Pull) string { + if p.Base { + return "base image" + } + return "image" +} + +var imageExistsRule = rule{ + id: "image.exists", + title: "Images exist in their registries", + needs: []fact.ID{fact.Registry, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + reported := map[string]bool{} + for _, p := range Pulls(env.Project, env.Host) { + res, ok := env.Images[ImageKey(p.Ref, p.Platform)] + if p.Local || !ok || res.Err == nil || reported[p.Service+p.Ref] { + continue + } + reported[p.Service+p.Ref] = true + switch { + case errors.Is(res.Err, registry.ErrNotFound): + out = append(out, Finding{ + Rule: "image.exists", + Severity: fact.Error, + Service: p.Service, + Title: fmt.Sprintf("%s %s does not exist", pullKind(p), p.Ref), + Evidence: []string{"registry: " + firstLine(res.Err)}, + Fix: "Check the tag on the registry's web page; tags are often renamed or removed.", + Location: p.Location.String(), + Predicts: "failed to resolve reference \"" + strings.Replace(registry.Canonical(p.Ref), "index.docker.io/", "docker.io/", 1) + "\": not found", + }) + case errors.Is(res.Err, registry.ErrUnauthorized): + out = append(out, Finding{ + Rule: "image.exists", + Severity: fact.Warning, + Service: p.Service, + Title: fmt.Sprintf("%s %s is private or does not exist", pullKind(p), p.Ref), + Evidence: []string{"registry: " + firstLine(res.Err), "Docker Hub gives the same answer for private and missing repositories"}, + Fix: "Check the name, or `docker login` to the registry that hosts it.", + Location: p.Location.String(), + Predicts: "pull access denied, repository does not exist or may require 'docker login'", + }) + } + } + return out + }, +} + +var imagePlatformRule = rule{ + id: "image.platform", + title: "Images ship the platform this host runs", + needs: []fact.ID{fact.Daemon, fact.Registry, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + var out []Finding + h := env.Host + for _, p := range Pulls(env.Project, h) { + res, ok := env.Images[ImageKey(p.Ref, p.Platform)] + if !ok || res.Err != nil { + continue + } + img := res.Image + want := registry.Normalize(p.Platform) + evidence := []string{ + fmt.Sprintf("host: daemon runs %s (%s)", h.Platform, h.OperatingSystem), + fmt.Sprintf("registry: %s ships %s", p.Ref, strings.Join(img.Platforms, ", ")), + } + if p.Explicit { + evidence = append(evidence, "project: platform "+want+" requested explicitly") + } + + available := false + for _, pl := range img.Platforms { + if registry.Compatible(pl, want) { + available = true + } + } + + if img.Index && !available { + fix := "Use an image or tag that publishes " + want + "." + if !p.Explicit { + for _, pl := range img.Platforms { + if _, emu := h.CanRun(pl); emu { + fix = fmt.Sprintf("Add `platform: %s` to run it under emulation, or use an image that publishes %s.", pl, want) + break + } + } + } + out = append(out, Finding{ + Rule: "image.platform", + Severity: fact.Error, + Service: p.Service, + Title: fmt.Sprintf("%s %s has no %s variant", pullKind(p), p.Ref, want), + Evidence: evidence, + Fix: fix, + Location: p.Location.String(), + Predicts: "no matching manifest for " + want + " in the manifest list entries", + }) + continue + } + + // The image will be fetched for its own platform; it must be + // runnable here. + runAs := want + if !available && len(img.Platforms) == 1 { + runAs = img.Platforms[0] + } + native, emulated := h.CanRun(runAs) + switch { + case native: + case !emulated && !h.EmulationKnown: + out = append(out, Finding{ + Rule: "image.platform", + Severity: fact.Warning, + Service: p.Service, + Title: fmt.Sprintf("%s %s is %s only; could not tell whether this host emulates it", pullKind(p), p.Ref, runAs), + Evidence: append(evidence, "host: the daemon's kernel could not be inspected for binfmt handlers"), + Fix: "Check with `docker run --rm --platform " + runAs + " alpine uname -m`, or use an image built for " + h.Platform + ".", + Location: p.Location.String(), + Predicts: "exec format error (if no emulation)", + }) + case emulated && h.Emulators[registry.Normalize(runAs)] == "qemu" && qemuCrash(p.Ref) != "": + out = append(out, Finding{ + Rule: "image.platform", + Severity: fact.Error, + Service: p.Service, + Title: fmt.Sprintf("%s %s crashes under QEMU %s emulation", pullKind(p), p.Ref, runAs), + Evidence: append(evidence, "host: "+runAs+" is emulated with QEMU (no Rosetta)", "known: this image does not run under QEMU user-mode emulation"), + Fix: "Use a native " + h.Platform + " alternative, enable Rosetta (`colima start --vz-rosetta`, or Docker Desktop's Rosetta setting), or run on an amd64 host.", + Location: p.Location.String(), + Predicts: qemuCrash(p.Ref), + }) + case emulated: + out = append(out, Finding{ + Rule: "image.platform", + Severity: fact.Warning, + Service: p.Service, + Title: fmt.Sprintf("%s %s will run under %s emulation", pullKind(p), p.Ref, runAs), + Evidence: append(evidence, "host: can emulate "+strings.Join(h.Emulated, ", ")), + Fix: "Expect it to be several times slower; JIT runtimes and databases can crash under emulation. Prefer a native " + h.Platform + " image.", + Location: p.Location.String(), + Predicts: "The requested image's platform (" + runAs + ") does not match the detected host platform (" + h.Platform + ")", + }) + default: + out = append(out, Finding{ + Rule: "image.platform", + Severity: fact.Error, + Service: p.Service, + Title: fmt.Sprintf("%s %s is %s only and this host cannot run it", pullKind(p), p.Ref, runAs), + Evidence: append(evidence, "host: no emulation for "+runAs), + Fix: "Install QEMU binfmt handlers (`docker run --privileged --rm tonistiigi/binfmt --install all`) or use an image built for " + h.Platform + ".", + Location: p.Location.String(), + Predicts: "exec format error", + }) + } + } + return out + }, +} + +var credentialsRule = rule{ + id: "registry.credentials", + title: "Docker credential helper works", + needs: []fact.ID{fact.DockerCLI}, + check: func(_ context.Context, env *Env) []Finding { + helper := env.Host.MissingCredentialHelper + if helper == "" { + return nil + } + return []Finding{{ + Rule: "registry.credentials", + Severity: fact.Error, + Title: "Docker's configured credential helper " + helper + " is not installed", + Evidence: []string{"host: ~/.docker/config.json names " + helper + ", which is not on PATH"}, + Fix: "Install the helper, or remove the \"credsStore\" entry from ~/.docker/config.json (common after uninstalling Docker Desktop).", + Predicts: "error getting credentials - err: exec: \"" + helper + "\": executable file not found in $PATH", + }} + }, +} + +func qemuCrash(ref string) string { + for _, k := range knownFor(ref) { + if k.qemuCrash != "" { + return k.qemuCrash + } + } + return "" +} + +func firstLine(err error) string { + s := err.Error() + if i := strings.IndexByte(s, '\n'); i >= 0 { + s = s[:i] + } + if len(s) > 200 { + s = s[:200] + "…" + } + return s +} diff --git a/pkg/preflight/rules/owner_unix.go b/pkg/preflight/rules/owner_unix.go new file mode 100644 index 0000000..934cfa3 --- /dev/null +++ b/pkg/preflight/rules/owner_unix.go @@ -0,0 +1,17 @@ +//go:build !windows + +package rules + +import ( + "os" + "syscall" +) + +// owner returns the numeric owner of a file. +func owner(fi os.FileInfo) (int, bool) { + st, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return 0, false + } + return int(st.Uid), true +} diff --git a/pkg/preflight/rules/owner_windows.go b/pkg/preflight/rules/owner_windows.go new file mode 100644 index 0000000..b3d1a6d --- /dev/null +++ b/pkg/preflight/rules/owner_windows.go @@ -0,0 +1,5 @@ +package rules + +import "os" + +func owner(os.FileInfo) (int, bool) { return 0, false } diff --git a/pkg/preflight/rules/permissions.go b/pkg/preflight/rules/permissions.go new file mode 100644 index 0000000..99101d1 --- /dev/null +++ b/pkg/preflight/rules/permissions.go @@ -0,0 +1,137 @@ +package rules + +import ( + "context" + "fmt" + "os" + "strconv" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/project" +) + +// containerUser returns the user a service's processes start as: the +// Compose `user:` value, else the image's USER. uid is -1 when the user is +// a name preflight cannot resolve without unpacking the image. +func containerUser(env *Env, svc *project.Service) (user string, uid int) { + user = svc.User + if user == "" { + ref := serviceImage(svc) + if ref != "" { + want := hostPlatform(env.Host) + if svc.Platform != "" { + want = svc.Platform + } + if res, ok := env.Images[ImageKey(ref, want)]; ok && res.Image != nil { + user = res.Image.User + } + } + } + name, _, _ := strings.Cut(user, ":") + switch name { + case "", "root", "0": + return user, 0 + case "nobody": + return user, 65534 + } + if n, err := strconv.Atoi(name); err == nil { + return user, n + } + return user, -1 +} + +// strictDataDirs are images that chmod their data directory at start-up +// and refuse to run when they cannot, which happens on bind mounts from a +// Windows filesystem. +var strictDataDirs = []struct{ match, target, predicts string }{ + {"postgres", "/var/lib/postgresql", `FATAL: data directory "/var/lib/postgresql/data" has invalid permissions`}, +} + +var permissionsRule = rule{ + id: "mounts.permissions", + title: "Containers can write to their bind mounts", + needs: []fact.ID{fact.LocalDaemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + var out []Finding + for _, svc := range env.Project.Services { + user, uid := containerUser(env, svc) + for _, b := range svc.Binds { + src := rel(env, b.Source) + + if h.SELinux && b.SELinux == "" { + out = append(out, Finding{ + Rule: "mounts.permissions", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("SELinux will block access to bind mount %s", src), + Evidence: []string{"host: SELinux is enabled for Docker", "project: " + src + " is mounted without :z or :Z"}, + Fix: fmt.Sprintf("Mount it as %s:%s:z (shared) or :Z (private to this container).", src, b.Target), + Location: svc.Location.String(), + Predicts: "Permission denied", + }) + } + + if h.ClientOS == "windows" && !b.ReadOnly { + ref := serviceImage(svc) + for _, d := range strictDataDirs { + if strings.Contains(ref, d.match) && strings.HasPrefix(b.Target, d.target) { + out = append(out, Finding{ + Rule: "mounts.permissions", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("%s cannot set permissions on data folder %s bind-mounted from Windows", d.match, src), + Evidence: []string{"host: Docker on Windows; files bind-mounted from the Windows filesystem ignore chmod", "project: " + b.Target + " is a bind mount"}, + Fix: "Use a named volume for the data folder (e.g. `pgdata:" + b.Target + "`), or keep the folder inside the WSL filesystem.", + Location: svc.Location.String(), + Predicts: d.predicts, + }) + } + } + } + + if b.ReadOnly || uid == 0 || h.MapsOwnership() { + continue + } + who := fmt.Sprintf("user %q", user) + if uid >= 0 { + who = fmt.Sprintf("uid %d", uid) + } + + fi, err := os.Stat(b.Source) + if err != nil { + if !b.CreateHostPath { + continue // mounts.bind reports this + } + out = append(out, Finding{ + Rule: "mounts.permissions", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("Docker will create %s owned by root, but the container runs as %s", src, who), + Evidence: []string{"host: " + src + " does not exist; Docker creates missing bind sources as root", "image: runs as " + who}, + Fix: fmt.Sprintf("Create %s yourself and `chown` it to the container's uid, or use a named volume.", src), + Location: svc.Location.String(), + Predicts: "Permission denied", + }) + continue + } + own, ok := owner(fi) + if !ok || uid < 0 || own == uid || fi.Mode().Perm()&0o002 != 0 { + continue + } + out = append(out, Finding{ + Rule: "mounts.permissions", + Severity: fact.Warning, + Service: svc.Name, + Title: fmt.Sprintf("%s is owned by uid %d, but the container writes as uid %d", src, own, uid), + Evidence: []string{fmt.Sprintf("host: %s owner %d, mode %s", src, own, fi.Mode().Perm()), "image: runs as " + who}, + Fix: fmt.Sprintf("`sudo chown -R %d %s`, run the service with `user: \"%d\"`, or mount it read-only if it only reads.", uid, src, own), + Location: svc.Location.String(), + Predicts: "Permission denied", + }) + } + } + return out + }, +} diff --git a/pkg/preflight/rules/resources.go b/pkg/preflight/rules/resources.go new file mode 100644 index 0000000..1b0bf07 --- /dev/null +++ b/pkg/preflight/rules/resources.go @@ -0,0 +1,374 @@ +package rules + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/project" +) + +const mib = 1024 * 1024 + +// knownImage records hard host requirements of popular images that are not +// visible in their manifests. Each entry is tied to the error the image +// prints when the requirement is not met. +type knownImage struct { + match string + minMemory int64 + maxMapCount int64 + + // qemuCrash is the error printed when the image runs under QEMU + // user-mode emulation, which it does not support. + qemuCrash string + + skip func(env map[string]string) bool + predicts string +} + +var knownImages = []knownImage{ + { + match: "mssql/server", + minMemory: 2000 * mib, + qemuCrash: "sqlservr: Invalid mapping of address … in reserved address space below 0x400000000000", + predicts: "sqlservr: This program requires a machine with at least 2000 megabytes of memory.", + }, + { + match: "elasticsearch", + maxMapCount: 262144, + skip: singleNode, + predicts: "max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]", + }, + { + match: "opensearch", + maxMapCount: 262144, + skip: singleNode, + predicts: "max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]", + }, + { + match: "sonarqube", + maxMapCount: 262144, + predicts: "max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]", + }, +} + +// singleNode: Elasticsearch skips its bootstrap checks in single-node mode. +func singleNode(env map[string]string) bool { + return env["discovery.type"] == "single-node" +} + +// imagesOf returns the service image plus the external base images its +// build uses. +func imagesOf(svc *project.Service) []string { + var refs []string + if svc.Image != "" { + refs = append(refs, svc.Image) + } + if svc.Build != nil && svc.Build.Dockerfile != nil { + for _, st := range svc.Build.Dockerfile.Stages { + if st.BaseStage < 0 { + refs = append(refs, st.Base) + } + } + } + return refs +} + +func knownFor(ref string) []knownImage { + var out []knownImage + for _, k := range knownImages { + if strings.Contains(ref, k.match) { + out = append(out, k) + } + } + return out +} + +func known(svc *project.Service) []knownImage { + var out []knownImage + for _, ref := range imagesOf(svc) { + for _, k := range knownImages { + if strings.Contains(ref, k.match) && (k.skip == nil || !k.skip(svc.Environment)) { + out = append(out, k) + } + } + } + return out +} + +var memoryRule = rule{ + id: "resources.memory", + title: "Docker has enough memory for the services", + needs: []fact.ID{fact.Daemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + avail := h.MemTotal + where := fmt.Sprintf("host: Docker daemon has %s of memory", humanBytes(avail)) + if h.IsDesktop() && h.ClientMem > 0 { + where = fmt.Sprintf("host: Docker Desktop VM has %s (this machine has %s; containers only see the VM)", humanBytes(avail), humanBytes(h.ClientMem)) + } + var out []Finding + var total int64 + var parts []string + for _, svc := range env.Project.Services { + need := max(svc.MemReservation, svc.MemLimit) + reason := "limit/reservation" + for _, k := range known(svc) { + if k.minMemory > avail { + fix := "Give Docker more memory." + if h.IsDesktop() { + fix = "Raise Docker Desktop's memory (Settings → Resources) above " + humanBytes(k.minMemory) + "." + } + out = append(out, Finding{ + Rule: "resources.memory", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("%s needs at least %s of memory", k.match, humanBytes(k.minMemory)), + Evidence: []string{where}, + Fix: fix, + Location: svc.Location.String(), + Predicts: k.predicts, + }) + } + if k.minMemory > need { + need, reason = k.minMemory, "known minimum for "+k.match + } + } + if svc.MemLimit > avail { + out = append(out, Finding{ + Rule: "resources.memory", + Severity: fact.Warning, + Service: svc.Name, + Title: fmt.Sprintf("memory limit %s is larger than all memory Docker has", humanBytes(svc.MemLimit)), + Evidence: []string{where}, + Fix: "The limit cannot be reached; the kernel OOM-kills the container first. Lower the limit or give Docker more memory.", + Location: svc.Location.String(), + Predicts: "OOMKilled", + }) + } + if need > 0 { + n := int64(max(svc.Replicas, 1)) + total += need * n + parts = append(parts, fmt.Sprintf("%s %s×%d (%s)", svc.Name, humanBytes(need), n, reason)) + } + } + if total > avail { + sort.Strings(parts) + out = append(out, Finding{ + Rule: "resources.memory", + Severity: fact.Warning, + Title: fmt.Sprintf("services need %s together; Docker has %s", humanBytes(total), humanBytes(avail)), + Evidence: append([]string{where}, "project: "+strings.Join(parts, ", ")), + Fix: "Expect OOM kills under load. Give Docker more memory or run fewer services/replicas.", + Predicts: "OOMKilled / exit code 137", + }) + } + return out + }, +} + +// A registry reports compressed layer sizes; unpacked images are typically +// 2–3× larger. +const unpackFactor = 2.5 + +// VM engines need room on the host to boot and to grow their disk image. +const ( + vmMinFree = 2 << 30 + vmWarnFree = 10 << 30 +) + +var installerRule = rule{ + id: "host.installer", + title: "Docker Desktop runs from Applications", + needs: []fact.ID{fact.Daemon}, + check: func(_ context.Context, env *Env) []Finding { + if !env.Host.RunningFromInstaller { + return nil + } + return []Finding{{ + Rule: "host.installer", + Severity: fact.Warning, + Title: "Docker Desktop is running from its installer disk image", + Evidence: []string{"host: the Docker VM was started from /Volumes/…/Docker.app"}, + Fix: "Quit Docker Desktop, drag it to Applications, eject the Docker disk and start it from Applications. A copy started from the disk can keep the socket and hang every command.", + }} + }, +} + +var hostDiskRule = rule{ + id: "host.disk", + title: "This machine has room for Docker's VM", + needs: []fact.ID{fact.LocalDaemon}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + if !h.UsesVM() || h.ClientDiskFree == 0 || h.ClientDiskFree >= vmWarnFree { + return nil + } + f := Finding{ + Rule: "host.disk", + Severity: fact.Warning, + Title: fmt.Sprintf("only %s free on this machine; Docker's VM disk grows here", humanBytes(h.ClientDiskFree)), + Evidence: []string{"host: " + humanBytes(h.ClientDiskFree) + " free on the home volume"}, + Fix: "Free disk space (caches, old simulators, `docker system prune`). Keep at least 10 GiB free.", + } + if h.ClientDiskFree < vmMinFree { + f.Severity = fact.Error + f.Title = fmt.Sprintf("only %s free on this machine; Docker's VM cannot start or grow", humanBytes(h.ClientDiskFree)) + f.Predicts = "no space left on device / VM fails to start" + } + return []Finding{f} + }, +} + +var diskRule = rule{ + id: "resources.disk", + title: "Enough disk for the images to pull", + needs: []fact.ID{fact.LocalDaemon, fact.Registry, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + if h.DiskFree == 0 { + return nil + } + var compressed int64 + counted := map[string]bool{} + var biggest []string + for _, p := range Pulls(env.Project, h) { + key := ImageKey(p.Ref, p.Platform) + res := env.Images[key] + if p.Local || res.Err != nil || res.Image == nil || counted[key] { + continue + } + counted[key] = true + compressed += res.Image.CompressedSize + if res.Image.CompressedSize > 200*mib { + biggest = append(biggest, fmt.Sprintf("%s %s", p.Ref, humanBytes(res.Image.CompressedSize))) + } + } + need := int64(float64(compressed) * unpackFactor) + free := h.DiskFree + where := fmt.Sprintf("host: %s free", humanBytes(free)) + // A VM disk is a sparse file on this machine: it can only grow as + // far as the host volume allows. + if h.UsesVM() && h.ClientDiskFree > 0 && h.ClientDiskFree < free { + free = h.ClientDiskFree + where = fmt.Sprintf("host: VM disk has %s free, but this machine only %s", humanBytes(h.DiskFree), humanBytes(free)) + } + if !h.DiskExact && free == h.DiskFree { + where += " on this machine (Docker's VM disk may have less)" + } + evidence := []string{where, fmt.Sprintf("registry: %s to download, ≈%s unpacked", humanBytes(compressed), humanBytes(need))} + if len(biggest) > 0 { + evidence = append(evidence, "largest: "+strings.Join(biggest, ", ")) + } + switch { + case need > free: + return []Finding{{ + Rule: "resources.disk", + Severity: fact.Error, + Title: "not enough disk space to pull the images", + Evidence: evidence, + Fix: "Free space (`docker system prune`) or enlarge Docker's disk.", + Predicts: "no space left on device", + }} + case h.DiskExact && need > free*9/10: + return []Finding{{ + Rule: "resources.disk", + Severity: fact.Warning, + Title: "pulling the images will nearly fill the disk", + Evidence: evidence, + Fix: "Free space with `docker system prune`.", + }} + } + return nil + }, +} + +var gpuRule = rule{ + id: "resources.gpu", + title: "GPU requests can be satisfied", + needs: []fact.ID{fact.Daemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + h := env.Host + hasNvidia := false + for _, r := range h.Runtimes { + if strings.Contains(r, "nvidia") { + hasNvidia = true + } + } + var out []Finding + for _, svc := range env.Project.Services { + if !svc.GPU || hasNvidia { + continue + } + evidence := []string{"host: runtimes " + strings.Join(h.Runtimes, ", ") + " (no nvidia)"} + fix := "Install the NVIDIA Container Toolkit and restart Docker." + if h.ClientOS == "darwin" { + evidence = append(evidence, "host: Docker on macOS cannot pass GPUs to containers") + fix = "Run this service on a Linux or Windows host with an NVIDIA GPU, or make the GPU optional." + } + out = append(out, Finding{ + Rule: "resources.gpu", + Severity: fact.Error, + Service: svc.Name, + Title: "service requests a GPU this host cannot provide", + Evidence: evidence, + Fix: fix, + Location: svc.Location.String(), + Predicts: gpuError(h.ServerVersion), + }) + } + return out + }, +} + +// gpuError is the daemon's refusal: Docker 29 resolves GPUs through CDI +// and words it differently from earlier engines. +func gpuError(serverVersion string) string { + if serverVersion != "" && !versionLess(serverVersion, "29.0.0") { + return "failed to discover GPU vendor from CDI: no known GPU vendor found" + } + return `could not select device driver "" with capabilities: [[gpu]]` +} + +var sysctlRule = rule{ + id: "kernel.sysctl", + title: "Kernel settings meet image requirements", + needs: []fact.ID{fact.LocalDaemon, fact.ComposeFile}, + check: func(_ context.Context, env *Env) []Finding { + have, ok := env.Host.Sysctls["vm.max_map_count"] + var out []Finding + for _, svc := range env.Project.Services { + for _, k := range known(svc) { + if k.maxMapCount == 0 || (ok && have >= k.maxMapCount) { + continue + } + if !ok { + out = append(out, Finding{ + Rule: "kernel.sysctl", + Severity: fact.Warning, + Service: svc.Name, + Title: fmt.Sprintf("%s needs vm.max_map_count ≥ %d; could not read it on this host", k.match, k.maxMapCount), + Evidence: []string{"host: the daemon's kernel could not be inspected"}, + Fix: "Check with `sysctl vm.max_map_count` where the daemon runs.", + Location: svc.Location.String(), + Predicts: k.predicts, + }) + continue + } + out = append(out, Finding{ + Rule: "kernel.sysctl", + Severity: fact.Error, + Service: svc.Name, + Title: fmt.Sprintf("%s needs vm.max_map_count ≥ %d", k.match, k.maxMapCount), + Evidence: []string{fmt.Sprintf("host: vm.max_map_count = %d", have)}, + Fix: fmt.Sprintf("sudo sysctl -w vm.max_map_count=%d (persist it in /etc/sysctl.conf), or set discovery.type=single-node for development.", k.maxMapCount), + Location: svc.Location.String(), + Predicts: k.predicts, + }) + } + } + return out + }, +} diff --git a/pkg/preflight/rules/rule.go b/pkg/preflight/rules/rule.go new file mode 100644 index 0000000..6c6547a --- /dev/null +++ b/pkg/preflight/rules/rule.go @@ -0,0 +1,190 @@ +// Package rules holds the preflight rules. Each rule joins a project +// requirement with a host capability and predicts a concrete failure, +// quoting the evidence from both sides. +package rules + +import ( + "context" + "fmt" + "strings" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/host" + "github.com/raphgm/container-preflight/pkg/preflight/project" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +// Env is everything a rule may read. +type Env struct { + Project *project.Project + Host *host.Profile + Facts *fact.Set + + // Images holds registry lookups keyed by ImageKey. It is filled + // before rules run. + Images map[string]ImageResult +} + +type ImageResult struct { + Image *registry.Image + Err error +} + +func ImageKey(ref, platform string) string { + return registry.Canonical(ref) + "|" + registry.Normalize(platform) +} + +// Finding is one predicted failure (or risk), with the evidence behind it. +type Finding struct { + Rule string `json:"rule"` + Severity fact.Severity `json:"severity"` + Service string `json:"service,omitempty"` + Title string `json:"title"` + Evidence []string `json:"evidence,omitempty"` + Fix string `json:"fix,omitempty"` + Location string `json:"location,omitempty"` + + // Predicts is the error Docker would print, when known. It links the + // finding to real-world failure reports. + Predicts string `json:"predicts,omitempty"` +} + +// Rule checks one kind of project/host mismatch. +type Rule interface { + ID() string + Title() string + // Needs lists the facts that must be known for the rule to run. + Needs() []fact.ID + Check(ctx context.Context, env *Env) []Finding +} + +type rule struct { + id string + title string + needs []fact.ID + check func(ctx context.Context, env *Env) []Finding +} + +func (r rule) ID() string { return r.id } +func (r rule) Title() string { return r.title } +func (r rule) Needs() []fact.ID { return r.needs } +func (r rule) Check(ctx context.Context, env *Env) []Finding { return r.check(ctx, env) } + +// All returns every rule in report order. +func All() []Rule { + return []Rule{ + imageExistsRule, + imagePlatformRule, + credentialsRule, + buildContextRule, + buildKitRule, + composeFeaturesRule, + envRule, + memoryRule, + diskRule, + hostDiskRule, + installerRule, + gpuRule, + sysctlRule, + portConflictRule, + hostPortRule, + bindRule, + permissionsRule, + fileSharingRule, + } +} + +// hostPlatform is the daemon's platform, or this machine's when the daemon +// is unknown (they match for local Docker Desktop, Colima and Engine). +func hostPlatform(h *host.Profile) string { + if h.Platform != "" { + return h.Platform + } + return "linux/" + h.ClientArch +} + +// Pull is an image Docker will fetch for a service: either the service image +// or a base image of a build stage that BuildKit will actually build. +type Pull struct { + Service string + Ref string + Platform string + Explicit bool + Base bool + Location project.Location + + // Local is true when the image is already in the daemon, so Compose + // will not pull it. Its platform still matters. + Local bool +} + +// Pulls lists every image the project uses, for the platform Docker will +// request. +func Pulls(p *project.Project, h *host.Profile) []Pull { + var out []Pull + seen := map[string]bool{} + add := func(pl Pull) { + pl.Local = h.LocalImages[registry.Canonical(pl.Ref)] + key := pl.Service + "|" + ImageKey(pl.Ref, pl.Platform) + if !seen[key] { + seen[key] = true + out = append(out, pl) + } + } + native := hostPlatform(h) + + for _, svc := range p.Services { + targets := []string{native} + explicit := false + if svc.Platform != "" { + targets, explicit = []string{svc.Platform}, true + } else if svc.Build != nil && len(svc.Build.Platforms) > 0 { + targets, explicit = svc.Build.Platforms, true + } + + if svc.Image != "" { + for _, t := range targets { + add(Pull{Service: svc.Name, Ref: svc.Image, Platform: t, Explicit: explicit, Location: svc.Location}) + } + } + if svc.Build == nil || svc.Build.Dockerfile == nil { + continue + } + df := svc.Build.Dockerfile + reach, err := df.Reachable(svc.Build.Target) + if err != nil { + continue + } + for _, i := range reach { + st := df.Stages[i] + if st.BaseStage >= 0 || strings.EqualFold(st.Base, "scratch") || st.Unresolved() { + continue + } + for _, t := range targets { + pl, exp := t, explicit + switch { + case strings.Contains(st.Platform, "BUILDPLATFORM"): + pl, exp = native, true + case strings.Contains(st.Platform, "TARGETPLATFORM"): + case st.Platform != "" && !strings.Contains(st.Platform, "$"): + pl, exp = st.Platform, true + } + add(Pull{Service: svc.Name, Ref: st.Base, Platform: pl, Explicit: exp, Base: true, Location: st.Location}) + } + } + } + return out +} + +func humanBytes(n int64) string { + const unit = 1024 + if n < unit { + return fmt.Sprintf("%d B", n) + } + div, exp := int64(unit), 0 + for m := n / unit; m >= unit; m /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %ciB", float64(n)/float64(div), "KMGTPE"[exp]) +} diff --git a/pkg/preflight/rules/rules_test.go b/pkg/preflight/rules/rules_test.go new file mode 100644 index 0000000..7843d75 --- /dev/null +++ b/pkg/preflight/rules/rules_test.go @@ -0,0 +1,510 @@ +package rules + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/raphgm/container-preflight/pkg/preflight/fact" + "github.com/raphgm/container-preflight/pkg/preflight/host" + "github.com/raphgm/container-preflight/pkg/preflight/project" + "github.com/raphgm/container-preflight/pkg/preflight/registry" +) + +func load(t *testing.T, files map[string]string) *project.Project { + t.Helper() + dir := t.TempDir() + for name, content := range files { + p := filepath.Join(dir, name) + if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(p, []byte(content), 0o644); err != nil { + t.Fatal(err) + } + } + facts := fact.NewSet() + p, err := project.Load(context.Background(), dir, facts) + if err != nil { + t.Fatal(err) + } + if r, ok := facts.Root(fact.ComposeFile); ok { + t.Fatalf("compose load failed: %s", r.Detail) + } + return p +} + +// armDesktop is a MacBook running Docker Desktop with 4 GiB for the VM. +func armDesktop() *host.Profile { + return &host.Profile{ + ClientOS: "darwin", ClientArch: "arm64", ClientMem: 16 << 30, + Platform: "linux/arm64", OperatingSystem: "Docker Desktop", + MemTotal: 4 << 30, Runtimes: []string{"runc"}, + ComposeVersion: "2.29.1", BuildxInstalled: true, + Emulated: []string{"linux/amd64"}, EmulationKnown: true, + Sysctls: map[string]int64{"vm.max_map_count": 262144}, + Local: true, DiskFree: 50 << 30, + LocalImages: map[string]bool{}, PublishedPorts: map[string][]host.Container{}, + } +} + +// oldLinux is an amd64 server with distro packages and default sysctls. +func oldLinux() *host.Profile { + return &host.Profile{ + ClientOS: "linux", ClientArch: "amd64", + Platform: "linux/amd64", OperatingSystem: "Ubuntu 20.04", + MemTotal: 8 << 30, Runtimes: []string{"runc"}, + ComposeVersion: "1.29.2", EmulationKnown: true, + Sysctls: map[string]int64{"vm.max_map_count": 65530}, + Local: true, DiskFree: 2 << 30, DiskExact: true, + LocalImages: map[string]bool{}, PublishedPorts: map[string][]host.Container{}, + } +} + +// fakeRegistry answers from a table: ref -> platforms (prefix "single:" for a +// single-platform image), or an error. +type fakeRegistry map[string]string + +func (f fakeRegistry) Resolve(_ context.Context, ref, platform string) (*registry.Image, error) { + v, ok := f[ref] + if !ok { + return nil, fmt.Errorf("%w: %s", registry.ErrNotFound, ref) + } + if v == "401" { + return nil, fmt.Errorf("%w: %s", registry.ErrUnauthorized, ref) + } + img := ®istry.Image{Ref: ref, Index: true, CompressedSize: 500 << 20} + if u, rest, ok := strings.Cut(v, "|user="); ok { + v, img.User = u, rest + } + if s, ok := strings.CutPrefix(v, "single:"); ok { + img.Index, v = false, s + } + img.Platforms = strings.Split(v, ",") + return img, nil +} + +func run(t *testing.T, r Rule, p *project.Project, h *host.Profile, reg fakeRegistry) []Finding { + t.Helper() + env := &Env{Project: p, Host: h, Facts: fact.NewSet(), Images: map[string]ImageResult{}} + for _, pl := range Pulls(p, h) { + img, err := reg.Resolve(context.Background(), pl.Ref, pl.Platform) + env.Images[ImageKey(pl.Ref, pl.Platform)] = ImageResult{img, err} + } + return r.Check(context.Background(), env) +} + +func titles(fs []Finding) string { + var out []string + for _, f := range fs { + out = append(out, string(f.Severity)+": "+f.Title) + } + return strings.Join(out, "\n") +} + +func expect(t *testing.T, fs []Finding, sev fact.Severity, substr string) { + t.Helper() + for _, f := range fs { + if f.Severity == sev && strings.Contains(f.Title, substr) { + return + } + } + t.Errorf("want %s finding containing %q, got:\n%s", sev, substr, titles(fs)) +} + +func expectNone(t *testing.T, fs []Finding) { + t.Helper() + if len(fs) > 0 { + t.Errorf("want no findings, got:\n%s", titles(fs)) + } +} + +var multiArch = "linux/amd64,linux/arm64" + +func TestImagePlatform(t *testing.T) { + p := load(t, map[string]string{"compose.yaml": `services: + db: {image: "mcr.microsoft.com/mssql/server:2022-latest"} + legacy: {image: "acme/amd64-index:1"} + pinned: {image: "acme/amd64-index:1", platform: linux/amd64} + ok: {image: "postgres:16"} +`}) + reg := fakeRegistry{ + "mcr.microsoft.com/mssql/server:2022-latest": "single:linux/amd64", + "acme/amd64-index:1": "linux/amd64", + "postgres:16": multiArch, + } + + fs := run(t, imagePlatformRule, p, armDesktop(), reg) + expect(t, fs, fact.Warning, "mssql/server:2022-latest will run under linux/amd64 emulation") + expect(t, fs, fact.Error, "acme/amd64-index:1 has no linux/arm64 variant") + expect(t, fs, fact.Warning, "acme/amd64-index:1 will run under linux/amd64 emulation") // pinned + if len(fs) != 3 { + t.Errorf("postgres should pass; got:\n%s", titles(fs)) + } + + noEmu := armDesktop() + noEmu.OperatingSystem, noEmu.Emulated = "Ubuntu 24.04", nil + fs = run(t, imagePlatformRule, p, noEmu, reg) + expect(t, fs, fact.Error, "is linux/amd64 only and this host cannot run it") + + colima := armDesktop() + colima.OperatingSystem, colima.Emulators = "Ubuntu 24.04", map[string]string{"linux/amd64": "qemu"} + fs = run(t, imagePlatformRule, p, colima, reg) + expect(t, fs, fact.Error, "mssql/server:2022-latest crashes under QEMU linux/amd64 emulation") + + rosetta := armDesktop() + rosetta.Emulators = map[string]string{"linux/amd64": "rosetta"} + expect(t, run(t, imagePlatformRule, p, rosetta, reg), fact.Warning, "mssql/server:2022-latest will run under linux/amd64 emulation") + + unknown := armDesktop() + unknown.OperatingSystem, unknown.Emulated, unknown.EmulationKnown = "Ubuntu 24.04", nil, false + fs = run(t, imagePlatformRule, p, unknown, reg) + expect(t, fs, fact.Warning, "could not tell whether this host emulates it") + if strings.Contains(titles(fs), "cannot run it") { + t.Error("unknown emulation must not be reported as a certain failure") + } + + expectNone(t, run(t, imagePlatformRule, p, oldLinux(), reg)) +} + +func TestBaseImagesOfBuildsAreChecked(t *testing.T) { + p := load(t, map[string]string{ + "compose.yaml": "services:\n app: {build: .}\n", + "Dockerfile": `FROM --platform=$BUILDPLATFORM golang:1.23 AS build +FROM acme/amd64-index:1 AS unused +FROM acme/runtime:1 +`, + }) + reg := fakeRegistry{"golang:1.23": multiArch, "acme/runtime:1": "linux/amd64", "acme/amd64-index:1": "linux/amd64"} + fs := run(t, imagePlatformRule, p, armDesktop(), reg) + expect(t, fs, fact.Error, "base image acme/runtime:1 has no linux/arm64 variant") + if strings.Contains(titles(fs), "amd64-index") { + t.Error("unreachable stage must not be checked") + } +} + +func TestImageExists(t *testing.T) { + p := load(t, map[string]string{"compose.yaml": `services: + a: {image: "redis:7.9.99"} + b: {image: "acme/private:1"} + c: {image: "redis:7"} +`}) + h := armDesktop() + h.LocalImages[registry.Canonical("redis:7")] = true + fs := run(t, imageExistsRule, p, h, fakeRegistry{"acme/private:1": "401"}) + expect(t, fs, fact.Error, "redis:7.9.99 does not exist") + expect(t, fs, fact.Warning, "acme/private:1 is private or does not exist") + if len(fs) != 2 { + t.Errorf("local image must not be looked up:\n%s", titles(fs)) + } +} + +func TestBuildContext(t *testing.T) { + p := load(t, map[string]string{ + "compose.yaml": `services: + web: {build: ./web} + api: {build: {context: ./api, target: nope}} + gone: {build: ./missing} +`, + "web/Dockerfile": `FROM node:20 AS build +COPY package.json yarn.lock ./ +COPY .env ./ +COPY ../shared ./shared +FROM nginx +COPY --from=build /app /app +COPY dist/ /usr/share/nginx/html +`, + "web/package.json": "{}", + "web/.env": "", + "web/.dockerignore": ".env\n", + "api/Dockerfile": "FROM alpine AS base\n", + }) + fs := run(t, buildContextRule, p, armDesktop(), nil) + expect(t, fs, fact.Error, `COPY source "yarn.lock" not found`) + expect(t, fs, fact.Error, `COPY source ".env" is excluded by .dockerignore`) + expect(t, fs, fact.Error, `"../shared" is outside the build context`) + expect(t, fs, fact.Error, `COPY source "dist/" not found`) + expect(t, fs, fact.Error, `build target "nope" is not a stage`) + expect(t, fs, fact.Error, "build context missing does not exist") + if strings.Contains(titles(fs), "package.json") { + t.Error("existing file flagged") + } +} + +func TestBuildKit(t *testing.T) { + p := load(t, map[string]string{ + "compose.yaml": "services:\n app: {build: .}\n", + "Dockerfile": "FROM alpine\nRUN --mount=type=cache,target=/c true\nCOPY --chmod=755 x /x\nRUN <