Dockerメモ

# Dockerについて調べたので備忘録メモ的な。

自分用なので他人が読むことを考慮してないですけど、何か間違いがあって指摘したい気分ならコメントか何か入れてください。

## コンテナ vs VM
なんかコンテナってやつはVMとは違うらしい。
[Microsoftが良い感じな説明してた](https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/)
まぁ、コンテナのほうが色々便利な場合もあるし基本的によほどのことをしないならコンテナのほうが幸せになれるよね的な。

## container vs image
class/instance的な感じでimage/containerという理解。
同じimageのcontainerが複数存在できるけど、複数の同じcontainerが存在することはあり得ないよね。

## dockerのCLIツール

### docker run [options] {image} / docker rm [options] {container_name/id}
`docker run {image}` でコンテナを作る（動かす）
`docker rm {container}` でコンテナを消す

###### 使いそうなoption(`run`):
- `-i` interactive mode (MinTTYとかだと `winpty docker run -it {image}`)
- `-t` terminal
- `-d` daemon化する(detachのdっぽい)再起動したとき勝手に起動するんだっけ・・・？
- `-p {machine_port:container_port}` portをlocalhostにバインドする
- `-P` 適当な空いているportにバインドする
- `--rm` stopしたらコンテナをrmする。
- `-v {host/path:container/path}` ホストマシンのドライブに、コンテナ内のパスのものを保存する（DBとか）[^1]

[^1]: ハマりpointとしてWindowsの場合は画面の右下の![image](https://qiita-image-store.s3.amazonaws.com/0/100271/dea14d5a-8059-595d-15a0-1df4f4a74f78.png)こいつの設定でShared DriveをEnableして管理者UsernameとPasswordが必要。

### docker ps [options]
`docker ps` linuxの`ps`コマンドと似た感じで「起動しているコンテナとその情報」を表示する

###### 使いそうなoption:
- `-a` stopしているコンテナの情報も表示する
- `-l` 最も最近編集したコンテナを表示する
- `-q` PID(多分コンテナのUUID的なもの、rmとかに与えるパラメータ)を抽出する。

### docker start/stop {container_name/id}
`docker start`で停止しているコンテナを動かす
`docker stop`で動いているコンテナを止める(消さない)

### docker exec {container_name/id} {command}
`docker exec`で起動しているコンテナ内で新しいプロセスを起動する
ex: `docker exec adoring_shaw bash` でコンテナ内のLinuxを探索する。

### docker build [options] {path_to_dockerfile}
`docker build {path_to_dockerfile}`でDockerfileと呼ばれる.shのようなファイルを元にimageをコンパイルしていく感じ。

###### 使いそうなoption:
- `-t {user/image:tag}` 変なimageの名前(<none> <none>になるんだっけ・・・)じゃなくてちゃんと名前つける


### docker images
`docker ps`のimage版みたいな。 gitとかもこういう機能があるといいのだが・・・

### docker rmi [options] {image}
`docker rmi {image}` でimageを削除する。

### docker top {container_name/id}
`docker top`linuxの`top`と似たやつ。コンテナの中のリソース使用率を表示。

### docker logs [options] {container}
`docker logs`コンテナのstdoutを表示。

###### 使いそうなoption:
- `-f` linuxの`tail -f`のように逐次更新される。


## DockerHub系

### docker commit [options] {container_name/id} [new_name]
`docker commit {container_name/id} [new_name]`でコンテナの現在の状態からimageを新しく作る

###### 使いそうなoption:
- `-a "{Author <e-mail>}` authorをつける
- `-m "{message}"` commit messageをつける

### docker login
`docker login` で dockerhubにログインする(セッション中persistする)

### docker pull {user/image:tag}
(gitと同じ)`docker pull` でDocker Hubからimageの最新版を落としてくる
`tag`を忘れると`latest`という特殊なタグ（最新版とは限らない）を落とされるので明示的に指定しよう。

### docker push {user/image:tag}
(gitと同じ)`docker push`でDocker Hubに変更をupする
`tag`を忘れると`latest`という特殊なタグ（最新版とは限らない）を勝手に作られるので明示的に指定しよう。

### docker tag {image} {tag}[^2]
`docker tag`で既存のimageと内容は全く同じな別の名前のimage作る。 DockerHubにpushする前に username/imagename:tag形式にするときとかに使う.

[^2]: tagはversion numberみたいなもの。

# docker-compose

docker-composeは複数のコンテナ(db, serverなど)をまとめて起動するためのツール。ROS Launch的なものを感じる
各コンテナはserviceと呼ばれる模様。
`docker-compose.yml`というファイルに様々な設定を書き込んでいく感じ。([完全なReference](https://docs.docker.com/compose/compose-file/))

## 注意点
### expose と portsの違い
docker-composeをするときにデフォルトでcompose内の独自ネットワークが構築される。これはLocalhostから隔離された環境なので内部からしかアクセスできないようになってる（多分）
ポートの公開に2種類あって:

- exposeはdocker-compose内の他のコンテナに対してポートを公開する設定。
- portsはlocalhostのポートとコンテナのポートをバインドする設定（docker run -pと同じ）。

### depends_onまたはlinksを使う
compose内のホスト名はservice名で繋げられるけど、そのためには

- `depends_on`をする。この場合dependencyが先に起動される。
- `links`をする。この場合ただ `curl -X PUT http://db:5984/hogehoge`などができる。

例：

```yaml:docker-compose.yml
version: "2"
services:
  srv:
    image: spaghet/srv:latest
    build: .
    ports:
      - "80:80"
    depends_on:
      - db
  db:
    image: klaemo/couchdb
    volumes:
      - //c/Users/spaghet/Documents/hoge/fuga/:/opt/couchdb/data
    expose:
      - "5984"
```