← 返回首页
Create a Dev Container

Documentation

Topics Overview Overview Linux macOS Windows VS Code for the Web Raspberry Pi Network Additional Components Uninstall VS Code Tutorial Copilot Quickstart User Interface Personalize VS Code Install Extensions Tips and Tricks Intro Videos Overview Setup Quickstart Overview Language Models Context Tools Agents Customization Trust & Safety Overview Agents Tutorial Agents Window Planning Memory Tools Subagents Local Agents Copilot CLI Cloud Agents Third-Party Agents Overview Chat Sessions Add Context Inline Chat Review Edits Checkpoints Artifacts Panel Debug Chat Interactions Prompt Examples Overview Instructions Prompt Files Custom Agents Agent Skills Language Models MCP Hooks Plugins Context Engineering Customize AI Test-Driven Development Edit Notebooks with AI Test with AI Test Web Apps with Browser Tools Debug with AI MCP Dev Guide OpenTelemetry Monitoring Inline Suggestions Smart Actions Best Practices Security Troubleshooting FAQ Cheat Sheet Settings Reference MCP Configuration Workspace Context Display Language Layout Keyboard Shortcuts Settings Settings Sync Extension Marketplace Extension Runtime Security Themes Profiles Overview Voice Interactions Command Line Interface Telemetry Basic Editing IntelliSense Code Navigation Refactoring Snippets Overview Multi-Root Workspaces Workspace Trust Tasks Debugging Debug Configuration Testing Port Forwarding Integrated Browser Overview Quickstart Staging & Committing Branches & Worktrees Repositories & Remotes Merge Conflicts Collaborate on GitHub Troubleshooting FAQ Getting Started Tutorial Terminal Basics Terminal Profiles Shell Integration Appearance Advanced Overview Enterprise Policies AI Settings Extensions Telemetry Updates Overview JavaScript JSON HTML Emmet CSS, SCSS and Less TypeScript Markdown PowerShell C++ Java PHP Python Julia R Ruby Rust Go T-SQL C# .NET Swift Working with JavaScript Node.js Tutorial Node.js Debugging Deploy Node.js Apps Browser Debugging Angular Tutorial React Tutorial Vue Tutorial Debugging Recipes Performance Profiling Extensions Tutorial Transpiling Editing Refactoring Debugging Quick Start Tutorial Run Python Code Editing Linting Formatting Debugging Environments Testing Python Interactive Django Tutorial FastAPI Tutorial Flask Tutorial Create Containers Deploy Python Apps Python in the Web Settings Reference Getting Started Navigate and Edit Refactoring Formatting and Linting Project Management Build Tools Run and Debug Testing Spring Boot Modernizing Java Apps Application Servers Deploy Java Apps GUI Applications Extensions FAQ Intro Videos GCC on Linux GCC on Windows GCC on Windows Subsystem for Linux Clang on macOS Microsoft C++ on Windows Build with CMake CMake Tools on Linux CMake Quick Start C++ Dev Tools for Copilot Editing and Navigating Debugging Configure Debugging Refactoring Settings Reference Configure IntelliSense Configure IntelliSense for Cross-Compiling FAQ Intro Videos Get Started Navigate and Edit IntelliCode Refactoring Formatting and Linting Project Management Build Tools Package Management Run and Debug Testing FAQ Overview Node.js Python ASP.NET Core Debug Docker Compose Registries Deploy to Azure Choose a Dev Environment Customize Develop with Kubernetes Tips and Tricks Overview Jupyter Notebooks Data Science Tutorial Python Interactive Data Wrangler Quick Start Data Wrangler PyTorch Support Azure Machine Learning Manage Jupyter Kernels Jupyter Notebooks on the Web Data Science in Microsoft Fabric Foundry Toolkit Overview Foundry Toolkit Copilot Tools Create Agents Models Playground Agent Builder Agent Inspector Evaluation Tool Catalog Fine-Tuning (Automated Setup) Fine-Tuning (Project Template) Model Conversion Tracing Profiling (Windows ML) FAQ File Structure Manual Model Conversion Manual Model Conversion on GPU Setup Environment Without Foundry Toolkit Template Project Migrating from Visualizer to Agent Inspector Overview Getting Started Resources View Deployment VS Code for the Web - Azure Containers Azure Kubernetes Service Kubernetes MongoDB Remote Debugging for Node.js Overview SSH Dev Containers Windows Subsystem for Linux GitHub Codespaces VS Code Server Tunnels SSH Tutorial WSL Tutorial Tips and Tricks FAQ Overview Tutorial Attach to Container Create Dev Container Advanced Containers devcontainer.json Dev Container CLI Tips and Tricks FAQ Default Keyboard Shortcuts Default Settings Substitution Variables Tasks Schema
Copy as Markdown

