Image: .dockerignore patterns match only at the root, so local builds send and ship the downloaded datasets and every __pycache__ #1141
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#1141
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What exists today
.dockerignore:6(data),:12(__pycache__) and:13(*.py[cod]) are matched relative to the context root, as Docker's.dockerignorerules say (Gofilepath.Matchper path,**needed for any depth). So they exclude./dataand a root__pycache__only.Measured in the working tree:
src/postulo/jobs/datais 71 MB, of which only the licence notes andnace-2.1.json(177 KB) are tracked; the rest isesco-1.2.1.json(6.4 MB),esco-skills-1.2.1.zip(4.7 MB),geonames-cities1000.txt(32 MB),geonames-countryinfo.txtandgeonames-cities1000.sqlite(30.5 MB), written byfetch_escoandfetch_geonames. The__pycache__directories undersrctotal about 12.5 MB (du).Correction to the candidate: the cost is not only the context sent.
docker/Dockerfile:92(COPY src ./src) and:293(COPY --from=build /app/src ./src) carry those files into the runtime image, where nothing reads them (the image reads GeoNames and ESCO from/app/data/geonamesand/app/data/esco,:160-161).docker compose -f docker/compose.yml -f docker/compose.build.yml up --buildandscripts/check-image.shboth build from the working tree, so a source install made on a machine that has run the app ships 71 MB of dead data. Thestylesstage'sCOPY srcat:33copies them as well. CI checks out a clean tree, so the published images are not affected.Side finding:
geonames-cities1000.sqlite(src/postulo/jobs/places.py:55,LOOKUP_FILE) is not in.gitignore;git statusshows it untracked (??)..gitignore:48-55lists the ESCO files andgeonames-*.txtbut notgeonames-*.sqlite(norgeonames-postcodes.sqlite,places.py:62), so a carelessgit add -Awould commit 30 MB.What would change
.dockerignore:**/__pycache__,**/*.py[cod], and the dataset files by path:src/postulo/jobs/data/esco-*andsrc/postulo/jobs/data/geonames-*(the trackednace-2.1.jsonand licence notes stay).**/node_modulesand**/.pytest_cachewhile there..gitignore: add/src/postulo/jobs/data/geonames-*.sqlite.tests/test_image_build.pythat every dataset pattern undersrc/in.gitignorehas a matching.dockerignoreline would keep the two together.What it saves or protects
small-medium: on a developer machine with the datasets fetched, 71 MB of GeoNames and ESCO files plus about 12.5 MB of
__pycache__undersrcgo into the build context and, throughCOPY src, into the local image; CI images are unaffectedAccessibility
none
Decisions
.gitignoreline is the same class of mistake.Found by the efficiency and reliability audit of 2026-10-30 (finding I5; index postulo/postulo#1108). Checked against
mainatdaee30b15(2026-10-30).