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

 

 

 

 

 

 

 

 

 

 

————————占位符

posted @ 2018-12-14 09:18  小寒1206  阅读(17104)  评论(0编辑  收藏  举报