---
# System prepended metadata

title: 第7章 建立與使用 Dockerfile
tags: [docker, 語法, dockerfile, '2021']

---

# 第7章 建立與使用 Dockerfile


# 觀念圖

https://i.imgur.com/mw2hZqY.png
![](https://i.imgur.com/mw2hZqY.png)

docker client - dokcer terminal 下指令的地方
build context - 下了 docker build 指令的時候我們當下的目錄被稱為 build context (一定有 Dockerfile)
docker engine - docker daemon 接受 docker build指令 
一開始執行的時候會將 build context (硬體主機上的) 拷貝一份到虛擬機器上

tmp ContainerX - 臨時的 container

COPY /src(是虛擬機上的 Linux OS檔案系統們，中間區塊，Copied Context那塊) /dst (臨時跑起來的 container02)


# 語法
## 情境式語法 - From 

> 去找 base image 得來源

```
// linux command
pwd
touch - 建造空白檔案
cat - 印出檔案內容
```
### 範例
alpine是輕量的linux

```dockerfile=
FROM alpine:latest
```

docker build -t dockerhubname/00x .


docker run dockerhubname/00x cat /etc/os-release (使用 image 提供的指令)
docker run dockerhubname/00x -it /bin/sh
docker run -d dockerhubname/00x tail -f /dev/null (會一直跑 container 不會消失)
docker exec -it container_id  /bin/sh (進入到正在跑的 container 裡)

## 情境式語法 - ENTRYPOINT

> 預設啟動 container 會執行的指令 

ENTRYPOINT["tail", "-f", "/dev/null"]

```dockerfile=
FROM alpine:latest
ENTRYPOINT ["tail", "-f", "/dev/null"]
```

docker build -t xxxx/002 .
docker run -d xxxx/002

## 情境式語法 - RUN

> 去使用任何 base image(ex:alpine) 指令, 是在 image building 執行

### 手動進去 docker 裝 apache

```
docker run -d -p 8080:80 xxxx/002
docker exec -it container_id /bin/sh

// 在 docker container 裡面
apk --update add apache2 (安裝 apache)
rm -rf /var/cache/apk/*
httpd -D FOREGROUND
echo $(docker-machine ip) 
```

### 在 dockerfile 裡面安裝 apache

```dockerfile=
FROM alpine:latest
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
ENTRYPOINT ["http", "-D", "FOREGROUND"]
```

```
docker run -d -p 8081:80 xxxx/004
docker container ls
echo $(docker-machine ip) 
```

## 情境式語法 - ENV

> 設定環境變數

```
定義方式 => ENV myworkdir /var/www/localhost/htdocs
使用方式 => ${myworkdir}
```


兩個 RUN 指令會啟動一個暫時的 container 但是兩個是獨立的所以當

```
RUN cd /var/www
RUN pwd
```

這兩個位置會是不一樣的

```
RUN cd /var/www && pwd 

或

RUN cd /var/www \
    && pwd 
```
會是正確的


### 無ENV
```dockerfile=
FROM alpine:latest
MAINTAINER　MyName
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
RUN cd /var/www/localhost/htdocs \
    && echo "Hello world 1 Jake" >> index.html 
RUN cd /var/www/localhost/htdocs \   
    && echo "Hello world 2 Jake" >> index.html 
RUN cd /var/www/localhost/htdocs \     
    && echo "Hello world 3 Jake" >> index.html 
ENTRYPOINT ["http"]
CMD ["-D", "FOREGROUND"]
```

```
docker run -d -p 8080:80 xxxxx/005
echo $(docker-machine ip) 
```

### 有ENV 
```dockerfile=
FROM alpine:latest
MAINTAINER　MyName
ENV myworkdir /var/www/localhost/htdocs
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
RUN cd ${myworkdir} \
    && echo "Hello world 1 Jake" >> index.html 
RUN cd ${myworkdir} \   
    && echo "Hello world 2 Jake" >> index.html 
RUN cd ${myworkdir} \     
    && echo "Hello world 3 Jake" >> index.html 
    
ENTRYPOINT ["httpd"]
CMD ["-D", "FOREGROUND"]
```



## 情境式語法 - WORKDIR

> 預設工作路徑也就是當在 build 時會在那個路徑底下開始作業(每一個暫時container 開始時)

```
ENV myworkdir /var/www/localhost/htdocs

WORKDIR ${myworkdir}
```


```dockerfile=
FROM alpine:latest
ENV myworkdir /var/www/localhost/htdocs
WORKDIR ${myworkdir}
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
RUN echo "Hello world 1 Jake" >> index.html 
RUN echo "Hello world 2 Jake" >> index.html 
RUN echo "Hello world 3 Jake" >> index.html 
ENTRYPOINT ["http", "-D", "FOREGROUND"]
```

## 情境式語法 - ARG

> 動態變數，可以在建立 image 時動態改變值

```dockerfile=
FROM alpine:latest
ENV myworkdir /var/www/localhost/htdocs
ARG whoami=Jake
WORKDIR ${myworkdir}
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
RUN echo "Hello world 1 ${whoami}" >> index.html 
RUN echo "Hello world 2 ${whoami}" >> index.html 
RUN echo "Hello world 3 ${whoami}" >> index.html 
ENTRYPOINT ["http", "-D", "FOREGROUND"]
```

```
docker build -t xxxx/006 .
docker run -d -p 8080:80 xxxx/006
echo $(docker-machine ip) 
docker build --build-arg whoami=Tony  -t xxx/test07 . 
docker run -d -p 8089:80 xxx/test007
```

## 情境式語法 - COPY

下載教材 content.txt

> linux vm 空間複製到 container 空間

```dockerfile=
FROM alpine:latest
ENV myworkdir /var/www/localhost/htdocs
ARG whoami=Jake
WORKDIR ${myworkdir}
RUN apk --update add apache2
RUN rm -rf /var/cache/apk/*
RUN echo "Hello world 1 ${whoami}" >> index.html 
RUN echo "Hello world 2 ${whoami}" >> index.html 
RUN echo "Hello world 3 ${whoami}" >> index.html 
COPY ./content.txt (Linux VM 空間) ./ (container 空間)
RUN ls -l ./
RUN cat ./content.txt >> index.html
ENTRYPOINT ["http", "-D", "FOREGROUND"]
```

```
docker build -t xxx/008 .
docker run -d -p 8090:80 xxx/008
echo $(docker-machine ip) 
```

###### tags: `2021`  `docker` `dockerfile` `語法`


{%hackmd BJrTq20hE %}
