Skip to content

fix: Support custom Dockerfiles in devcontainer builds with --replace#1855

Merged
aknysh merged 5 commits intomainfrom
osterman/devcontainer-dockerfile-fix
Dec 10, 2025
Merged

fix: Support custom Dockerfiles in devcontainer builds with --replace#1855
aknysh merged 5 commits intomainfrom
osterman/devcontainer-dockerfile-fix

Conversation

@osterman
Copy link
Copy Markdown
Member

@osterman osterman commented Dec 10, 2025

What

  • Support rebuilding devcontainer images from Dockerfile with --replace flag
  • Simplify Dockerfile using official install script for automatic version/platform detection
  • Add comprehensive test coverage for rebuild operations
  • Fix error message formatting to properly wrap YAML examples in code fences
  • Add new example atmos.yaml showing devcontainer with custom Dockerfile configuration

Why

The --replace flag now properly handles custom Dockerfile builds, allowing users to rebuild their custom images when they make changes to their Dockerfile. The install script simplification eliminates complexity and ensures automatic detection of Atmos version and platform architecture.

References

Closes support for reproducible custom devcontainer builds with Geodesic base images.

Summary by CodeRabbit

  • New Features

    • Added support for building custom devcontainers from Dockerfiles with inline build configuration.
    • Introduced top-level devcontainer configuration structure in atmos.yaml.
    • Enhanced --replace flag with conditional rebuild behavior for custom Dockerfile builds.
  • Documentation

    • Added Quick Start section and updated devcontainer examples.
    • Updated shell command documentation with Dockerfile rebuild scenarios.
    • Improved example configuration with new devcontainer structure.
  • Bug Fixes

    • Fixed code fence handling to prevent double-wrapping in examples.
    • Optimized image pulling to avoid failures for locally built devcontainer images.

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

@osterman osterman requested review from a team as code owners December 10, 2025 16:35
@github-actions github-actions bot added the size/m Medium size PR label Dec 10, 2025
@mergify
Copy link
Copy Markdown

mergify bot commented Dec 10, 2025

Important

Cloud Posse Engineering Team Review Required

This pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes.

To expedite this process, reach out to us on Slack in the #pr-reviews channel.

@mergify mergify bot added the needs-cloudposse Needs Cloud Posse assistance label Dec 10, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 10, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

osterman and others added 2 commits December 10, 2025 10:45
- Simplify Dockerfile using official install.sh script for automatic version/platform detection
- Add buildImageIfNeeded() to rebuild images from Dockerfile when using build configuration
- Update devcontainer example documentation with quick start guide
- Add test coverage for rebuild with custom Dockerfile builds
- Fix error message formatting in ErrorBuilder to wrap examples in code fences

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
When using a build configuration (Dockerfile), the image is built locally
and doesn't exist in any remote registry. Pulling after building fails
with "unable to copy from source docker://localhost/...".

This fix skips the pull step when an image was just built locally.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@osterman osterman force-pushed the osterman/devcontainer-dockerfile-fix branch from 4842e48 to 1e8a00c Compare December 10, 2025 16:45
@osterman osterman changed the title feat: Support custom Dockerfiles in devcontainer builds with --replace fix: Support custom Dockerfiles in devcontainer builds with --replace Dec 10, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 10, 2025

Caution

Review failed

The head commit changed during the review from 9ccbad2 to 6655b13.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/devcontainer-dockerfile-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

osterman and others added 2 commits December 10, 2025 10:52
The go-licenses tool generates incorrect URL for
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 by appending v2/ to
the path, but the LICENSE.txt is actually at internal/endpoints/LICENSE.txt

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 10, 2025

Caution

Review failed

The head commit changed during the review from 1e8a00c to 9ccbad2.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/devcontainer-dockerfile-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.12%. Comparing base (d07d554) to head (6655b13).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1855      +/-   ##
==========================================
+ Coverage   73.09%   73.12%   +0.03%     
==========================================
  Files         550      550              
  Lines       53168    53176       +8     
