In https://github.com/jupyter/repo2docker/pull/829 the legacy buildpack (LegacyBinderDockerBuildPack) is removed, but actually it can still be used in binder config folder, because detect method only checks the Dockerfile at the root:
was this on purpose? Or should we create a PR and change it to check Dockerfile in binder_dir?
Btw I know this is not a realistic usecase, but if a repo contains
this will also throws error saying that legacy buildpack is removed, but actually it should pick python buildpack.
I think it should not check for Dockerfile in binder_dir, since that never worked for the legacy buildpack, but it should probably add:
if self.binder_dir:
return False
before checking the top-level Dockerfile contents to make sure legacy is never used if binder_dir is present.
Should we add this special casing? Everywhere else in repo2docker we have the "rule" that "if there is a Dockerfile it is used, nothing else counts". Here we'd start inverting that "Dockerfile wins, unless it is a legacy one, and your have config files in a binder sub-directory, but not if the config isn't in a sub-directory." (or something like that) The point being it is more complex than the current rule.
I'm wondering if there is a reason for repo owners wanting to keep the legacy Dockerfile instead of deleting it when they don't want to use it any more. If there is no use-case for keeping it I'd vote for a solution that encourages people to remove the legacy Dockerfile as a solution to problems/weird behaviour.
tl;dr: I think the logic we have now is right, and we shouldn't make any changes.
Everywhere else in repo2docker we have the "rule" that "if there is a Dockerfile it is used, nothing else counts"
Not quite, because binder_dir takes top priority and determines how we check "if there is a Dockerfile". If a binder directory exists, we consider no files outside this directory, even Dockerfiles.
The logic (excluding Legacy) is more like:
which results in the effective priority:
binder/Dockerfilebinder/requirements.txt/Dockerfilei.e. the presence of binder/requirements.txt means top-level Dockerfile is and should be ignored. However, we currently special-case top-level Dockerfile matching the legacy Dockerfile pattern as the actual first priority, taking precedence over the presence of the binder directory.
Should we add this special casing?
I think special-casing legacy makes sense, since it is, somewhat by definition, a special case. The goal of the Legacy buildpack is to keep some fraction of old pre-repo2docker Binder repos working, and not use any of the newer repo2docker logic in that case.
Stepping back, I think the logic for picking legacy should be:
Is this repo built for the old Binder, before repo2docker was a thing?
So the question is really, in the presence of a top-level Dockerfile that looks like it was built for the old Binder, does the presence of a .binder or binder directory indicate that the repo has been updated for repo2docker instead of the old Binder? It's ambiguous because we have an old Dockerfile but also a newer binder directory with other files.
Case for using Legacy in this situation:
binder with no special meaning for the old binder,Case for not using Legacy in this situation:
Now that I think of it, our current logic makes more sense than the change I proposed for two reasons:
To make this change, we would be enabling a new partial transition from Binder v1 to repo2docker without dropping support for the old way, which hasn't been operation for a couple of years now.
Most helpful comment
I think it should not check for
Dockerfilein binder_dir, since that never worked for the legacy buildpack, but it should probably add:before checking the top-level Dockerfile contents to make sure legacy is never used if binder_dir is present.