If you’re configuring your Dev Container in VS Code also check out the VS
Code documentation. Particularly for extra information
on rebuilding your container, recovery mode and accessing logs.
- Single Container Setup: This simplest scenario runs everything you need inside a single container. It’s ideal for most projects where one environment can handle your entire development stack—for instance, a Node.js application with all dependencies and tools in one container.
- Multi-Container Setup with Docker Compose: For more complex projects involving multiple services—such as a web application with a separate database—Docker Compose allows you to define and orchestrate multiple containers. Each service operates in its own container, yet they function together as a unified environment.
Starting with a custom Dockerfile
If you’re using a single container and already have a Dockerfile, you can base your Dev Container configuration on it. Here’s how you might set it up:- build: Builds the container from the Dockerfile in the parent directory.
- vscode: Installs the ESLint extension for JavaScript linting in VS Code.
- remoteUser: Specifies the user inside the container (set to node).
Starting with a Docker Compose
In this example, we set up a multi-container environment using Docker Compose. This setup includes two containers: one for the application (service container) and another for the PostgreSQL database.Beware that devcontainer’s interaction with docker compose can quickly lead to broken environments, due to unforeseen interactions between your devcontainer and Docker services.devcontainer.json: This file defines the development container configuration and ties it to the Docker Compose setup.
- dockerComposeFile: Points to the Docker Compose file that defines the services.
- service: Specifies the main development container (app).
- workspaceFolder: Defines the working directory inside the container.
- vscode: Installs the necessary VS Code extensions.
- remoteUser: Specifies the user inside the container (set to node).
- name: Sets the name to ensure containers are properly identified under a specific project name.
- app service: This container is used for development. It builds from a Dockerfile and mounts the project directory as a volume. The command is overridden to keep the container alive (sleep infinity), and it shares the network stack with the db service (network_mode: service:db), which simplifies access to the database.
- db service: This container runs PostgreSQL and is configured with environment variables for the user, password, and database name. The database data is persisted using a Docker named volume (postgres-data).
Iterating and Rebuilding
After modifying the devcontainer.json file, you must rebuild your container to apply the changes. You can initiate a rebuild from VS Code using the Gitpod Flex: Rebuild Container command. During this process, Ona will disconnect your session, then automatically reconnect you once the rebuild is complete. You can also rebuild your environment from the terminal using the Gitpod CLI. For instance, to trigger a rebuild from your environment, use:Recovery mode
If errors occur when the devcontainer is started during a rebuild, recovery mode allows you to examine environment logs, adjust the devcontainer.json file to resolve issues, and attempt the rebuild again.Environment Isolation Considerations
The Dev Container runs in an isolated Linux VM. Although the VM is part of the environment, the content and structure of the host is not customizable and may change at any time. Relying on the structure or contents of the underlying host impacts the portability and stability of your devcontainer configuration. It’s crucial to respect this isolation to maintain portable and reliable Dev Container configurations:- Use initializeCommand and avoid adding dependencies to the VM.
- Opt for named volumes instead of bind mounts, as Docker controls them.
- Consider that “localEnv” in parameter expansion refers to the host VM, not your local machine, even when running locally.
Host Network Stack
By default, the dev container network is isolated from the VM. However, you can configure the devcontainer to use the host’s network stack, which is necessary for port sharing.- For a single container, add
--network=host
in the.devcontainer.json
file: - For multiple containers, use
network_mode: host
in thedocker-compose.yml
file:
Elevated privileges
Some development environments require elevated container privileges. If needed, add the followingrunArgs
to your devcontainer.json
:
.NET Development
The Common Language Runtime (CLR) will crash without elevated privileges. Without these privileges, the language server will fail to start, making IntelliSense, debugging, and other IDE experiences unavailable.Using Private Container Images
Currently, basic authentication (username/password) is supported for most registry types. AWS ECR is also supported only when using AWS EC2 runners.
- Go to your Project Settings > Secrets
- Create a new Container Registry secret with the appropriate registry URL and credentials. For detailed instructions, see the Secrets documentation.
- The environment will automatically authenticate with the registry using the credentials you provided.
References
- Refer to containers.dev/implementors/json_reference/ for the reference documentation of devcontainer.json format.
- For a catalog of Dev Container features, visit containers.dev/features.