docker-compose:Dockerfile参数以及说明

Posted 炸了毛的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker-compose:Dockerfile参数以及说明相关的知识,希望对你有一定的参考价值。

文章目录


一、Dockerfile

FROM

选择基础镜像,docker当前要生成的镜像以哪个镜像为基础。

FROM java

RUN

容器 构建时 需要运行的命令(区别于后面的CMD)

有两种格式:

  • shell命令格式
RUN commond
构如:建时,打印hello world
RUN echo "Hello World !"   
  • exec 格式
RUN ["executable", "param1", "param2"]
RUN ["echo","Hello world !"] 

CMD

容器启动之后要运行的命令

注意 CMD一个文件中只能有一条指令Dockerfile。如果您列出多个,CMD 则只有最后一个会生效。

三种格式:

  • shell命令格式
CMD echo "Hello World !"   
  • exec格式
CMD ["executable", "param1", "param2"]
CMD ["echo","Hello world !"] 
  • 作为 ENTRYPOINT 的参数使用

若 变量 ENTRYPOINT 存在,CMD将作为参数进行传递,而不是执行。

ENTRYPOINT

容器启动之后要运行的命令,同上述CMD ,同样若有多个参数,只有最后一个参数生效。

也是两种形式:

ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

1、docker至少指定一个CMD 或者 ENTRYPOINT命令

2、CMD 在运行时会被参数覆盖

不同格式下CMDENTRYPOINT的关系:

没有ENTRYPOINTENTRYPOINT nginx -cENTRYPOINT [“nginx”,“-c”]
没有CMD报错,至少存在一个/bin/bash -c nginx -cnginx -c
CMD [“nginx.conf”]nginx.conf/bin/bash -c nginx -c nginx.confnginx -c nginx.conf
CMD nginx.conf/bin/bash -c nginx.conf/bin/bash -c nginx -c nginx.confnginx -c /bin/bash -c nginx.conf

所以若指定nginx配置文件应该使用 ENTRYPOINT ["nginx","-c"]CMD ["nginx.conf"],并且CMD命令可被替换,所以通常用这种格式。

LABLE

标签 键值对的形式

LABEL <key>=<value> <key>=<value> <key>=<value> ...

如 打上作者标签
LABLE author = '杀生丸'
若要引用变量请使用双引号,单引号会直接解析成字符串输出
LABLE author = "xxx-$author"

LABLE替换了 MAINTAINER 的使用

MAINTAINER <name>

EXPOSE

对外暴露的端口

EXPOSE <port> [<port>/<protocol>...]

ADD

将主机的文件复制到镜像中,如仅限本地的 tar 提取和远程 URL 支持

