10.1 Codespaces, Customization, and Dev Containers

Key Takeaways

  • A GitHub codespace is a cloud development environment: a Docker container on a GitHub-hosted Linux virtual machine that you open from the browser, Visual Studio Code, or GitHub CLI.
  • The remote development container is always Linux; Windows and macOS are not supported operating systems for that container even when the laptop runs Windows or macOS.
  • Teams customize Codespaces with Configuration-as-Code in devcontainer.json (usually .devcontainer/devcontainer.json). With no config, GitHub uses a default Ubuntu-based image of popular languages and tools.
  • Personalization is separate from team customization: a selected dotfiles repository plus Visual Studio Code Settings Sync. Do not put personal themes or aliases in devcontainer.json.
  • Every personal GitHub account includes a monthly free Codespaces quota (GitHub Free: 15 GB-month and 120 compute hours; GitHub Pro: 20 GB-month and 180 hours). Organizations on GitHub Team or GitHub Enterprise can pay for members' and collaborators' codespaces created from organization-owned repositories.
Last updated: August 2026

Why GH-900 tests Codespaces

Domain 4 of GitHub Foundations (GH-900)—Apply modern development practices, 10–15% of the exam—asks you to describe GitHub Codespaces and how to set up, customize, and use dev containers. The January 2026 outline is product knowledge: what a codespace is, where the compute actually runs, how a team shares one environment, how you personalize your own editor, and who pays. GH-900 is not a Docker certification and it is not the dedicated GitHub Actions exam. You will not be asked to author a production multi-stage Dockerfile from memory. You will be asked whether the environment is a laptop VM, a browser-only sandbox, or a cloud Linux container, and whether a setting belongs in devcontainer.json or in your dotfiles.

GitHub Codespaces is a development environment hosted in the cloud. GitHub's own definition is the sentence to memorize: each codespace is hosted in a Docker container running on a virtual machine. You customize the project for everyone by committing configuration files to the repository—Configuration-as-Code—so every contributor gets a repeatable environment instead of a unique laptop snowflake.

The stack: editor, container, virtual machine

Three layers show up in exam stems. Mixing them is how people pick github.dev or Docker Desktop when the question is Codespaces.

LayerWhat it isWhat GH-900 wants you to notice
EditorBrowser, Visual Studio Code, or GitHub CLIYou connect to the codespace; the codespace is not the editor itself
Dev containerA Docker container configured for developmentThis is where your shell, runtimes, ports, and most extensions actually live
Virtual machineA GitHub-hosted Linux VMMachine size is cores, RAM, and disk; you have limited access to the outer host

GitHub documents a selection of virtual machine types, from 2 cores, 8 GB RAM, and 32 GB storage up to 32 cores, 128 GB RAM, and 128 GB storage. Compute billing scales with cores: an hour on a 16-core machine costs eight times an hour on a 2-core machine. Storage is a separate meter (GB-month / GB-hours).

Regardless of your local operating system, the codespace runs in a Linux environment. Windows and macOS are not supported operating systems for the remote development container. A Windows laptop still gets a Linux container. A Mac still gets a Linux container. That fact is the classic trap against “Codespaces matches your laptop OS so you can run Windows-only installers inside it.”

When you connect, you are placed inside the Docker container. You have limited access to the outer Linux virtual machine host. If a question says you should “SSH into the Azure host and install a Windows Server feature,” that is not how Codespaces works.

You can create a codespace from a template or from any branch or commit in a repository. Opening an existing codespace resumes the environment instead of building a brand-new container. Personal GitHub accounts can start without changing settings or providing payment details, because a monthly free quota is included on Free and Pro.

Connect from three clients

GitHub documents three ways to attach to the same cloud environment:

  1. Browser — the Visual Studio Code web client on GitHub.com, with no local install.
  2. Visual Studio Code — the desktop app attached to the remote container.
  3. GitHub CLIgh codespace commands to create, open, SSH, and rebuild.

