Creating a Development Environment Using VS Code's Dev Container
A sequel article has been posted 🥳🎉 (June 8, 2023): [Sequel! Dev Container] Creating a cloud development environment with GitHub Codespaces .
Introduction
Hello. Torii here, from the team[^1][^2] Common Services Development Group that develops payment platforms used by multiple services.
Finding your IDE doesn't work even though you created it according to the procedure manual; having to check how different-version SDKs work and install them separately for each product; and so on... I suspect a lot of people reading this article have experienced woes like these when creating a local development environment. Creating a local development environment is one of the more tedious tasks that can befall new product development members.
In this article, I want to share an example of how Visual Studio Code (from here on, VS Code)'s Dev Container was used to create a development environment, simplify it, and make it the standard one.
What is VS Code's Dev Container?
A Dev Container environment is a development environment created using the VS Code Dev Containers extension. You can use it if both VS Code and Docker are available. (Windows / Mac / Linux.)
As the following figure shows, launching Dev Container lets you use a Docker container as a full-featured development environment from within VS Code. Mount the source code from the host machine, and the VS Code extension will get installed inside the container. That means there's no need to consider conflicts with the libraries that are already installed. For example, when developing on the host machine, if the specified version of node.js
for another project is different, you might need to manage the version of node.js
with n package and — depending on the situation — possibly switch versions.
Cited from Developing inside a Container
The details for the Dev Container environment (the VS Code settings, extensions, libraries to install, services to start, etc.) can be defined in devcontainer.json
, Dockerfile
, and docker-compose.yml
. The Dev Container environment will be built automatically using these settings, making things vastly simpler than installing everything separately. The environment creation procedure document also only goes up to building the Dev Container. There's also no need to consider OS differences when multiple people are doing the development work.
Procedure for creating a Dev Container environment
In this example, we want to create a new React app using Create React App.
Environment used
- PC: Surface Laptop 4
- Windows 10: 21H2 (WSL2)
- WSL2: Ubuntu 20.04
- VS Code: 1.73.0
Prerequisites
- VS Code is installed.
- Docker is installed (on WSL2 if using Windows).
- Docker Desktop for Windows/Mac is installed.
1. Install the Dev Containers extension
First, open VS Code in the directory you want to use as the workspace. Next, install the Dev Containers VS Code extension. Remote Development (which includes Dev Containers) is also okay.
2. Start setup with Reopen in Container
Click the icon at the bottom left and select Reopen in Container from the menu at the top of the screen. (Create Dev Container will create the Dev Container in another directory.)
3. Select the settings for the Dev Container environment you want to create
In this example, we chose Ubuntu.
4. Select the version of the Docker container image
5. Select the features you want to add
In this example, we chose Node.js (via NVM) and yarn
, which are required to create a React app. Select the features you want to add and click 🆗 to start building the Dev Container.
6. Dev Container build complete
When the build is complete, the VS Code connected to the Dev Container will launch automatically. You'll see that a file .devcontainer/devcontainer.json
has been created, and Dev Container
is shown in the bottom left. (Previously, .devcontainer/Dockerfile
also used to be created.) Open the terminal in VS Code (ctrl + shift + @
) and run the following command, and you'll see that the required libraries have been installed.
console $ node -v v18.12.1 $ yarn -v 1.22.19
Next, run Create React App.
console $ npx create-react-app typesript
A prompt will appear, showing that you can go ahead and create it as is. (Creating the React app and confirming that it launches aren't the main topic, so I'll skip them.)
How do you like that? If you've ever manually installed node.js
, yarn
, and create-react-app
, I think you'll see how much simpler this way is.
Next, let’s build the Dev Container environment that we created in this example.
Building an existing Dev Container environment
Prerequisites
The prerequisites are the same as for creating the environment.
- VS Code is installed.
- Docker is installed (on WSL2 if using Windows).
- Docker Desktop for Windows/Mac is installed.
1. Open the Dev Container workspace on the host machine
First, open the workspace you created earlier in VS Code on the host machine.
Note: If the Dev Containers extension isn't installed
If the Dev Containers extension isn't installed, please install it in the recommended way shown in the following figure.
2. Select Reopen in Container
If the Dev Containers extension is already installed, a configuration file for the Dev Container like in the following figure will exist, so you'll be asked if you want to reopen in the Dev Container. Select Reopen in Container, and building the Dev Container will start.
2. Environment creation complete!
With that, you're all done building the pre-created Dev Container environment. From now on, you can also launch it by selecting Reopen in Container in the same manner. In Windows, you can also open it directly from the taskbar's VS Code context menu, as shown below.
A command like the one below is necessary when completing creation for launching the React app, but we'll discuss the setup for it later.
console // node.js package installation $ yarn install
You can create the pre-created environment this way in very few steps.
Sample devcontainer.json
Next, I'll show you an example of my own Dev Container setup. The VS Code settings and extensions define a linter, formatter, and so on. There are also settings for other development support functions, so please do check it out if you're interested.
json { // Set the Dev Container's name "name": "test-devcontainer", // Specify the container launch options // --name Specify the name of the Docker container to build // If this isn't specified, generate it randomly "runArgs": ["--name=test-devcontainer"], // Docker container image "image": "mcr.microsoft.com/devcontainers/base:jammy", // VS Code settings "settings": { "stylelint.validate": ["css", "scss"], "scss.validate": false, "css.validate": false, "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": true, "source.fixAll.stylelint": true }, // sticky scroll settings "editor.stickyScroll.enabled": true, "editor.stickyScroll.maxLineCount": 5, "workbench.colorCustomizations": { "editorStickyScroll.background": "#00708D", "editorStickyScrollHover.background": "#59A2B5" }, // Settings to import with absolute path in typescript "typescript.preferences.importModuleSpecifier": "non-relative" }, // VS Code extensions to add "extensions": [ "ms-vscode.live-server", "dbaeumer.vscode-eslint", "stylelint.vscode-stylelint", "Syler.sass-indented", "esbenp.prettier-vscode", "ms-python.python", "streetsidesoftware.code-spell-checker", "naumovs.color-highlight", "burkeholland.simple-react-snippets", "formulahendry.auto-rename-tag", "MariusAlchimavicius.json-to-ts", "dsznajder.es7-react-js-snippets", "styled-components.vscode-styled-components", "Gruntfuggly.todo-tree", "42Crunch.vscode-openapi", "mhutchie.git-graph" ], // Settings (recommended) for users running it in the container "remoteUser": "vscode", // Libraries to install "features": { "ghcr.io/devcontainers/features/node:1": { "version": "lts" }, "ghcr.io/devcontainers/features/python:1": { "version": "3.9" } }, // Commands to run when the Dev Container is created "postCreateCommand": "sh .devcontainer/post-create.sh" }
If you didn't run yarn install
separately in the pre-created environment above, you can get it done automatically when the environment is created, by defining it with the postCreateCommand
option. Personally, I create a separate script and run the sequence of commands required after the container has been created.
.devcontainer/post-create.sh
# Adding supplementary git bash commands
echo 'source /usr/share/bash-completion/completions/git' >> ~/.bashrc
# Settings to pass through the yarn global path
echo 'export PATH="$HOME/.yarn/bin:$PATH"' >> ~/.bashrc
# Installing openapi-generator-cli
yarn global add @openapitools/openapi-generator-cli
yarn install ```
## Perceived pros and cons of adopting it
The following are what I felt to be pros and cons when doing development in the Dev Container environment.
### Pros
- It's easy to simplify the environment creation procedure.
- You don't have to worry about the host machine's OS when working with multiple developers.
- You don't' need to follow a different procedure for each library and package.
- For backend work, it makes heavy use of MySQL and Redis, so it offers even more power.
- Environment creation can be declaratively defined and standardized, so it won't vary from person to person.
- You can also define VS Code settings and extensions.
- You won't run into unexpected bugs due to version differences.
- It won't contaminate the local environment, or conflict with other workspaces.
### Cons
- It can't meet the needs of people who want to use a different IDE from VS Code.
- You can't use your preferred terminal.
- It requires fairly high system specs.
- It's tricky to use while sharing your screen with Zoom.
- Using WSL2 with Windows is rather heavy.
- The Mac version has issues with file I/O.
- These can apparently be resolved by setting up a named volume for `devcontainer.json`[^3].
## Conclusion
What did you think? I hope you got an idea of how handy Dev Container is.
I remember having to pick through a long procedure document to create environments in the past, so I think it’s gotten much easier now. Also, I really got a sense of how useful Dev Container is when we actually invited members from other product development teams to join us as guests for some mob programming, and they were able to get it up and running immediately.
For my next trial-and-error experiments, I want to try the following:
- Tuning Dev Container's performance, referring to the official article.
- Putting Docker on Amazon EC2, and using Dev Container via [ Remote Development using SSH](https://code.visualstudio.com/docs/remote/ssh).
- Doing development using IntelliJ IDEA's [Remote Development](https://pleiades.io/help/idea/remote-development-starting-page.html#start_from_IDE).
- Creating environments on [GitHub Codespaces ](https://github.co.jp/features/codespaces).
[^1]: Other Payment Platform Initiatives Part 1. [[About how we incorporated Domain-Driven Design (DDD) into payment platforms, with a view toward global expansion as well](https://blog.kinto-technologies.com/posts/2022_08_30_start_ddd/).]
[^2]: Other Payment Platform Initiatives Part 2. [[About how a team of people who'd all been with the company for less than a year successfully developed a new system through remote mob programming](https://blog.kinto-technologies.com/posts/2022-12-06-RemoteMobProgramming/).]
[^3]: [ Official article: Improve container performance](https://code.visualstudio.com/remote/advancedcontainers/improve-performance).
関連記事 | Related Posts
[Sequel! Dev Container] Creating a cloud development environment with GitHub Codespaces
[続!Dev Container] GitHub Codespacesでクラウド開発環境を構築
Debugging my React project with VS Code
VS CodeでReactプロジェクトをデバッグしたい話
Deploying SvelteKit to AWS - Irregular Svelte series 06
Building an AWS Serverless Architecture Using Nx Monorepo Tool and Terraform
We are hiring!
【クラウドセキュリティエンジニア】SCoE G/東京・大阪
Security Center of Excellence ( SCoE ) グループについてSCoE グループは、マルチクラウド ( AWS, Google Cloud, Azure ) 環境のセキュリティガバナンスを担当しています。KINTO テクノロジーズ内だけでなく、グループ内の関連組織とも協力しながら、業務に行います。
【フロントエンドエンジニア】新車サブスク開発G/東京
新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、TOYOTAのクルマのサブスクリプションサービス『KINTO ONE』のWebサイトの開発、運用を行っていただきます。