docker实践入门之四
Posted 猛禽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker实践入门之四相关的知识,希望对你有一定的参考价值。
在前一个实践中,我们演示了如何使用现成的image来运行container供我们使用,这一节我们来试试自己建立image。
使用交互方式创建image
在第一篇文章里说过,通过对一个container执行commit操作可以创建一个image,这里先用这个方法做一个例子。
首先需要一个基本image,目前docker推荐的是用一个轻量级linux发行版:Alpine Linux,这个发行版的最大优点就是小,只有不到5M。
docker pull alpine
docker run -it alpine /bin/sh
现在进入了alpine的交互环境,为了方便在国内使用,首先修改/etc/apk/repositories文件,把默认的源改为ustc的:
https://mirrors.ustc.edu.cn/alpine/v3.3/main
https://mirrors.ustc.edu.cn/alpine/v3.3/community
官方源在国内速度太慢了。然后更新并安装python3环境:
apk update
apk add python3
apk add curl
curl -O https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py
rm get-pip.py
好了,现在可以执行exit退出交互环境,然后commit成一个新的image:
docker ps -a | grep Exit
docker commit xxxx alpine-py3
第一条命令查看刚才退出的那个container的ID是什么,然后把那个ID(XXXX)放到第二条命令里,即可生成一个叫alpine-py3的image。
注意,container ID不需要输入完整,只要前几位,保证唯一即可。
现在,可以来试试这个新的alpine-py3:
docker run -it alpine-py3 /bin/sh
现在这个交互环境里就是已经安装好py3的container了。
使用build命令自动创建
使用交互方式虽然看起来简单,但是实用性有限,最大的问题就是不能实现自动化操作——比如你需要一个新的image的时候,又要手工跑一堆命令,有没有办法让它自动构建呢?
当然有办法,那就用build命令,通过Dockerfile来创建image。
一个与上一例子一样结果的Dockerfile是这样的:
FROM alpine
MAINTAINER raptor<raptor.zh@gmail.com>
RUN echo "https://mirrors.ustc.edu.cn/alpine/v3.3/main" > /etc/apk/repositories \\
&& echo "https://mirrors.ustc.edu.cn/alpine/v3.3/community" >> /etc/apk/repositories \\
&& apk update \\
&& apk add python3 curl \\
&& curl -O https://bootstrap.pypa.io/get-pip.py \\
&& python3 get-pip.py \\
&& rm get-pip.py
这个文件算是一个比较简单的例子,只用到三个Dockerfile命令:FROM指定一个基础image,这里指定为alpine。MAINTAINER指定这个Dockerfile的维护者,仅作为一个说明。RUN是最主要的命令,后面跟一个shell命令(就是前一个例子中交互操作时输入的命令)。
本来多个shell命令可以用多个RUN来跑,但是这里是用&&连接起来的一串。之所以这样用,是因为一个RUN会生成一个中间container,虽然之后会被删除,但总是多余的工作量,放在一起就可以避免这种事,build的时候可以稍微快一点。
然后用这样的命令即可生成一个新的image,image的名字叫做alpine-py3a:
docker build -t alpine-py3a .
注意,Dockerfile的文件名必须是Dockerfile,build命令中的“.”表示当前目录,也是Dockerfile所在的目录。之所以指定目录而不是Dockerfile文件,是因为还可以对目录中的其它文件进行操作。
现在用交互操作也可以打开一个已经安装好python3的环境:
docker run -it alpine-py3a /bin/sh
跟前一个例子一样。
往image里添加文件,创建一个实际应用
前一个例子是通过echo来修改repositories文件,当然也可以把改好的文件直接放到image里去替换掉。
...
COPY repositories /etc/apk/
RUN apk update ...
其中repositories就是改好的repositories文件,放在跟Dockerfile同一目录中。
现在以一个bottle的web应用为例,以下为应用包含的文件和目录:
start.py
requirements.txt
static
|-default.css
具体内容就不列了,只是举个栗子而已。其中start.py为主文件,requirements.txt为python依赖包,views目录下为模板文件index.html。
然后把这些全部放到Dockerfile所在的目录下的app子目录中。新的Dockerfile是这样的:
FROM alpine
MAINTAINER raptor<raptor.zh@gmail.com>
EXPOSE 5000
COPY repositories /etc/apk/
RUN mkdir /var/app
COPY app /var/app/
WORKDIR /var/app/
RUN apk update \\
&& apk add python3 curl \\
&& curl -O https://bootstrap.pypa.io/get-pip.py \\
&& python3 get-pip.py \\
&& rm get-pip.py \\
&& pip3 install -r requirements.txt
CMD python3 start.py
现在可以创建一个image并启动为一个微服务:
docker build -t app1 .
docker run -d -p 5000:5000 app1
这个Dockerfile相对来说比较完整了,多了几个命令:EXPOSE是指定在docker内网中开放指定端口,注意,这个命令只对docker内网有效,-p参数与这个命令无关,所以如果不在docker内网中使用服务的话,这条命令也可以不用。WORKDIR指定了container运行时默认的启动目录,所以后面的requirements.txt和start.py都不需要指定目录。另外,COPY命令也与前面不同,因为这里是COPY目录,注意,这里并不会把源目录一起COPY过来,所以并不会有/var/app/app这样的结果。
以上是关于docker实践入门之四的主要内容,如果未能解决你的问题,请参考以下文章