サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

master mind by c++; part5 Docker

今回やること

Docker環境の作成

Dockerとは

仮想環境を作成できるツール ( 参考: いまさらだけどDockerに入門したので分かりやすくまとめてみた - Qiita )

また 10年間のコンテナ技術の進化 - Qiita より下記を抜粋.

しかし、Dockerでは、アプリケーションの実行に必要な環境全体(すなわち、OS上のファイルシステム)を、コンテナイメージを使って直接パッケージ化します。このアプローチは、長い間PaaSユーザーを悩ませてきた一貫性の問題を解決します。一度公開すればどこでも動作するDockerイメージを作成することは、統一された開発・テスト環境を実現することすらできないBuildpackを構築するよりもはるかにスマートです。

さらに重要なのは、Dockerはコンテナイメージを作成する際のレイヤーも導入していることです。レイヤー(つまりコミット)に基づいてビルド、プッシュ、アップデートの操作を実装するのは、明らかにGitを参考にしています。このアプローチの利点は、GitHubと同じでもあります。イメージホスティング倉庫であるDocker Hubによって、あなたとあなたのソフトウェアがグローバルなソフトウェア配布に参加できるので、Dockerイメージの構築はもはや退屈でつまらない仕事ではありません。

Dockerの導入

Docker install

macの場合で説明します. docs.docker.com

このページから Docker Desktop for Mac をダウンロードします.
CPUがM1チップかIntelかでダウンロードするものが変わるので注意してください.

ダウンロードできたら開きます.
まずはコンテナを起動する必要があるので, 表示されているコマンドをターミナルにコピペします.

f:id:inarizuuuushi:20210601150738p:plain

準備はok.

Dockerfileの作成

仮想環境(コンテナ)を作成する上の仕様書であるDockerfileを作成します. ubuntuをベースに構築することにしましょう.

# ベースイメージ
FROM ubuntu:20.04

# 環境変数を設定
ENV HOME /master_mind_cpp
# コマンドを実行するディレクトリの設定
WORKDIR ${HOME}

# install packages via apt  # aptを使って色々install
RUN apt update -y
RUN apt install -y tzdata
RUN apt install -y build-essential cmake vim git libpthread-stubs0-dev libgtest-dev

# copy local files into image
COPY . .

# build
RUN mkdir build
RUN cd build && cmake .. && make

Dockerイメージの作成と起動

$ docker build -t master_mind .

master_mindはイメージ名なので, なんでもいいです. 起動は

$ docker run -it master_mind

root以外のuserで環境を構築したい場合

上記だとrootユーザーで環境が構築されます. ユーザーを指定して環境を構築したい場合は下記のような追記が必要です.
なお, 下記のuser, group, uid, gidには

$ id
uid=uid(user) gid=gid(group) ...

で出力される値を入力します.

FROM ubuntu:20.04

# install packages via apt
RUN apt update -y && apt-get update -y
RUN apt install -y sudo
RUN apt install -y tzdata
RUN apt install -y build-essential cmake vim git libpthread-stubs0-dev libgtest-dev

# setting user
ARG USER_NAME=user
ARG GROUP_NAME=group
ARG UID=uid
ARG GID=gid
ARG PASSWORD=${USER_NAME}

# add sudo to user
RUN groupadd -g ${GID} ${GROUP_NAME} && \
    useradd -m -s /bin/bash -u ${UID} -g ${GID} -G sudo ${USER_NAME} && \
    echo ${USER_NAME}:${PASSWORD} | chpasswd && \
    echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# switch root to user
USER ${USER_NAME}
WORKDIR /home/${USER_NAME}/

# copy local files into image
COPY --chown=${USER_NAME}:${USER_NAME} . .

# build our project
RUN mkdir build -p && rm -rf build/*
RUN cd build && cmake .. && make

また, ARG変数はコマンドラインから, イコールの右辺のデフォルト値の上書きが可能です.

$ docker build -t master_mind . --build-arg USER_NAME=XXX --build-arg UID=11111 ....

などなど.

Github action - docker

公式のものですね. docker build . ... が正常に動くかテストしてくれます.

name: Docker Image CI

 on:
   push:
     branches: [ main ]
   pull_request:
     branches: [ main ]

 jobs:

   build:

     runs-on: ubuntu-latest

     steps:
     - uses: actions/checkout@v2
     - name: Build the Docker image
       run: docker build . --file Dockerfile --tag my-image-name:$(date +%s)

対処したエラーたち

apt install -y cmake

docker buildにて apt install -y cmake を実行中に下記のように入力待ちでinstallが止まってしまう場合は, その前に

apt install -y tzdata

を行うことで解消されます.

 => => # questions will narrow this down by presenting a list of cities, representing                                                         
 => => # the time zones in which they are located.                                                                                            
 => => #   1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc                                                                     
 => => #   2. America     5. Arctic     8. Europe    11. SystemV                                                                              
 => => #   3. Antarctica  6. Asia       9. Indian    12. US                                                                                   
 => => # Geographic area:

pthread_getspecific

test.cppをコンパイル中の

undefined reference to `pthread_getspecific'

に対しては, Dockerfileに

apt install -y libpthread-stubs0-dev

を追加して, test/CMakeLists.txtのtarget_link_librariesに

target_link_libraries(
  test PUBLIC
  gtest
  gtest_main
  pthread  # 追加!!
  )

のように, 一番下にpthreadを追加すれば大丈夫でした. ( 参考: cmakeとgtestでテスト環境を作る | 技術系のど根性 )

まとめ

  • Docker環境構築のためのDockerfileを作成しました.
  • また root ユーザー以外で環境を構築する用のDockerfileを作成しました.
  • Github actionにDockerのテストを追加しました.

コード

参考

他の記事