From 130a81b98825f879577ce3adc690730eba3f330e Mon Sep 17 00:00:00 2001 From: Antoine Toussaint <312536060+antoinetoussaint-byte@users.noreply.github.com> Date: Wed, 21 Oct 2026 12:29:31 -0400 Subject: [PATCH] fix(builder): the uvicorn logging files are written into the project, where the build context is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #99 wrote uvicorn-log-config.json and codefly_uvicorn_logging.py into the render directory and COPY'd them from the context root; the build context is the service directory (or the assembled copy of it), so every image build failed at that COPY. They are now written into the project before any context is assembled — exactly where a native start writes them — and copied from code/ beside src. Co-Authored-By: Claude Fable 5.1 --- build_recipe_test.go | 2 ++ builder.go | 13 ++++++++----- templates/builder/Dockerfile.tmpl | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/build_recipe_test.go b/build_recipe_test.go index 82f4730..64518db 100644 --- a/build_recipe_test.go +++ b/build_recipe_test.go @@ -196,5 +196,7 @@ func TestBuildShipsSiblingPackages(t *testing.T) { "COPY --chown=appuser code/src code/src", "COPY --chown=appuser code/adapters code/adapters", "COPY --chown=appuser code/model_service code/model_service", + // uvicorn's logging configuration and filter, written by the builder (uvicorn_logging.go). + "COPY --chown=appuser code/uvicorn-log-config.json code/codefly_uvicorn_logging.py ./", }, copies) } diff --git a/builder.go b/builder.go index 63e1384..d1bca72 100644 --- a/builder.go +++ b/builder.go @@ -216,6 +216,14 @@ func (s *Builder) Build(ctx context.Context, req *builderv0.BuildRequest) (*buil // A project that is a member of a uv workspace in the service is built from // that workspace, copied whole (see enclosingUVWorkspace); its path sources // must then stay inside the service the context carries. + // uvicorn's logging configuration and its filter module, written into the + // project exactly as a native start writes them, before any context is + // assembled from it: the build context is the service directory (or the + // assembled copy of it), and the Dockerfile copies them from code/ beside + // src (uvicorn_logging.go). + if err := writeUvicornLogging(s.SourceLocation); err != nil { + return s.Base.Builder.BuildError(err) + } membership, err := enclosingUVWorkspace(s.Location, s.SourceLocation) if err != nil { return s.Base.Builder.BuildError(err) @@ -259,11 +267,6 @@ func (s *Builder) Build(ctx context.Context, req *builderv0.BuildRequest) (*buil if err := s.Base.Templates(ctx, docker, services.WithBuilder(builderFS).WithDestination("%s", outputDir)); err != nil { return s.Base.Builder.BuildError(err) } - // uvicorn's logging configuration and its filter module, which the - // Dockerfile copies beside the code (uvicorn_logging.go). - if err := writeUvicornLogging(outputDir); err != nil { - return s.Base.Builder.BuildError(err) - } image := s.DockerImage(dockerRequest).FullName() if assembled == nil { // Only the Dockerfile and its ignore were written, and the application's diff --git a/templates/builder/Dockerfile.tmpl b/templates/builder/Dockerfile.tmpl index d32b544..7424678 100644 --- a/templates/builder/Dockerfile.tmpl +++ b/templates/builder/Dockerfile.tmpl @@ -76,8 +76,8 @@ WORKDIR /app/code # uvicorn's logging configuration and the filter it names (uvicorn_logging.go): # health probes are dropped from the access log, everything else is as uvicorn -# writes it. Both files are rendered into the build context by the builder. -COPY --chown=appuser uvicorn-log-config.json codefly_uvicorn_logging.py ./ +# writes it. The builder writes both into the project before the build. +COPY --chown=appuser {{.ServicePrefix}}code/uvicorn-log-config.json {{.ServicePrefix}}code/codefly_uvicorn_logging.py ./ # Default REST port (overridden by codefly at runtime). CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8080", "--log-config", "uvicorn-log-config.json"]