Docker入門 個人的なTips集

# 概要

初めてDockerを勉強した時に気づいた内容をまとめました
下記で紹介するコマンドはどれもが基本的なコマンドなのですが、Dockerを勉強し始めたときにこんなのできないのか？という疑問からまとめました

勉強していく中で随時追加していきたいと思います

# Tips

## 一度きりしか立ち上げないコンテナを実行後に自動で削除する

テスト的にコンテナ作りをしているとrunする度にコンテナが増えていくので、
その都度個別にそれらのコンテナを消すのもめんどくさい
なので、
```--rm``` パラメータを追加することで実行完了後に自動的にコンテナを破棄してくれます
ただし、```-d``` パラメータとは共存できません

```
> docker run --rm -it xxxxxx-image command
```


## runコマンドでカレントディレクトリを参照する

ホストのディレクトリをマウントする際に、カレントディレクトリを取得する場合に使えます


コマンド実行時のカレントディレクトリを取得できる
- Powershellの場合(  **${PWD}**  )

```
> docker run -v ${PWD}:/usr/src/mount_dir hoge-image:hoge-tag
```
- コマンドプロンプトの場合(  **%cd%**  )

```
> docker run -v %cd%:/usr/src/mount_dir hoge-image:hoge-tag
```


## windowsのディレクトリをコンテナにマウントする時

dockerの設定でwindowsのドライブ共有設定が必要

![docker-setting.png](https://qiita-image-store.s3.amazonaws.com/0/30522/a94a7d49-1e01-56d0-4820-c2c804f2595e.png)


## Dockerfileで定義した環境変数をPG内(nodejs)から参照する

```text:Dockerfile
# HOGEHOGE_ENVという名の環境変数にtest_envを定義
ENV HOGEHOGE_ENV test_env
```
または

```text:command
# 値にスペースを含む場合は、ダブルクオートで括りましょう
# 例）-e HOGEHOGE="test env"
> docker run -d -e HOGEHOGE=text_env hogehoge-image
```

↓

```nodejs:app.js
// process.envから参照することが可能
process.env.HOGEHOGE_ENV
```

## 稼働中のコンテナにコマンドを発行する

```exec``` を用いることで稼働中のコンテナにコマンドを発行することができる

リファレンス -> [docker exec](https://docs.docker.com/engine/reference/commandline/exec/)

```
> docker exec -i hogehoge-contaner /bin/bash -c "echo 'test command'"
```

## 起動失敗したコンテナのログを見る


```
> docker logs コンテナ名/ID
```


## コンテナをすべて削除

```
> docker rm $(docker ps -aq)
```

## イメージをすべて削除

```
> docker rmi $(docker images -aq)
```

## 使っていないボリュームを削除

```
docker volume rm $(docker volume ls -qf dangling=true)
```

docker 1.13以降

```
> docker volume prune
```

## タグがnoneのイメージをまとめて削除

```
> docker rmi $(docker images -f dangling=true -q)
```

## 停止しているコンテナをまとめて削除

```
> docker rm $(docker ps -q -f status=exited)
```

## コンテナからホストのネットワークに繋がっているマシンにアクセスする（Windows）

ホストのイントラネット内にあるサービス（リポジトリ、Redmineなど）に接続するための設定方法

## コンテナのタイムゾーン設定

以下のように環境変数を追加することでコンテナのタイムゾーンが設定される

```
TZ=Asia/Tokyo
```

## Windows版Dockerの強制アンインストールする方法

Windows版Dockerをアップデートして起動できなくなり（初期化しても）、アンインストールするも応答なしになり途方に暮れた時に、
強制的にDockerをアンインストールする方法です
下記のコマンドを実行後

1. 下記のコマンドを実行し、Docker関連のコンポーネントを強制削除
 
    ```
    $ErrorActionPreference = "SilentlyContinue"

    kill -force -processname 'Docker for Windows', com.docker.db, vpnkit, com.docker.proxy, com.docker.9pdb, moby-diag-dl, dockerd

    try {
        ./MobyLinux.ps1 -Destroy
    } Catch {}

    $service = Get-WmiObject -Class Win32_Service -Filter "Name='com.docker.service'"
    if ($service) { $service.StopService() }
    if ($service) { $service.Delete() }
    Start-Sleep -s 5
    Remove-Item -Recurse -Force "~/AppData/Local/Docker"
    Remove-Item -Recurse -Force "~/AppData/Roaming/Docker"
    if (Test-Path "C:\ProgramData\Docker") { takeown.exe /F "C:\ProgramData\Docker" /R /A /D Y }
    if (Test-Path "C:\ProgramData\Docker") { icacls "C:\ProgramData\Docker\" /T /C /grant Administrators:F }
    Remove-Item -Recurse -Force "C:\ProgramData\Docker"
    Remove-Item -Recurse -Force "C:\Program Files\Docker"
    Remove-Item -Recurse -Force "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Docker"
    Remove-Item -Force "C:\Users\Public\Desktop\Docker for Windows.lnk"
    Get-ChildItem HKLM:\software\microsoft\windows\currentversion\uninstall | % {Get-ItemProperty $_.PSPath}  | ? { $_.DisplayName -eq "Docker" } | Remove-Item -Recurse -Force
    Get-ChildItem HKLM:\software\classes\installer\products | % {Get-ItemProperty $_.pspath} | ? { $_.ProductName -eq "Docker" } | Remove-Item -Recurse -Force
    Get-Item 'HKLM:\software\Docker Inc.' | Remove-Item -Recurse -Force
    Get-ItemProperty HKCU:\software\microsoft\windows\currentversion\Run -name "Docker for Windows" | Remove-Item -Recurse -Force
    #Get-ItemProperty HKCU:\software\microsoft\windows\currentversion\UFH\SHC | ForEach-Object {Get-ItemProperty $_.PSPath} | Where-Object { $_.ToString().Contains("Docker for Windows.exe") } | Remove-Item -Recurse -Force $_.PSPath
    #Get-ItemProperty HKCU:\software\microsoft\windows\currentversion\UFH\SHC | Where-Object { $(Get-ItemPropertyValue $_) -Contains "Docker" }
    ```
2. 「プログラムの追加と削除」に「Docker for Windows」が登録されたままになっているので、CCleanerなどのツールで削除する

引用：https://success.docker.com/KBase/How_to_completely_remove_Docker

## Dockerの旧バージョンをDLする

下記のリンクからDLする

https://download.docker.com/

or

chocolateyからインストールする
https://chocolatey.org/packages/docker-for-windows

## localeの設定

Amazonlinuxコンテナでlocaleを`LANG=ja_JP.UTF-8`で設定したが反映されなかった。
以下の設定でlocaleを正しく認識させる

```
RUN localedef -v -c -i ja_JP -f UTF-8 ja_JP.UTF-8; echo "";

env LANG=ja_JP.UTF-8
RUN rm -f /etc/localtime
RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

参考：https://qiita.com/yuki2006/items/6cea8c352e38f047b52a#comment-8e863c71962008035d0d

## Docker内の既存ネットワークに接続する場合

defaultエントリでexternalオプションを指定することで既存のネットワークに接続することができる

```yaml:docker-compose.yml
networks: 
  default:
    external: 
      name: xxxxx_xxxxxxxx
```

## コンテナとホストのファイルの所有者

コンテナのuid/gidとホストのuid/gidが同じであれば、同じユーザとして見なす

参考：https://unskilled.site/docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%86%85%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A8%E3%83%9B%E3%82%B9%E3%83%88%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A8%E3%81%AE%E9%96%A2%E4%BF%82/

## Windows Dockerでコンテナ内でDockerイメージのビルド

- dindのDockerイメージを使う
- ホストのDocker sockをコンテナにマウントして使う  
  docker run時にsockをマウントするだけ（Windows Dockerも同じ）

    ```
    > docker run -v /var/run/docker.sock:/var/run/docker.sock xxx
    ```
   docker-composeの場合は、予め`$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1`を設定する必要がある

## システム上限を上書きする

コンテナでシステムの上限値を上書きして実行するために`ulimits`パラメータを指定する必要がある
ちなみにコンテナ内でulimitコマンドを実行しても反映されないので、上記のパラメータは必須
例えば、ファイルオープン数の上限をあげるとか
※事前にホストのシステム上限値も同値に設定する必要がある
docker run:
http://docs.docker.jp/engine/reference/commandline/run.html#ulimits-ulimit
docker-compose:
http://docs.docker.jp/compose/compose-file.html#ulimits