On this page there are 7 sections

Create a Dev Container

The Visual Studio Code Dev Containers extension lets you use a Docker container as a full-featured development environment. It allows you to open any folder or repository inside a container and take advantage of Visual Studio Code's full feature set. A devcontainer.json file in your project tells VS Code how to access (or create) a development container with a well-defined tool and runtime stack. This container can be used to run an application or to provide separate tools, libraries, or runtimes needed for working with a codebase.

Path to creating a dev container

In this document, we'll go through the steps for creating a development (dev) container in VS Code:

  1. Create a devcontainer.json, which describes how VS Code should start the container and what to do after it connects.
  2. Make and persist changes to the dev container, such as installation of new software, through use of a Dockerfile.
  3. Configure multiple containers through Docker Compose.
  4. As you make changes, build your dev container to ensure changes take effect.

After any of the steps above, you'll have a fully functioning dev container, and you can either continue to the next step of this tutorial to add more features, or stop and begin working in the dev environment you currently have.

Note: The Dev Containers extension has a Dev Containers: Add Dev Container Configuration Files... command that lets you pick a pre-defined container configuration from a list. If you'd prefer to have a complete dev container immediately rather than building up the devcontainer.json and Dockerfile step-by-step, you can skip ahead to Automate dev container creation.

Create a devcontainer.json file

VS Code's container configuration is stored in a devcontainer.json file. This file is similar to the launch.json file for debugging configurations, but is used for launching (or attaching to) your development container instead. The dev container configuration is either located under .devcontainer/devcontainer.json or stored as a .devcontainer.json file (note the dot-prefix) in the root of your project.

You can use an image as a starting point for your devcontainer.json. An image is like a mini-disk drive with various tools and an operating system pre-installed. You can pull images from a container registry, which is a collection of repositories that store images. Here is a simple example devcontainer.json that uses a pre-built TypeScript and Node.js VS Code Development Container image:

{ "image": "mcr.microsoft.com/devcontainers/typescript-node", "customizations": { "vscode": { "extensions": ["streetsidesoftware.code-spell-checker"] } }, "forwardPorts": [3000] }

Note: Additional configuration will already be added to the container based on what's in the base image. For example, we add the streetsidesoftware.code-spell-checker extension above, and the container will also include "dbaeumer.vscode-eslint" as that's part of mcr.microsoft.com/devcontainers/typescript-node. This happens automatically when pre-building using devcontainer.json, which you may read more about in the pre-build section.

With the above devcontainer.json, your dev container is functional, and you can connect to and start developing within it. Try it out with the Dev Containers: Reopen in Container command:

After running this command, when VS Code restarts, you're now within a Node.js and TypeScript dev container with port 3000 forwarded and the ESLint extension installed. Once you're connected, notice the green remote indicator on the left of the Status bar to show you are connected to your dev container:

Additional dev container scenarios

Through a devcontainer.json file, you can:

  • Spin up a stand-alone container to isolate your toolchain or speed up setup.
  • Work with a container deployed application defined by an image, Dockerfile, or Docker Compose.
  • Use Docker or Kubernetes from inside a dev container to build and deploy your app.

If devcontainer.json's supported workflows do not meet your needs, you can also attach to an already running container instead.

Tip: Want to use a remote Docker host? See the Develop on a remote Docker host article for details on setup.

Install additional software

You may want to install additional software in your dev container. Once VS Code is connected to the container, you can open a VS Code terminal and execute any command against the OS inside the container. This allows you to install new command-line utilities and spin up databases or application services from inside the Linux container.

Most container images are based on Debian or Ubuntu, where the apt or apt-get command is used to install new packages. You can learn more about the command in Ubuntu's documentation. Alpine images include a similar apk command while CentOS / RHEL / Oracle SE / Fedora images use yum or more recently dnf.

Documentation for the software you want to install will usually provide specific instructions, but you may not need to prefix commands with sudo if you are running as root in the container.

For example:

# If sudo is installed and configured sudo apt-get update sudo apt-get install <package>

Let's say you want to install Git. You could run the following commands in the integrated terminal in VS Code:

"features": { "ghcr.io/devcontainers/features/azure-cli:1": { "version": "latest" } }

See the Dev Container Features specification for more details.

Rebuild

When editing the contents of the .devcontainer folder, you'll need to rebuild for changes to take effect. Use the Dev Containers: Rebuild Container command for your container to update.

