docs/devcontainer/architecture.md
This document provides a deep dive into how the MongoDB devcontainer is structured and how all the pieces work together.
The MongoDB devcontainer is built on several key components:
flowchart TD
VSCode["VS Code"]
Extension["Dev Containers Extension"]
DevContainer["devcontainer.json"]
Dockerfile["Dockerfile"]
Volumes["Volumes
- engflow
- cache
- venv
- history"]
BaseImage["Base Image
(Bazel RBE Ubuntu)"]
Toolchain["MongoDB Toolchain
(GCC, Clang, etc.)"]
Features["Features
- workstation
- git
- bazel
- docker"]
PostCreate["Post-Create Commands
- setup poetry
- setup venv
- setup clangd"]
VSCode --> Extension
Extension -->|reads| DevContainer
DevContainer -->|references| Dockerfile
DevContainer -->|mounts volumes| Volumes
Dockerfile -->|builds| BaseImage
BaseImage -->|installs| Toolchain
Toolchain -->|runs| Features
Features -->|executes| PostCreate
.devcontainer/
├── devcontainer.json # Main configuration file
├── Dockerfile # Container image definition
├── toolchain_config.env # Toolchain version and checksum
├── toolchain.py # Toolchain management script
├── features/ # Custom devcontainer features
│ └── workstation/
│ ├── devcontainer-feature.json
│ ├── install.sh
│ └── setup.sh
└── OWNERS.yml # Code ownership info
The Dockerfile starts from MongoDB's Remote Build Execution (RBE) image:
# The base image version is managed in .devcontainer/Dockerfile
# Check that file for the current version
ARG BASE_IMAGE=quay.io/mongodb/bazel-remote-execution:ubuntu24-<version>
FROM $BASE_IMAGE
This base image includes:
A non-root user is created with the same username as your host user:
ARG USERNAME=mongo-dev
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd $USERNAME && useradd -s /bin/bash --gid $USER_GID -m $USERNAME
Why?
The user gets passwordless sudo access for administrative tasks:
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/devcontaineruser
Bash history is configured to persist across container restarts:
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
&& mkdir /commandhistory \
&& touch /commandhistory/.bash_history \
&& chown -R $USERNAME /commandhistory \
&& echo "$SNIPPET" >> "/home/$USERNAME/.bashrc"
The /commandhistory directory is mounted from a Docker volume.
See Toolchain Installation section below.
Build event keywords are added for analytics:
RUN echo "common --bes_keywords=devcontainer:use=true" >> "$HOME/.bazelrc" && \
echo "common --bes_keywords=devcontainer:image=$BASE_IMAGE" >> "$HOME/.bazelrc" && \
echo "common --bes_keywords=devcontainer:username=$USERNAME" >> "$HOME/.bazelrc"
This helps MongoDB track devcontainer usage and identify issues.
The devcontainer uses several Docker volumes for persistence:
From devcontainer.json:
"mounts": [
{
"source": "engflow_auth",
"target": "/home/${localEnv:USER}/.config/engflow_auth",
"type": "volume"
},
{
"source": "${containerWorkspaceFolderBasename}-cache",
"target": "/home/${localEnv:USER}/.cache",
"type": "volume"
},
{
"source": "mongo-bashhistory",
"target": "/commandhistory",
"type": "volume"
}
]
| Volume | Purpose | Survives Container Rebuild? | Size Impact |
|---|---|---|---|
engflow_auth | EngFlow authentication credentials | ✅ Yes | Small |
{workspace}-cache | Bazel cache, tool caches | ✅ Yes | Large |
mongo-bashhistory | Command history | ✅ Yes | Small |
{workspace}-python3-venv | Python virtual environment | ✅ Yes | Medium |
The workspace itself is in a separate volume created by the clone command:
docker volume ls
# Shows: mongo-workspace (or your chosen name)
Benefits of Named Volumes:
docker volume commands# List all volumes
docker volume ls
# Inspect a volume
docker volume inspect engflow_auth
MongoDB requires specific compiler versions. The toolchain installation process ensures consistency.
The toolchain_config.env file contains architecture-specific toolchain definitions for both ARM64 and AMD64:
# Generated by toolchain.py
# DO NOT EDIT MANUALLY - run: python3 toolchain.py generate
# ARM64 Toolchain
TOOLCHAIN_ARM64_URL="https://s3.amazonaws.com/boxes.10gen.com/build/toolchain/mongodbtoolchain-ubuntu2404-arm64-..."
TOOLCHAIN_ARM64_SHA256="<sha256 checksum>"
TOOLCHAIN_ARM64_KEY="build/toolchain/mongodbtoolchain-ubuntu2404-arm64-..."
TOOLCHAIN_ARM64_LAST_MODIFIED="2025-07-21T20:49:55+00:00"
# AMD64 Toolchain
TOOLCHAIN_AMD64_URL="https://s3.amazonaws.com/boxes.10gen.com/build/toolchain/mongodbtoolchain-ubuntu2404-..."
TOOLCHAIN_AMD64_SHA256="<sha256 checksum>"
TOOLCHAIN_AMD64_KEY="build/toolchain/mongodbtoolchain-ubuntu2404-..."
TOOLCHAIN_AMD64_LAST_MODIFIED="2025-07-21T19:57:00+00:00"
Note: This file is auto-generated. To update toolchain versions, run:
python3 .devcontainer/toolchain.py generate
The Dockerfile automatically selects the correct toolchain based on the target platform:
# Load configuration and select architecture-specific toolchain
ARG TARGETPLATFORM
COPY .devcontainer/toolchain_config.env /tmp/toolchain_config.env
RUN set -e; \
. /tmp/toolchain_config.env; \
# Select toolchain based on platform
if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
TOOLCHAIN_URL="$TOOLCHAIN_ARM64_URL"; \
TOOLCHAIN_SHA256="$TOOLCHAIN_ARM64_SHA256"; \
ARCH="arm64"; \
elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
TOOLCHAIN_URL="$TOOLCHAIN_AMD64_URL"; \
TOOLCHAIN_SHA256="$TOOLCHAIN_AMD64_SHA256"; \
ARCH="amd64"; \
else \
echo "Unsupported platform: $TARGETPLATFORM"; \
exit 1; \
fi; \
echo "Target platform: $TARGETPLATFORM"; \
echo "Architecture: $ARCH"; \
echo "Installing toolchain from: $TOOLCHAIN_URL"; \
# Download
curl -fSL "$TOOLCHAIN_URL" -o /tmp/toolchain.tar.gz; \
# Verify checksum (security!)
echo "$TOOLCHAIN_SHA256 /tmp/toolchain.tar.gz" | sha256sum -c -;
# Extract
RUN mkdir -p /opt/mongodbtoolchain/revisions && \
tar -xzf /tmp/toolchain.tar.gz -C /opt/mongodbtoolchain/revisions; \
rm /tmp/toolchain.tar.gz; \
chown -R ${USERNAME} /opt/mongodbtoolchain;
# Run installation script
USER $USERNAME
RUN /opt/mongodbtoolchain/revisions/*/scripts/install.sh
Multi-Architecture Support:
TARGETPLATFORM build argument is automatically set by Docker based on your host architecturelinux/arm64 (Apple Silicon, ARM servers) and linux/amd64 (Intel/AMD processors)The MongoDB toolchain includes:
The toolchain is managed by the MongoDB team. When updates are available, you'll get them automatically when you:
You don't need to manually update the toolchain.
Dev Containers support modular "features" - reusable units of functionality.
From devcontainer.json:
"features": {
"./features/workstation": {}, // Custom
"ghcr.io/devcontainers/features/git:1": {}, // Official
"ghcr.io/devcontainers-community/features/bazel:1": {}, // Community
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},// Official
"ghcr.io/devcontainers/features/common-utils:2": { // Official
"username": "${localEnv:USER}"
}
}
The features/workstation feature is MongoDB-specific.
Structure:
features/workstation/
├── devcontainer-feature.json # Metadata and configuration
├── install.sh # Runs during image build
└── setup.sh # Runs during container creation
What it does:
Mounts Python venv volume (from devcontainer-feature.json):
"mounts": [
{
"source": "${containerWorkspaceFolderBasename}-python3-venv",
"target": "${containerWorkspaceFolder}/python3-venv",
"type": "volume"
}
]
Runs setup script that installs:
The devcontainer.json includes extensive VS Code settings:
"clangd.checkUpdates": true,
"clangd.path": "${workspaceFolder}/buildscripts/clangd_vscode.sh",
"clang-format.executable": "${workspaceRoot}/bazel-out/.../clang-format",
Why clangd?
"python.defaultInterpreterPath": "python3-venv/bin/python",
"python.autoComplete.extraPaths": [
"/opt/mongodbtoolchain/v5/share/gcc-*/python"
],
"mypy-type-checker.importStrategy": "fromEnvironment",
"editor.defaultFormatter": "charliermarsh.ruff"
Uses the virtual environment Python and Ruff for formatting.
"prettier.prettierPath": "bazel-bin/node_modules/.aspect_rules_js/[email protected]/node_modules/prettier",
"eslint.validate": ["javascript"],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
Uses Bazel-managed Prettier and ESLint.
"[c]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.formatOnSave": true
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.formatOnSave": true
},
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
Recommended extensions are automatically installed:
After the container starts, several commands run to finalize setup:
"postCreateCommand": {
"fixVolumePerms": "sudo chown -R $(whoami): ${containerEnv:HOME}/.config/engflow_auth && sudo chown -R $(whoami): ${containerEnv:HOME}/.cache",
"venvActivation": "echo 'source ${containerWorkspaceFolder}/python3-venv/bin/activate && ${containerWorkspaceFolder}/buildscripts/poetry_sync.sh' >> ~/.bashrc && echo 'source ${containerWorkspaceFolder}/python3-venv/bin/activate && ${containerWorkspaceFolder}/buildscripts/poetry_sync.sh' >> ~/.zshrc;",
"createDataDir": "sudo mkdir -p /data/db && sudo chown -R $(whoami): /data/db",
"reportDockerServerPlatform": "echo \"\ncommon --bes_keywords=devcontainer:docker_server_platform=$(docker version --format '\"{{.Server.Platform.Name}}\"')\" >> ${containerEnv:HOME}/.bazelrc",
"reportDockerServerVersion": "echo \"\ncommon --bes_keywords=devcontainer:docker_server_version=$(docker version --format '\"{{.Server.Version}}\"')\" >> ${containerEnv:HOME}/.bazelrc",
"reportArch": "echo \"\ncommon --bes_keywords=devcontainer:arch=$(uname -i)\" >> ${containerEnv:HOME}/.bazelrc",
"fetchTags": "if [ -f .git/shallow ]; then git fetch --unshallow --tags; else git fetch --tags; fi || true"
}
What these commands do:
The workstation feature's postCreateCommand:
sudo chown -R $(whoami): ${containerWorkspaceFolder}/python3-venv && \
sudo chown $(whoami): ${containerWorkspaceFolder}/.. && \
bash /workspace-setup.sh
The setup.sh script then:
poetry install to install all dependencies"containerEnv": {
"HOME": "/home/${localEnv:USER}"
}
Added to .bashrc during setup:
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
export PATH="$PATH:$HOME/.local/bin"
export HISTFILE=/commandhistory/.bash_history
export PROMPT_COMMAND='history -a'
When you activate the toolchain environment:
source /opt/mongodbtoolchain/revisions/*/activate
This sets:
CC, CXX: Compiler pathsPATH: Toolchain binariesLD_LIBRARY_PATH: Toolchain librariesBuild Time (Dockerfile):
Container Creation (Features + postCreateCommand):
Runtime:
See Advanced Usage for details on:
Next Steps: