docker-tutorial
This repo is a translation of the docs.docker.com.
Also, you can check the English version here.
2. Containers - 容器
You new development environment - 新的开发环境
如果你曾经写过Python, 你知道你首先要做的是在你的机器上安装Docker运行环境。设想一下这种情况,你有两个应用程序需要依赖一个相同的库,但是需要的版本不相同,这将会是一件非常糟糕的事情,而且实际开发的情况远比这要复杂。
使用Docker你可以把一个Python运行环境打包成一个镜像,然后你可在其中开发你的Python程序了,所有的库、依赖关系还有你的应用程序都是独立的不会被其他外界因素所影响。
Define a container with Dockerfile - 使用Dockerfile定义容器
Dockerfile
定义了你容器内部的环境和与外界交互的方式。当Dockerfile相同是,容器就是相同的。
Dockerfile
创建一个空目录,并且进入那个目录,创建一个文件名为Docekrfile
的文件,复制以下文本到其中。
# 使用一个官方的Python运行环境当做基本环境FROM python:2.7-slim# 设置工作目录为/appWORKDIR /app# 复制当前目录内容到容器中的/app目录ADD . /app# 安装requirements.txt文件中描述的所有需要的包RUN pip install --trusted-host pypi.python.org -r requirements.txt# 开放80端口给外部EXPOSE 80# 定义环境变量ENV NAME Word# 当容器启动时运行app.pyCMD ["python", "app.py"]
这个Dockerfile
以来一系列的文件,我们接下来创建他们。
The app itself - 应用程序
在同一个目录下创建requirements.txt
和app.py
两文件。当Docekrfile
构建镜像时,由于我们使用了定义了ADD
所以目录下的文件会被添加到镜像中。我们把80端口暴露到外界,所以可以通过80端口查看APP。
requirements.txt
Flask Redis
app.py
from flask import Flaskfrom redis import Redis, RedisErrorimport osimport socket# Connect to Redisredis = 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 = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {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)
Build the app - 构建应用程序
我们已经准备好构建应用程序了,确保你仍然在新建目录的顶层,ls
后应该显示如下内容:
$ ls app.py Dockerfile requirements.txt
现在运行以下的命令来构建,这条命令会创建一个Docker镜像,我们可以使用-t
给他取一个名字:
$ docker build -t friendlyhello .
使用docker image ls
命令显示镜像列表:
$ docker image ls REPOSITORY TAG IMAGE ID friendlyhello latest a59873218b7e python 2.7-slim 02ca219cf841 hello-world latest e38bc07ac18e
Run the app - 运行应用程序
运行程序,使用-p
参数把主机的4000端口映射到容器的80端口:
$ docker run -p 4000:80 friendlyhello * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
Python应用程序在容器中http://0.0.0.0:80
提供了服务,我们把他映射到了主机的4000端口,所以可以通过http://localhost:4000
来获取他。
我们可以用curl
命令来访问这个应用程序提供的服务:
$ curl http://localhost:4000 <h3>Hello World!</h3><b>Hostname:</b> 49e76c9dd43a<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
好了,接下来关闭程序了,按下CRTL+C
就可以终止程序了。
由于这个程序是一个提供http服务的程序,所以我们可以让他在后台运行,可以使用-d
参数:
$ docker run -d -p 4000:80 friendlyhello fbb2987bfa430b15a8616d0e77259b2f746c9005511607058c588010558f791c
你将会得到一个很长的APP ID,然后程序就在后台运行了,可以使用docker container ls
来查看容器和他们简短的容器ID:
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fbb2987bfa43 friendlyhello "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:4000->80/tcp gifted_nobel
现在可以用docker container stop
来终止这个容器,通过容器的ID来指定关闭的容器:
$ docker container stop fbb2987bfa43 fbb2987bfa43
Share your image - 分享你的镜像
Docker容器可以分发,就像Github上的仓库一样,我们可以去网上拉取别人或者是一些大公司已经建立的镜像,并且在他们的基础上构建我们自己的镜像,我们前面的例子就是这样的,当然我们也可以分享出我们自己的镜像来给别人使用。
Log in with you Docker ID - 用Docker ID登录
如果你还没有Docker账户,可以注册一个hub.docker.com.
登录Docker ID
$ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: Password: Login Succeeded
Tag the image - 为镜像起名
给镜像起名的格式是username/repository:tag
,tag
是可选的,但是推荐用tag来区分容器。
可以使用docker img image
来给镜像命名:
$ docker tag image username/repository:tag
例如:
$ docker tag friendlyhello chenjie3323/get-started:part2
然后,可以使用docker image ls
来查看刚刚打标签的镜像
$ docker iamge ls REPOSITORY TAG IMAGE ID CREATED SIZE chenjie3323/get-started part2 009af17a4c6a 25 minutes ago 132MB friendlyhello latest 009af17a4c6a 25 minutes ago 132MB <none> <none> a59873218b7e 30 minutes ago 132MB python 2.7-slim 02ca219cf841 3 days ago 120MB hello-world latest e38bc07ac18e 2 months ago 1.85kB
Publish the image - 发布镜像
上传你起好名的镜像:
$ docker push username/repository:tag
例如:
$ docker push chenjie3323/get-started:part2 The push refers to repository [docker.io/chenjie3323/get-started] e383c98e1701: Pushed 0f7c4f3da142: Pushed 13cfd850c910: Pushed 7dd909bc1884: Mounted from library/python 13fd5e03bfb3: Mounted from library/python 28a70ee9f822: Mounted from library/python 9c46f426bcb7: Mounted from library/python part2: digest: sha256:afeaef89398ffd676bf20cc200b1619405111ea071d869bc71eae271eff36c2b size: 1788
上传完成后,你的镜像就可以开放给其他人拉取了。如果登录到Docker hub你还能看到你的镜像。
Pull and run the image from the remote repository - 从远程仓库拉取和运行镜像
当使用docker run
命令运行镜像时,如果本地没有这个镜像,docker会自动的从网上拉取,并自动解决依赖的镜像。
命令速记
# 使用当前目录下的Dockerfile创建经镜像$ docker build -t friendlyhello .# 运行"friendlyname",把容器80映射到主机4000端口$ docker run -p 4000:80 friendlyname # 同上,但是以后台方式运行$ docker run -d -p 4000:80 friendlyname# 显示所有运行的容器$ docker container ls# 显示所有容器包括未运行的$ docker container ls -a# 关闭特定的容器$ docker container stop <hash># 强制关闭特定容器$ docker container kill <hash># 从本机中移除特定的容器$ docker container rm <hash># 从本机中移除所有容器$ docker container rm $(docker container ls -a -q)# 显示本机中所有的镜像$ docker image ls -a# 移除特定的镜像$ docker image rm <image id># 移除所有镜像$ docker image rm $(docker image ls -a -q)# 登录Docker hub账户$ docker login# 为上传的镜像打标签$ docker tag <image> username/repository:tag# 上传镜像$ docker push username/repository:tag# 运行远程镜像$ docker run username/repo:tag
作者:Jimmy_Will
链接:https://www.jianshu.com/p/562edc275d1a