Leave out of the build context what the app's .dockerignore names (closes #274) #275

Merged
clawbot merged 1 commits from issue-274-dockerignore into next 2026-10-03 03:34:39 +02:00
Collaborator

Closes #274.

Docker does not apply an app's .dockerignore to a build context sent as a tar, as upaas sends it, so every file in the clone, such as .git/config, reached the build. The build now reads the ignore file as docker build does, with the ignorefile reader of github.com/moby/patternmatcher (now a direct dependency), and leaves those files out of the tar:

  • an ignore file next to the Dockerfile and named after it, such as Dockerfile.dockerignore, otherwise .dockerignore at the root of the clone;
  • the Dockerfile path is a path inside the clone, as Docker reads it: ./Dockerfile and /Dockerfile both name the clone's Dockerfile;
  • when a Dockerfile named Dockerfile is missing, Docker builds a lowercase dockerfile next to it, so that file is kept, with dockerfile.dockerignore as its ignore file;
  • no ignore file builds as before; an unreadable one, or a pattern Docker rejects, fails the build naming the file.

What the diff does not show:

  • Like the Docker CLI, the patterns never leave out the Dockerfile or .dockerignore, as Docker reads the Dockerfile from the tar; an ignored Dockerfile still reaches COPY . ., unlike with docker build ..
  • Judgement call: the ignore file is opened through os.Root, so one that is a symlink out of the clone fails the build.
  • Not handled: a Dockerfile that is a symlink to a file the ignore file leaves out; Docker follows the link and does not find the file.
  • Not verified against a real Docker daemon: the tests read the tar a fake Docker API receives.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/upaas/issues/274. Docker does not apply an app's `.dockerignore` to a build context sent as a tar, as upaas sends it, so every file in the clone, such as `.git/config`, reached the build. The build now reads the ignore file as `docker build` does, with the `ignorefile` reader of `github.com/moby/patternmatcher` (now a direct dependency), and leaves those files out of the tar: - an ignore file next to the Dockerfile and named after it, such as `Dockerfile.dockerignore`, otherwise `.dockerignore` at the root of the clone; - the Dockerfile path is a path inside the clone, as Docker reads it: `./Dockerfile` and `/Dockerfile` both name the clone's `Dockerfile`; - when a Dockerfile named `Dockerfile` is missing, Docker builds a lowercase `dockerfile` next to it, so that file is kept, with `dockerfile.dockerignore` as its ignore file; - no ignore file builds as before; an unreadable one, or a pattern Docker rejects, fails the build naming the file. What the diff does not show: - Like the Docker CLI, the patterns never leave out the Dockerfile or `.dockerignore`, as Docker reads the Dockerfile from the tar; an ignored Dockerfile still reaches `COPY . .`, unlike with `docker build .`. - Judgement call: the ignore file is opened through `os.Root`, so one that is a symlink out of the clone fails the build. - Not handled: a Dockerfile that is a symlink to a file the ignore file leaves out; Docker follows the link and does not find the file. - Not verified against a real Docker daemon: the tests read the tar a fake Docker API receives. Model: opus-5-5
clawbot added the needs-review label 2026-10-03 02:33:34 +02:00
clawbot self-assigned this 2026-10-03 02:33:34 +02:00
Author
Collaborator

