Skip to content

Conversation

@alco
Copy link
Member

@alco alco commented Jan 20, 2026

Summary

  • Creates a unique, per-platform Dockerfile path so Blacksmith uses separate sticky disks for image layer caching
  • Without this, caches produced by builds for different platforms trample each other and only the last written cache persists

Problem

When building multi-platform Docker images (amd64 and arm64), both platform builds use the same Dockerfile path. Blacksmith's sticky disk caching keys on the Dockerfile path, causing the caches to overwrite each other. Only one platform benefits from caching in subsequent builds.

Evidence from run #21174363588

This run happened immediately after run #21173980401 where both platforms had successfully built. Despite both caches being freshly populated, only one platform could use its cache:

amd64 build (cache HIT) — most build steps are CACHED:

#10 CACHED
#11 [builder  6/17] COPY mix.* /builder/electric/
#11 CACHED
#12 [builder 10/17] COPY lib /builder/electric/lib/
#12 CACHED
#13 [builder  3/17] RUN mix local.hex --force && mix local.rebar --force
#13 CACHED
#14 [builder  8/17] RUN MIX_OS_DEPS_COMPILE_PARTITION_COUNT=4 mix deps.compile
#14 CACHED
#15 [builder  9/17] COPY rel /builder/electric/rel
#15 CACHED
...

arm64 build (cache MISS) — expensive steps like mix deps.compile run from scratch:

#10 [builder  2/17] RUN apt-get update -y && ...
#10 CACHED
#11 [builder  3/17] RUN mix local.hex --force && mix local.rebar --force
#11 CACHED
#12 CACHED
#13 [builder  5/17] COPY --from=electric-telemetry / /builder/electric-telemetry
#14 [builder  6/17] COPY mix.* /builder/electric/
#15 [builder  7/17] RUN mix deps.get
#16 [builder  8/17] RUN MIX_OS_DEPS_COMPILE_PARTITION_COUNT=4 mix deps.compile
#17 [builder  9/17] COPY rel /builder/electric/rel
...

The arm64 build had to run mix deps.compile (~60s) while amd64 got it from cache.

Solution

Create a unique Dockerfile path per platform by prepending a cache scope comment:

/tmp/sync-service.Dockerfile.amd64
/tmp/sync-service.Dockerfile.arm64

This ensures Blacksmith treats each platform's build cache independently.

Summary by CodeRabbit

  • Chores
    • Improved multi-platform Docker build caching by isolating per-platform build files to prevent cross-platform cache interference and speed up builds.
    • Updated Docker image publishing to target a different image repository namespace and adjusted CI publishing configuration accordingly.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Swaps Docker Hub targets and credentials to ALCO-specific repos/secrets and adds a CI step that creates a per-platform temporary Dockerfile (path exported via SYNC_SERVICE_DOCKERFILE) so the multi-arch build step consumes a platform-specific Dockerfile for isolated caching and publishing.

Changes

Cohort / File(s) Change Summary
GitHub Actions Workflow — Sync Service Docker Build
.github/workflows/sync_service_dockerhub_image.yml
Replaced Docker Hub repo names with alco variants and switched login secrets to DOCKERHUB_USERNAME_ALCO/DOCKERHUB_TOKEN_ALCO. Added a CI-only step that writes a per-platform temporary Dockerfile, exports its path via SYNC_SERVICE_DOCKERFILE, and updated the build/publish steps to consume that file per-platform.

Sequence Diagram(s)

sequenceDiagram
  participant GH as GitHub Actions
  participant Prep as Dockerfile Prep Step
  participant Build as Docker Buildx (per-platform)
  participant DH as Docker Hub

  GH->>Prep: run per-platform step\ncreate temporary Dockerfile\nexport SYNC_SERVICE_DOCKERFILE
  GH->>Build: invoke buildx with\nfile=SYNC_SERVICE_DOCKERFILE\nbuild per-platform images
  Build->>DH: login using ALCO secrets\npush images (per-platform / multi-arch)
  DH-->>Build: acknowledge push
  Build-->>GH: report status
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

Possibly related PRs

Suggested reviewers

  • balegas
  • msfstef

Poem

🐰 I hopped into CI with cheer,
Per-platform Dockerfiles appear,
Caches stay tidy, builds run clear,
Push to ALCO — hop, no fear! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: creating per-platform Dockerfiles for proper Docker image layer caching, which is the core objective of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.41%. Comparing base (9be9e74) to head (21fc809).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #3747       +/-   ##
===========================================
+ Coverage   75.75%   87.41%   +11.66%     
===========================================
  Files          11       23       +12     
  Lines         693     2011     +1318     
  Branches      171      528      +357     
