---
# System prepended metadata

title: Docker 基礎指令筆記

---

# Docker 基礎指令筆記


<font size=5.5 color="#228b22">1. 顯示執行中的Container。</font>
```
docker ps [OPTION]
```

| OPTION   |     意義             |
| -------- | --------            |
| -a       | 顯示所有Container，包括未啟動的Container     |
| -n       | 顯示 n 個最後(最新)創建的Container    |



<font size=5.5 color="#228b22">2. 刪除 Container</font>
```
docker rm [CONTAINER]
```


<font size=5.5 color="#228b22">3. 顯示Images。</font>
```
docker images
```


<font size=5.5 color="#228b22">4. 刪除 Image</font>
```
docker rmi [IMAGE]
```


<font size=5.5 color="#228b22">5. 透過Image產生Container</font>
```
docker run [OPTION] [IMAGE]
```
**標準的建立Container並執行指令**
當我們在終端機下docker run [image]時，會產生Container並以前台姿勢進入容器內(attached狀態)，此時無法跟Container互動，要透過OPTION指令才能與之互動，若平常時只需要將起Container啟動在後台，則只需要docker run -d [Image]，因為無需互動，不需要-it。

| OPTION           | 意義                                                                                                                     |
|:---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| -i (interactive) | -i = Keep STDIN open even if not attached，沒有 -i 的話 container 就收不到你打的字，所以當需要與Container做互動(輸入指令給Container，Container會回傳指令結果）時會用。                                                                |
| -t (terminal)    | 透過terminal模式進入Container。                                                                                               |
| -d (detach)      | 讓Container處於後台運行，d=detached(分離的)。                                                                                 |
| -p (port)        | 設定主機主機的port轉接到Container的port，ex: -p 8080:80 代表把主機的8080 port所有流量轉發到web這個Container的80 port。 |
| --name    | 指定這個Container的名字。                                                                  

```
$ docker run -itd -p 6666:7777 --name myubuntu ubuntu
8a24bd2e4239cd42b0c8cc55c73c6030760c6a5cef02b728d181d7bd72dfc7bc
$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS                                       NAMES
8a24bd2e4239   ubuntu    "/bin/bash"   33 seconds ago   Up 31 seconds   0.0.0.0:6666->7777/tcp, :::6666->7777/tcp   myubuntu
```




<font size=5.5 color="#228b22">6. 進入Container</font>

<font size=4>**在Docker中有兩種做法**</font>
* <font size=5 color="#ee496a">docker attach</font>

```
docker attach [CONTAINER ID]
```
讓在背景執行的Container回到前台，<font color="#ee496a">要注意退出時可能會使Container也跟著被關閉</font>。
```
$ docker run -itd ubuntu
eafbed991e79124ded07c7fd312f06c0dc3e5e5ba723dc5f41f4e5877e8e1acb
$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
eafbed991e79   ubuntu    "/bin/bash"   3 seconds ago   Up 2 seconds             affectionate_beaver
$ docker attach eafbed991e79
root@eafbed991e79:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@eafbed991e79:/# whoami
root
```

* <font size=5 color="#ee496a">docker exec</font>
```bash
docker exec -it [CONTAINER ID] [COMMAND]
```
以終端機模式進入Container，且<font color="#ee496a">退出時也不會使Container關閉</font>，所以較推薦此方法。

```
$ docker run -itd ubuntu
c6e841452580e9b08c051b9d13cffe5bf833331e6eb64680cf5355482683cd12
$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
c6e841452580   ubuntu    "/bin/bash"   5 minutes ago   Up 5 minutes             gracious_swirles
$ docker exec -it c6e841452580 bash
root@c6e841452580:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@c6e841452580:/# exit
exit
$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
c6e841452580   ubuntu    "/bin/bash"   5 minutes ago   Up 5 minutes             gracious_swirles
```

---

<font size=5.5 color="#228b22">7. 在外部向執行中的Container內部下指令</font>
```
docker exec [OPTION] [CONTAINER ID] [COMMAND]
```
> <font size=3>這個指令很簡單，就是在外部向執行中的Container內部下指令，此時會呼叫Container內部的shell程式來執行你下的指令。</font>
```
$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED             STATUS             PORTS     NAMES
c6e841452580   ubuntu    "/bin/bash"   About an hour ago   Up About an hour             gracious_swirles
$ docker exec c6e841452580 whoami
root
```


<font size=6 color="#228b22">8. Dockerfile</font>
> <font size=3>在Docker的世界中，，所有Container都需要透過Image來建立，但從[Dockerhub](https://hub.docker.com/)上Pull下來的Image未必滿足我們的需求，此時可以透過Dockerfile來建置自己的Image，換句話說Dockerfile就是客製化Image的腳本。</font>

```
docker build -t myImage .
```

Dockerfile結構大致分為四個部分
1. 基礎映像檔(image)資訊
2. 維護者資訊
3. 映像檔操作指令
4. 容器啟動時需執行的指令
```
FROM ubuntu:18.04

MAINTAINER shawn

EXPOSE 8080

WORKDIR /app

COPY application.jar /

RUN tar zxvf apache-tomcat-7.0.82.tar.gz

ENV JAVA_HOME=/jdk1.8.0_152
ENV PATH=$PATH:/jdk1.8.0_152/bin

CMD ["/apache-tomcat-7.0.82/bin/catalina.sh", "run"]
```

* <font size=5>**FROM**</font>：使用到的 Docker Image 名稱。

* <font size=5>**MAINTAINER**</font>：說明，撰寫和維護這個Dockerfile的人是誰。
* <font size=5>**EXPOSE**</font>：設定容器運行時提供服務的通訊埠。
* <font size=5>**WORKDIR**</font>：設定當前的工作目錄
* <font size=5>**COPY**</font>： 把本機(Local)的檔案複製到Image裡，第一個參數為local檔案的位置，第二個參數為此檔案想放在容器裡的位置。
* <font size=5>**RUN**</font>：最重要的部分，RUN指令後面放Linux指令(因為base image是ubuntu)，想要在Image上設定或安裝都須將命令寫於此，用來執行安裝和設定這個Image需要的東西。
* <font size=5>**ENV**</font>：用來設定容器的環境變數。
* <font size=5>**CMD**</font>：當此執行docker run時會執行的指令，<font size=3 color="#9fb420">**要特別注意的事如下**：</font>

1. <font size=3 color="#e1565b">**Dockerfile中只能有一行CMD，若有多行CMD，則只有最後一行會生效。**</font>
2. <font size=3 color="#e1565b">**若在建立Container時有帶執行的命令，則CMD的指令會被蓋掉。**</font>
例如：單純執行docker run <image id>時，CMD所定義的指令一樣會被執行，<font size=5>但</font>當執行docker run <image id> bash時，因為多了bash指令，Container就會執行bash，而原本CMD中定義的值就會被覆蓋。

<font size=5 color="#1faf69">其他常用指令</font>

* <font size=5>**ADD**</font>：基本上與**COPY**相同，都能從複製本地檔案到容器中，但有兩個地方不太一樣
1. ADD的一個特性是<font color="#457bde">**有能力自動解壓檔案**</font>。所以如果是個可識別的壓縮格式(tar, gzip, bzip2, etc)的本地檔案，就會被解壓到指定容器檔案系統的路徑。
2. ADD指令可以使用URL作為參數。當遇到URL時候，<font color="#457bde">**可以通過URL下載檔案且複製到指定位置**</font>，例子如下
```
ADD http://foo.com/bar.go /myapp
```
>**所以<font size=3 color="#e1565b">建議使用COPY而非ADD</font>，因為若你想從遠端下載的話，不如直接使用 RUN wget ...**。

* <font size=5>**ENTRYPOINT**</font>：和**CMD**一樣，用來設定映像檔啟動Container時要執行的指令，但不同的是，<font size=3 color="#e1565b">**ENTRYPOINT一定會被執行，而不會有像CMD覆蓋的情況發生**</font>，<font size=3 color="#9fb420">**使用ENTRYPOINT的注意事項如下：**</font>
1.  <font size=3 color="#457bde">**Dockerfile中只能有一行ENTRYPOINT，若有多行ENTRYPOINT，則只有最後一行會生效。**</font>
2.  若在建立Container時有帶執行的命令，<font size=3 color="#457bde">**ENTRYPOINT的指令不會被覆蓋**</font>，也就是一定會執行。
3.  如果想要覆蓋ENTRYPOINT的預設值，則在啟動Container時，可以加上「–entrypoint」的參數，例如：docker run –entrypoint




---
