# 第7章 建立與使用 Dockerfile
# 觀念圖
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 %}