Dev Env using docker-compose and VSCode - Part 2
Tags: developers, vscode, docker
Published: 2021-01-02 06:47:38

---
title: Dev Env using docker-compose and VSCode - Part 2
published: true
description: configure VS Code to use the development environment within docker
tags: developers, vscode, docker
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/98ywsvbvdyrqtyhmq6se.png
---

Continuing from the [previous post](https://dev.to/mandraketech/dev-env-using-docker-compose-and-vs-code-1ofb) where we setup a docker-compose file, in this part, we will connect to the environment and do some development.

Remember that just deployed a docker-compose based environment with no code, just a volume, in it. 

Prerequisites:
- VS Code installed on your machine
- Remote Containers extension installed within VS Code ( `ms-vscode-remote.remote-containers` )
- git

# Step one: Connecting to the container using VS Code

Most of the hard work done. Use the Remote Container extension to connect to the webapi container. To do that, start with `F1`, and type `Attach to Running Container`. On selecting this option, you will see the list of containers running. Select the one that has `webapi` in its name. The one on my setup reads this: `my-dev-env-webapi-1`.

After a little bit of "installing" and "preparing", VS Code starts up. Open the folder `/usr/src/app`. This is the location where we have our `webapi-code` volume mounted. You are now working inside the container.

Now, when you start the terminal inside VS Code, it is already running inside the container. And the prompt should show you so.

When in the terminal run the following:
```
cd /usr/src/app
git clone https://github.com/navneetkarnani/nodejs-db-test
cd nodejs-db-test
npm install
```

This will checkout code that I have written to connect to the mentioned database, and fail if it cannot. To test it, run the following:
```
npm start
```

And you should see a failure that the environment variable MONGO_DB is not defined.

# Updating the environment

We know that our application would see this in the production environment, and that is why we fail, if it is not available. So, lets update our runtime to have that, and be as close to the production environment as possible.

We can close this window. And go back to the docker-compose.yaml in `my-dev-env`.

In the services section, under webapi, lets add an environment variable that our app is expecting. The entire webapi section will look like this:

```
  webapi:
    image: node:lts
    environment:
      - MONGO_DB=mongodb://mongo:27017/test
    volumes:
      - webapi-code:/usr/src/app
      - webapi-root:/root
    command: ["/bin/bash", "-c", "--", "while true; do sleep 86400; done"]
```

Notice the extra `environment` section we added. Pointing the `MONGO_DB` to the host named `mongo` at port `27017`. The name `mongo` will resolve to the name of the service we used in the docker-compose file for the database. If you have a different name, do change it to the same. Docker will do a DNS lookup internally, so our apps don't need to know the IP addresses.

If you try to resolve this from your host (the machine on which docker is running), this will not resolve. Nor will you be able to connect to this database, because we have not opened up any ports from within the container for the external world. All safe.

# Testing the configuration

Then go back and run the `docker-compose up -d` command.

The console should show:
```
Recreating my-dev-env_webapi_1 ... done
my-dev-env_mongo_1 is up-to-date
```

Attach to the container again, using the "Attach to Running Container" action, as before. You may also use the small green button on the bottom left of the VS Code window as a shortcut.

Start the terminal inside VS Code, and then:
```
cd /usr/src/app/nodejs-db-test
npm start
```

You should see: 
```
> sample@0.0.0 start /usr/src/app/nodejs-db-test
> node ./bin/www

Connected to database
```

# Multiple coding containers ? Really advanced stuff !!

So, if you wanted multiple containers where you want to code, you could easily extend this to do that. Just make sure the volume mounts are unique / appropriate. eg: you want to add another service named: `auth-server` that runs on nodejs. Just copy the `webapi` section and make appropriate changes.

On the VS Code side, there is a small set of steps you will need to remember. Why ? because Remote Container extension, by default, keeps the VS Code settings based on the image used. And, if multiple containers have the same image, you will just keep seeing things overwriting each other, and not understand what is happening.

After a lot of hunting with the documentation, I found that Remote Containers created the same `devcontainer` files, but automatically, and wired up to use the image name. 

The documentation is here, and not very explicit. Look for in this: [Named Containers](https://code.visualstudio.com/docs/remote/attach-container#_attached-container-configuration-files) 

Here are the steps to make it work for me, your results may vary based on your OS. I am on MacOS, so the Global setting are located under `~/Library/Application Support/Code/User/globalStorage/ms-vscode-remote.remote-containers`. When we connect to a container, the configuration is created under the `imageConfigs` directory. If you want to not use a universal config for the image, because you use the same ( node:lts ) for all your dev containers, but with different directories for checkout / breakpoints, etc, then you need to copy the file from there to `nameConfig` with the name of the container as the name of the file. I filed an [Issue on Github](https://github.com/microsoft/vscode-remote-release/issues/4237) to get some usability improvements.

So, coming back. Here are the steps I ran on my laptop:

```
cd ~/Library/Application\ Support/Code/User/globalStorage/ms-vscode-remote.remote-containers
cd nameConfig
cp ../imageConfigs/node%3alts.json my-dev-env_webapi_1.json
```

# In Summary
In these two articles, we created a docker-compose file that enabled us to work entirely in a container, with no code locally stored.

As containers, and related technologies mature, new use cases replace old ones, and this one is a great hybrid between running a VNC based environment, vs splitting the load on the server and the client. Plus, the added benefit that the dev environment can look closer to the production one.

This can enable interesting workflows, like doing development on a remote docker host, maybe in a datacenter or on Digital Ocean [Referral Link](https://m.do.co/c/ea02167f0f0f) where the memory needs of the application are larger than the one available on the developer laptop.

This article originally published at: https://blog.mandraketech.in/dev-env-using-docker-compose-and-vscode-part-2