All three put you in the same container. Switching clients does not change the fact that the compute is in the cloud, and it does not turn the codespace into github.dev. github.dev is a different product (section 10.2): a browser sandbox with no virtual machine and no terminal.

Loading diagram...
A codespace is a Linux container on a GitHub-hosted VM

Configuration-as-Code: set up and customize with dev containers

Whenever you work in a codespace, you are using a development container (dev container) on a virtual machine. A dev container is a Docker container specifically configured as a fully featured development environment. Adding one or more configurations to the repository lets you define the runtimes and tools people need—or even a choice of environments for different kinds of work in a large repository.

The primary file is devcontainer.json. It can declare frameworks, tools, Visual Studio Code extensions, port forwarding, and a reference to a Dockerfile. GitHub's teaching distinction is the one GH-900 will twist: treat devcontainer.json as customization (what everyone working on the codebase needs) rather than personalization (what you like). Linters, language runtimes, and required extensions belong in the committed file. Color themes, keybindings, and personal shell aliases do not.

Usual locations:

  • .devcontainer/devcontainer.json (the common default)
  • .devcontainer.json at the repository root (the filename must begin with a period)
  • Alternative configs at .devcontainer/SUBDIRECTORY/devcontainer.json — only one directory level below .devcontainer (.devcontainer/teamA/devcontainer.json works; .devcontainer/teamA/testing/devcontainer.json does not)

If multiple configurations exist, the user chooses one when creating the codespace. Settings are not imported or inherited between devcontainer.json files, so keep a configuration's Dockerfile and scripts in the same subdirectory. A monorepo might offer .devcontainer/frontend/devcontainer.json and .devcontainer/api/devcontainer.json. Codespaces created from a template repository's Use this template button use the default .devcontainer/devcontainer.json (or root .devcontainer.json) and do not present a configuration picker.

The file is JSONC (JSON with comments). Point a linter at JSONC, not strict JSON, or the comments look like errors.

You can add a Dockerfile next to the config and reference it with a build.dockerfile property, or set an image property to an existing image that organization policy allows. If neither a Dockerfile nor an image is found, GitHub uses the default container image. Features—self-contained install units from the Development Containers spec—let you add tools, runtimes, or libraries without writing every RUN apt-get line by hand.

You can add a predefined configuration from the Command Palette (Codespaces: Add Dev Container Configuration Files) while working in a codespace, or from a repository's Code dropdown (Configure dev container). After you edit the file, apply it with Codespaces: Rebuild Container or gh codespace rebuild. Rebuild clears changes outside /workspaces. The clone of the repository lives under /workspaces and is preserved. If the new configuration fails, the codespace can start in recovery mode so you can read the creation log and fix devcontainer.json.

The default Ubuntu image

If you create a codespace from a repository without any dev container configuration, GitHub Codespaces clones the repository into an environment that uses the default Ubuntu Linux image—an image that already includes a selection of popular languages and tools. GitHub documents runtime families such as Python, Node, PHP, Java, Go, C++, Ruby, and .NET Core/C#, plus data-science tools such as JupyterLab and Conda, and utilities such as Git, GitHub CLI, yarn, openssh, and vim. A codespace created from a template may start with some initial configuration on top of that default. For a small project that already matches those tools, you do not have to invent a custom image before the first codespace.

GitHub does not charge for storage of containers built from the default dev container image. If you build from a custom base image, the storage volume includes that custom container as well as the files in the repository. Adding Features on top of the default image does not, by itself, turn the default image into a billed custom base.

Personalization: dotfiles and Settings Sync

Two account-level tools personalize your codespaces, not the team's:

