docker 容器入门(二)

写在前面的话

每篇一句

书到用时方恨少,事非经过不知难。

通过dockerfile配置文件定义运行容器

你可以将容器内部运行所依赖的所有资源和步骤定义在的Dockerfile文件中

Dockerfile 例子

目录结构

1
2
3
4
5
6
7
8
[root@localhost docker]# tree
.
└── app
├── app.py
├── Dockerfile
└── requirements.txt
1 directory, 3 files

Dockerfile 内容

以#号开头的行都是注释,为每个命令行写注释是个好习惯,方便别人了解每个步骤功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -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"]

requirements.txt 内容

定义了app.py python脚本所需的 flask(python轻量web框架)用来显示http页面,redis(缓存数据库)用来记录访客数量

1
2
Flask
Redis

app.py 内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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)

构建镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[root@localhost app]# pwd
/data/docker/app
[root@localhost app]# ls -l
总用量 12
-rw-r--r-- 1 root root 665 10月 22 16:40 app.py
-rw-r--r-- 1 root root 481 10月 22 16:38 Dockerfile
-rw-r--r-- 1 root root 12 10月 22 16:39 requirements.txt
[root@localhost app]# docker build -t dockerfiletestapp .
Sending build context to Docker daemon 4.608kB
Step 1/7 : FROM python:2.7-slim
2.7-slim: Pulling from library/python
85b1f47fba49: Pull complete
a5e401c4a903: Pull complete
9f744658dd62: Pull complete
562843cc69f8: Pull complete
Digest: sha256:b614fcd205ffe3f8a993dd29cc74fac6399a70d07e0d20a07f4222e968b79466
Status: Downloaded newer image for python:2.7-slim
---> 9724e90f1f17
Step 2/7 : WORKDIR /app
---> 40fcd39ff30a
Removing intermediate container fee56dd2f3d7
Step 3/7 : ADD . /app
---> 046356d78b97
Removing intermediate container 71a0202d1eb3
Step 4/7 : RUN pip install -r requirements.txt
---> Running in fbd0773ab2c4
Collecting Flask (from -r requirements.txt (line 1))
Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
Collecting Redis (from -r requirements.txt (line 2))
Downloading redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting itsdangerous>=0.21 (from Flask->-r requirements.txt (line 1))
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting Jinja2>=2.4 (from Flask->-r requirements.txt (line 1))
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting Werkzeug>=0.7 (from Flask->-r requirements.txt (line 1))
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting click>=2.0 (from Flask->-r requirements.txt (line 1))
Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask->-r requirements.txt (line 1))
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis
Successfully installed Flask-0.12.2 Jinja2-2.9.6 MarkupSafe-1.0 Redis-2.10.6 Werkzeug-0.12.2 click-6.7 itsdangerous-0.24
---> 9956c6e6c7c9
Removing intermediate container fbd0773ab2c4
Step 5/7 : EXPOSE 80
---> Running in 9d54cce05d2e
---> dd270ef27c69
Removing intermediate container 9d54cce05d2e
Step 6/7 : ENV NAME World
---> Running in e80e94eeaf05
---> c3639bed347a
Removing intermediate container e80e94eeaf05
Step 7/7 : CMD python app.py
---> Running in 6c6a47319e18
---> 6410ee31b207
Removing intermediate container 6c6a47319e18
Successfully built 6410ee31b207
Successfully tagged dockerfiletestapp:latest

docker image 可以查看到刚下载的python镜像和按照dockerfile构建的dockerfiletestapp

1
2
3
4
5
[root@localhost app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerfiletestapp latest 6410ee31b207 2 minutes ago 195MB
python 2.7-slim 9724e90f1f17 12 days ago 184MB
hello-world latest 05a3bd381fc2 5 weeks ago 1.84kB

前台运行容器

-p 选项将容器内部端口80 映射到所在虚拟机的8080 端口

1
2
3
4
[root@localhost app]# docker run -p 8080:80 dockerfiletestapp
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
172.17.0.1 - - [22/Oct/2017 09:16:05] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [22/Oct/2017 09:16:25] "GET / HTTP/1.1" 200 -

通过浏览器访问 容器所在虚拟机ip 192.168.0.146:8080

虚拟机宿主机浏览器访问

虚拟机宿主机命令行访问

1
2
zakizqzhangdeMacBook-Pro:~ zakizqzhang$ curl http://192.168.0.146:8080
<h3>Hello World!</h3><b>Hostname:</b> f5295eca69d8<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

1
2
3
4
5
docker ps 查看当前运行容器ID 也就是上面容器呈现的页面的Hostname
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f5295eca69d8 dockerfiletestapp "python app.py" 26 minutes ago Up 26 minutes 0.0.0.0:8080->80/tcp optimistic_goldberg
----纸上得来终觉浅绝知此事要躬行----
最好的赞赏是您的阅读!
0%