basecamp / kamal

Deploy web apps anywhere.
https://kamal-deploy.org
MIT License
9.41k stars 362 forks source link

Build from a git archive #700

Closed djmb closed 3 months ago

djmb commented 4 months ago

Building directly from a checkout will pull in uncommitted files, or more sneakily, files that are git ignored, but not docker ignored.

To avoid this, we'll add an option to build from a git archive of HEAD instead. Docker doesn't provide a way to build directly from a git repo, so instead we create a tarball of the current HEAD with git archive and pipe it into the build command.

When building from a git archive, we'll still display the warning about uncommitted changes, but we won't add the _uncommitted_... suffix to the container name as they won't be included in the build.

~Perhaps this should be the default, but we'll leave that decision for now.~

Actually after some thought, I think we should make this the default if no build context is set, then we don't need a new option, and if someone wants to retain the existing behaviour they can set the context to ..

Fixes: https://github.com/basecamp/kamal/issues/524 (and H/T @byroot for the suggestion).

99linesofcode commented 2 months ago

This is a bit implicit and could be documented more clearly somehow.

voberoi commented 2 months ago

This also broke my build. Would be great to clearly document this.

In my case I rely on a script to generate a couple of files for me pre-build, and they need to be in the builder context.

Adding this to config did what I needed:

builder:
  context: "."
jpdombrowski commented 2 months ago

Are you aware that this leads to .dockerignore not being applied?

djmb commented 2 months ago

Ah I wasn't aware no - @jpdombrowski, but you are right - see https://github.com/docker/buildx/issues/2353. Not an issue if .dockerignore is a subset of .gitignore but its probably not wise to assume that. May need to rethink this change 😬

byroot commented 2 months ago

I don't follow. if .dockerignore is committed, it should end up in the archive, no?

jpdombrowski commented 2 months ago

It ends ends up in the archive, but the build context piped in as a git archive tarball is not processed the same way as when building from local files using docker build ..

I just noticed my image size growing and investigated.

Personally would revert this for now, because its highly unexpected behaviour that could easily go unnoticed. That .dockerignore is a subset of .gitignore is likely rare (.gitignore is often included in .dockerignore)

byroot commented 2 months ago

Personally would revert this for now, because its highly unexpected behaviour that could easily go unnoticed.

I'm sure there must be a way to make the dockerignore file work. Reverting means going back to potentially building with git ignored (potentially secrets) or uncommitted changes. Which is just as bad if not worse.

djmb commented 2 months ago

Ok, going to try https://github.com/basecamp/kamal/pull/798 instead and build from a local clone.

A bit annoying that it will leave some state around, even if it's in a tmpdir, but docker does seem to be a bit faster about generating the build context on subsequent builds from a directory so we get something out of it.

@99linesofcode, @voberoi - it will now log about using the clone directory and if there are uncommitted changes it will warn you about whether they are being included or excluded. Hopefully that's a bit better than before.