[PYTHON] [January 2020] Let's start the explosive "development container" with VS Code's Remote Container in earnest.

Start dash from "Development environment + container with all projects" with Remote Conainer of VSCode! ??

Are you using VS Code's Remote Conainer for development? If you just want to enter an existing container, you can use Remote SSH, but let's use Remote Container as a "part of the local development environment", rather as ** local development environment = Remote Container **. It's Reiwa! ~~ (It's already been 2 years ...?) ~~

Especially when using a Mac, Python, PHP, Ruby, etc. are included from the beginning, so there is a ** development environment **, but these are relatively built into the macOS ecosystem, so they are unnecessary. You can't add or remove packages. It breaks easily like brew ... Especially ** in addition to version upgrade **. At all, it will be crazy with a margin. That's why if you're programming with Python or Ruby on your Mac, you'll end up in a situation where you can't go back **. To prevent that from happening, let's get started with "Development with Remote Container" ~!

Introduction of "Dev Container" function

Did you know that there is an item and repository called "Try a dev container" on the original site of Remote Container and the original Github?

"dev container" is a sample of the project that comes with a container with development environment, and a sample of dev-container is prepared for each of the following languages.

For example, the sample for node.js and Javascript has the following tree.

% git clone https://github.com/Microsoft/vscode-remote-try-node nodejs-dev-sample
% cd nodejs-dev-sample
% tree -a -I ".git"
.
├── .devcontainer
│   ├── Dockerfile
│   └── devcontainer.json
├── .eslintrc.json
├── .gitattributes
├── .gitignore
├── .vscode
│   └── launch.json
├── LICENSE
├── README.md
├── package.json
├── server.js
└── yarn.lock

If you exclude only .git with the tree command and display all, it will be as above. What is worrisome here is ... .devcontainer, isn't it? !! The contents Dockerfile and devcontainer.json are as follows.

#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------

FROM node:10

# The node image includes a non-root user with sudo access. Use the "remoteUser"
# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
# will be updated to match your local UID/GID (when using the dockerFile property).
# See https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# Configure apt and install packages
RUN apt-get update \
    && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \ 
    #
    # Verify git and needed tools are installed
    && apt-get -y install git iproute2 procps \
    #
    # Remove outdated yarn from /opt and install via package 
    # so it can be easily updated via apt-get upgrade yarn
    && rm -rf /opt/yarn-* \
    && rm -f /usr/local/bin/yarn \
    && rm -f /usr/local/bin/yarnpkg \
    && apt-get install -y curl apt-transport-https lsb-release \
    && curl -sS https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/pubkey.gpg | apt-key add - 2>/dev/null \
    && echo "deb https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update \
    && apt-get -y install --no-install-recommends yarn \
    #
    # Install eslint globally
    && npm install -g eslint \
    #
    # [Optional] Update a non-root user to UID/GID if needed.
    && if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \
        groupmod --gid $USER_GID $USERNAME \
        && usermod --uid $USER_UID --gid $USER_GID $USERNAME \
        && chown -R $USER_UID:$USER_GID /home/$USERNAME; \
    fi \
    # [Optional] Add add sudo support for non-root user
    && apt-get install -y sudo \
    && echo node ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME \
    #
    # Clean up
    && apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*

# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=dialog

I will post the above explanation later, and then the contents of devcontainer.json are ...

devcontainer.json


{
    "name": "Node.js Sample",
    "dockerFile": "Dockerfile",

    // Use 'appPort' to create a container with published ports. If the port isn't working, be sure
    // your server accepts connections from all interfaces (0.0.0.0 or '*'), not just localhost.
    "appPort": [3000],

    // Comment out the next line to run as root instead.
    "remoteUser": "node",

    // Use 'settings' to set *default* container specific settings.json values on container create. 
    // You can edit these settings after create using File > Preferences > Settings > Remote.
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    // Specifies a command that should be run after the container has been created.
    "postCreateCommand": "yarn install",

    // Add the IDs of extensions you want installed when the container is created in the array below.
    "extensions": [
        "dbaeumer.vscode-eslint"
    ]
}

And, it is a file in a format that is a mixture of container settings and vscode settings.json. You can probably imagine what this setting is, but what happens when you open this folder in VS Code ... give it a try! Before that, if the Docker daemon is not started, please start the Docker daemon in advance. If you are using Windows or Mac, please start Docker for Desktop.