ADD [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

将home开头的所有文件复制到mydir文件夹下
ADD hom* /mydir/

COPY

ADD,复制文件,只能从主机复制文件到镜像中。

COPY [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

将home开头的所有文件复制到mydir文件夹下
COPY hom* /mydir/

VOLUME

容器卷,也就是挂在数据,用于数据保存和持久化工作

VOLUME ["/data"]

USER

指定该镜像以什么样的用户去执行,如果都不指定,默认是root

WORKDIR

工作目录,进入容器后的落脚点,如果不指定则是 /.

WORKDIR /xxx/

ENV

环境变量、键值对的形式,运行时ENV 依然有效。

ENV <key>=<value> ...

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\\ The\\ Dog
ENV MY_CAT=fluffy

ARG

使用ARGENV指令来指定指令可用的变量RUN。若变量同名,ENV有更高优先级。运行时ARG无效。

FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=$CONT_IMG_VER:-v1.0.0
RUN echo $CONT_IMG_VER

示例

FROM alpine
WORKDIR /app
COPY src/ /app  #相似命令ADD,ADD自带解压
RUN echo >> 1.txt
CMD tail -f 1.txt #ENTRYPOINT俩如果未指定都是继承自父镜像,如果祖辈也都没指定CMD或ENTRYPOINT,则镜像无法构建

最后构建镜像

docker build -t test .
-t tag 镜像名称 . 当前目录

运行镜像,生成新的容器。

docker run test

二、docker-compose编排

images

指定镜像

# 描述 Compose 文件的版本信息
version: "3.9"

# 定义服务,可以多个
services:
  redis-6382: # 服务名称
    image: redis:7.0 # 创建容器时所需的镜像

container_name

默认事故services下标签作为容器名,也可自己指定。

container_name: app

build

指定dockerfile 进行构建,在dockerfile文件中设置的参数无需再docker-compose.yml中再次设置。

可以直接指定目录,默认读取Dockerfile文件,也可以如下所示指定文件

 build: /path/to/build/dir

 build:
  context: ./dir
   dockerfile: Dockerfile-alternate

command

容器启动后的命令,如指定redis的配置文件

command: redis-server /etc/redis/redis.conf

depends_on

表示指定镜像之间的依赖关系,以及启动顺序。理解成sping的依赖即可。

如下,web依赖了db以及redis,所以会先加载redis和db容器,最后加载web容器。

services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

entrypoint

Dockerfile中的作用。

env_file

指定文件,可将文件内容作为环境变量添加到容器中,但是在容器构建期间环境变量无效。

env_file:
  - ./a.env
  - ./b.env

environment

设置环境变量,可以将变量保存到容器中。

environment:
  RACK_ENV: development
  SHOW: "true"
  USER_INPUT:

external_links

在使用Docker过程中,我们会有许多单独使用docker run启动的容器,为了使Compose能够连接这些不在docker-compose.yml中定义的容器,我们需要一个特殊的标签,就是external_links,它可以让Compose项目里面的容器连接到那些项目配置外部的容器(前提是外部容器中必须至少有一个容器是连接到与项目内的服务的同一个网络里面)。

external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql

labels

容器中打上标签,同Dockerfile的lable作用

labels:
  com.example.description: "Accounting webapp"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""

links

定义在不同容器的网络链接。 链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”

web:
  links:
    - db
    - db:database
    - redis

ports

宿主机与容器映射的端口。 [HOST:]CONTAINER[/PROTOCOL]

ports:
 - "3000"
 - "8000:8000"

network_mode

网络模式

network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"

networks

定义容器附加的网络,默认是bridge模式

services:
  some-service:
    networks:
      - some-network
      - other-network

也可指定别名使用子标签 aliases ,相同的服务可以在不同的网络有不同的别名。

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2

restart

重启策略

	restart: "no"
    restart: always
    restart: on-failure
    restart: unless-stopped

volumes

挂载一个目录或者一个已存在的数据卷容器

services:
  redis-6382: # 服务名称
    volumes: # 数据卷,目录挂载
      - /var/lib/mysql # 只指定一个目录,在容器内部创建容器卷
      - /usr/local/redis_cluster/master01/conf:/etc/redis
      - /usr/local/redis_cluster/master01/data:/data

volumes_from

从其他容器或服务挂载数据卷。

volumes_from:
  - service_name
  - service_name:ro
  - container:container_name
  - container:container_name:rw

working_dir

工作目录

示例

安装mysql以及redis集群

具体说明参考:

redis集群搭建过程

Mysql集群搭建过程

# 描述 Compose 文件的版本信息
version: "3.9"

# 定义服务,可以多个
services:
  mysql_master: # 服务名称
    image: mysql # 创建容器时所需的镜像
    container_name: mysql_master # 容器名称
    restart: always # 容器总是重新启动
    privileged: true
    volumes: # 数据卷,目录挂载
      - /usr/local/mysql_cluster/master/data:/var/lib/mysql:rw
      - /usr/local/mysql_cluster/master/conf/my.cnf:/etc/mysql/my.cnf
    environment:
        - MYSQL_ROOT_PASSWORD=******
  mysql_slave: # 服务名称
    image: mysql # 创建容器时所需的镜像
    container_name: mysql_slave # 容器名称
    restart: always # 容器总是重新启动
    privileged: true
    volumes: # 数据卷,目录挂载
      - /usr/local/mysql_cluster/slave/data:/var/lib/mysql:rw
      - /usr/local/mysql_cluster/slave/conf/my.cnf:/etc/mysql/my.cnf
    environment:
        - MYSQL_ROOT_PASSWORD=******
   redis-6382: # 服务名称
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6382 # 容器名称
    restart: always # 容器总是重新启动
    network_mode: "host" # host 网络模式
    volumes: # 数据卷,目录挂载
      - /usr/local/redis_cluster/master01/conf:/etc/redis
      - /usr/local/redis_cluster/master01/data:/data
    command: redis-server /etc/redis/redis.conf # 覆盖容器启动后默认执行的命令

  redis-6383:
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6383
    network_mode: "host"
    volumes:
      - /usr/local/redis_cluster/master02/conf:/etc/redis
      - /usr/local/redis_cluster/master02/data:/data
    command: redis-server /etc/redis/redis.conf

  redis-6384:
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6384
    network_mode: "host"
    volumes:
      - /usr/local/redis_cluster/master03/conf:/etc/redis
      - /usr/local/redis_cluster/master03/data:/data
    command: redis-server /etc/redis/redis.conf

  redis-6385: # 服务名称
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6385 # 容器名称
    restart: always # 容器总是重新启动
    network_mode: "host" # host 网络模式
    volumes: # 数据卷,目录挂载
      - /usr/local/redis_cluster/slave01/conf:/etc/redis
      - /usr/local/redis_cluster/slave01/data:/data
    command: redis-server /etc/redis/redis.conf

  redis-6386:
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6386
    network_mode: "host"
    volumes:
      - /usr/local/redis_cluster/slave02/conf:/etc/redis
      - /usr/local/redis_cluster/slave02/data:/data
    command: redis-server /etc/redis/redis.conf

  redis-6387:
    image: redis:7.0 # 创建容器时所需的镜像
    container_name: redis-6387
    network_mode: "host"
    volumes:
      - /usr/local/redis_cluster/slave03/conf:/etc/redis
      - /usr/local/redis_cluster/slave03/data:/data
    command: redis-server /etc/redis/redis.conf

Dockerfile 和 docker-compose.yml的区别

明确概念

Dockerfile 是拿来构建自定义镜像的,并没有直接生成容器。只是可以在运行镜像时运行容器而已。
做容器编排以部署环境,是使用 docker-compose.yml 文件进行的,里面可能会需要用到 Dockerfile 。

总结

Dockerfile是用来构建镜像的,若是想使用这个镜像的话还需要使用docker run命令来运行这个镜像,从而生成运行一个容器
docker-compose.yml是用来编排项目的,里面包含使用各种镜像创建的容器服务,使用的镜像可以是网络上的,也可以是根据使用Dockerfile文件来生成的镜像,相当于是把上一步的这个工作给做了

docker-compose.yml使用的镜像可以是网络上的,具体是这样的,优先使用本地存在的镜像,本地没有的话才会从 Docker Hub网站上下载,若想直接使用私有仓库镜像,则需要事先从私有仓库镜像给拉取到本地才行

Dockerfile

把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,这个脚本就是 Dockerfile。

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 文件示例

// 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-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.26.0/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、创建一个空目录。
2、定义 Dockerfile,方便迁移到任何地方
3、编写 docker-compose.yml 文件
4、运行 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! 该页面已被访问 {} 次。
‘.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

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 出来的镜像来创建。
某个服务需要用到 Dockerfile build 出来的镜像,则在 docker-compose 里面指明 build 的文本位置和文件名
yml 文件可以指定 volume 和 network

如下,是一个使用了 network 和 volumes 参数的例子(放在与 service 同层的关系):

version: ‘3.0‘

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:Dockerfile参数以及说明的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose gives ERROR: Cannot locate specified Dockerfile: Dockerfile

docker-compose:Dockerfile参数以及说明

在 Dockerfile/Docker-Compose 中使用提交的容器镜像是不是可行? [复制]

可以将来自docker-compose.yml的env变量传递给dockerfile吗?

如何将docker-compose.yml转换为Dockerfile

无法运行rake db:使用docker-compose在Dockerfile中创建