ActiveJob-only k8s deployment, thin base image#73764
Open
carl-codeorg wants to merge 13 commits into
Open
Conversation
Signed-off-by: Nick Lathe <nick.lathe@code.org>
Planning artifacts only, no implementation. Six OpenSpec changes covering the docker image rework (rails-way multi-stage targets, thin runtime composition), the k8s process model, secrets rotation, a devcontainer, and CI seeded-DB snapshots. Each change has proposal/design/specs/tasks and validates with `openspec validate`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds an ActiveJob-only Skaffold deployment path and restructures the k8s Docker image lineage around a slim official Ruby base image.
The image hierarchy now follows the Rails-style split:
base: runtime OS packages only, fromruby:3.2.11-slim-bookwormbuild: compiler/toolchain layer used for bundle, uv, and frontend build workruntime: non-root production image with built artifacts and no dev toolchaindev: same base plus local development tools such as build-essential, Node, Chromium, zsh, and awscliIt also adds an
activejob-onlySkaffold profile that builds a smaller runtime image with the frontend build skipped and a narrower Bundler group set. This gives us a working path for ActiveJob experiments without carrying the full frontend asset build through each iteration. This PR doesn't get a cold Skaffold build to complete within the 20-minute goal, but I figured we should start committing some of these base changes first before continuing to iterate.The changes to the base image were generated using Codex 5.5 following an OpenSpec design from Fable 5.
Details
ruby:3.2.11-slim-bookworm.libjemalloc2and an arch-independentLD_PRELOADpath.devtarget mutable.bootsnapout of the development-only Gemfile group and precompiles bootsnap caches during image build.skaffold build -p mimic --cache-artifacts=falsestill validates Dockerfile changes.uv, missing JS runtime behavior for ActiveJob, and zsh assumptions in container commands.Changes to the main Dashboard app
Most of this PR is scoped to the
k8sdirectory, making it very safe in general. However, there are two changes outside of k8s:Bootsnap moved out of dev dependencies in the Gemfile. If there is a reason we need to keep this as a dev dependency, let me know. Otherwise, it seems the modern Rails way is to use Bootsnap to speed up the boot process in production. The Rails-generated Dockerfiles do this. Summary of what we get from using bootsnap outside of dev:
development.rband the Prosopite initializer changed to check forGem.loaded_specs.key?('prosopite'). This avoids situations where the development Rails config is loaded, but the prosopite gem is missing because ofBUNDLE_WITHOUT=development:testbeing set during Docker build.Validation
skaffold dev --trigger=manual -p activejob-only -p setup-db-minimalskaffold build --cache-artifacts=falseskaffold build -p mimic --cache-artifacts=falsebundle installwith native-extension coverage and one dashboardspring testunitdivesize comparison recordedopenspec validate docker-rails-way-image --strictgit diff --check./tools/hooks/pre-commitNotes
The generic cold
skaffold build --cache-artifacts=falsecompleted, but build time is still not acceptable long-term. Measured wall clock was8223.02s; most of the time was spent in Bundler, especially arounddevise_invitable. This PR accepts that as follow-up work because the new image structure is functional and compatible with the existing Skaffold workflow.Ruby 3.2 is still past upstream EOL. This PR pins the slim image digest and makes a later Ruby 3.4 upgrade much smaller, but it does not perform that upgrade.
Image size improvements from switching to a ruby-slim base instead of Ubuntu:
code-dot-orgcode-dot-org-coreactive-job-onlyLinks
Testing story
Deployment notes
Privacy and security