When Docker starts, launch VS Code and open nodejs-dev-sample. Then ... スクリーンショット 2020-01-03 14.10.20.png

dev container configuration found, open in container? I got an inquiry saying ! And when you click Reopen in Container ... スクリーンショット 2020-01-03 14.22.25.png After a while ... it opened! The status bar at the bottom left turns green and you are connected to Remote, and the words "Dev Container: Node.js Sample" are dazzling! That's right. If you have the .devcontainer folder and devcontainer.json settings and the appropriate Dockerfile, it will automatically generate a container that mounts the entire file in the project folder and open the project with VS Code. !!

Also, the noteworthy point of the Dockerfile here is that docker has solved the problem "root" user problem. "Developing in a container" sounds good, but most images run as-is and often leave the user as "root", so the owner of the file being updated in the container is "root". There was an annoying problem with becoming ". If you write a Dockerfile on your own, you can do anything, but you can't write it one by one, and if you write a Dockerfile one by one, it's okay if the development environment gets dirty ** It's a company PC **, isn't it? ?? This Dockerfile politely supports that, so the root user problem has been successfully resolved.

By the way, you can also manage containers from VSCode ... スクリーンショット 2020-01-03 14.23.29.png In this way, you can manage which container is used in which project from VS Code. In particular, ** Docker does not know which folder the Dockerfile was used to launch the container ** (or rather, it creates an image and starts the container, so it doesn't really matter which folder the Dockerfile created the image). This is useful.

How do you use it?

First, let's introduce the original repository. You can tell from the repository name which language the sample project is for.

Actually, if you have the .devcontainer folder, the devcontainer.json settings, and the Dockerfile to be used, it will do it automatically, so only these files are created by copy and paste from the original repository. Is also an ant. However, it is troublesome to copy and paste every time, so let's arrange the procedure as follows.

1. Clone as a template

Clone the above repository with "project name" as follows.

$ git clone https://github.com/microsoft/vscode-remote-try-php my-first-php

The argument after the repository name is the folder name to be created, and the first miso is to clone with another name.

2. Delete and recreate history

Of course, if you just cloned it, it includes all the commit history of the original repository. It's okay to reuse it as it is, but in most cases you'll be worried. So, roughly delete the following .git.

$ rm -rf .git

With this, I completely forgot the past commit history. By the way, let's delete unnecessary files. You don't need anything other than .devcontainer. .Vscode is up to you.

Then, when cleaning is completed, initialize it as a new repository.

$ git init
...

This is the first step for a new development container project!

3. Customize Dockerfile

In an actual project, it is necessary to include DB, Angular, Aws, Firebase, CLI such as Azure, etc., so it is almost impossible to use the Dockerfile as it is. Therefore, put the command to install the necessary tools in the Dockerfile in advance.

I will omit the description of the Dockerfile here. .. ..

4. Customize devcontainer.json

devcontainer.json is a very important file where you can set the project name, forwarding port, required VSCode plugin, etc. A list of settings can be found at:

Let's extract some of the settings used in the sample repository ...

--settings… This is the setting value of VSCode setting.json used in the container. --appPort… Port to forward --postCreateCommand… Command executed after container creation --extensions… VS Code plugin installed on the remote side

Is it an important customization point?

Also, according to the reference, docker-compose.yml seems to be available.

After setting these, if you open the folder from VS Code, the project including the development environment will start immediately!

Summary

When I wrote the introductory part of the function of VScode Remote container, I reviewed the official document ... The volume is not perfect. I was worried about how deep this should be, but since it was an introductory edition, I tried not to touch it (laughs). The links are scattered throughout the text, but the official help for Remote Container is a startling page.

This is the volume that I can write this book ...

By the way, this time we will end here!

Recommended Posts

[January 2020] Let's start the explosive "development container" with VS Code's Remote Container in earnest.
Start multiple containers in VS Code's Remote Container to switch between tasks
Build a Go development environment with VS Code's Remote Containers
Log in to the remote server with SSH
Use Docker development container conveniently with VS Code
Edit and debug the code in the Raspberry Pi with VS Code's SSH connection feature
Allow real-time code checking in Python development with VS Code
[No venv required] The strongest Python development environment created with Remote Containers [VS Code / Docker]