---
# System prepended metadata

title: Docker Intro
tags: [mynote]

---

###### tags: `mynote`
# Docker Intro

[TOC]

## Image
Image 包裝了一個執行特定環境所需要的資源。

每個 image 都有獨一無二的 digest，這是從 image 內容做 sha256 產生的。這個設計能讓 image 無法隨意改變內容，維持資料一致性。

雖然 image 裡有必要的資源，但它無法獨立執行，必須要靠 container 間接執行。

## Container
基於 image 可以建立出 Container。

它的概念像是建立一個可讀寫內容的外層，架在 image 上。實際存取 container 會經過可讀寫層與 image，因此看到的內容會是兩者合併後的結果。

Container 特性跟 image 不一樣，因為有可讀寫層，所以 container 可以讀寫，也可以拿來執行。
:::info
container可以儲存資料， 如果重新創建container，就會變為一個全新的os
:::
## Repository
Repository 是存放 image 的空間。

Docker 設計類似分散式版本控制的方法來存放各種 image。而分散式架構就會有類似 git 的 pull / push 行為，實際做的事也跟 git 類似：為了要跟遠端的 repository 同步。

另一個與 repository 很像，但容易混用的名詞為 Registry，後者涵蓋範圍更廣，包含了更多 repository 與身分驗證功能等，通常比較常討論的也是 registry。

目前 Docker 預設的 registry 為 DockerHub，大多數程式或服務的 image 都能在上面找得到。

Image、container、repository 之間的關係就像光碟一樣：早期世紀帝國等光碟遊戲，會需要搭配其他可讀寫空間（如硬碟），才有辦法執行。

Image 像光碟片一樣，唯讀且不能獨立執行
Container 像硬碟一樣，可讀可寫可執行
Repository 則是光碟盒，而 Registry 則是像光碟零售商

# `docker run image_name`    
==docker run的行為如下==
1. 前景建立並執行 container
2. 等待執行程式結束（exit）後，會回到前景的命令提示字元
3. 該 container 會被標記成結束狀態



# `docker ps`
列出所有 Docker 容器
![](https://i.imgur.com/k64bJL0.png)


# `docker run -d -p 8080:80 httpd`
-p 後面參數 8080:80 的意思代表：當連線到 host 的 8080 port 會轉接到 container 的 80 port。以上面的指令為例，只要輸入 http://localhost:8080/ 即可接到 container 所啟動的 HTTP 服務。
![](https://i.imgur.com/dMnWeW2.png)


# `docker exec -it container_name bash`
進入container內部

# `docker logs -f web`
即時顯示docker內部狀態
![](https://i.imgur.com/IviePvY.png)


## how to choose base image
![](https://i.imgur.com/kv1NM67.png)


## image layer
image需要搭配container才能使用
因為container會創建一個R/W layer
user才可以對image做讀寫
:::info
選擇正確的base image， 因之後安裝其它套件可能造成layer增加而佔用空間
所以建議在dockerfile就建置好image所需要的套件
:::

![](https://i.imgur.com/LgQe960.png)
 ## `docker image history image_name`
show all history of the image
 ![](https://i.imgur.com/zEzTAnt.png)

:::info
很多image都是用alpine linux來製作的
alpine linux是輕量版linux
:::

## 如何製作image


1. crete a folder and name a file `dockerfile`
2. write down your config in dockerfile
```dockerfile=
From nginx:1.19.6-alpine
maintainer dennis huang
copy index.html /usr/share/nginx/html/ #copy file to image
CMD ["nginx","-g","daemon off;"] 
```
![](https://i.imgur.com/0pXHrEe.png)

3. build image
```shell=
docker build -t myfirstimage2 .
```
4. run image
```shell=
docker run -p 8080:80 -d myfirstimage2
```
5. check the results
```shell=
curl http:\\localhost:8080
```
![](https://i.imgur.com/88cJQeP.png)



# Docker with VSCODE
## deploy
1. open a folder for project
![](https://i.imgur.com/hCh9IaF.png)

3. 選取 Remote-Containers: Add Development Container Configuration Files
![](https://i.imgur.com/9UHByvU.png)
3. set devcontainer.json
![](https://i.imgur.com/2ZG4OSw.png)
4. open folder in container
![](https://i.imgur.com/yDKazkk.png)

5. 確定已經進入container
![](https://i.imgur.com/7lhV4Kg.png)

6. 如果想要加修改devcontainer.json，例如預載extension
    - 找到extension ID
    ![](https://i.imgur.com/YKN2a4a.png)
    -加入devcontainer.json
    ![](https://i.imgur.com/8Bg0pE6.png)
    - rebuild container
    ==需要在container內部執行此動作==
    ![](https://i.imgur.com/ZgmWkM3.png)

## Install heoku in docker
```shell=
sudo curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
```

# FAQ
## container內的git出現一堆modified文件怎麼辦？
A: 增加一個.gitattributes file
並加入如下內容
```
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
```
![](https://i.imgur.com/FoGIzQu.png)