Dotfiles. In GitHub Codespaces settings, select a repository you own and enable Automatically install dotfiles. When a new codespace is created, GitHub clones that repository and looks for install.sh, install, bootstrap.sh, bootstrap, script/bootstrap, setup.sh, setup, or script/setup. If none of those files exist, files and folders that start with . are symlinked into $HOME. Use this for shell aliases, prompt config, and tools you personally always want. Changes apply to new codespaces; they do not retrofit existing ones. Dotfiles can run arbitrary scripts—review them before you enable a repo. Codespaces does not currently apply User-scoped Visual Studio Code settings from a dotfiles repository.

Settings Sync. Synchronizes Visual Studio Code settings, keyboard shortcuts, snippets, extensions, and UI state between machines. If you use Codespaces in the browser or in Visual Studio Code, Settings Sync can give the codespace editor the same setup as your local Visual Studio Code. In the web client, Settings Sync is disabled by default unless you enable it in Codespaces user preferences. Two-way sync depends on your list of trusted repositories (the same list GPG verification uses). Do not turn on two-way Settings Sync for repositories you do not trust.

If a stem wants every contributor to have ESLint and Node 20, that is devcontainer.json. If it wants your alias gs='git status' and a dark theme, that is dotfiles and Settings Sync.

Who pays for Codespaces

Every personal GitHub account includes a monthly free quota of compute time and storage. You can start on a personal Free or Pro plan without changing settings or adding a card.

Personal planStorage per monthCompute time per month
GitHub Free for personal accounts15 GB-month120 hours
GitHub Pro20 GB-month180 hours

After the included amounts, usage is billed to the personal account if a payment method and budget allow it. If the account has no valid payment method, usage is blocked once the quota is gone. You can add payment details, export changes to a branch, or wait until the next billing cycle resets included compute. Compute hours reset each cycle; storage charges accrue by the hour and reset at cycle start.

GitHub plans for organizations and enterprises do not include a free Codespaces quota. Owners of organizations on GitHub Team and GitHub Enterprise can pay for their members' and collaborators' use of Codespaces created from organization-owned repositories. If use will be billed to the organization or its parent enterprise, GitHub shows that when the codespace is created. Those codespaces are owned by the organization and can be deleted by an organization owner. Removing a user from the organization or repository automatically deletes their codespaces.

If you create a codespace from an organization-owned repository and the organization is not configured to pay, the usage is charged to your personal account. Codespaces created from a fork are billed to the personal account unless the upstream organization has allowed that user to use Codespaces at the organization's expense.

GitHub Codespaces is not available for repositories owned by managed user accounts (Enterprise Managed Users). A managed user cannot be the billable owner of a codespace, which also blocks publishing a template codespace to a new personal repository.

Costs are always billed monthly, even if the GitHub account is otherwise billed annually. Budgets cap spend. Organization Free is not “unlimited Codespaces.”

Exam traps for D4.4

  • Codespaces is a cloud Linux container on a VM, not github.dev and not Docker Desktop required on the laptop.
  • Windows or macOS laptop ≠ Windows or macOS container. The remote environment is Linux.
  • devcontainer.json is team customization. Dotfiles and Settings Sync are personal.
  • No config → default Ubuntu image, not “Codespaces refuses to start.”
  • Multiple configs live one level under .devcontainer/ and are not inherited from each other.
  • Rebuild wipes work outside /workspaces.
  • Personal accounts have a monthly free quota. Team and Enterprise organizations can pay for members. Org and enterprise plans themselves have no included free Codespaces quota.
  • EMU-owned repositories cannot use Codespaces.
  • Connect from browser, Visual Studio Code, or GitHub CLI—three clients, one container.
Test Your Knowledge

A developer on a Windows laptop creates a GitHub codespace for a Python repository. Which statement about that environment is accurate according to GitHub Docs?

A
B
C
D
Test Your Knowledge

A team wants every contributor's codespace to include Node.js 20, the ESLint extension, and a forwarded port for the app, while each person keeps their own editor theme and shell aliases. What should they put where?

A
B
C
D
Test Your Knowledge

According to GitHub Docs, who gets included Codespaces usage and who can pay for organization members?

A
B
C
D