---
# System prepended metadata

title: Docker and Container A02 - 常用指令
tags: [學習筆記, 教學, DockerCLI, Docker]

---

###### tags: `教學` `Docker` `學習筆記` `DockerCLI`

# Docker and Container A02 - 常用指令



[TOC]

---
## part1

### 啟動
```linux=
開啟服務
$ sudo systemctl start docker.service
$ sudo service docker start
設定開機啟動
$ sudo systemctl enable docker.service
停止服務
$ sudo service docker stop
查看服務狀態
$ sudo systemctl status docker.service
```



### Registry 
* `docker login`：進入Registry
* `docker login localhost:8080`，經由8080進入倉庫
* `dokcer logout`：退出Registry(docker hub)
* `docker pull aaa:latest`：抓取aaa專案最新的版本
* `docker push <image>:<tag>`：把映像檔推到倉庫（docker hub）
*  尋找映像檔：
	```
	docker search nginx  ，搜尋nginx這個映像檔
	docker search nginx --stars=3 --no-trunc busybox
	```
* 將映像檔從倉庫拉到本地(pull)：`docker pull nginx`
* 將映像檔從本地推到倉庫(push)：`docker push eon01/nginx  localhost:5000/myadmin/nginx`

### image
* `docker images` ：可以看到本地的image有哪些
* `docker rmi aaa`：刪除aaa這個image(rmi = remove image)
* `docker run aaa:bbb`：執行aaa專案的docker image(bbb的版本)
* `docker run aaa echo "hey001"`： echo "hey001"這種東西
* `docker run aaa df`：看看這個image的磁碟空間
* `docker run aaa ls /`：看看這個image的根目錄下有什麼東西
* `docker run -it aaa /bin/sh`：執行/bin/裡面的shell
* `docker run -d -it aaa /bin/sh`：-d在背景執行-，這樣不會主動印出log
* `docker tag [source] [target]`: 替image加上標籤/別名
* `docker commit [container id] [new image name]`，將容器轉換為image
* `docker inspect <image>`， 查看映像檔的詳細資料



#### more Images
1. Building Images：
 - `docker build -t <image>:<tag> <run_directory> -f <dockerfile>`，使用dockerfile建立一個映像檔
  
	```dockerfile=
	docker build .
	docker build github.com/creack/
	docker-firefoxdocker build - < Dockerfile
	docker build - < context.tar.gz
	docker build -t eon/infinite .
	docker build -f myOtherDockerfile .curl example.com/remote/Dockerfile | 
	docker build -f - .
	```
1. Loading a Tarred Repository from a File or the Standard Input Stream：`docker load < ubuntu.tar.gzdocker load --input ubuntu.tar`
1. Save an Image to a Tar Archive：`docker save busybox > ubuntu.tar`
1. Showing the History of an Image：`docker history`
1. Creating an Image Fron a Container：`docker commit nginx`
1. Tagging an Image：`docker tag nginx eon01/nginx`



### Container
* `docker container ls`：列出容器
* `docker ps`，列出正在執行的容器(process status)
	* -a：顯示所有的容器，包括未運行的。
    - -f：根據條件過濾顯示的內容。
    - --format：指定返回值的模板文件。
    - -l：顯示最近創建的容器。
    - -n：列出最近創建的n個容器。
    - --no-trunc：不截斷輸出。
    - -q：靜默模式，只顯示容器編號。
    - -s：顯示總的文件大小。
* `docker exec -it ert43yer /bin/sh`：進入ert43yer這個container執行shell
	* -i = --interactive，把標準輸入綁定到容器上

#### 基本操作1
1. 創建容器(create)：`docker create -t -i eon01/infinite --name infinite`
1. 執行容器(run)：`docker run -it --rm --name infinite -d eon01/infinite`
    - --rm：當容器終止時會自動刪除
3. 容器更名：`docker rename infinite infinity`
   * 將infinite改成infinity
4. 映像檔更名：`$ docker tag [imageid] [name:tag]`
5. 移除容器：`$ docker rm infinite`
6. 更新容器：`$ docker update --cpu-shares 512 -m 300M infinite`

#### 基本操作2
1. 啟動容器：`docker start nginx`
1. 停止容器：`docker stop nginx`
1. 重開：`docker restart nginx`
1. 暫停：`docker pause nginx`
1. 取消暫停：`docker unpause nginx`
1. 阻塞容器：`docker wait nginx`
1. 殺掉容器：`docker kill nginx`
1. 與現有容器連接：`docker attach nginx`

#### 特別操作
1. `docker run -v [外部位置]:[Container內部位址]`：利用外部位置來取代Container內部的位置，可以為資料夾或是檔案。

#### 從容器取得資訊：
1. 查看執行中的容器：`docker ps`，`docker ps -a`
1. Container Logs：`docker logs <container>`
1. Inspecting Containers：
	```
	docker inspect <container>
	docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q)
	```
