Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider utilizing parameterized Dockerfiles as a means to reduce duplication #231

Open
MichaelSimons opened this issue Jan 16, 2020 · 3 comments

Comments

@MichaelSimons
Copy link
Member

Investigate whether or not utilizing parameterized Dockerfiles would reduce the amount of duplication and ease the maintenance cost of the Dockerfiles. It may help increase the developer productivity.

An example of this would be to parameterize the Alpine base image tag within the Alpine Helix Dockerfiles. The base image tag appears to be the only thing different between the various versions

alpine 3.11 amd64 vs alpine 3.10 amd64

The FROM image argument value can be specified within the manifest.

@am11
Copy link
Member

am11 commented Sep 3, 2021

First of all, my +1 for proposing to DRY stuff in this repo, it is getting baggy by day, and I think it is possible to accomplish true DRY'ness while maintaining the tidiness/readability.

After experimented a few approaches in CI runs of recent PRs and seeing what is and isn't possible/supported, I have a few ideas that I'd like to share, which I believe would scale with a few moving parts.

Here are my 2 cents...

There are two kinds of duplicates which I think worth pursuing:

  1. docker commands; which we solve with WithNode and helix relying on (otherwise useless) amd64 base image.
  • Solution: for this, we can (and in this day and age, should) use one physical Dockerfile with multi-stages, without needing to publish an intermediate/base container to the registry.
  1. dependency list per OS (across versions x architectures with minor exceptions here and there).
  • Background: Dockerfile grammar does not provide INCLUDE or more accurately PASTE idioms for templating OOTB. Their official guidance for syntax extensibility is that we can create our own custom ones in frontend, use # syntax directive in Dockerfile and define some custom semantics on top, which sounds too much (maintenance) work for (relatively) a little gain.
  • Solution: given the above situation, the most natural thing to use is preprocessor, which any C compiler on any platform can expand (think e.g. an #include "../helix_common_dependencies" line in a Dockerfile.in). The semantics of preprocessor are well-established, well-documented and well-understood including its limitations, but it quite adequately fulfills what we need here. Using this we can describe the whole platform matrix as chain of logical partial files and calling clang -E Dockerfile.in -D SomeThingReadFrom_manifest_json... to expand/emit the real Dockerfiles on-the-fly (which will be .gitignore'd) before invoking buildx etc. This likely has zero negative effects on caching. This will deduplicate it all and only requires a good, understandable logical structuring of (partial) files; which we anyway have to do with other options.

@mthalman
Copy link
Member

mthalman commented Sep 3, 2021

Note that our infrastructure does now have support for Dockerfile templates and are being used by the dotnet/dotnet-docker and microsoft/dotnet-framework-docker repos. See documentation and example template.

@am11
Copy link
Member

am11 commented Sep 10, 2021

Great! I can attempt to convert Alpine 3.13 and 3.14 to use the templates and DRY out the repetitions.
Most like would need your help, @mthalman on passing build-time vars correctly. :)

I presume Alpine 3.12 and below can probably be deleted, based on https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md#linux; that .NET 6 only supports Alpine 3.13+?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

No branches or pull requests

3 participants