概述
docker-compose,可以实现从 Dockerfile 来构建 docker 镜像。
安装
在 mac 下,默认已经安装了 docker-compose。其它环境下的安装见官方文档
Python web 应用示例
本小节实现一个 python web 应用,使用了 Flask 框架,保存点击数据到 redis 中。
准备工作
已经安装好了 Docker Engine 和 Docker Compose
设置
创建工程目录
$ mkdir composetest
$ cd composetest
创建 app.py 文件
内容如下
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
其中 redis 是本容器的主机名;Redis 服务使用默认端口 6379
创建 requirements.txt 文件
内容如下
flask
redis
编写 DockerFile
内容如下
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
含义
FROM python:3.4-alpine: 以Python 3.4镜像为基础来建立新镜像
ADD . /code : 把当前.目录加入到镜像的/code目录下
WORKDIR /code : 设置工作目录为 /code
RUN pip install -r requirements.txt : 安装python依赖
CMD ["python", "app.py"] : 启动的默认命令 python app.py
定义服务文件 docker-compose.yml
内容如下
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
定义了两个服务,web 和 redis.
其中 web 服务
- 使用当前目录下的 Dockerfile 来生成
- 将容器中的 5000 端口提供给外部的 5000 端口,其中 5000 端口为 Flask web 服务器的默认端口
redis 服务使用公开的 redis 镜像
生成和运行镜像
生成镜像
执行
docker-compose up
结果如下
[abeffect@fox composetest]$ docker-compose up
Building web
Step 1/5 : FROM python:3.4-alpine
3.4-alpine: Pulling from library/python
ab7e51e37a18: Pull complete
4a57a4e05b89: Pull complete
547e91589715: Pull complete
3a89af968cdb: Pull complete
1d882d2fb1c0: Pull complete
Digest: sha256:e716e8ca57060b881433ebcfe72b8c2f81c2d9c05b02b868c6540ff80400c9cd
Status: Downloaded newer image for python:3.4-alpine
---> ec2a8f24cd3f
Step 2/5 : ADD . /code
---> e15132d21a7f
Step 3/5 : WORKDIR /code
---> ba3d1a3f3c9d
Removing intermediate container 4af36b601af8
Step 4/5 : RUN pip install -r requirements.txt
---> Running in 15668592c1cc
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.10-py2.py3-none-any.whl (126kB)
Collecting click>=2.0 (from flask->-r requirements.txt (line 1))
Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting Werkzeug>=0.7 (from flask->-r requirements.txt (line 1))
Downloading Werkzeug-0.13-py2.py3-none-any.whl (311kB)
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, click, Werkzeug, flask, redis
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.13 click-6.7 flask-0.12.2 itsdangerous-0.24 redis-2.10.6
---> 1257635dcda5
Removing intermediate container 15668592c1cc
Step 5/5 : CMD python app.py
---> Running in 25cad534cd57
---> 42b4b60fdd57
Removing intermediate container 25cad534cd57
Successfully built 42b4b60fdd57
Successfully tagged composetest_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
1160f4abea84: Pull complete
a8c53d69ca3a: Pull complete
2dbffccae30e: Pull complete
0a00d98b862d: Pull complete
6162f8e8bd54: Pull complete
ed931789deac: Pull complete
Digest: sha256:0153c5db97e5852b25c5c4715cf88cff9d9dfd8fef5c4c81df8b4dd1a984abc7
Status: Downloaded newer image for redis:alpine
Creating composetest_redis_1 ...
Creating composetest_web_1 ...
Creating composetest_redis_1
Creating composetest_web_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1 | 1:C 16 Dec 05:06:10.723 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 16 Dec 05:06:10.723 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 16 Dec 05:06:10.723 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 16 Dec 05:06:10.724 * Running mode=standalone, port=6379.
redis_1 | 1:M 16 Dec 05:06:10.724 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 16 Dec 05:06:10.724 # Server initialized
redis_1 | 1:M 16 Dec 05:06:10.724 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1 | 1:M 16 Dec 05:06:10.724 * Ready to accept connections
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | * Debugger is active!
web_1 | * Debugger PIN: 196-949-087
查看结果
打开浏览器 http://localhost:5000/,可见
Hello World! I have been seen 4 times.
查看新镜像
[abeffect@fox ~]$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest 42b4b60fdd57 5 minutes ago 92.9MB
[abeffect@fox ~]$ docker inspect 42b4b60fdd57
[
{
"Id": "sha256:42b4b60fdd574d18f27884f32edf2cc4449523eb97d1554661aec5e50fe1efd3",
"RepoTags": [
"composetest_web:latest"
],
"RepoDigests": [],
"Parent": "sha256:1257635dcda544e585de8b2ea1307ff0b7faf6a15c8ab90fc88aa1a6086d1cf0",
"Comment": "",
"Created": "2017-12-16T05:04:27.8917461Z",
"Container": "25cad534cd57b81a9c6a06f298dd7b1a5c0191dc5f22abf9504fe7275648b627",
"ContainerConfig": {
"Hostname": "25cad534cd57",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D",
"PYTHON_VERSION=3.4.7",
"PYTHON_PIP_VERSION=9.0.1"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"python\" \"app.py\"]"
],
"ArgsEscaped": true,
"Image": "sha256:1257635dcda544e585de8b2ea1307ff0b7faf6a15c8ab90fc88aa1a6086d1cf0",
"Volumes": null,
"WorkingDir": "/code",
"Entrypoint": null,
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "17.09.0-ce",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D",
"PYTHON_VERSION=3.4.7",
"PYTHON_PIP_VERSION=9.0.1"
],
"Cmd": [
"python",
"app.py"
],
"ArgsEscaped": true,
"Image": "sha256:1257635dcda544e585de8b2ea1307ff0b7faf6a15c8ab90fc88aa1a6086d1cf0",
"Volumes": null,
"WorkingDir": "/code",
"Entrypoint": null,
"OnBuild": [],
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 92857408,
"VirtualSize": 92857408,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/e83123443e921e32993dd696e7695b379a294a18cdef437eceb9357528495ea5/diff:/var/lib/docker/overlay2/9cfaa5ec27e127277ee46b31b4dec42ead3ee226d78a18d4e73d790afdb36192/diff:/var/lib/docker/overlay2/c5322d8fc626f222705ca47245659fb61a8425cb19cae870313816a6f7cdd795/diff:/var/lib/docker/overlay2/a0973b7fa22766473abcba4de270ca158fe7a880edfbeb9e951bd8df7e092cdc/diff:/var/lib/docker/overlay2/4fa6628eb56d3084ca7df065efcbd67da2a28830a88a21d8f4be4ce0ac329b1a/diff:/var/lib/docker/overlay2/fc1d51ffe7967f8159ed2d2d7008a32b2d106ddbf6b87f4fccadd2e3e16fae5c/diff",
"MergedDir": "/var/lib/docker/overlay2/ff7f62d0dea47792506e149a63e87b79b545835be28cb176256df6d0f11a56a8/merged",
"UpperDir": "/var/lib/docker/overlay2/ff7f62d0dea47792506e149a63e87b79b545835be28cb176256df6d0f11a56a8/diff",
"WorkDir": "/var/lib/docker/overlay2/ff7f62d0dea47792506e149a63e87b79b545835be28cb176256df6d0f11a56a8/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:52a5560f4ca0b62c53985258faceddc20afe53fca394aec8a32083e01659d9fd",
"sha256:7c5ea328fb338eacb5da19231dff14cfeb5f4048541efd160ecd3f0351862124",
"sha256:c30b37dd392440c1c27a25382477535de1d11d939eb34c49b23868f11b6d706b",
"sha256:97291ed7e0ce205b5bc6c47668975b75dab976f07748dd7002f93c54a7b5c74d",
"sha256:8348954981b10ddde61e6f520992d54f3b2847a520330ebcbd95cbb01d0d5b50",
"sha256:bd34a5638bcc4c1b68420ee40d46e8844c0d12657eb9ab7720aae3af93a5b437",
"sha256:24edd138c6481e9a541537e3740d205db7bd285f4f00ad02622a1ddb95ff69dd"
]
},
"Metadata": {
"LastTagTime": "2017-12-16T05:04:28.0303435Z"
}
}
]
停止应用
docker-compose down
或者
Ctrl+C
Gracefully stopping... (press Ctrl+C again to force)
Stopping composetest_web_1 ... done
Stopping composetest_redis_1 ... done
增加一个 bind 点
修改 docker-compose.yml 文件,增加一个 bind 点。
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
volumes 参数将当前目录挂载到容器的 code 目录下,实现可以动态修改 code 目录内容,而不用重新生成镜像。
重新生成镜像
[abeffect@fox composetest]$ docker-compose up
Recreating composetest_web_1 ...
Starting composetest_redis_1 ...
Starting composetest_redis_1
Recreating composetest_web_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1 | 1:C 16 Dec 05:46:49.230 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 16 Dec 05:46:49.230 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 16 Dec 05:46:49.230 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 16 Dec 05:46:49.231 * Running mode=standalone, port=6379.
redis_1 | 1:M 16 Dec 05:46:49.231 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 16 Dec 05:46:49.231 # Server initialized
redis_1 | 1:M 16 Dec 05:46:49.231 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1 | 1:M 16 Dec 05:46:49.231 * DB loaded from disk: 0.000 seconds
redis_1 | 1:M 16 Dec 05:46:49.231 * Ready to accept connections
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | * Debugger is active!
web_1 | * Debugger PIN: 196-949-087
更新应用
- 修改 app.py 文件,将 return 行的内容更改如下
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
- 刷新浏览器,可见
Hello from Docker! I have been seen 13 times.
其它命令
- docker-compose up -d
后台运行参数 -d
[abeffect@fox composetest]$ docker-compose up -d
Starting composetest_web_1 ...
Starting composetest_redis_1 ...
Starting composetest_web_1
Starting composetest_web_1 ... done
- docker-compose ps
[abeffect@fox composetest]$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
composetest_web_1 python app.py Up 0.0.0.0:5000->5000/tcp
- docker-compose run web env
docker-compose run 参数,在容器外,运行容器内的命令
[abeffect@fox composetest]$ docker-compose run web env
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c58f98dd0dc6
TERM=xterm
LANG=C.UTF-8
GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D
PYTHON_VERSION=3.4.7
PYTHON_PIP_VERSION=9.0.1
HOME=/root
- docker-compose --help
查看其它命令
- docker-compose stop
停止由-d 参数启动的容器
[abeffect@fox composetest]$ docker-compose stop
Stopping composetest_web_1 ... done
Stopping composetest_redis_1 ... done
- docker-compose down --volumes
停止所有,删除 redis 的数据 volumes
[abeffect@fox composetest]$ docker-compose down --volumes
Removing composetest_web_run_6 ... done
Removing composetest_web_run_5 ... done
Removing composetest_web_run_4 ... done
Removing composetest_web_run_3 ... done
Removing composetest_web_run_2 ... done
Removing composetest_web_run_1 ... done
Removing composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing network composetest_default
到此,已经了解了 docker-compose 的基本运行.
常用指令
见 docker-compose 帮助
build | Build or rebuild services |
bundle | Generate a Docker bundle from the Compose file |
config | Validate and view the Compose file |
create | Create services |
down | Stop and remove containers, networks, images, and volumes |
events | Receive real time events from containers |
exec | Execute a command in a running container |
help | Get help on a command |
images | List images |
kill | Kill containers |
logs | View output from containers |
pause | Pause services |
port | Print the public port for a port binding |
ps | List containers |
pull | Pull service images |
push | Push service images |
restart Restart services | |
rm | Remove stopped containers |
run | Run a one-off command |
scale | Set number of containers for a service |
start | Start services |
stop | Stop services |
top | Display the running processes |
unpause Unpause services | |
up | Create and start containers |
version Show the Docker-Compose version information |
示例:
ps List containers
docker-compose ps
docker ps -a
config
docker-compose -f lnmp.yaml config
docker-compose -f lnmp.yaml config --services
docker-compose -f lnmp.yaml config --volumes
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于