==========================================
+ Hits        38862    38884      +22     
+ Misses      11449    11436      -13     
+ Partials     2857     2856       -1     
Flag Coverage Δ
unittests 73.12% <100.00%> (+0.03%) ⬆️

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

Files with missing lines Coverage Δ
errors/formatter.go 89.36% <100.00%> (+0.23%) ⬆️
pkg/devcontainer/lifecycle_rebuild.go 88.88% <100.00%> (+0.88%) ⬆️
pkg/devcontainer/operations.go 89.04% <100.00%> (-0.04%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@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: 2

🧹 Nitpick comments (1)
examples/devcontainer-build/README.md (1)

50-50: Convert emphasis to headings for proper document structure.

Lines 50 and 58 use bold emphasis for "Option 1" and "Option 2", but these should be formatted as markdown headings (###) instead. This improves document semantics, accessibility, and enables proper table-of-contents generation.

Apply this diff:

-**Option 1: Include devcontainer.json file**
+### Option 1: Include devcontainer.json file
-**Option 2: Define build configuration inline**
+### Option 2: Define build configuration inline

Also applies to: 58-58

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d07d554 and 9ccbad2.

📒 Files selected for processing (10)
  • errors/formatter.go (1 hunks)
  • examples/devcontainer-build/Dockerfile (1 hunks)
  • examples/devcontainer-build/README.md (3 hunks)
  • examples/devcontainer-build/atmos.yaml (1 hunks)
  • examples/devcontainer-build/devcontainer.json (1 hunks)
  • pkg/devcontainer/lifecycle_rebuild.go (1 hunks)
  • pkg/devcontainer/lifecycle_rebuild_test.go (1 hunks)
  • pkg/devcontainer/operations.go (1 hunks)
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx (4 hunks)
  • website/docs/cli/commands/devcontainer/shell.mdx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • pkg/devcontainer/operations.go
  • errors/formatter.go
  • pkg/devcontainer/lifecycle_rebuild.go
  • pkg/devcontainer/lifecycle_rebuild_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/devcontainer/operations.go
  • pkg/devcontainer/lifecycle_rebuild.go
  • pkg/devcontainer/lifecycle_rebuild_test.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/docs/cli/commands/devcontainer/shell.mdx
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
website/docs/cli/commands/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

All CLI commands need Docusaurus documentation using <dl> for arguments/flags. Follow Docusaurus conventions: frontmatter (slug, title, etc.), purpose note, screengrab, usage/examples/arguments/flags sections. File location: website/docs/cli/commands/<command>/<subcommand>.mdx. Always build after changes: cd website && npm run build

Files:

  • website/docs/cli/commands/devcontainer/shell.mdx
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Use assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • pkg/devcontainer/lifecycle_rebuild_test.go
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts require YAML front matter with slug, title, authors, and tags. Use <!--truncate--> after intro. ONLY use existing tags from website/blog/*.mdx - check before writing. Author field must be GitHub username, added to website/blog/authors.yml. Filename format: YYYY-MM-DD-feature-name.mdx. PRs labeled minor/major MUST include blog post

Files:

  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
🧠 Learnings (27)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 801
File: examples/quick-start-advanced/Dockerfile:9-9
Timestamp: 2024-11-23T00:13:22.004Z
Learning: When updating the `ATMOS_VERSION` in Dockerfiles, the team prefers to pin to the next future version when the PR merges, even if the version is not yet released.
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.

Applied to files:

  • pkg/devcontainer/operations.go
📚 Learning: 2024-12-12T15:17:45.245Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos.d/atmos.d/tools/helmfile.yml:10-10
Timestamp: 2024-12-12T15:17:45.245Z
Learning: In `examples/demo-atmos.d/atmos.d/tools/helmfile.yml`, when suggesting changes to `kubeconfig_path`, ensure that the values use valid Go template syntax.

Applied to files:

  • pkg/devcontainer/operations.go
  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*.go : Embed examples from `cmd/markdown/*_usage.md` using `//go:embed`. Render with `utils.PrintfMarkdown()`

Applied to files:

  • errors/formatter.go
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/README.md
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/devcontainer.json
  • examples/devcontainer-build/Dockerfile
  • examples/devcontainer-build/README.md
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
📚 Learning: 2025-01-08T19:01:32.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/test-vendor/test-components/main.tf:1-7
Timestamp: 2025-01-08T19:01:32.938Z
Learning: In the examples/tests directory of the atmos project, code examples are intentionally kept minimal and simple to facilitate understanding. Avoid suggesting additional complexity or validations that might make the examples harder to follow.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/README.md
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/README.md
📚 Learning: 2024-11-12T03:15:15.627Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 775
File: examples/quick-start-advanced/Dockerfile:9-9
Timestamp: 2024-11-12T03:15:15.627Z
Learning: It is acceptable to set `ARG ATMOS_VERSION` to a future version like `1.105.0` in `examples/quick-start-advanced/Dockerfile` if that will be the next release.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/devcontainer.json
  • examples/devcontainer-build/Dockerfile
  • examples/devcontainer-build/README.md
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/Dockerfile
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/Dockerfile
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.yaml : NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
  • examples/devcontainer-build/README.md
📚 Learning: 2025-09-24T20:45:40.401Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: tests/fixtures/scenarios/atmos-auth/stacks/deploy/nonprod.yaml:3-4
Timestamp: 2025-09-24T20:45:40.401Z
Learning: In Atmos stack files, the correct syntax for importing other stack files is `import:` (singular), not `imports:` (plural). All stack files in the Atmos codebase consistently use `import:` followed by a list of paths to import.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-01-19T22:30:27.600Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-01-19T22:30:27.600Z
Learning: The Atmos YAML function `!include` allows downloading local or remote files from different sources and assigning their contents to sections in stack manifests. It supports various protocols (file, http, git, s3, etc.) and can filter content using YQ expressions.

Applied to files:

  • examples/devcontainer-build/atmos.yaml
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands need Docusaurus documentation using `<dl>` for arguments/flags. Follow Docusaurus conventions: frontmatter (slug, title, etc.), purpose note, screengrab, usage/examples/arguments/flags sections. File location: `website/docs/cli/commands/<command>/<subcommand>.mdx`. Always build after changes: `cd website && npm run build`

Applied to files:

  • website/docs/cli/commands/devcontainer/shell.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • website/docs/cli/commands/devcontainer/shell.mdx
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • pkg/devcontainer/lifecycle_rebuild_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • pkg/devcontainer/lifecycle_rebuild_test.go
📚 Learning: 2024-11-23T00:13:22.004Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 801
File: examples/quick-start-advanced/Dockerfile:9-9
Timestamp: 2024-11-23T00:13:22.004Z
Learning: When updating the `ATMOS_VERSION` in Dockerfiles, the team prefers to pin to the next future version when the PR merges, even if the version is not yet released.

Applied to files:

  • examples/devcontainer-build/Dockerfile
  • examples/devcontainer-build/README.md
  • website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • examples/devcontainer-build/Dockerfile
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • examples/devcontainer-build/Dockerfile
📚 Learning: 2025-11-01T20:24:29.557Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1714
File: NOTICE:0-0
Timestamp: 2025-11-01T20:24:29.557Z
Learning: In the cloudposse/atmos repository, the NOTICE file is programmatically generated and should not be manually edited. Issues with dependency license URLs in NOTICE will be resolved when upstream package metadata is corrected.

Applied to files:

  • examples/devcontainer-build/Dockerfile
📚 Learning: 2025-01-17T00:18:57.769Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Applied to files:

  • examples/devcontainer-build/Dockerfile
🪛 LanguageTool
examples/devcontainer-build/README.md

[typographical] ~7-~7: To join two clauses or introduce examples, consider using an em dash.
Context: ...lls Atmos. ## Files - atmos.yaml - Configuration showing how to use devcont...

(DASH_RULE)

🪛 markdownlint-cli2 (0.18.1)
examples/devcontainer-build/README.md

50-50: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


58-58: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (8)
examples/devcontainer-build/devcontainer.json (1)

7-7: Build args now align cleanly with the Dockerfile.

GEODESIC_VERSION matches the Dockerfile ARG, and dropping ATMOS_VERSION here is consistent with delegating Atmos version/arch detection to the install script inside the Dockerfile.

pkg/devcontainer/operations.go (1)

353-360: Updated build example matches the new devcontainer config shape.

The example YAML now reflects the top-level devcontainer.my-dev.spec.build layout and is consistent with the new examples, which will make the error hint much less confusing.

pkg/devcontainer/lifecycle_rebuild.go (1)

71-85: Rebuild flow now correctly prefers local Dockerfile builds over remote pulls.

Building first and then conditionally skipping pullImageIfNeeded when config.Build is set matches the intended --replace behavior for custom Dockerfiles and avoids trying to pull locally-tagged images such as atmos-devcontainer-<name> from a registry.

pkg/devcontainer/lifecycle_rebuild_test.go (1)

398-490: Dockerfile-based rebuild tests cover both happy path and failure path well.

These cases do a solid job of:

  • Verifying Build is called with the expected Context, Dockerfile, Tags, and Args.
  • Ensuring the created container uses the built image (atmos-devcontainer-geodesic).
  • Asserting that a failed build surfaces as ErrContainerRuntimeOperation.

This gives good confidence that the new rebuild flow behaves correctly for custom Dockerfiles.

examples/devcontainer-build/Dockerfile (1)

7-10: Using the official install script keeps the Dockerfile simple and aligned with tool behavior.

Delegating Atmos installation to install.sh and verifying with atmos version is a clean way to handle version and platform detection without custom logic in the Dockerfile.

website/docs/cli/commands/devcontainer/shell.mdx (1)

42-44: Docs for --replace and custom Dockerfile rebuilds now match the implementation.

The updated --replace flag description (build vs image cases) and the dedicated “Rebuilding Custom Dockerfiles” section line up with the new rebuild flow and give users a clear, concrete example of how to iterate on a Dockerfile-backed devcontainer.

Also applies to: 85-98

examples/devcontainer-build/atmos.yaml (1)

1-63: Example atmos.yaml clearly demonstrates Dockerfile-based devcontainer setups.

The combination of geodesic (include-based spec) and geodesic-inline (inline build spec) gives a straightforward, minimal example of both workflows, and the alias plus stacks section tie it into typical Atmos usage without adding unnecessary complexity.

website/blog/2025-12-05-geodesic-production-ready-devcontainer.mdx (1)

1-11: Blog post structure and metadata look solid.

The YAML front matter includes all required fields (slug, title, authors, tags, date), the author is a GitHub username (osterman), the truncate marker is present, and the filename follows the YYYY-MM-DD-feature-name convention. The content effectively demonstrates the new devcontainer features with clear examples.

One note: you'll want to verify that all tags (feature, geodesic, devcontainers, docker, developer-experience, devops) are existing tags already used in other blog posts per the guidelines. I don't have access to check other blog files, but that's a quick manual verification.

- Fix comment punctuation for godot linter in errors/formatter.go
- Fix inconsistent container naming in README (geodesic-atmos → geodesic)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@aknysh aknysh merged commit 827b828 into main Dec 10, 2025
57 checks passed
@aknysh aknysh deleted the osterman/devcontainer-dockerfile-fix branch December 10, 2025 18:26
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Dec 10, 2025
@github-actions
Copy link
Copy Markdown

These changes were released in v1.203.0-test.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/m Medium size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants