DockerでUbuntu + C言語の環境構築(Linuxプログラミング用)

「ふつうのLinuxプログラミング」という書籍でOSを作りながらOSの仕組みを作ろう！と思い立ったものの環境構築が面倒だったのでDockerを使ってサクッとUbuntu + C言語の環境を作りました。
その手順と最終的なDockerファイルを共有しようと思います。

#追記
・最後にコマンドをまとめたDockerfileを元に再度イメージとコンテナを作る工程を記載しました

#Dockerファイル
この時点ではどんなパッケージとかが必要になるかよく分かってなかったので、ubuntuのdockerイメージを使って基礎となるイメージを構築する最低限の記述だけします。

```dockerfile
FROM ubuntu:latest
RUN mkdir /workspace
ADD ./workspace /workspace
WORKDIR /workspace
```
今回は`workspace`を作業ディレクトリにしました。

#Dockerイメージ作成
docker buildコマンドの-tオプションでリポジトリとタグ名を指定します。

```php
docker build -t yorinton/ubuntu .
//docker build -t [タグ名] [Dockerfileのパス]
```

#Dockerコンテナ作成

```php
docker run -i -t -v /vagrant/linux-pj/workspace:/workspace イメージID
//-i：標準入力をオープンにする
//-t：擬似ターミナルを割り当て
//-v:指定したディレクトリにマウント
```

ここでコンテナが起動します。

#必要なパッケージのインストール

##インストールの準備
ここから必要なパッケージをインストールしていきますが、
`apt-get install パッケージ名`を実行しても見つからない、と出てしまいました。先に`update`でパッケージリストを更新する必要があるようです。

```
root@9300a0gI/workspace# apt-get update

Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security/universe Sources [52.0 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:5 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [489 kB]
Get:6 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]      
Get:7 http://archive.ubuntu.com/ubuntu xenial/universe Sources [9802 kB]         
Get:8 http://security.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [12.9 kB]
Get:9 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [224 kB]
Get:10 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [3479 B]
Get:11 http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1558 kB]                                                                                 
Get:12 http://archive.ubuntu.com/ubuntu xenial/restricted amd64 Packages [14.1 kB]                                                                           
Get:13 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9827 kB]                                                                             
Get:14 http://archive.ubuntu.com/ubuntu xenial/multiverse amd64 Packages [176 kB]                                                                            
Get:15 http://archive.ubuntu.com/ubuntu xenial-updates/universe Sources [224 kB]                                                                             
Get:16 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [851 kB]                                                                          
Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [13.7 kB]                                                                   
Get:18 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [699 kB]                                                                      
Get:19 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [18.5 kB]                                                                   
Get:20 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [5176 B]                                                                        
Get:21 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [6354 B]                                                                    
Fetched 24.5 MB in 13s (1768 kB/s)                                                                                                                           
Reading package lists... Done
```

これでパッケージをインストールする準備が出来ました。

##`sudo`インストール
`sudo`でインストールしようとしましたが、そもそも`sudo`が無いとのことでしたので、インストールします。
あとでDockerファイルにまとめるので全て`-y`をつけておきます。

```
root@9300a0gI/workspace#apt-get -y install sudo
```

##`gcc`インストール
今回C言語でLinuxプログラミングをしたかったので、C言語のコンパイラである`gcc`をインストールします。

```
root@9300a0gI/workspace#sudo apt-get -y install build-essential
```
gccがインストールされたかの確認(バージョン確認)

```
root@9300a0gI/workspace#gcc -dumpversion
```

##`Git`インストール
バージョン管理したいのでGitもインストールします。

```
root@9300a0gI/workspace#sudo apt-get -y install git
```

##`vim`インストール
ファイルの作成・編集もしたいのでvimもインストール
vimなくても他のsublimeとかのテキストエディタでもいいのですが、ちょっとしたファイルの編集はvimの方が個人的に早いのでvimもインストールしておきます。

```
root@9300a0gI/workspace#sudo apt-get -y install vim
```

##manコマンドインストール

```
root@9300a0gI/workspace#sudo apt-get -y install man
```
このままだと、2のシステムコールが見れないので以下を実行

```
root@9300a0gI/workspace#sudo apt-get -y install manpages-dev
```

#Dockerファイルにまとめる
ここまででLinuxプログラミング出来る環境は整いましたが、別の環境でも簡単に構築出来るように一応Dockerファイルにまとめておこうと思います。
RUN命令で&で上記のインストールコマンドを繋いで記述します。

```Dockerfile
FROM ubuntu:latest
RUN mkdir /workspace
ADD ./workspace /workspace
WORKDIR /workspace

#ここから追加分
RUN apt-get update
RUN apt-get -y install sudo && \
    sudo apt-get -y install build-essential && \
    sudo apt-get -y install git && \
    sudo apt-get -y install vim && \
    sudo apt-get -y install man && \
    sudo apt-get -y install manpages-dev && \
    apt-get install -y strace
```
ちなみに`bash`は最初から入ってました。
他に必要なパッケージ等あれば上記のような形で追記していけばOK.

先にコンテナ内で実行してうまく行くことを確認してからDockerfileに追記して行くと確実です。

#作ったDockerfileを元にdockerイメージ&コンテナ作成

dockerイメージの作成
`Dockerfile`があるディレクトリで以下を実行

```
docker build -t linux-prog .
```

dockerコンテナの作成
straceを使う場合は`--security-opt seccomp:unconfined`をつけないとデフォルトだとエラーになる

```
docker run -i -t -v /vagrant/linux-pj/workspace:/workspace --security-opt seccomp:unconfined [イメージID]
```



(参考)
[効率的に安全な Dockerfile を作るには](https://qiita.com/pottava/items/452bf80e334bc1fee69a)
[【入門】Dockerfileの基本的な書き方](https://techblog.recochoku.jp/1022)
[Dockerfile リファレンス](http://docs.docker.jp/engine/reference/builder.html#run)
[Docker環境でstrace](https://qiita.com/aka_tkb/items/8ad77df66423367a8488)