3. Containers Events：`docker events <container>`
4. List the ports a docker container is running on
：`docker port <container>`
5. `docker top <container>` Running Processes / Show a 'top' view of processes running on a container
6. `docker stats <container>`，Container Resource Usage / Show a 'top' view of all docker containers
7. 檢查容器文件系統上的變更：`docker diff <container>`

#### 容器內外交換資料 （docker cp）
> 從容器內複製東西出來，把東西送到容器內
```dockerfile=
# Mount a local directory to your container 掛載本地資料夾到容器
docker run -v <local_dir>:<container_dir> <image>
# Copy file or folder from a docker container to host machine  從容器內複製東西出來
docker cp <container>:<container_dir> <local_dir>
# Copy file or folder from local machine onto a container 從本地複製東西進到容器
docker cp <local_dir> <container>:<container_dir>
```


---
### Dockerfile
* `vi Dockerfile`：編輯dockerfile </br>
![](https://i.imgur.com/YeOQwMw.jpg)
	* 第一行：去找最新版的image(alpine為image名)
	* 第二行第三行：根據XXX進行安裝
	* 第四行：啟動指令
* `docker build -t myimage .`：在當下目錄用dockerfile來建立一個image(名為myimage)
* `docker run -d -p 80:80 myimage`：在背景執行image，並指定port
* docker run -d -p 127.0.0.1:<local_port>:<docker_port> <image>，將本地埠號連結到容器本身


                                                             
### 掃描
- 掃描image與Dockerfile：雖然上傳到某些映像檔倉庫也會掃描，包版完先掃描可以節省很多時間
* `$ docker scan <image>`，掃描映像檔
* `$ docker scan --file Dockerfile <image:tag>`，掃描(所在地的)Dockerfile和指定的映像檔

---
## part2
### 刪除
1. `docker rmi xxxxx`，删除xxx這個映像檔
6. `docker rmi $(docker images -aq)`，删除所有的映像檔
7. `docker image prune`，移除未使用的映像檔
	1.  `REPOSITORY` 與 `TAG` 標示為 `<none>`
	2.  沒有其他 image 或 container 與此 image 有相依
9. `docker rm nginx`，刪除容器
10. `docker rm -v nginx`，刪除容器和它的資料卷
11. `docker ps -aq`，列出所有的容器 ID
12. `docker stop $(docker ps -aq)`，停止所有的容器
13. `docker rm $(docker ps -aq)`，删除所有的容器
14. `docker rm $(docker ps -a -f status=exited -q)`，移除全部退出的容器
15. `docker rmi $(docker images -f dangling=true -q)`，移除無相關的映像檔，此映像檔沒有與任何資源相連結
16. `docker volume rm $(docker volume ls -f dangling=true -q)`，移除無相關的資料卷
17. `docker system prune`，移除所有未使用的資源
	- all stopped containers
	- all networks not used by at least one container
	- all dangling images
	- all build cache
1. `docker kill [container]`: Kill a particular container.
1. `docker kill $(docker ps -q)`: Kill all containers that are currently running.
1. `docker rm [container]`: Delete a particular container that is not currently running.
1. `docker rm $(docker ps -a -q)`: Delete all containers that are not currently running.

- [參考資料](https://iter01.com/572355.html)

---

### 清理
> 把當下的都清理掉
1. 停止全部container：`$ docker stop $(docker container ls -aq)`
2. 清掉所有沒在用的container和image：`$ docker system prune`，確認(y)
3. 清除所有images：`$ docker rmi $(docker images -aq)`
4. 清除volume（如果有資料的話）：`$ docker volume rm $(docker volume ls)`




---

### 查看log或其他資訊
- `$ docker history [image]`: 展示個別映像檔的歷史
- `$ docker logs [Container]`：查看紀錄
- `$ journalctl -xe`：查看系統歷程
- `$ docker logs -f <container>`，持續追蹤這個容器的log
- `$ docker logs -t <container>`，顯示log的時間戳記
- `$ docker system info`，顯示與docker有關的資訊
- `$ docker system df`，顯示docker的磁碟空間使用情形



---

## part3
### Networking

1. Creating Networks：
	```dockerfile=
	docker network create -d overlay MyOverlayNetwork
	docker network create -d bridge MyBridgeNetwork
	docker network create -d overlay \  
	  --subnet=192.168.0.0/16 \  
	  --subnet=192.170.0.0/16 \  
	  --gateway=192.168.0.100 \  
	  --gateway=192.170.0.100 \  
	  --ip-range=192.168.1.0/24 \  
	  --aux-address="my-router=192.168.1.5" --aux-address="my-switch=192.168.1.6" \  
	  --aux-address="my-printer=192.170.1.5" --aux-address="my-nas=192.170.1.6" \  
	  MyOverlayNetwork
	```
1. Removing a Network：`docker network rm MyOverlayNetwork`
1. Listing Networks：`docker network ls`
1. Getting Information About a Network：`docker network inspect MyOverlayNetwork`
1. Connecting a  Running Container to a Network：`docker network connect MyOverlayNetwork nginx`
1. Connecting a Container to a Network When it Starts：`docker run -it -d --network=MyOverlayNetwork nginx`
1. Disconnecting a Container from a Network：`docker network disconnect MyOverlayNetwork nginx`

---
### Docker Volumes 
```dockerfile=
# List volumes
docker volume ls
# Create a volume
docker volume create <volume>
# Delete a volume
docker volume rm <volume>
# Show volume metadata
docker volume inspect <volume>
# Delete all volumes not attached to a container
docker volume prune


```



### Docker Compose
> 一次處理一堆container
```dockerfile=
# Start your docker-compose defined resources in detached mode 啟動compose
$ docker-compose up -d -f <docker_compose_yaml> 
# Stop all docker-compose resources  停止compose
$ docker-compose stop
# Destroy all docker-compose resources 關掉compose
$ docker-compose down

# Show docker-compose processes 列出現有的container
$ docker-compose ps
# Show docker-compose logs 查看log
$ docker-compose logs
# Show docker-compose resource consumption
$ docker-compose top
# 根據Dockerfile去製作全新的image來用。`--no-cache`指令會跟docker daemon說不要使用本地已經有的image。
$ docker-compose build --no-cache
```



---

### Docker Swarm
1. 安裝Docker Swarm：`curl -ssl https://get.docker.com | bash`
1. 初始化Swarm：`docker swarm init --advertise-addr 192.168.10.1`
1. Getting a Worker to Join the Swarm：`docker swarm join-token worker`
1. Getting a Manager to Join the Swarm：`docker swarm join-token manager`
1. Listing Services：`docker service ls`
1. Listing nodes：`docker node ls`
1. 創建服務：`docker service create --name vote -p 8080:80 instavote/vote`
1. Listing Swarm Tasks：`docker service ps`
1. 擴展服務：`docker service scale vote=3`
1. 更新服務：

```dockerfile=
docker service update --image instavote/vote:movies vote
docker service update --force --update-parallelism 1 --update-delay 30s nginx
docker service update --update-parallelism 5--update-delay 2s --image instavote/vote:indent vote
docker service update --limit-cpu 2 nginx
docker service update --replicas=5 nginx
```



---


### 複製文件
* `docker cp mycontainer:/opt/file.txt /opt/local/`
* `docker cp /opt/local/file.txt mycontainer:/opt/`

### 使用別名
**範例：使用 npm**
> 設定好後，打 npm 就等於打了長長一串 docker run 指令了。到這裡讀者也能感受，最後用起來的感覺會跟平常使用 npm 一模一樣，幾乎可以取代安裝工具。
1. alias npm="`docker run -it --rm -v \$PWD:/source -w /source node:14-alpine npm`"
2. npm

---

### 參數
* `-e`|--environment，key=value
* `-d`|--detach 背景執行 container
* `-it` 通常需要跟 container 互動，因此會加這個選項
* `-p`|--publish 把 container 的 port 公開到 host 上，格式為 [[[IP:]HOST_PORT:]CONTAINER_PORT]
	* 給完整格式的話，會把 IP:HOST_PORT 綁定到 CONTAINER_PORT；如果沒給 IP，則 IP 會代 0.0.0.0；如果連 HOST_PORT 也沒給，則會使用 0.0.0.0 加上隨機選一個 port，如 0.0.0.0:32768。
* `-f`|--force 如果是執行中的 container，會強制移除（使用 SIGKILL）
* `-i`|--interactive 和 -t|--tty 
* `-v`|--volume，掛載 volume 到這個 container 上，格式為 **[/host]:[/container]:[參數]**
* `-v $PWD:/source` 把本機目錄綁定到 container，$PWD 為執行指令時的當下目錄，/source 則是 container 裡的絕對路徑
* `-w /source` 是進去 container 時，預設會在哪個路徑下執行指令
* `npm -v` 在 container 執行的指令，可以視需求換成其他指令
* `-w`|--workdir 指定預設執行的路徑

---

### docker指令圖解
- ![docker指令圖解](https://i.imgur.com/ejjka86.png)

---

#### 延伸閱讀、參考資料
- [更詳細的 Docker 操作方法](https://ithelp.ithome.com.tw/articles/10252871)
- [DOCKER 移除 CONTAINERS、IMAGES、VOLUMES 與 NETWORKS 的方法](https://blog.clarence.tw/2019/09/10/docker-removing-containers-images-volumes-and-networks/)
- [joshhu 全面易懂的Docker指令大全](https://joshhu.gitbooks.io/dockercommands/content/)
- [Docker Cheat Sheet](https://swissarmydevops.com/wp-content/uploads/2020/11/Docker_Cheat_Sheet-1.pdf)


---

- [回到目錄](https://hackmd.io/@Hualiteq/r1lye3M3d)

