.dockerignore doesn't honor subdirectory exclusion patterns
Expected Behaviour
When using a .dockerfile as follows:
*
!example2
!example4/nested
!example5/example5.txt
!index.js
The above directories and files should be included in the build context.
Actual Behaviour
example4/nested directory and example5/example5.txt are missing
Steps to Reproduce Define this test in checkout of repo:
import path from "path";
import { GenericContainer } from "./generic-container";
describe("GenericContainer", () => {
jest.setTimeout(180_000);
const fixtures = path.resolve(__dirname, "..", "..", "fixtures", "docker");
it("should honour .dockerignore file", async () => {
// ARRANGE
const context = path.resolve(fixtures, "docker-with-dockerignore");
const container = await GenericContainer.fromDockerfile(context).build();
const startedContainer = await container.withExposedPorts(8080).start();
const { output } = await startedContainer.exec(["find"]);
console.log(output)
expect(output).toContain("example2.txt");
expect(output).toContain("example4.txt");
expect(output).toContain("example5.txt");
expect(output).not.toContain("example6.txt");
await startedContainer.stop();
});
});
Update .dockerignore in testcontainers-node-main/packages/testcontainers/fixtures/docker/docker-with-dockerignore/.dockerignore with:
*
!example2
!example4/nested
!example5/example5.txt
!index.js
The test will fail with:
GenericContainer › should honour .dockerignore file
expect(received).toContain(expected) // indexOf
Expected substring: "example4.txt"
Received string: ".
./example2
./example2/example2.txt
./index.js
./Dockerfile
"
18 |
19 | expect(output).toContain("example2.txt");
> 20 | expect(output).toContain("example4.txt");
| ^
21 | expect(output).toContain("example5.txt");
22 | expect(output).not.toContain("example6.txt");
Debug notes
It seems like tar.pack is the issue, as it doesn't go into subdirectories:
testcontainers [DEBUG] jonjam: For path ".dockerignore" isIgnored: true +2ms
testcontainers [DEBUG] jonjam: For path "example1.txt" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "example2" isIgnored: false +0ms
testcontainers [DEBUG] jonjam: For path "example3" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "example4" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "example5" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "example6" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "example7" isIgnored: true +1ms
testcontainers [DEBUG] jonjam: For path "exist1.txt" isIgnored: true +0ms
testcontainers [DEBUG] jonjam: For path "index.js" isIgnored: false +0ms
testcontainers [DEBUG] jonjam: For path "example2/example2.txt" isIgnored: false +3ms
Thanks for raising a detailed issue @JonJam, I can also reproduce it.
Looks like the dockerignore function from @balena/dockerignore works correctly by adding the correct rule, but the callback from tar.pack does not give the full path (example7/nested/file.txt), only the enclosing dir (example7/nested) which does not result in a match.
No problem @cristianrgreco.
Sorry I forgot to add a note that I confirmed @balena/dockerignore works as expected in a node playground :)