83
69

More than 3 years have passed since last update.

VSCode devcontainerを使って面倒な開発環境を作る

Last updated at Posted at 2021-03-24

概要

ある案件で、opencvを使って映像を扱うサービスを構築した。
各開発者の開発環境をどう作るか頭を悩ませた。
opencvをビルドするのに2時間近くかかってしまうし、gstreamerのインストールやらもろもろのライブラリやら考えると、環境整備だけで気が遠くなりそう。

検索していると以下のような記事を見かけた。

あらかじめ開発環境をdocker image化しておき、それをそれぞれの開発PC上で起動する事ができれば、開発参画が簡単になるのでは?
ということで、試してみた。

要件

  • 開発言語はgolang1.15
  • opencv4.5.1
  • gocv0.26.0
  • gstreamer
  • Redis

gstreamerで映像を受け取ってgocvで画像処理。結果をRedisに格納。

手順

事前に必要なものは

module desc
VSCode IDE
VSCode Remote Container VSCodeの拡張モジュール
github token ghcr.ioにアクセスするためのtoken
Docker for windows windows上での開発なので
VcXsrv dockerコンテナ内で扱う映像を表示するため

試した内容は、上のブランチの内容を少し変更したもの。

project_root/
   .devcontainer/
      devcontainer.json
      (*Dockerfile)
      docker-compose.json

上記を作成する。開発環境用のコンテナのみでいいならdocker-compose.ymlは不要だが、どうせなら必要なサーバー一式全て立ち上げてしまいたいので、今回はDockerfileは不要。

1. 自前のdevcontainerを用意する

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.137.0/containers/go/.devcontainer/base.Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT}

vscode-vs-try-goに含まれるDockerfileにはこのように書かれている。
つまり、goのバージョンごとにdevcontainerの元となるimageが公開されている。これをもとに、自分専用の開発環境イメージを作成し、それをdockerリポジトリから各開発者の環境にpullできるようにする。

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.137.0/containers/go/.devcontainer/base.Dockerfile
ARG VARIANT="1.15"
# ARG OPENCV_VERSION="4.3.0"
# for gocv v0.26
FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT}
ENV OPENCV="4.5.1"

WORKDIR /src
# https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html
# Install minimal prerequisites (Ubuntu 18.04 as reference)
RUN apt update && apt install -y cmake g++ wget unzip libgtk2.0-dev pkg-config glib-2.0
# Install gstreamer
RUN sudo apt-get -y install \
    gstreamer1.0-dev \
    gstreamer1.0-tools \
    gstreamer1.0-doc \
    gstreamer1.0-libav \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    libgstreamer1.0-dev \
    libgstreamer-plugins-base1.0-dev \
    libgstreamer-plugins-bad1.0-dev

# Download and unpack sources
RUN wget -O opencv.zip https://github.com/opencv/opencv/archive/${OPENCV}.zip
RUN wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/${OPENCV}.zip
RUN unzip opencv.zip
RUN unzip opencv_contrib.zip
# Create build directory and switch into it
RUN mkdir -p build
WORKDIR /src/build
# Configure
RUN cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-${OPENCV}/modules -D OPENCV_GENERATE_PKGCONFIG=YES -D CMAKE_BUILD_TYPE=Release -D WITH_GTK=ON -D WITH_GSTREAMER=ON ../opencv-${OPENCV}
# Buildpkg
RUN cmake --build -j4 . | tee error.log
RUN make install

そこで上記のようなDockerfileを作成。ここで作成したイメージをdocker repositoryにpushする。

  • 今回はGithub Container Repositoryを使用した。
  • 公開されているdevcontainer-go1.15のイメージにgstreamerを追加し、それからWITH_GSTREAMER=onオプション付きでopencvをビルドしている。

  • gocvがopencvとリンクするために、opencvはOPENCV_GENERATE_PKGCONFIG=YESオプション付きでビルドし、PKG_CONFIG_PATHを環境変数に設定する必要があった。opencv単体をインストールするのではなくgo get gocv.io/x/gocvしてgocv配下でmakeすればこの辺りの手間はなくなるかもしれない。

docker push ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest

でpush。

2. .devcontainer配下に必要なファイルを作成する

devcontainer.json

{
    "name": "Go",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/app",
    "extensions": [
        "golang.Go"
    ],
    "remoteUser": "vscode"
}

オリジナルから一部変更。imageではなくdocker-composeなので、buildを削除して
dockerComposeFileとserviceを追加している。

docker-compose.yml

version: '3'
services:
  redis:
    image: redis:latest
    ports:
      - "6379:6379"
  app:
    image: ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest
    environment:
      - "DISPLAY=host.docker.internal:0"
      - "LD_LIBRARY_PATH=/usr/local/lib"
      - "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig"
    volumes:
      - ../:/app:cached
    command: sleep infinity
    links:
      - redis

以上2つのファイルをプロジェクトに追加。

プロジェクトディレクトリ上でvscodeを開くとこんな画面が現れる。

image.png

Reopen in Container を選べば、docker-composeが起動してコンテナ内に切り替わる。

評価

dockerコンテナ内で開発するのは理想ではあるものの、敷居が高い印象がある。
だが、vscode devcontainerはあらかじめ開始するための各言語のキットが用意されており、簡単に開始する事ができるのが好印象だと感じた。特にContainer内外の切り替えが殆どシームレスな感覚で移動できるため、必要な時だけContainerに入るような運用もできた。

単純なWebアプリケーションとデータベース程度なら必要性は低いかもしれないが、環境を作るのが面倒なサービスなら、docker化するメリットは大きいのではないだろうか。

もちろん、それなりのPC性能が要求される事はお忘れなきよう。

メリット

  • 開発環境作成のハードルが高い場合、開発参画へのハードルを下げられる
  • 全開発者が完全に同じ環境で開発できる
  • 構成が変わっても、最初にイメージを作成する時間+pullする時間以外かからない
  • ci環境やprod環境と大きく変わらない環境で開発できる

デメリット

  • 開発環境がVSCodeに限定される
  • 開発者全員がDockerをインストールしなければいけない
  • 開発者全員がDockerに慣れなければならない
  • 素にインストールするのと比べると、それなりに重くはなる

結局、一番の障壁は「開発者のDocker慣れ」だと思う。重さの問題はお金で解決できるが、慣れの問題は価値観が絡むので、なかなか難しい。

もっとこうしたらいい、などご意見あればください。

https://qiita.com/kishibashi3/items/2b1e342d1ce3957b3dc8
へ続く

83
69
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
69