In this installment of our series, we’re going to explore Visual Studio Code’s Development Containers. This feature allows you to run VSCode directly within your project’s Docker container, enabling you to develop and debug your application from within the same environment where it will ultimately be deployed. By doing so, you can ensure a consistent and reproducible development environment across different machines, without having to install or configure any dependencies locally (except for Docker and VSCode itself).
Before proceeding with this step, ensure that you have the following extension installed:
Dev Containers Extension: In Visual Studio Code, install the “Dev Containers” extension by opening the Extensions view (Ctrl+Shift+X
on Windows/Linux or Cmd+Shift+X
on macOS), searching for “Dev Containers,” and installing the extension. Alternatively, you can install the “Remote Development” extension pack by Microsoft, which includes the Dev Containers and a few other extensions that let you open any folder in a container on a remote machine, as well as on your local computer.
With the prerequisites in place, we can now configure VSCode to use a Dev Container for our project.
Create a .devcontainer
Folder: In the root of your project, create a new folder named .devcontainer
.
Create a devcontainer.json
File: Inside the .devcontainer
folder, create a new file named devcontainer.json
with the following content:
{
"name": "MERN Backend Dev Container",
"dockerComposeFile": ["../docker-compose.yml"],
"service": "app",
"workspaceFolder": "/workspace",
"shutdownAction": "stopCompose",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
}
}
This configuration file tells VSCode to use the docker-compose.yml
file in the parent directory to build and run the Dev Container. It also specifies that the Dev Container should be based on the app
service, and that the workspace folder should be mounted at /workspace
inside the container. Moreover, it directs VSCode to halt the Docker Compose services when the Dev Container is closed.
The extensions listed in the devcontainer.json
file are specific to the Dev Container environment. Even if these extensions are already installed in your local VSCode environment, they won’t automatically be available inside the Dev Container. This is because the Dev Container is essentially a separate, isolated development environment running inside a Docker container. Therefore, any extensions you want to use inside the Dev Container must be explicitly listed in the devcontainer.json
file.
Before we can start using the Dev Container, let’s change the docker-compose.yml
file to run Express app container without starting the server. This is because we want to start the server manually from within the Dev Container.
- command: /bin/sh -c "npm run seed && npm run dev" # Run the seed script and then start the app
+ command: /bin/sh -c "sleep infinity" # Keep the container running
The command sleep infinity
will keep the container running indefinitely, allowing us to start the server manually from within the Dev Container.
With the Dev Container configured, you can now start developing and debugging your application within the container.
Open the Command Palette: In Visual Studio Code, press Ctrl+Shift+P
(or Cmd+Shift+P
on macOS) to open the Command Palette.
Open the Project in a Dev Container: In the Command Palette, search for “Reopen in Container” and select the option “Dev Container: Reopen in Container.” This will build the Dev Container and open your project inside it.
Start the Development Server: Once the Dev Container is ready, open a new terminal in Visual Studio Code (`Ctrl+Shift+“) and run the following command:
npm run dev
This will start the development server using nodemon
and ts-node
. You should see the following output in the terminal:
Connected to MongoDB
Connected to Redis
Server is running on port 3000
You can now make changes to your code, and the server will automatically restart to reflect those changes. You can also debug your application directly within the Dev Container by setting breakpoints and using the built-in debugger in VSCode.
By setting up a development environment with VSCode Dev Containers, you can ensure a consistent and reproducible development experience across different machines. The Dev Container encapsulates all the dependencies and configurations required for your project, eliminating the need for manual setup and reducing potential conflicts with other projects on your local machine.
In the next step, we’ll create a production Docker image for our application so we can deploy it to a cloud provider. Stay tuned!