開発環境のコンテナ化


根拠


使用するFedora Silverblue 年の間、私はアップルの壁の庭の所有者の世界(恥のために)に戻って、私が失敗した1つのものは「不変の」ホストの考えで、すべてを封じ込めています.

Unlike other operating systems, Silverblue is immutable. This means that every installation is identical to every other installation of the same version. The operating system that is on disk is exactly the same from one machine to the next, and it never changes as it is used.
Silverblue’s immutable design is intended to make it more stable, less prone to bugs, and easier to test and develop.


SilverBlueは、すべてをコンテナ化することを奨励しています.私はもはやLinuxマシンからは動作しませんが、私はこの哲学に続くことを決めた.

クリーンホスト


このワークフローを使用すると、ホストを原始的な状態に保つことができます.たとえば、サンドボックされているGUIアプリの一握りを除いて、私の個人的なMacにはDockerしかインストールされていません.これは重要です、あなたのホストに直接パッケージをインストールすることは、どのバイナリとライブラリがあなたのOSプロバイダーから、そして、ユーザーがインストールされているかをdisentangleすることを難しくすることができます.Linuxシステムでは、従来のパッケージマネージャは「Base Bootimage」を知らない.これは多くのハードバグと予期しない結果の更新中に見つけるにつながる.注:MacOS、MacOS Catalina、重要なOSファイルの場所から始まるために/usr/bin/ are mounted on a dedicated read-only system volume デフォルトでこの厳密な問題を解決する.しかし、これは2の点2で概説されるように、それ自身の問題のセットをつくりますthis comment 自作の管理者から.

自由への自由


これまで、いくつかのコマンドをかろうじてブログやスタックオーバーフローの答えから理解し、ちょうどあなたの指を交差し、あなたの息を保持したEnter あなたの端末のキー?コンテナ内で開発中に何かが壊れたら、単にそのコンテナを捨てて新しいものを作成できます.開発コンテナの内部では、恐るべきパッケージをインストールすることができず、最悪の場合には、新しいコンテナを作成することによって、元の状態にロールバックすることができます.

これ以上の紛争


簡単にそれぞれのプロジェクトのための専用の環境を作成することができます.という考えに似ている venv , OSレベルを除く.あなたのホストは、あなたが2年前からあなたのコースのうちの1つのためにチュートリアルに従うためにインストールしなければならなかったそのランダムな必須のパッケージをもはや含まなければなりません.

統合環境


あなたのチームの誰もが同じOS(Linuxディストリビューション)にある.さらに、開発コンテナのイメージがプロジェクトの必要な開発ツールのセットをインストールすることを確認できます.これは多くのケースを解決しなければならない.プロジェクトのDockerイメージをソースコントロールに確認するか、コンテナレジストリにアップロードできます.

動作方法


高いレベルでは、それぞれのプロジェクトのためのDocker画像を維持したり、いくつかの長期的な“ペット”コンテナの周りを維持するのは簡単です.BINDマウントを使用すると、すべてのソースコードファイルをホストに保持し、コンテナからアクセス/更新できます.
ホストと開発コンテナ間の統合の量を調整できます.たとえば、Linuxのワークステーションにいる場合は、開発コンテナで作業を行うことができますホストのユーザーディレクトリのホームディレクトリ、ウェイランドとX 11ソケット、ネットワーク、リムーバブルデバイス(USBスティックのような)、Systemdジャーナル、SSHエージェント、D - Bus、Ulimits、/devとUdevデータベースなどを提供することによって、あなたの開発コンテナでの作業をほとんど区別できない感じToolbox ).

リモートコンテナ拡張


上記の全てを手動で行うことができます.
docker run -it -v $(pwd):/workspace development-container /bin/bash
これはカレントワーキングディレクトリを/workspace コンテナ内のディレクトリとbashシェルにアタッチします.しかし、これは面倒です.
幸いにも、あなたのプライマリコードエディタとしてVisual Studioのコードを使用する場合Remote-Containers extension それは非常にコンテナの開発環境のワークフローに従うように簡単になります.
上記の多くを自動化することによって、拡張子はコンテナとエディタとターミナルを統合します.そして、すべてがあなたのホストで動いているかのようにVSコードを使うことができます.たとえば、VSコード拡張子をコンテナにインストールし、通常通りに使用できます.また、どのように多くの統合をカスタマイズすることができます、あなたが前にインストールしたい拡張機能を使用して devcontainer.json ファイル.

