本文講解如何在本地構建一個基礎的Docker Python環境鏡像,並擴展這個基礎鏡像構建Python運行環境,之后再構建自己的Python應用。
創建基礎鏡像
Docker 提供了兩種方法來創建基礎鏡像,一種是通過引入tar包的形式,另外一種是通過一個空白的鏡像來一步一步構建,本文使用的是第二種方法,既FROM scratch
scratch是Docker保留鏡像,鏡像倉庫中的任何鏡像都不能使用這個名字,使用FROM scratch表明我們要構建鏡像中的第一個文件層。
如果我們有一個Linux下可執行的二進制文件,可以構建一個簡單的鏡像,僅執行這個二進制。下面是Dockerfile。
FROM scratch
ADD hello /
CMD ["/hello"]
注意因為Docker是基於Linux的虛擬機,所以二進制應該是在Linux可運行的,作者在Mac下編譯了一個簡單的c程序,在運行的時候會遇到下面的錯誤。
standard_init_linux.go:190: exec user process caused "exec format error"
查看這個文件的信息是hello: Mach-O 64-bit executable x86_64
構建的過程很簡單,執行如下命令。
$ docker build -t chello:0.1 .
通過 docker images 命令可以本地的鏡像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
chello 0.1 0ffaacaa21e5 36 minutes ago 8.43kB
這樣就是一個基礎的鏡像,但是如果需要基礎鏡像發揮更多的作用,我們還需要其他的工作。Docker中的容器運行在操作系統中,共享了操作系統的內核。對於在Mac、Windows平台下,則是基於Linux虛擬機的內核。而Linux內核僅提供了進程管理、內存管理、文件系統管理等一些基礎的管理模塊。除此之外,我們還需要一些Linux下的管理工具,包括ls、cp、mv、tar以及應用程序運行依賴的一些包。因此我們就需要首先構建一個Minimal的操作系統鏡像,在此基礎上構建Python環境,再構建應用鏡像。這樣就實現了鏡像文件分層,今后如果我們需要更新Python版本,那么只需要對這一層進行更新就可以。
Docker 的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統就是上文說到的UnionFS。在Docker鏡像的最底層是bootfs。這一層與我們典型的Linux/Unix系統是一樣的,包含boot加載器和內核。當boot加載完成之后整個內核就都在內存中了,此時內存的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs。Docker在bootfs之上的一層是rootfs(根文件系統)。rootfs就是各種不同的操作系統發行版,比如Ubuntu,Centos等等。Docker 核心技術與實現原理 這篇文章,作者閱讀了 rootfs 的規范,指出構建rootfs一些必須的文件夾。
創建 Linux 鏡像:alpine
目前比較流行的 rootfs 應該就是 alpine 了,因為他的體積特別小,最簡單的環境只需要 5M ,下面是他的目錄結構,下載地址在 這里。

下載了 alpine 之后,我們構建 Dockerfile
FROM scratch
ADD alpine-minirootfs-3.8.0_rc8-x86_64.tar.gz /
CMD ["/bin/sh"]
構建鏡像
bogon:alpine rousseau$ docker build -t alpine:3.8 .
Sending build context to Docker daemon 4.148MB
Step 1/3 : FROM scratch
--->
Step 2/3 : ADD alpine-minirootfs-3.8.0_rc8-x86_64.tar.gz /
---> dc4ab7451b42
Step 3/3 : CMD ["/bin/sh"]
---> Running in 6a878a1394a4
Removing intermediate container 6a878a1394a4
---> 4e0b9a3dffba
Successfully built 4e0b9a3dffba
Successfully tagged alpine:3.8
運行
bogon:alpine rousseau$ docker run -i -t alpine:3.8 /bin/sh
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ # uname -a
Linux 9e6234b63505 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 Linux
Dockerfile 中相關參數
- FROM 指的是依賴的基礎鏡像,如scratch表示的是空白的,從零開始的。依賴的鏡像可以是本地的,也可以是遠程庫的
- ADD 指的是添加本地文件到鏡像中,如果遇到linux可解壓格式文件,會自動解壓,這就是為什么整個文件中沒有對tar.gz進行顯式解壓
- RUN 運行命令,如安裝軟件的相關命令
- CMD 設置啟動Container時默認執行的命令,這個可以在啟動容器時覆蓋
相關的命令
# 查看容器的日志
$ docker logs b4ce4d2d7cb6
standard_init_linux.go:190: exec user process caused "exec format error"
參考資料:
1、Create Base Image
2、How can I make my own base image for Docker?
3、Moby Project
4、Docker-library python
5、Ubuntu 16.04 LTS
6、alpine
7、alpine download
8、Docker 核心技術與實現原理
9、BusyBox
