概要
ある案件で、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を開くとこんな画面が現れる。
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
へ続く