必要条件

  • Docker CLIとエンジン
  • ビジュアルスタジオコード
  • リモートコンテナ拡張
  • 作成.ディレクトリ名


    あなたが必要になります.devcontainer/ 各プロジェクトのディレクトリ.これはリモートコンテナが探すディレクトリで、開発コンテナ用のDockerFileを格納するのに使われますdevcontainer.json 設定ファイル.
    プロジェクトを格納するディレクトリを作成し、サンプルファイルを作成します.
    mkdir my-project && cd my-project
    echo $'#!/bin/bash\necho "hello word"' > hello.sh
    
    ではコマンドパレットを開く⌘⇧p )とリモートコンテナの型:開発コンテナ設定ファイルを追加します.

    そこから始めることができる多くのベースイメージがあります錆プロジェクトを作成し、錆ベース画像を探しているとしましょう.

    このイメージのために、それから、あなたはOSバージョンを選択することを促します(錆DockerイメージはDebianベースであるので起こります、そこで、我々はここでDebian版を選びます).

    次のステップでは、あなたのDevコンテナにすばやく機能/拡張機能を追加します.これは本質的にはdevcontainer.json 私たちがもう少し詳細に調査するconfigファイル.ここで魚の殻とgitを選びました.

    次のいくつかの手順では、これらの余分な機能のバージョンを選択するプロンプトが表示されます.
    この後.devcontainer ディレクトリはDockerfileとともに生成されますdevcontainer.json ファイル.
    詳しく見ましょうdevcontainer.json . これは、有用なコメントのフィールドの各説明をたくさん付属しています.
    // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
    // https://github.com/microsoft/vscode-dev-containers/tree/v0.231.1/containers/rust
    {
      "name": "Rust",
      "build": {
        "dockerfile": "Dockerfile",
        "args": {
          // Use the VARIANT arg to pick a Debian OS version: buster, bullseye
          // Use bullseye when on local on arm64/Apple Silicon.
          "VARIANT": "buster"
        }
      },
      "runArgs": [
        "--cap-add=SYS_PTRACE",
        "--security-opt",
        "seccomp=unconfined"
      ],
    
      // Set *default* container specific settings.json values on container create.
      "settings": {
        "lldb.executable": "/usr/bin/lldb",
        // VS Code don't watch files under ./target
        "files.watcherExclude": {
          "**/target/**": true
        },
        "rust-analyzer.checkOnSave.command": "clippy"
      },
    
      // Add the IDs of extensions you want to be installed when the container is created.
      "extensions": [
        "vadimcn.vscode-lldb",
        "mutantdino.resourcemonitor",
        "matklad.rust-analyzer",
        "tamasfe.even-better-toml",
        "serayuzgur.crates"
      ],
    
      // Use 'forwardPorts' to make a list of ports inside the container available locally.
      // "forwardPorts": [],
    
      // Use 'postCreateCommand' to run commands after the container is created.
      // "postCreateCommand": "rustc --version",
    
      // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
      "remoteUser": "vscode",
      "features": {
        "git": "latest",
        "fish": "latest"
      }
    }
    
    This section Docker CLIでできるほとんど何でも指定できます.例えば、runArgs キーはコンテナーを実行するときに使用するDocker CLI引数の配列を指定できます.
    生成されたDockerFileも全く自明です.
    # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.231.1/containers/rust/.devcontainer/base.Dockerfile
    
    # [Choice] Debian OS version (use bullseye on local arm64/Apple Silicon): buster, bullseye
    ARG VARIANT="buster"
    FROM mcr.microsoft.com/vscode/devcontainers/rust:0-${VARIANT}
    
    # [Optional] Uncomment this section to install additional packages.
    # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    #     && apt-get -y install --no-install-recommends <your-package-list-here>
    

    さらにDockerFileとdevContainerをカスタマイズします。JSON


    編集しましょうdevcontainer.json ファイルとDockerFile“DockerからDocker”をサポートする.
    一方、「開発中にDockerとDockerを使用したい場合はどうすればよいのでしょうか?」という疑問があります.あなたの開発コンテナの中にDockerエンジンをインストールして、「Docker in Docker」を走らせることが可能ですが、これは説明される理由の数に推薦されませんhere . より多くの意味をなすのは、開発コンテナにDocker CLIとDocker構成だけをインストールし、コンテナの中からホストのDockerエンジンを呼び出して新しいコンテナを起動することです.
    DockerFileを修正してDocker CLIをインストールします.
    # Install Docker CLI.
    RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
        && apt-get -y install \
        ca-certificates curl gnupg lsb-release \
        # libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang make build-essential \
        && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
        && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
        && apt-get update && apt-get -y install docker-ce-cli="5:20.10.12~3-0~debian-bullseye"
    # Install Docker Compose.
    RUN curl -sSL "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
        && chmod +x /usr/local/bin/docker-compose
    
    次に、コンテナのDockerソケットをホストのDockerソケットにマウントして、devコンテナからホストのDockerエンジンを制御する必要があります.
    通常、Docker CLIを使ってください.
    docker run -v /var/run/docker.sock:/var/run/docker.sock ...
    
    しかし、我々はまた、経由で同じことを達成することができますdevcontainer.json . 単にmounts キー.また、動作するためにはコンテナとしてrootに接続する必要があります.
    {
        "name": "Rust",
        "build": {
            "dockerfile": "Dockerfile",
            "args": {
                "VARIANT": "bullseye"
            }
        },
        "runArgs": [
            "--cap-add=SYS_PTRACE",
            "--security-opt",
            "seccomp=unconfined"
        ],
        "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
    
    ...
    
        "remoteUser": "root"
    }
    

    開発コンテナの構築と使用


    では、再度コマンドパレットを開き、“Rebuild and Return in Container”に入力します.

    これはDockerfileからコンテナをビルドし、devcontainer.json .
    VSコード端末に行き、OSリリースファイルをチェックしてみてください.
    root ➜ /workspaces/my-project $ cat /etc/os-release
    PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
    NAME="Debian GNU/Linux"
    VERSION_ID="11"
    VERSION="11 (bullseye)"
    VERSION_CODENAME=bullseye
    ID=debian
    HOME_URL="https://www.debian.org/"
    SUPPORT_URL="https://www.debian.org/support"
    BUG_REPORT_URL="https://bugs.debian.org/"
    
    ホストから作成したファイルもあります.
    root ➜ /workspaces/my-project $ ls
    hello.sh
    
    開発コンテナの内部からDockerコンテナを右側に起動することもできます.
    root ➜ /workspaces/my-project $ docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    7050e35b49f5: Pull complete 
    Digest: sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (arm64v8)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    ...
    
    Aを行うdocker ps , VSのコンテナーを作成したVSコードが“vsc - nameプロジェクト名ルートディレクトリ”という名前で実行できます.他のコンテナがホスト上で動作しているのを見ることもできます.
    root ➜ /workspaces/my-project $ docker ps
    CONTAINER ID   IMAGE                                             COMMAND                  CREATED         STATUS         PORTS     NAMES
    c3ceb43b1f81   vsc-my-project-0a087c264c6455c09d6a06823954d1e2   "/bin/sh -c 'echo Co…"   2 minutes ago   Up 2 minutes             keen_knuth
    
    また、コードは自動的にあなたのコンテナー内のポートをホストに転送するので、たとえば、Webアプリケーションでハッキングしている場合は、開発コンテナからサーバーを起動し、ホストのブラウザを右側のポートに向けるだけで動作します.

    結論


    それはなぜあなたの開発のワークフローを格納するあなたの時間価値があるのかを簡単に見ていた幸いなことに、リモートコンテナの拡張では、まったく時間がかかりません.
    また、既存のコンテナに接続するように、リモートコンテナの拡張機能を行うことができます他のクールなものの束もありますそこから、すべてのお気に入りとコードの拡張子をインストールすることができます.他のコンテナエンジンでも動作できますPodman . 私は非常にそれをチェックアウトをお勧めしますhttps://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers !