Docker image: fetch_esco writes into the root-owned source tree, so the documented install step fails #411
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#411
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?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading the image build against the install guide's ESCO step.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atjobs/models.py:974(JobPosting.save);jobs/esco.py,jobs/places.py,fetch_esco.py,docker/Dockerfileanddocker/entrypoint.shhave not changed.The ESCO classification is read from, and written to, a directory beside the code, and nothing lets an operator move it. In the image that directory belongs to root while the container runs as
postulo, so the command the install guide tells every Docker operator to run cannot write its files. GeoNames met the same problem and was givenPOSTULO_GEOLOCATIONS_DIRon the data volume; ESCO was not.jobs/esco.py:84(DATA_DIR = Path(__file__).resolve().parent / "data", no environment override, unlikejobs/places.py:37-39);jobs/management/commands/fetch_esco.py:162-172(Command.handlewritesesco-<revision>.json.tmpandesco-skills-<revision>.zipintoDATA_DIR);docker/Dockerfile:266-267(COPY --from=build /app/src ./src, no--chown, so root-owned);docker/Dockerfile:322-329(only/app/datais given topostulo, thenUSER postulo);docker/entrypoint.sh:22-30(fetches GeoNames only); wikiInstalling-Postulo.md:10,:94,:321-324.docker compose -f docker/compose.yml exec postulo python manage.py fetch_esco --revision 1.2.1. The command runs aspostulo, harvests the whole classification (the guide says about half a minute), then fails with aPermissionErrorwriting into/app/src/postulo/jobs/data. From then on no listing title gets an ISCO-08 code (JobPosting.save,jobs/models.py:971), the title box offers no unit groups and the skill box offers nothing. An operator who works around it withexec -u rootwrites into the container layer: the files are gone at the nextdocker compose pull && up -d, and theworkerandschedulercontainers ofdocker/compose.yml, which run the same image separately, never have them, so a listing saved by the worker (a capture) gets no code.docker/Dockerfile:271-272, "the running container should not need to write to its own image") andplaces.py:36repeats.POSTULO_ESCO_DIRinesco.DATA_DIR(or one variable for both reference datasets), defaulting to the package directory for a source install; set it to/app/data/escoin the Dockerfile'sENVblock besidePOSTULO_GEOLOCATIONS_DIR, and create the directory with the other/app/dataones. Optionally fetch it in the entrypoint when absent, with a failure logged and not fatal, as for GeoNames. Then correctInstalling-Postulo.md: the files live on the data volume and survive a pull, so the "run the line again" advice at:97-98and:321-324goes.Done when
tests/test_esco.pyhas a test that setsPOSTULO_ESCO_DIR, reloadspostulo.jobs.escoand findsDATA_DIRthere; it fails today.tests/test_image_build.pyhas a test that the Dockerfile setsPOSTULO_ESCO_DIRunder/app/data; it fails today.