===========================================
+ Hits          525     1758     +1233     
- Misses        167      251       +84     
- Partials        1        2        +1     
Flag Coverage Δ
packages/experimental 87.73% <ø> (ø)
packages/react-hooks 86.48% <ø> (ø)
packages/start 82.83% <ø> (ø)
packages/typescript-client 93.55% <ø> (?)
packages/y-electric 56.05% <ø> (ø)
typescript 87.41% <ø> (+11.66%) ⬆️
unit-tests 87.41% <ø> (+11.66%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alco
Copy link
Member Author

alco commented Jan 20, 2026

Note to self: need to test it before merging by temporarily substituting my own Docker Hub repo and confirmed the caching behaviour by creating a few runs of the workflow.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/sync_service_dockerhub_image.yml:
- Around line 168-169: Replace the temporary Docker Hub credentials used in the
workflow (the username and password fields referencing
secrets.DOCKERHUB_USERNAME_ALCO and DOCKERHUB_TOKEN_ALCO) with the production
secrets; update the username and password entries to point to the canonical
production secret names (the same ones used in the build job) so the workflow
uses the proper production DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets before
merging.
- Around line 114-115: Replace the temporary personal Docker Hub secrets used in
the workflow: change the username and password values that reference
DOCKERHUB_USERNAME_ALCO and DOCKERHUB_TOKEN_ALCO back to the production secrets
(restore the original secret names used for CI/CD). Edit the username/password
entries in the sync_service_dockerhub_image.yml workflow (the lines providing
username: and password:) to reference the correct production secret identifiers
instead of DOCKERHUB_USERNAME_ALCO and DOCKERHUB_TOKEN_ALCO.
- Around line 26-27: The DOCKERHUB_REPO and DOCKERHUB_CANARY_REPO environment
variables currently point to a personal account; change them back to the
official production repositories by replacing DOCKERHUB_REPO: alco/electric with
DOCKERHUB_REPO: electricsql/electric and DOCKERHUB_CANARY_REPO:
alco/electric-canary with DOCKERHUB_CANARY_REPO: electricsql/electric-canary
(update the values wherever DOCKERHUB_REPO or DOCKERHUB_CANARY_REPO appear in
the workflow file).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73374da and 21fc809.

📒 Files selected for processing (1)
  • .github/workflows/sync_service_dockerhub_image.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build_and_push_image (linux/arm64/v8, arm64, blacksmith-4vcpu-ubuntu-2404-arm)
  • GitHub Check: Test packages/typescript-client w/ sync-service
  • GitHub Check: Test packages/experimental w/ sync-service
  • GitHub Check: Test packages/start w/ sync-service
  • GitHub Check: Test packages/react-hooks w/ sync-service
  • GitHub Check: Test packages/y-electric w/ sync-service
  • GitHub Check: Run Lux integration tests
🔇 Additional comments (2)
.github/workflows/sync_service_dockerhub_image.yml (2)

117-130: Core caching solution looks good.

The approach of prepending a platform-specific # blacksmith-cache-scope comment creates unique Dockerfile paths per platform, which should give Blacksmith separate sticky disks for layer caching. The use of set -euo pipefail ensures failures are properly caught.


137-137: Correctly references the per-platform Dockerfile.

The build step properly consumes the SYNC_SERVICE_DOCKERFILE environment variable set in the previous step, ensuring each platform build uses its unique Dockerfile path.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +26 to +27
DOCKERHUB_REPO: alco/electric
DOCKERHUB_CANARY_REPO: alco/electric-canary
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Revert temporary Docker Hub repositories before merging.

These point to a personal Docker Hub account (alco/*) instead of the official electricsql/* repositories. Per the commit message, this is intentionally temporary for testing. Ensure these are reverted to the production values before merge.

-  DOCKERHUB_REPO: alco/electric
-  DOCKERHUB_CANARY_REPO: alco/electric-canary
+  DOCKERHUB_REPO: electricsql/electric
+  DOCKERHUB_CANARY_REPO: electricsql/electric-canary
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
DOCKERHUB_REPO: alco/electric
DOCKERHUB_CANARY_REPO: alco/electric-canary
DOCKERHUB_REPO: electricsql/electric
DOCKERHUB_CANARY_REPO: electricsql/electric-canary
🤖 Prompt for AI Agents
In @.github/workflows/sync_service_dockerhub_image.yml around lines 26 - 27, The
DOCKERHUB_REPO and DOCKERHUB_CANARY_REPO environment variables currently point
to a personal account; change them back to the official production repositories
by replacing DOCKERHUB_REPO: alco/electric with DOCKERHUB_REPO:
electricsql/electric and DOCKERHUB_CANARY_REPO: alco/electric-canary with
DOCKERHUB_CANARY_REPO: electricsql/electric-canary (update the values wherever
DOCKERHUB_REPO or DOCKERHUB_CANARY_REPO appear in the workflow file).

Comment on lines +114 to +115
username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Revert temporary credentials before merging.

These use personal secrets (DOCKERHUB_USERNAME_ALCO, DOCKERHUB_TOKEN_ALCO) instead of the production credentials. Revert to the original secrets.

-          username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
-          password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
+          username: ${{ secrets.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
🤖 Prompt for AI Agents
In @.github/workflows/sync_service_dockerhub_image.yml around lines 114 - 115,
Replace the temporary personal Docker Hub secrets used in the workflow: change
the username and password values that reference DOCKERHUB_USERNAME_ALCO and
DOCKERHUB_TOKEN_ALCO back to the production secrets (restore the original secret
names used for CI/CD). Edit the username/password entries in the
sync_service_dockerhub_image.yml workflow (the lines providing username: and
password:) to reference the correct production secret identifiers instead of
DOCKERHUB_USERNAME_ALCO and DOCKERHUB_TOKEN_ALCO.

Comment on lines +168 to +169
username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Revert temporary credentials before merging.

Same as the build job—revert to production secrets.

-          username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
-          password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
+          username: ${{ secrets.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
username: ${{ secrets.DOCKERHUB_USERNAME_ALCO }}
password: ${{ secrets.DOCKERHUB_TOKEN_ALCO }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
🤖 Prompt for AI Agents
In @.github/workflows/sync_service_dockerhub_image.yml around lines 168 - 169,
Replace the temporary Docker Hub credentials used in the workflow (the username
and password fields referencing secrets.DOCKERHUB_USERNAME_ALCO and
DOCKERHUB_TOKEN_ALCO) with the production secrets; update the username and
password entries to point to the canonical production secret names (the same
ones used in the build job) so the workflow uses the proper production
DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets before merging.

@alco
Copy link
Member Author

alco commented Jan 21, 2026

The first manual test has shown that this "fix" doesn't solve the problem.

@alco alco marked this pull request as draft January 21, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants