docker関連のよく使うコマンドまとめ


## docker composeのアップ

```bash
# 通常起動（初回はデーモン起動ではなく、状態が見れるこちらでやるのが良い）
# イメージを元にコンテナを作成して起動する動作となる
docker compose up

# docker-compose関連外のコンテナを起動時に削除する
docker compose up --remove-orphans

# デーモン起動
docker compose up -d 
```

## docker composeのダウン

```bash
# コンテナとネットワークが削除される
# コンテナ内のデータも消えるので、残したい場合、ボリュームを指定すること。
# 逆に言えばコンテナ内の肥大化しやすいログ情報などは、down時に消えて
# up時にイメージと同じになるので、小さく保てる。
docker-compose down

# イメージ消して、ボリューム消して、関連外のコンテナを削除する
docker-compose down --rmi all --volumes --remove-orphans
```

## docker compose stop start

```bash
docker-compose stop
docker-compose satrt
```
コンテナを削除しないのと、立ち上がりが速いです。

ちょっと確認していないですが、立ち上がりの速さから再起動していないのでは？と思われます。
（そして時は動き出す。みたいな状況では？）

## 一時的にコンテナを作成して中に入るコマンド

```bash
docker run -it --rm alpine:latest ash
```

余談だが、alpine系はbashではなく、組み込み系で使われているashを使っている

## npm installだけやるワンライナー

```bash
docker run --rm -t -w /app -v $(pwd):/app node:20-alpine sh -c 'apk update && apk upgrade --no-cache && npm install -g npm@latest && npm install'
```

対象ディレクトリに移動してから使う。
また、ワークスペースとかボリュームの部分を変える（上記だと `app` の部分）

## database関連で使っているやり方

```bash
# コンテナ外からヒアドキュメントを使って、複数のクエリを実行する方法
docker exec -i -e MYSQL_PWD=**** コンテナ名 mysql -u root <<\EOF
select version();
DROP DATABASE IF EXISTS test_db;
CREATE DATABASE test_db
  CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
EOF

# dumpファイルを流し込む方法（時間の測定は必須ではないがあると便利）
date && time docker exec -i -e MYSQL_PWD=**** コンテナ名 mysql test_db -uroot < /tmp/dump.sql
```

## コマンドがうまく渡せない時

```bash
docker exec コンテナ名 sh -c 'echo hoge'
```

## 一旦リセットしたい場合

```bash
# 左が、全てのコンテナ、イメージ、ネットワークを削除
# 右が、volumeの削除
$ docker system prune -fa && docker volume prune -fa
```

Rancher-Desktopなどは、ファクトリーリセット機能があるので、そちらを使うのもあり。
（ファクトリーリセットは、CPUのコア数設定などもリセットかかるので、再設定も忘れずに！！）

## ファイル名指定でのビルド

```bash
docker build . --file ./Dockerfileaaa --tag 'test-aaa:latest'
```
ファイル名が `Dockerfile` であればデフォルト名と同じなので省略できる。

## イメージをアウトプットしたりインポートしたり

```bash
# export
docker save --output /tmp/hoge 'test-aaa:latest'

# import
docker load --input /tmp/hoge
```

こちらは、GithubActionsなどで毎回ビルドすると時間が掛かる場合に有用。

`actions/cache@v3` でexportファイルを保存すれば、Dockerfileに変化があったときだけビルドすることができ、実行時間を大幅に短縮できる。

## docker-engineでhost.docker.internalを使うには一工夫必要

```bash:docker-compose.override.yaml
version: "3.5" # docker-compose.yamlのバージョンと合わせる

services:
  app: # host.docker.internalを使用したいサービス名
    extra_hosts:
      - "host.docker.internal:host-gateway"
```

参考記事: https://qiita.com/skobaken/items/03a8b9d0e443745862ac

`host.docker.internal` は、docker-desktopなどの機能のため、docker-engineでは一手間必要らしい。

## 注意点など

* docker-composeのlinksやdepends_onを使えば、コンテナの起動順を制御することはできるが、他のコンテナの起動を待つことはできない
  * 未確認だが、`wait-for-it` とか `dockerize` とかで待てるらしい
  * 参考: https://qiita.com/ngyuki/items/70f7da9f55af964e2e83
  * 自分は簡易なシェルスクリプトで対応した
* Linux環境では仮想化が不要だが、docker-desktopなどで導入してしまうと、仮想化機能が使われてしまう
  * GUIがほしくて劣化を気にしないなら、その限りではない
  * ちなみに、仮想環境を使用したくない場合、docker-engineを使う
* チームが違うシステムなどでは、無理に１つのcomposeに全部入れるよりも、複数のcomposeで動かす方が管理しやすい
* `host.docker.internal` を使うとhost側に対してアクセスできるので、複数composeを動かすときなどは、上記を使うとアクセスしやすい
* ハイフンの有無で、`docker-compose`と`docker compose`とコマンドに違いがあり、ハイフン無しのほうが最新なのでそちらを使うのが良い

## 実行環境について

今の会社では、MacでRancherDesktop（OSS）を使用しているが、OrbStack（有償）のほうが色々と快適。

個人では無償で使えるので、MacならOrbStackがおすすめ。

## 総評

dockerと言っても色々ありますね。

Linux以外だと、仮想環境のオーバーヘッドなり、色々とあるので、快適に使っていきたいですね。