Docker学习笔记(二)

docker-tutorial (2018-7-1)

GitHub仓库

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

# 设置工作目录为/app
WORKDIR /app

# 复制当前目录内容到容器中的/app目录
ADD . /app

# 安装requirements.txt文件中描述的所有需要的包
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 开放80端口给外部
EXPOSE 80

# 定义环境变量
ENV NAME Word

# 当容器启动时运行app.py
CMD ["python", "app.py"]

这个Dockerfile以来一系列的文件,我们接下来创建他们。

The app itself - 应用程序

在同一个目录下创建requirements.txtapp.py两文件。当Docekrfile构建镜像时,由于我们使用了定义了ADD所以目录下的文件会被添加到镜像中。我们把80端口暴露到外界,所以可以通过80端口查看APP。

requirements.txt
Flask
Redis
app.py
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 = "<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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容