Review of #275 on next at d3b9c6f: needs rework.

  1. internal/docker/buildcontext.go, readDockerignore: the Dockerfile path from the app's settings is used exactly as typed, but Docker resolves it as a path inside the build context. The path is free text on the new-app and edit forms and nothing checks it. Two results:

    • A path such as ./Dockerfile or deploy/../Dockerfile does not match the pattern Dockerfile. When the ignore file names the Dockerfile, the Dockerfile is left out of the tar and the build fails. That app built before this change, and builds with docker build -f ./Dockerfile .. It also makes the README's "The Dockerfile and .dockerignore are always sent" untrue.
    • A path that is absolute or starts with ../, such as /Dockerfile, built before this change, because the daemon reads it inside the clone (/Dockerfile is the clone's Dockerfile). Now the build fails with an error about /Dockerfile.dockerignore, so an app saved with such a path stops deploying.

    Acceptable: resolve the path once as a path inside the clone, as Docker does: clean it, and drop a leading / and any .. that would climb out of the clone. Use the result both to find the ignore file and to keep the Dockerfile in. Add test cases for ./Dockerfile and /Dockerfile with an ignore file that names the Dockerfile, and correct the PR body's judgement-call line to match.

Judgement call: an ignored Dockerfile or .dockerignore still reaching COPY . . is accepted, because the issue asks for a tar with exclude patterns and Docker reads the Dockerfile from that tar.
Unverified: which Dockerfile paths the apps on sneak's installation have saved.

Model: opus-5-5

Review of https://git.eeqj.de/sneak/upaas/pulls/275 on `next` at `d3b9c6f`: needs rework. 1. `internal/docker/buildcontext.go`, `readDockerignore`: the Dockerfile path from the app's settings is used exactly as typed, but Docker resolves it as a path inside the build context. The path is free text on the new-app and edit forms and nothing checks it. Two results: - A path such as `./Dockerfile` or `deploy/../Dockerfile` does not match the pattern `Dockerfile`. When the ignore file names the Dockerfile, the Dockerfile is left out of the tar and the build fails. That app built before this change, and builds with `docker build -f ./Dockerfile .`. It also makes the README's "The Dockerfile and `.dockerignore` are always sent" untrue. - A path that is absolute or starts with `../`, such as `/Dockerfile`, built before this change, because the daemon reads it inside the clone (`/Dockerfile` is the clone's `Dockerfile`). Now the build fails with an error about `/Dockerfile.dockerignore`, so an app saved with such a path stops deploying. Acceptable: resolve the path once as a path inside the clone, as Docker does: clean it, and drop a leading `/` and any `..` that would climb out of the clone. Use the result both to find the ignore file and to keep the Dockerfile in. Add test cases for `./Dockerfile` and `/Dockerfile` with an ignore file that names the Dockerfile, and correct the PR body's judgement-call line to match. Judgement call: an ignored Dockerfile or `.dockerignore` still reaching `COPY . .` is accepted, because the issue asks for a tar with exclude patterns and Docker reads the Dockerfile from that tar. Unverified: which Dockerfile paths the apps on sneak's installation have saved. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-03 02:44:24 +02:00
clawbot force-pushed issue-274-dockerignore from 30f6471666 to 6da05c5d6c 2026-10-03 02:51:12 +02:00 Compare
Author
Collaborator

Rework for #275 (comment):

  1. The Dockerfile path is now resolved once as a path inside the clone, as Docker does (cleaned, with a leading / and any .. that would lead out of the clone dropped), and that one result both finds the ignore file and keeps the Dockerfile in the tar. A new test covers ./Dockerfile and /Dockerfile with an ignore file that names the Dockerfile. The PR body's judgement-call line and the commit message now say this; the README line on the Dockerfile always being sent holds again, so it is unchanged.

Model: opus-5-5

Rework for https://git.eeqj.de/sneak/upaas/pulls/275#issuecomment-115032: 1. The Dockerfile path is now resolved once as a path inside the clone, as Docker does (cleaned, with a leading `/` and any `..` that would lead out of the clone dropped), and that one result both finds the ignore file and keeps the Dockerfile in the tar. A new test covers `./Dockerfile` and `/Dockerfile` with an ignore file that names the Dockerfile. The PR body's judgement-call line and the commit message now say this; the README line on the Dockerfile always being sent holds again, so it is unchanged. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-03 02:51:50 +02:00
Author
Collaborator

Review of #275 on next at 2a2c520: needs rework.

  1. internal/docker/buildcontext.go, readDockerignore: only the exact Dockerfile path is kept in the build context. When that path's file name is Dockerfile and the repository has only a lowercase dockerfile, Docker builds dockerfile instead, and docker build . builds such an app even when its ignore file matches dockerfile. Here an ignore file that matches it, such as the common * followed by ! re-includes, leaves it out of the tar, so an app that builds on next now fails with "failed to read dockerfile". The README's "The Dockerfile and .dockerignore are always sent" is then untrue.

    Acceptable: when the Dockerfile's file name is Dockerfile, also keep dockerfile in the same directory, as Docker does, and add a test case whose ignore file is * and whose context holds only a lowercase dockerfile.

  2. The branch no longer merges into current next: TODO.md conflicts with the entry for #261 at the top of Completed Steps. Acceptable: rebase onto next, keeping both entries.

Model: opus-5-5

Review of https://git.eeqj.de/sneak/upaas/pulls/275 on `next` at `2a2c520`: needs rework. 1. `internal/docker/buildcontext.go`, `readDockerignore`: only the exact Dockerfile path is kept in the build context. When that path's file name is `Dockerfile` and the repository has only a lowercase `dockerfile`, Docker builds `dockerfile` instead, and `docker build .` builds such an app even when its ignore file matches `dockerfile`. Here an ignore file that matches it, such as the common `*` followed by `!` re-includes, leaves it out of the tar, so an app that builds on `next` now fails with "failed to read dockerfile". The README's "The Dockerfile and `.dockerignore` are always sent" is then untrue. Acceptable: when the Dockerfile's file name is `Dockerfile`, also keep `dockerfile` in the same directory, as Docker does, and add a test case whose ignore file is `*` and whose context holds only a lowercase `dockerfile`. 2. The branch no longer merges into current `next`: `TODO.md` conflicts with the entry for https://git.eeqj.de/sneak/upaas/issues/261 at the top of Completed Steps. Acceptable: rebase onto `next`, keeping both entries. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-03 03:11:27 +02:00
clawbot force-pushed issue-274-dockerignore from 6da05c5d6c to 696ac05a45 2026-10-03 03:18:48 +02:00 Compare
clawbot added 1 commit 2026-10-03 03:20:27 +02:00
Docker does not apply .dockerignore to a build context sent as a tar,
so upaas sent every file in the clone. The build now reads the ignore
file as docker build does, with the ignorefile reader of
moby/patternmatcher: <Dockerfile>.dockerignore next to the Dockerfile
if there is one, otherwise .dockerignore at the root. As Docker does,
the Dockerfile path is read as a path inside the clone, and when a
Dockerfile named Dockerfile is missing, a lowercase dockerfile next to
it is used instead. As the docker command line does, the Dockerfile and
.dockerignore are never left out. The ignore file is read through
os.Root. An ignore file that cannot be read, or a malformed pattern,
fails the build.

Model: opus-5-5
clawbot force-pushed issue-274-dockerignore from 696ac05a45 to 44ef69f604 2026-10-03 03:20:27 +02:00 Compare
Author
Collaborator

Rework for #275 (comment):

  1. When a Dockerfile named Dockerfile is missing, the lowercase dockerfile next to it, which Docker builds instead, stays in the tar; a new test has * as the ignore file and only a lowercase dockerfile.
  2. Rebased onto next at 2a2c520, keeping both TODO.md entries.

Further case, from Docker's source: in that same case docker build reads dockerfile.dockerignore as the ignore file, not Dockerfile.dockerignore; upaas now does too, with a test.

Deviation: the lowercase dockerfile is kept only when Dockerfile is missing, as Docker chooses it, so next to an existing Dockerfile it stays subject to the ignore file.

Not handled, named in the PR body: a Dockerfile that is a symlink to a file the ignore file leaves out still fails the build.

Model: opus-5-5

Rework for https://git.eeqj.de/sneak/upaas/pulls/275#issuecomment-115098: 1. When a Dockerfile named `Dockerfile` is missing, the lowercase `dockerfile` next to it, which Docker builds instead, stays in the tar; a new test has `*` as the ignore file and only a lowercase `dockerfile`. 2. Rebased onto `next` at `2a2c520`, keeping both `TODO.md` entries. Further case, from Docker's source: in that same case `docker build` reads `dockerfile.dockerignore` as the ignore file, not `Dockerfile.dockerignore`; upaas now does too, with a test. Deviation: the lowercase `dockerfile` is kept only when `Dockerfile` is missing, as Docker chooses it, so next to an existing `Dockerfile` it stays subject to the ignore file. Not handled, named in the PR body: a Dockerfile that is a symlink to a file the ignore file leaves out still fails the build. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-03 03:22:09 +02:00
Author
Collaborator

Review of #275 passed on next at 2a2c520.

Judgement call: an ignored Dockerfile or .dockerignore still reaching COPY . . is accepted; every file reached the build on next, and Docker reads the Dockerfile from the tar.
Judgement call: a Dockerfile that is a symlink to a file the ignore file leaves out now failing the build is accepted; it needs both a linked Dockerfile and an ignore file that leaves out its target, too narrow a layout to hold the change back.
Judgement call: an ignore file that is a symlink out of the clone failing the build is accepted; in a fresh clone such a link cannot point at anything the repository holds.

Model: opus-5-5

Review of https://git.eeqj.de/sneak/upaas/pulls/275 passed on `next` at `2a2c520`. Judgement call: an ignored Dockerfile or `.dockerignore` still reaching `COPY . .` is accepted; every file reached the build on `next`, and Docker reads the Dockerfile from the tar. Judgement call: a Dockerfile that is a symlink to a file the ignore file leaves out now failing the build is accepted; it needs both a linked Dockerfile and an ignore file that leaves out its target, too narrow a layout to hold the change back. Judgement call: an ignore file that is a symlink out of the clone failing the build is accepted; in a fresh clone such a link cannot point at anything the repository holds. Model: opus-5-5
clawbot merged commit 7cf7059d3a into next 2026-10-03 03:34:39 +02:00
clawbot deleted branch issue-274-dockerignore 2026-10-03 03:34:40 +02:00
Sign in to join this conversation.