DockerでC++開発環境構築（CentOS版） 

# 概要

C++の学習をする必要があるため、コンパイル＆実行環境をDockerにて作成する。
「[DockerでC++開発環境構築（ubuntu版）](https://qiita.com/yuzutarogo/items/8898377739b5c674743f)」にて環境は構築済みだがDockerの学習のため
**CentOSで同様環境を構築したらどのような違いがあるかを検証する**。


## 作業における補足

- CentOSでコンテナをする
- 今回は学習目的のため、g++でコンパイルが行える環境ができればよい
- イメージ名：cppdev-cent
- コンテナ名：cppdev-cent
- 階層構造は以下のとおり

```
cppdev-cent
 ├ src
 │  └ hello.cpp
 │ 
 ├ Dockerfile
 └ docker-compose.yml
```

# 確認用のC++プログラムを作成
```c++:hello.cpp
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello! CentOS!" << endl;
    return 0;
}
```

# Dockerfile の作成

```:Dockerfile
FROM centos:centos7
ENV DEBIAN_FRONTEND=noninteractive
RUN yum update -y && \
    yum groupinstall -y 'Development Tools' && \
    yum install -y cmake clang libssl-dev vim
```

【補足】

**DEBIAN_FRONTEND=noninteractive**
yum でインストールするものの中には対話形式で設定を行うものがある。
Docker だと選択肢に答えようがない（入力できない）のでこの環境変数を設定する。
※あとのコマンドで「-y」オプションを入れているので不要かもしれない

**yum update -y**
パッケージを更新する。
※-y：全ての問い合わせに「yes」で応答したものとして実行する

**yum groupinstall -y 'Development Tools'**
Ubuntuの場合の「build-essential」と同等で開発に必須のビルドツールをインストールする。
gcc(GNU C Compiler)やg++(GNU C++ Compiler), makeなどがインストールされる。
※インストール後、Dockerコンテナにはいって
　「yum groupinfo "Development Tools" 」
　を実行するとグループに含まれるパッケージを確認できる

**yum install -y パッケージ名**
指定したパッケージをインストールする。
※-y：全ての問い合わせに「yes」で応答したものとして実行する

**cmake**
コンパイラに依存しないビルド自動化のためのフリーソフトウェア。

**clang**
プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラフロントエンド。

**libssl-dev**
何用にインストールが必要なのか調査中。

**vim**
Dockerコンテナに入ってviでファイル編集を行うため。


# docker-compose.ymlの作成

```:docker-compose.yml
version: "3.3"
services:
  cppdev-cent:
    build:
      context: .
      dockerfile: Dockerfile
    image: cppdev-cent
    container_name: cppdev-cent
    volumes:
      - type: bind
        source: .
        target: /cppdev
    stdin_open: true
    tty: true
    working_dir: /cppdev/src/build
```


【補足】
**version: "3.3"**
docker-compose.ymlのファイルフォーマットバージョンを宣言している。※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/)

**build**

　**context**
　Dockerfile を含むディレクトリへのパスを設定 ※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/#context)　

　**dockerfile**
　指定されたパスの Dockerfile を使ってビルドを行う。 ※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/#dockerfile)　

**image**
build に加えて image も指定した場合、Compose はビルドイメージに名前をつける。　※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/#build)　

**container_name**
デフォルトのコンテナー名ではない、独自のコンテナー名を設定する　※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/#container_name)

