Dockerfile 和 docker-compose 的使用
资源:
1、github 上的 docker 手册:https://github.com/docker-library/
2、docker-hub : https://hub.docker.com/
————————— 使用Dockerfile定制镜像(images) ————————
【明确概念】:Dockerfile 是拿来构建自定义镜像的,并没有直接生成容器。只是可以再运行镜像运行容器而已。
做容器编排以部署环境,是使用 docker-compose.yml 文件进行的,里面可能会需要用到 Dockerfile 。
原因:可以使用 commit 将容器保存为镜像,但是不要使用这种方法。因为会把所有的改动全部记录下来,不小心就可能导致镜像非常的臃肿。并且这属于黑箱操作,除了操作者本人,其他人都不知道修改了什么。
把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
// 一个例子:
1、创建一个最简单的 Dockerfile 文件
// 1、创建 Dockerfile mkdir mynginx cd mynginx vim Dockerfile // 2、输入以下内容并保存: FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html // 在 Dockerfile 目录下执行,生成新的自定义 images docker build -t nginx:v3 .
———— . 表示的是【 当前目录下的(所有内容)送给 docker-engineer 构建 images 】 ,并命名为 nginx:v3。所以一般情况下建一个空目录,然后将Dockerfile 和所需的资源放入。再执行 build
———— 理解构建上下文对于镜像构建是很重要的,避免犯一些不应该的错误。比如有些初学者在发现 COPY /opt/xxxx /app
不工作后,于是干脆将 Dockerfile
放到了硬盘根目录去构建,结果发现 docker build
执行后,在发送一个几十 GB 的东西,极为缓慢而且很容易构建失败。那是因为这种做法是在让 docker build
打包整个硬盘,这显然是使用错误。
Dockerfile 部分指令:
// FROM 指定基础镜像 FROM nginx // RUN 执行命令。每一条 RUN 都会生成一层,一个需求尽量使用&&,这样就减少了 RUN ,即减少了分层 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html RUN yum update && yum install -y vim \ python-dev // COPY: 源路径下的 package.json 复制到新一层的镜像路径/usr/src/app COPY package.json /usr/src/app/ // WORKDIR 指定工作目录。指定下层工作的目录为容器内的/data,尽量使用绝对目录 WORKDIR /data // ADD 添加,ADD能自动解压文件。以下例子最终 hello 在/data/test 下 WORKDIR /data ADD hello test/ // COPY 拷贝 与ADD类似,只是不能解压缩文件。 WORKDIR /DATA COPY hello test/ // CMD 执行命令 CMD ["python", "app.py"] // ENV 设置环境变量 定义 NAME=Happy Feet,那么之后就可以使用 $NAME 来执行了 ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet"
// VOLUMES
挂载 // EXPOSE 端口暴露 EXPOSE <端口1> [<端口2>...]
—— 所以你应该创建 Dockerfile ,分享给别人,就可以创建一个跟你一样的镜像了。而不是直接分享镜像给别人。
———————— 多容器应用 - Docker-compose ————————
docker-compose 是官方开源项目,负责实现对 Docker 容器集群的快速编排,部署分布式应用。
通过一个单独的 docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)
// 安装docker-compose:
mac 和 win 下已经默认装好了。而 linux 下得手动安装。有三种方式,这里我们采用二进制包的方式
$ sudo curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose // 测试 docker-compose docker-compose --version
// 一般使用步骤:
1、创建一个空目录。
1、定义 Dockerfile,方便迁移到任何地方
2、编写 docker-compose.yml 文件
3、运行 docker-compose up 启动服务
// docker-compose 使用举例:
下面我们用 Python
来建立一个能够记录页面访问次数的 web 网站。
1、建一个空目录:
mkdir -p /data/test
2、在该空文件下建立 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! 该页面已被访问 {} 次。\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True)
3、编写 Dockerfile 文件:
FROM python:3.6-alpine ADD . /code WORKDIR /code RUN pip install redis flask CMD ["python", "app.py"]
4、编写 docker-compose.yml 文件
version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
—— 此时该空目录下共有:app.py、Dockerfile、docker-compose.yml 文件
5、执行 docker-compose 项目
docker-compose up
———— 这样,你访问本地5000端口就会增加一次访问次数。
// yml 模板文件的说明:
示例文件:
version: '3' services: phpfpm: image: yoogr/phpfpm:0.0.1 container_name: ct-phpfpm build: context: . dockerfile: Dockerfile expose: - "9000" volumes: - ${DIR_WWW}:${DIR_WWW}:rw - ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro - ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw - ./conf/supervisor/conf.d:/etc/supervisor/conf.d/:ro - ./log/php-fpm/:/var/log/php-fpm/:rw - ./log/supervisor/:/var/log/supervisor/:rw command: supervisord -n links: - mysql:mysql - redis:redis
—— 每个 service 代表一个 container,container 可以通过 dockerhub的 image 来创建,也可以从本地的 Dockerfile build 出来的镜像来创建。
—— yml 文件可以指定 volume 和 network。
某个服务需要用到 Dockerfile build 出来的镜像,则在 docker-compose 里面指明 build 的文本位置和文件名。请查看以上例子。
—— 这里有点问题,就是使用了 links,这个官方已经不建议使用了。link 其实相当于在容器 host 文件添加了名字,类似于172.17.0.3 mysql
—— 请使用 network,就是自己创建一个bridge,然后把所有 container 都连在上面。
// 如下,是一个使用了 network 和 volumes 参数的例子(放在与 service 同层的关系):
version: '3' services: wordpress: image: wordpress ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_PASSWORD: examplepass network: - my-bridge db: image: mysql:5.7 environment: MYSQL_DATABASE: wordpress MYSQL_ROOT_PASSWORD: 123456 volumes: - mysql-data:/var/lib/mysql networks: - my-bridge volumes: my-data networks: my-bridge: driver:bridge
—— 以上例子。网络和卷的定义类似于 docker network create
和 docker volume create。
如果你没有指定连接network,那么才会使用 link。
// docker-compose 常用命令:
// up 该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作 docker-compose up [options] [SERVICE...] // -d 比较常用,不会打印过程。 //down 停止 up 命令所启动的容器,并移除网络。——这里需要特别注意,up 启动的,不应该使用rm 去删除,因为这样无法删除网络 docker-compose down // run 命令 docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...] // ps 查看项目中的所有容器 docker-compose ps // restart 重启服务 docker-compose restart [options] [SERVICE...]。 // stop start 停止和开启容器 docker-compose stop xxx docker-compose start xxx // kill 强制停止某容器 docker-compose kill -s SIGINT // rm 删除指定或所有的服务容器 docker-compose rm -f [service] // build 重建某个容器,在 Dockerfile 发生了改变的时候,可以重建image。然后再 up 运行起来所有的容器 docker-composer build //重建所有容器 docker-compose build xxx //重建指定容器 //exec 进入某个容器 docker-compose exec -it ct-phpfpm /bin/bash // images 查看compose文件中包含的镜像 docker-compose images // pull 拉取依赖 docker-compose pull [options] [SERVICE...] // push 推送服务依赖的镜像到 Docker 镜像仓库。 docker-compose push // port 打印某容器的映射端口 docker-compose port xxx // config 验证 docker-compose 文件格式是否正确 docker-compose config// top 查看所有容器的进程 docker-compose top
————————占位符