Docker容器镜像

如果想要开发一个基于python的应用,传统的开发方式中,首先要在本地操作系统中安装python。但Docker不用,只需要找到已经安装了python运行时环境的image即可,不需要本地操作系统中安装phthon,不只如此,image中可以包含任何应用运行时所需的构件。image本身是一种分层的特殊格式文件,在取得安装了python运行时环境的基础层以后,按下来就是把我们自己开发的东西逐层打包进去,构建新image。新image的构建通过定义Dockerfile文件实现,首先它有一个基础image,就是包含python运行时环境的镜像,接下来就是一系列的命令,将我们应用需要的库、文件、代码逐层加进去,最后打包。

创建简单Dockerfile

首先创建一个新目录并cd到此目录下,在此目录下创建名为Dockerfile的新文件,并将如下代码复制到文件中:

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

接下来创建Dockerfile文件中需要的两个文件,requirements.txt与app.py。requirements.txt包含两行内容,指出需要额外安装的python库,pip通过此文件安装我们需要依赖的库,内容如下:

Flask
Redis

app.py文件为python代码,是需要执行的程序,内容如下:

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "cannot connect to Redis, counter disabled"

    html = "

Hello {name}!

" \ "Hostname: {hostname}
" \ "Visits: {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)

将以上两个文件放在与Dockerfile文件同级的目录下,整个开发工作已经结束。在用Dockerfile构建新的image之前,先解释一下文件内容。
FROM python:2.7-slim
本条命令的意思是把python:2.7-slim当成本次构建的基础镜像,如果python:2.7-slim在本地不存在,则Docker自动从默认的镜像仓库中拉取,当然也可以通过设置修改Docker自带的默认image仓库。
WORKDIR /app
本条命令的意思是设置image的工作目录。
COPY . /app
本条命令会将刚才创建的两个文件复制到app目录下。
RUN pip install --trusted-host pypi.python.org -r requirements.txt
利用requirements.txt中的内容安装依赖库
EXPOSE 80
镜像在运行时对外暴露 80号端口。
ENV NAME World
设置镜像运行时的环境变量。
CMD ["python", "app.py"]
启动app.py程序。

Docker在用Dockerfile文件构建新镜像时,每运行一条命令就在原始镜像的基础上新增加一层。

构建镜像

首先确认当前目录下的文件:

$ ls
Dockerfile		app.py			requirements.txt

执行如下命令构建image:

docker build -t friendlyhello .

构建好的image目前被保存在本地文件系统中,可以为其添加tag,并上传到镜像仓库中。执行如下命令确认:

$ docker image ls

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

运行镜像

docker run -p 4000:80 friendlyhello

命令中的80端口号是容器网络内部的一个端口号,不能与外界通信,-p命令的意思是将80端口号映射成宿主机的4000端口号,这样就可以从外部访问此应用了。
可以在浏览器中打开http://localhost:4000试一下,注意网络问题如防火墙、DNS、代理等。

以上命令运行的容器会占用一个前端,通过如下命令使容器运行在后台:

docker run -d -p 4000:80 friendlyhello

通过如下命令确认容器是否在运行:
 

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

其中的CONTAINER ID由Docker自动生成,如果运行容器时没有特别指明主机名称,则此ID就是容器运行时的主机名称。

结束容器运行:

docker container stop 1fa4ab2cf395

需要注意的是,结束容器运行不代表此容器从系统中删除了。每个容器在运行时,在原来image的基础上会再添加一个可读写层,在容器运行过程中涉及到的修改操作如增加了某个文件、修改了某个文件的内容等,实际上会添加到这个可读写层,其它的层是不可修改的。当窗口停止运行时,其读写层仍然存在,在下次启动时继续使用。因此想要将容器删除还需要调用另外一个专门删除的命令。

你可能感兴趣的:(Docker)