However, if you rebuild the container, you will have to reinstall anything you've installed manually. To avoid this problem, you can use the postCreateCommand property in devcontainer.json or a custom Dockerfile.

A custom Dockerfile will benefit from Docker's build cache and result in faster rebuilds than postCreateCommand. However, the Dockerfile runs before the dev container is created and the workspace folder is mounted and therefore does not have access to the files in the workspace folder. A Dockerfile is most suitable for installing packages and tools independent of your workspace files.

The postCreateCommand actions are run once the container is created, so you can also use the property to run commands like npm install or to execute a shell script in your source tree (if you have mounted it).

"postCreateCommand": "bash -i scripts/install-dependencies.sh"

Tools like NVM won't work without using -i to put the shell in interactive mode:

{ "build": { "dockerfile": "Dockerfile" }, "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint"] } }, "forwardPorts": [3000] }

When you make changes like installing new software, changes made in the Dockerfile will persist even upon a rebuild of the dev container.

In your Dockerfile, use FROM to designate the image, and the RUN instruction to install any software. You can use && to string together multiple commands.

{ "name": "[Optional] Your project name here", "dockerComposeFile": "../docker-compose.yml", "service": "the-name-of-the-service-you-want-to-work-with-in-vscode", "workspaceFolder": "/default/workspace/path/in/container/to/open", "shutdownAction": "stopCompose" }

See the devcontainer.json reference for information on other available properties such as the workspaceFolder and shutdownAction.

Once you have added a .devcontainer/devcontainer.json file to your folder, run the Dev Containers: Reopen in Container command (or Dev Containers: Open Folder in Container... if you are not yet in a container) from the Command Palette (F1).

If the containers are not already running, VS Code will call docker-compose -f ../docker-compose.yml up in this example. The service property indicates which service in your Docker Compose file VS Code should connect to, not which service should be started. If you started them by hand, VS Code will attach to the service you specified.

You can also create a development copy of your Docker Compose file. For example, if you had .devcontainer/docker-compose.devcontainer.yml, you would just change the following line in devcontainer.json:

# Overrides default command so things don't shut down after the process ends. command: /bin/sh -c "while sleep 1000; do :; done"

If you have not done so already, you can "bind" mount your local source code into the container using the volumes list in your Docker Compose file.

For example:

"remoteUser": "your-user-name-here"

If you want all processes to run as a different user, add this to the appropriate service in your Docker Compose file:

# Required for ptrace-based debuggers like C++, Go, and Rust cap_add: - SYS_PTRACE security_opt: - seccomp:unconfined

After you create your container for the first time, you will need to run the Dev Containers: Rebuild Container command for updates to devcontainer.json, your Docker Compose files, or related Dockerfiles to take effect.

Using localhost in Docker Compose

You can add other services to your docker-compose.yml file as described in Docker's documentation. However, if you want anything running in this service to be available in the container on localhost, or want to forward the service locally, be sure to add this line to the service config:

version: '3' services: your-service-name-here: volumes: # Mounts the project folder to '/workspace'. While this file is in .devcontainer, # mounts are relative to the first file in the list, which is a level up. - .:/workspace:cached # [Optional] Required for ptrace-based debuggers like C++, Go, and Rust cap_add: - SYS_PTRACE security_opt: - seccomp:unconfined # Overrides default command so things don't shut down after the process ends. command: /bin/sh -c "while sleep 1000; do :; done"

This same file can provide additional settings, such as port mappings, as needed. To use it, reference your original docker-compose.yml file in addition to .devcontainer/docker-compose.extend.yml in a specific order:

docker-compose -f docker-compose.yml -f .devcontainer/docker-compose.extend.yml up

While the postCreateCommand property allows you to install additional tools inside your container, in some cases you may want to have a specific Dockerfile for development. You can also use this same approach to reference a custom Dockerfile specifically for development without modifying your existing Docker Compose file. For example, you can update .devcontainer/docker-compose.extend.yml as follows:

[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-java)

You can also include an open in dev container link directly:

📁 github.com 📁 devcontainers 📁 templates 📁 .devcontainer

Once in place, the configuration will be automatically picked up when using any of the Dev Containers commands. Once in the container, you can also select Dev Containers: Open Container Configuration File from the Command Palette (F1) to open the related devcontainer.json file and make further edits.

The path used for looking up the configuration is derived from the output of git remote -v. If the configuration is not found when you attempt to reopen the folder in a container, check the log Dev Containers: Show Container Log in the Command Palette (F1) for the list of the paths that were checked.

Next steps