[docker/docker-compose入門]新型コロナのせいでお家時間が長くなり、switchやりたいけども転売ヤーのせいで買えなくなったのでマリオになりきれるものを作った

# この記事の目的
サークル内映像班の映像投影システムでdocker-composeを使用予定だが、非エンジニアの割合が多いため、それらの解説するため+アウトプットの練習

# はじめ
よしとらです。
映像ツールをdocker-composeとraspiで作成したいなあって思ったので、docker-composeの入門を書きます…

qiita初投稿なので、読みにくいかもです…ごめんなさい…

新型コロナウイルスのせいで、新歓公演がなくなり、研究室配属されても自宅作業になってしまいました…
研究室の担当教員からは輪講でいっぱい英語文献読んで、慣れてねって言われて頑張ってますが、24時間ずっと頑張ることが不可能でした、

息抜きとしてswitchを買って、ゲームをしたいのですが…

![スクリーンショット (245).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598587/94e3c76a-2a58-1b1f-a680-a7f38b8c8364.png)

くそたけえ…
転売ヤーとコロナは滅んでほしいですね…

なので自作したいなあって思いました。
~~[世の中には一からswitch作ったお方](https://gigazine.net/news/20200416-man-build-nintendo-switch/)がいますね、僕がやったら燃やすか爆破させそうですね~~

担当教員からは、いろんな技術触ってね～とslackで書いてあったので、団内の映像ツールのインフラでdocker/docker-composeを使おうと思っているので、それを触ります。

# 今回作成するもの
Web系で今後必ず使うであろうdocker/docker-composeの練習として、それを使って何か作ります、

docker-composeはアルバイトで使っていますが、一から設定して何か作成したことはなかったので頑張ります…

switchといえば任天堂ですね、
任天堂はいろいろゲームを作って出してますね、

その中でも一番有名なのはマリオですね、
なのでマリオになりきれるものを作ります。

## 実際に作るものの詳細
マリオといえば道端にあるブロックを破壊して、コインやアイテムをかっさらいますね、
なのでPC上にブロックを表示させて、クリックする度にコインが得られる音を発声するものを作っていきます

# 大雑把なdockerとdocker-composeについて
docker/docker-composeはWeb界で必ず扱いますね、
個人的に一言で表すと「環境による不具合を防ぐとても強いツール」だと思ってます(間違っていたらごめんなさい)

開発で一番大変なのは最初の環境構築で、バージョンが違うものをインストールすると動かないなんてことが日常的にありますね
でもdocker/docker-composeを使うことで一度決めた環境(バージョン等)をそのまま構築できるのでそんなことはなりません！！
~~[あれでも、windows 10proとrailsとdocker-composeでエラーが…]( https://crieit.net/posts/Windows-Docker-Rails-sprockets)~~

## docker/docker-composeの構築
docker/docker-composeを使うにしても最初はそれらの環境構築をします！これは逃げられません

今回はubuntu18.04ltsで行います
[ubuntu18.04ltsのインストールの仕方](https://linuxfan.info/ubuntu-18-04-install-guide)
[パソコン一つでインストールして元のデータを消してしまうかも、怖いって思う人はvirtual boxとか使ったほうが良いですね](https://qiita.com/pyon_kiti_jp/items/0be8ac17439abf418e48)
(わからなかったら、解説記事書きます…)

### dockerのインストール
最初にubuntuの更新とアップグレード、dockerのインストールで必要なソフトウェアのインストールを行います
これを行わないと何もできません

```cmd:instal-software
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y \
     apt-transport-https \
     ca-certificates \
     curl \
     software-properties-common
```
インストールしたソフトウェアの簡単な解説は以下の感じです

|ソフトウェア|解説|
|:---------:|:--:|
|apt-transport-https|セキュリティ関係。https通信が使えるようになるソフトかな？|
|ca-certificates|これもセキュリティ関係。SSL接続の時の証明書関係を扱うソフトかな？|
|curl|通信関係。手打ちでインターネットに接続できるソフト。|
|software-properties-common|ソフト管理関係かな？|

上手くインストールできたらいっぱい文字が出てきて処理を終えます

次にdockerがインストールできるように以下のコマンドで[GPG公開鍵](https://xtech.nikkei.com/it/article/Keyword/20091204/341579/)をインストールします

```cmd:install-GPGkey
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

上手く鍵がインストールできたかは以下のコマンドで確認できます

```cmd:check-install-key
sudo apt-key fingerprint 0EBFCD88
```

コマンドを実行した結果の中から、uidの行に「Docker Release (CE deb) <docker@docker.com>」と書かれていれば成功です

次はapt-getでインストールできるようにaptレポジトリの設定をします
基本的にdockerのstableをインストールすれば問題ないのでそれをインストールできるようにします(他にedgeやtestがあるよ！！)

使ってCPUの派閥(?)によってコマンドが違いますので気を付けてください…

x86_64(インテルやamdのCPU)

```cmd:x86_64でのやり方
sudo add-apt-repository \
     "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable"
```

armhf(ARMのCPU)

```cmd:armhfでのやり方
sudo add-apt-repository \
     "deb [arch=armhf] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable
```

インストール結果を反映させるためにapt-getを更新します

```cmd:update
sudo apt-get update
```

ここまでくれば、docker本体のインストールができます！やったね！
docker本体は以下のコマンドでインストールできます

```cmd:docker-install
sudo apt-get install -y docker-ce
```

インストールしたdockerは管理者権限(sudo)を付けないと扱えずとても不便です
なので管理者権限を付与しましょう

```cmd:add-docker-sudo
sudo usermod -aG docker $USER
```

あとは再起動していきます

### dockerのhello worldと簡単な解説/イメージ

dockerのhello world(インストールできたかのテスト)は以下のコマンドでできます

``` cmd:hello-world
docker run hello-world
```

このコマンドで以下のような結果が表示されたら成功です！やったね！

``` cmd:docker-hello-world-result
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

dockerはイミュータブルインストラクションの考えが基礎となっています。
イミュータブルは不変・変わらない、インストラクションは命令といった意味です
つまり、最初だけどのように動く等の命令を決めれば、次回以降それを使いまわして行こうって考えです。

dockerは以下のようなイメージで動いてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598587/2cc07216-afc7-f4b9-d6a3-c092eb3e5c53.png)


- dockerエンジン(docker本体のこと)上にdockerコンテナを乗っけて動かす
- dockerコンテナはdockerエンジン内で動かす仮想環境のこと
- つまりdockerエンジンの上に新しく環境を作ってその上で実行しているということ

dockerコンテナは以下のようなイメージで動いてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598587/d847a38c-9915-6c64-9982-5231acea6fa8.png)


- dockerイメージは環境構築の手続き(何入れるよ！とかのこと)
- レイヤは環境構築メインのこと
- ベースイメージは仮想環境のOS等についてのこと(windows、os x、ubuntu etc..)


### docker-composeのインストール

こんどはdocker-composeをインストールします！！
docker-composeのインストールは、CURLで本体を直接インストールしますが、インストール先が管理者権限の必要な場所なので管理者権限(sudo)付きCURLでインストールします

以下のコマンドがインストールのためのコマンドですが、コマンド内の1.25.5はdocker-composeのバージョンなので[docker-composeのgithub]()からインストールしたいバージョンを見つけてそのバージョンにコマンドを書き換えます(latest releaseが最新版だよ)

```cmd:install-docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
```

docker-composeもdocker同様に管理者権限を付与したほうが楽なので付与します

```cmd:add-docker-compose-sudo
sudo chmod +x /usr/local/bin/docker-compose
```

これでdocker-composeのインストールが終わりました！やったね！

### docker-composeのhello worldと簡単な解説/イメージ

ではではdocker-composeのhello worldを行います
以下のdocker-compose.ymlファイルを作成していきます

```docker-compose.yml
version: '3.8'
services:
  hello:
    image: hello-world:latest
```

作成できたらそのファイルがある階層で以下のコマンドを実行してdocker-composeを立ち上げます

```cmd:docker-compose-run
docker-compose up
```

実行結果はdockerのhello worldとほぼほぼ同じです
似すぎているのはバグではありません

dockerで扱えるコンテナが一つに対してdocker-composeは複数のコンテナが扱えます
なのでdocker-compose.ymlを以下のように書き換えると、docker-composeを使って一度に複数のdockerのhello worldを行えます(普通やらないが)

```docker-compose.yml
version: '3.8'
services:
  hello:
    image: hello-world:latest
  hello2:
    image: hello-world:latest
```

複数扱えるようになると、サイトのサーバーのほかにデータベースを立ち上げられて、できることの幅が一気に増えます、

# pythonとflaskについて
## pythonについて
pythonは学習コストが低い扱いやすいスクリプト言語です
pythonは2系と3系がありますが、3系が主流だと思います

pythonでは以下のことができます

- 機械学習
- Web開発
- マイコンプログラミング
- 画像処理等々…

いろいろできますね、強いですね

## flaskについて
pythonのWebフレームワークです
Djangoの方が浸かってる人が多い感じしますが、Djangoは大規模な開発になります
それに対してFlaskは小・中規模な開発ができます
Flaskの方が学習コストが低くて初めてでも扱いやすいと思います
[ドキュメント](https://flask.palletsprojects.com/en/1.1.x/)も軽く、読みやすいと思います

## docker-compose上にflaskを動かす
### フォルダ構成

```
folder/
       app.py
       Dockerfile
       docker-compose.yml
```

### pythonファイルの作成

以下のファイルを作成します

```python:app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello world"

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)
```

### Dockerfileの作成

Dockerfileはdocker-composeの立ち上げを行った時、最初に実行すること書いていくファイルです

```Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
RUN pip install flask
COPY . .
CMD ["flask", "run"]
```

### 解説
### docker-compose.ymlの作成

docker-compose.ymlファイルはdocker-compose上のコンテナの環境を設定するファイルです

```docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "5000:5000"
```

### サーバー立ち上げ
以下のコマンドで立ち上げれます

```cmd
docker-compose up
```

立ち上げれたら、http://0.0.0.0:5000にアクセスすれば「hello world」と表示されます！やったあ！

Ctrl+Cで立ち上げをやめさせれます

### 解説
docker-compose upを行うことでDockerfileの内容を上から順に実行していきます
今回は「pythonイメージをインストール」して、「コンテナ上にディレクトリを作成」、「環境変数(ENV)の設定」、「必要なソフトウェアのインストール」、「実行」といった順で実行しています(かなり雑で端折っていますが…)


# 作成物
作成したものです　ー＞　https://github.com/KinoshitaYstr/mario
githubからダウンロードして、展開します
展開後のフォルダ内でdocker-compose upで立ち上げて、http://localhost:5000にアクセスすれば、ボックスが表示されます
ボックスをクリックすればコインがぶんどれます
(コードの解説が欲しかったら教えてください…)

# おわり
これでみんなもマリオですね、やっふー
# あとがき
任天堂法務部に睨まれたらこの記事非公開にするか消します
あと転売ヤーとコロナは任天堂法務部に睨まれるか一京円の罰金になってほしい
間違ってることがあったら教えてください…修正します…

![Screenshot_20200501_213232_com.android.chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598587/ffeab181-961e-2769-b8d0-582cc4e17d2d.jpeg)
さよなら…

# 参考文献
- https://kitsune.blog/docker-summary
- https://nishinatoshiharu.com/about-docker-compose/
- https://flask.palletsprojects.com/en/1.1.x/
- https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d
- https://packages.debian.org/ja/jessie/apt-transport-https
- https://packages.debian.org/ja/jessie/ca-certificates
- https://www.ossnews.jp/oss_info/Curl
- https://packages.debian.org/ja/jessie/software-properties-common
- https://urashita.com/archives/12325
- https://qiita.com/youtangai/items/ff67ceff5497a0e0b1af
- https://qiita.com/silverskyvicto/items/3a6b2082049aba7656ee
- https://github.com/docker/compose/releases
- https://qiita.com/KEINOS/items/43d9415e351d80f78c8b
- https://docs.docker.com/compose/compose-file/
- https://qiita.com/matsui2019/items/bbe8db8a0815325b8c66

# 使用した素材
- イラストや様から画像(https://www.irasutoya.com/2017/10/blog-post_455.html)
- 小森 平様から音源(https://taira-komori.jpn.org/freesound.html)

これ書いてる途中、なにやってんだろうって思ったけども冷静に考えてなにやってるんだろう…