**volumes** ※[詳細](https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/#volumes)

　**type**
　マウントタイプを表す。bindは、追加のバインドオプションを設定する。

　**source**
　バインドマウントにおいてはホスト上のパスを指定する。

　**target**
　ボリュームがマウントされるコンテナー内のパスを指定する。

**stdin_open**
「docker container run」のオプションに対応づいている（iオプションに相当）。
コンテナの標準入力とDockerホストの標準入力を接続する。

**tty**
「docker container run」のオプションに対応づいている（tオプションに相当）。
コンテナの標準出力とDockerホストの標準出力を接続する。

**working_dir**
「docker container run」のオプションに対応づいている（wオプションに相当）。
コンテナ内の作業用ディレクトリを指定。

# Dockerイメージ作成＆コンテナ起動

「docker-compose up」コマンドを実行するイメージ作成からコンテナ起動までを行う。

```:Powershell
> docker-compose up -d

Building cppdev-cent
Step 1/3 : FROM centos:centos7
centos7: Pulling from library/centos
ab5ef0e58194: Pull complete
Status: Downloaded newer image for centos:centos7
 ---> 5e35e350aded
Step 2/3 : ENV DEBIAN_FRONTEND=noninteractive
 ---> Running in a2a9e8cf5fd0
Removing intermediate container a2a9e8cf5fd0
 ---> b83498dfecd1
Step 3/3 : RUN yum update -y &&     yum groupinstall -y 'Development Tools' &&     yum install -y cmake clang libssl-dev vim
 ---> Running in 99ab786ea666
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors

・・・省略・・・

  Verifying  : cmake-2.8.12.2-2.el7.x86_64                                 7/11
  Verifying  : gpm-libs-1.20.7-6.el7.x86_64                                8/11
  Verifying  : lzo-2.06-8.el7.x86_64                                       9/11
  Verifying  : 2:vim-common-7.4.629-6.el7.x86_64                          10/11
  Verifying  : 2:vim-filesystem-7.4.629-6.el7.x86_64                      11/11

Installed:
  clang.x86_64 0:3.4.2-8.el7                cmake.x86_64 0:2.8.12.2-2.el7
  vim-enhanced.x86_64 2:7.4.629-6.el7

Dependency Installed:
  gpm-libs.x86_64 0:1.20.7-6.el7           libarchive.x86_64 0:3.1.2-14.el7_7
  llvm.x86_64 0:3.4.2-8.el7                llvm-libs.x86_64 0:3.4.2-8.el7
  lzo.x86_64 0:2.06-8.el7                  vim-common.x86_64 2:7.4.629-6.el7
  vim-filesystem.x86_64 2:7.4.629-6.el7    which.x86_64 0:2.20-7.el7

Complete!
Removing intermediate container 99ab786ea666
 ---> 22251db82170

Successfully built 22251db82170
Successfully tagged cppdev-cent:latest
WARNING: Image for service cppdev-cent was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating cppdev-cent ... done  
```

【補足】
**-d**
コンテナをバックグラウンドで実行する。

# コンテナ起動後の確認

- Dockerイメージを確認

docker-compose.ymlの「image」で指定した名称でDockerイメージを作成できている。
CentOSのほうがUbuntuに比べ、ベースのOS側の資産の容量が大きいことが分かる。

```:Powershell
> docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
cppdev-cent         latest              22251db82170        52 seconds ago      809MB
cppdev              latest              65c31f2d8ba7        11 hours ago        966MB
ubuntu              20.04               1d622ef86b13        5 days ago          73.9MB
centos              centos7             5e35e350aded        5 months ago        203MB
```

- コンテナを確認

docker-compose.ymlの「container_name」で指定した名称でDockerイメージを作成できている。

```:Powershell
> docker container ps -a

CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                     PORTS                    NAMES
cfa5307180c0        cppdev-cent           "/bin/bash"              About a minute ago   Up About a minute                                   cppdev-cent
e14ee88fd5b3        cppdev                "/bin/bash"              11 hours ago         Exited (255) 2 hours ago                            cppdev
```

- コンテナに入る

```:Powershell
> docker container exec -it cppdev-cent /bin/sh    
# cd /
# ls -la

total 64
drwxr-xr-x   1 root root  4096 Apr 29 03:20 .
drwxr-xr-x   1 root root  4096 Apr 29 03:20 ..
-rwxr-xr-x   1 root root     0 Apr 29 03:20 .dockerenv
-rw-r--r--   1 root root 12123 Oct  1  2019 anaconda-post.log
lrwxrwxrwx   1 root root     7 Oct  1  2019 bin -> usr/bin
drwxrwxrwx   1 root root     0 Apr 29 01:00 cppdev
drwxr-xr-x   5 root root   360 Apr 29 03:20 dev
drwxr-xr-x   1 root root  4096 Apr 29 03:20 etc
drwxr-xr-x   2 root root  4096 Apr 11  2018 home
lrwxrwxrwx   1 root root     7 Oct  1  2019 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Oct  1  2019 lib64 -> usr/lib64
drwxr-xr-x   2 root root  4096 Apr 11  2018 media
drwxr-xr-x   2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x   2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 125 root root     0 Apr 29 03:20 proc
dr-xr-x---   2 root root  4096 Oct  1  2019 root
drwxr-xr-x   1 root root  4096 Apr 29 03:19 run
lrwxrwxrwx   1 root root     8 Oct  1  2019 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x  13 root root     0 Apr 29 02:43 sys
drwxrwxrwt   1 root root  4096 Apr 29 03:19 tmp
drwxr-xr-x   1 root root  4096 Oct  1  2019 usr
drwxr-xr-x   1 root root  4096 Oct  1  2019 var
```

- サンプルプログラムをコンパイル＆実行

期待した動作をした。

```:Powershell（コンテナに入って実行）
# cd /cppdev/src
# g++ hello.cpp -o hello
# ./hello

Hello! CentOS!
```

# 関連記事

- [DockerでC++開発環境構築（ubuntu版）](https://qiita.com/yuzutarogo/items/8898377739b5c674743f)
- [DockerでC++開発環境構築（Alpine版）](https://qiita.com/yuzutarogo/items/d60ba007eae969be53ae)