5-Dockerfile文件
先練習一個例子:
-
創建
Dockerfile
文件FROM ubuntu:14.04 LABEL maintainer="vincent <jeffmanword@gmail.com>" RUN apt-get update && apt-get install -y redis-server EXPOSE 6397 ENTRYPOINT [ "/usr/bin/redis-server" ]
- FROM 是 我們選擇的 base 基礎鏡像
- LABEL 為 我們需要的標識,比如作者是誰
- RUN 是我們 執行的命令,必須使用連接符
- EXPOSE 暴漏的端口
- ENTRYPOINT 程序的入口
-
構建
docker build -t vincent/redis:latest .
關鍵字
-
FROM
FROM scratch # 制作base image
FROM centos # 使用base image
FROM ubuntu:14.04
盡量使用官方發布的image作為base image,原因很簡單,為了安全!
-
LABEL
LABEL maintainer="jeffmanword@gmail.com" LABEL version="1.0" LABEL description="This is description."
定義image的meta data,描述這個鏡像的信息
-
RUN
RUN yum update && yum install -y vim \python-dev # 反斜線換行RUN apt-get update && apt-get install -y perl \pwgen --no-install-recommends && rm -rf \/var/lib/apt/lists/* # 注意清理cacheRUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
使用
&&
的原因是因為,每一次RUN都會增加一層(類似commit),如果使用&&
連接,將只有一層。
總結: 為了無用分層,為了美觀,合并多條命令為一條,如果復雜的RUN請使用反斜線換行! -
WORKDIR
WORKDIR /root
WORKDIR /test # 如果沒有test文件夾將會自動創建 WORKDIR demo RUN pwd # 輸出結果應該是/test/demo
設定當前工作目錄的,類似
cd
命令。在使用的時候注意盡量不要用RUN cd,而是使用WORKDIR,并且路徑盡量使用絕對路徑,避免出錯。 -
ADD 和 COPY
ADD hello /
ADD test.tar.gz / # 添加到根目錄并解壓,這是與COPY的區別
WORKDIR /root ADD hello test/ # 添加到 /root/test/hello
WORKDIR /root COPY hello test/ # /root/test/hello
大部分情況下,COPY優先于ADD,ADD除了COPY外還有額外功能(如解壓),添加遠程文件請使用curl或者wget。
-
ENV
ENV MYSQL_VERSION 5.6 # 設置環境變量 RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \&& rm -rf /var/lib/apt/lists/* # 引用環境變量
盡量使用ENV,可以簡化Dockerfile,并增加可維護性(避免寫死)。
-
EXPOSE
EXPOSE 1080 443
EXPOSE 用來暴露端口,EXPOSE 只是聲明運行容器時提供的服務端口,這僅僅是一個聲明,在運行容器的時候并不會因為這個聲明就會開啟端口服務,你依舊需要使用 -P 或者 -p 參數映射端口。在 Dockerfile 中寫這樣的端口聲明有助于使用者理解這個鏡像開放哪些服務端口,以便配置映射。
-
VOLUME
VOLUME /data
-
CMD 和 ENTRYPOINT
- shell方式
RUN apt-get install -y vim CMD echo "hello word" ENTRYPOINT echo "hello docker"
RUN ["apt-get", "install", "-y", "vim"] CMD ["/bin/echo", "hello word"] ENTRYPOINT ["/bin/echo", "hello docker"]
- exec 方式
FROM ubuntu:16.04 WORKDIR / CMD ["ls"]
FROM ubuntu:16.04 WORKDIR / ENTRYPOINT ["ls"]
CMD 和 ENTRYPOINT 是容器啟動命令。這兩條命令的區別是ENTRYPOINT 可以讓我們把容器當成一條指令運行。CMD 命令為 docker 容器啟動時默認執行的命令,如果 docker run 指定了其他命令,CMD將會被忽略。
分別將上面exec的兩個例子構建成鏡像
docker build -t ubuntu-cmd . docker build -t ubuntu-entry .
$: docker run --rm ubuntu-cmd -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
$: docker run --rm ubuntu-entry -l total 4 drwxr-xr-x. 2 root root 4096 Jan 22 19:22 bin drwxr-xr-x. 2 root root 6 Apr 12 2016 boot drwxr-xr-x. 5 root root 340 Feb 10 09:44 dev drwxr-xr-x. 1 root root 66 Feb 10 09:44 etc drwxr-xr-x. 2 root root 6 Apr 12 2016 home drwxr-xr-x. 8 root root 96 Sep 13 2015 lib ...
制作一個hello word鏡像
-
編寫 一個 簡單 c 程序
hello.c
#include<stdio.h>int main() {printf("hello docker\n"); }
編譯成二進制
sudo yum install gcc glibc-static gcc -static hello.c -o hello
測試是否正常
[vagrant@10 hello-word]$ ./hello hello docker
-
創建Dockerfile
FROM scratch ADD hello / CMD ["/hello"]
-
創建鏡像
docker build -t 144.202.112.240:5000/hello-word .
輸出結果
Sending build context to Docker daemon 7.472MB Step 1/3 : FROM scratch---> Step 2/3 : ADD hello /---> Using cache---> 8d2cefe8cbf3 Step 3/3 : CMD ["/hello"]---> Using cache---> bb6f23084c78 Successfully built bb6f23084c78 Successfully tagged 144.202.112.240:5000/hello-word:latest
檢查是否構建成功
[vagrant@10 hello-word]$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE 144.202.112.240:5000/hello-word latest bb6f23084c78 23 hours ago 857kB
-
創建容器
docker run --rm 144.202.112.240:5000/hello-word
–rm 為 退出的時候自動刪除容器