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

# 概要

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

## 作業における補足

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

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

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

using namespace std;

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

# Dockerfile の作成

```:Dockerfile
FROM alpine:latest
RUN apk update && \
    apk add alpine-sdk cmake clang libressl-dev vim

```

【補足】

**apk update**
パッケージを更新する。
※ubuntuの場合の「apt-get update」と同等

**apk add パッケージ名**
指定したパッケージをインストールする。
※Alpine の場合、ubuntuでの「y」オプションに値するものはなさそう

**alpine-sdk**
開発に必須のビルドツールを提供しているパッケージ。
※ubuntuの場合の「build-essential」

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

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

**libressl-devl**
何用にインストールが必要なのか調査中。
※ubuntuの場合の「ibssl-dev」

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

# docker-compose.ymlの作成

```:docker-compose.yml
version: "3.3"
services:
  cppdev-alpine:
    build:
      context: .
      dockerfile: Dockerfile
    image: cppdev-alpine
    container_name: cppdev-alpine
    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-alpine
Step 1/2 : FROM alpine:latest
latest: Pulling from library/alpine
cbdbe7a5bc2a: Pull complete
Status: Downloaded newer image for alpine:latest
 ---> f70734b6a266
Step 2/2 : RUN apk update &&     apk add alpine-sdk cmake clang libressl-dev vim
 ---> Running in 97212ebaf19b
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
v3.11.6-7-g8feb2f8d2c [http://dl-cdn.alpinelinux.org/alpine/v3.11/main]
v3.11.6-5-g28d0524933 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community]
OK: 11270 distinct packages available
(1/61) Installing fakeroot (1.24-r0)
(2/61) Installing sudo (1.8.31-r0)
(3/61) Installing libcap (2.27-r0)
(4/61) Installing pax-utils (1.2.4-r0)
(5/61) Installing openssl (1.1.1g-r0)
(6/61) Installing libattr (2.4.48-r0)
(7/61) Installing attr (2.4.48-r0)
(8/61) Installing libacl (2.2.53-r0)
(9/61) Installing tar (1.32-r1)
(10/61) Installing pkgconf (1.6.3-r0)

・・・省略・・・

(59/61) Installing xxd (8.2.0-r0)
(60/61) Installing lua5.3-libs (5.3.5-r2)
(61/61) Installing vim (8.2.0-r0)
Executing busybox-1.31.1-r9.trigger
Executing ca-certificates-20191127-r1.trigger
OK: 396 MiB in 75 packages
Removing intermediate container 97212ebaf19b
 ---> 00b5ff4a559c

Successfully built 00b5ff4a559c
Successfully tagged cppdev-alpine:latest
WARNING: Image for service cppdev-alpine 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-alpine ... done
```

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

# コンテナ起動後の確認

- Dockerイメージを確認

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

```:Powershell
> docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
cppdev-alpine       latest              00b5ff4a559c        55 seconds ago      398MB
cppdev-cent         latest              22251db82170        42 minutes ago      809MB
cppdev              latest              65c31f2d8ba7        11 hours ago        966MB
ubuntu              20.04               1d622ef86b13        5 days ago          73.9MB
alpine              latest              f70734b6a266        5 days ago          5.61MB
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
15dd63ce1d6e        cppdev-alpine         "/bin/sh"                2 minutes ago       Up 2 minutes                                        cppdev-alpine
cfa5307180c0        cppdev-cent           "/bin/bash"              43 minutes ago      Up 43 minutes                                       cppdev-cent
e14ee88fd5b3        cppdev                "/bin/bash"              11 hours ago        Exited (255) 3 hours ago                            cppdev
```

- コンテナに入る

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

total 64
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 .
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 ..
-rwxr-xr-x    1 root     root             0 Apr 29 04:01 .dockerenv
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 bin
drwxrwxrwx    1 root     root             0 Apr 29 03:30 cppdev
drwxr-xr-x    5 root     root           360 Apr 29 04:01 dev
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 etc
drwxr-xr-x    2 root     root          4096 Apr 23 06:25 home
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 lib
drwxr-xr-x    5 root     root          4096 Apr 23 06:25 media
drwxr-xr-x    2 root     root          4096 Apr 23 06:25 mnt
drwxr-xr-x    2 root     root          4096 Apr 23 06:25 opt
dr-xr-xr-x  127 root     root             0 Apr 29 04:01 proc
drwx------    1 root     root          4096 Apr 29 04:04 root
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 run
drwxr-xr-x    2 root     root          4096 Apr 23 06:25 sbin
drwxr-xr-x    2 root     root          4096 Apr 23 06:25 srv
dr-xr-xr-x   13 root     root             0 Apr 29 02:43 sys
drwxrwxrwt    2 root     root          4096 Apr 23 06:25 tmp
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 usr
drwxr-xr-x    1 root     root          4096 Apr 29 04:01 var
```

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

期待した動作をした。

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

Hello! Alpine!
```

# 関連記事

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