Skip to content
:tech
← Articles

AI-translated. Read the original in KoreanEmbedded slides, videos and images remain in their original language.

Developing Inside a Container with VS Code

Developing Inside a Container with VS Code

Containers grow more popular by the day. If you started out deploying with Docker, Kubernetes, and other container tools, you may find it hard to imagine the bewildering range of unpredictable problems that could arise in deployment environments built with tools such as capistrano or fabric.

Containers can also bring development and deployment environments much closer together. With a well-configured docker-compose setup, you can reproduce something very close to production without too much trouble. That gives you confidence that if it runs locally, it will run when deployed. Nobody wants to develop nervously and deploy even more nervously, right?

But we always want more. Unless you write code in a plain text editor, you probably use an IDE. Wouldn’t it be great if your IDE could work inside the container too? This post explains why an in-container development environment is useful and how to set one up with VS Code.

Why run an IDE in a container?

A consistent environment for every developer

After cloning a repository, the first thing you usually do is read README.md carefully: you need to know how to develop and test the project. Fortunately, most languages have package managers. You fetch libraries with gem, npm, pip, mod, and so on. Run pip install -r requirements.txt and you’re done, right? Not quite—the Python version is wrong. You need Python 3.8.0. But another project still uses Python 2. You can’t keep reconfiguring Python every time you switch projects, so now you need virtualenv. And then there’s rvm, nvm… why is there so much to set up?

Even after putting the effort into containerizing an application with Docker, we often repeat this process. The container doesn’t contain the tools needed for development and debugging, and local tools may be required for the IDE’s IntelliSense features. We built a container, but can’t really use it for local development.

Setting up tests

Even when an application runs through docker-compose up, tests may still run in a local environment. Differences between development and deployment dependencies may leave the container without a test environment, and attaching a debugger can be difficult. Some languages support remote debugging, but you may have to start a test before connecting the debugger, or lose the convenience of clicking a single test button in your IDE to debug it.

Local test environments, meanwhile, make external dependencies for integration and acceptance tests tedious to configure. A good docker-compose setup can start all your test databases and connect them with one command. Locally, you need to start MySQL, Redis, and Elasticsearch, then configure each host separately through environment variables. Avoiding that hassle isn’t a good reason to write only unit tests!

Setting it up

For the details, see https://code.visualstudio.com/docs/remote/containers. I’ll cover just the basic configuration here.

VS Code’s Remote Container extension lets you configure a development environment inside a container. Like docker-compose, it uses a Dockerfile to define the environment. Create a .devcontainer folder at the project root and add a devcontainer.json file.

{
    "name": "Python 3",
    "dockerComposeFile": [
        "../docker-compose.yml",
        "docker-compose.yml"
    ],
    "service": "test",
    "workspaceFolder": "/app",
    "settings": {
        "python.pythonPath":
        "/usr/local/bin/python",
        "python.linting.flake8Enabled": true,
        "python.testing.pytestEnabled": true
    },
    "postCreateCommand": "apt-get update && apt-get install -y git && pip3 install flake8",
    "extensions": [
        "ms-python.python",
        "littlefoxteam.vscode-python-test-adapter"
    ]
}

This is an example devcontainer.json for a Python project. It includes the project’s docker-compose.yml and also .devcontainer/docker-compose.yml, which overrides particular settings for development.

Put shared VS Code settings in the settings field. Settings that developers should choose individually can go in their own local configuration files.

Use postCreateCommand to install development dependencies. Naturally, these are not included in the Docker image used for deployment.

List VS Code extensions under extensions. Because the environment runs inside a container, extensions installed after launching VS Code disappear when the image is rebuilt. Listing them here ensures they are installed whenever the image is built and VS Code starts.

Launching it

With the extension installed and .devcontainer configured, run Remote-Container: Reopen in Container.

And there it is: VS Code running in your container environment!

Conclusion

This feature was first released in May 2019, so it is still fairly new at the time of writing and has some rough edges. Even so, our tests suggest it is well worth trying. The days of walking every new developer through a manual project setup may finally be coming to an end.

Advantages of a container-based IDE setup

  • No separate per-project environment setup with tools such as rvm or virtualenv.
  • Much easier testing when databases or other external services are required.
  • An easy way to keep development environments consistent across the team.

Disadvantages of a container-based IDE setup

  • High resource usage.
  • Consequently, higher battery consumption.
  • Features such as IntelliSense can be a little slower.
All articles