docker-compose模板指令 命令行指令

1 篇文章 0 订阅
1 篇文章 0 订阅

一、docker-compose两个重要的概念

  1. 项目(project):有多个服务共同组成的完整的业务单元,定义在docker-compose.yml文件中
  2. 服务(service):一个服务对应一个应用容器,在一个项目中可以存在多个服务
书写格式:注意yml文件的书写格式,用空格缩进,用-符号写多个值
version: "3.0" # 表示使用的版本,必写

services: # 注意这里写的是复数,表示多个的意思
  tomcat: # 这个就是服务了,这里写的是付的名称,就是这个服务叫啥,注意这个开头用了2个空格缩进
    image: tomcat:8.0-jre8 # 表示创建当前这个服务所使用的镜像是那个, 注意这个开头也用了2个空格缩进
    ports: # 注意这个是端口,是复数
      - "8000:8000"
      - "4456:4456"

二、docker-compose 模板指令

1.引入两个概念

服务 service: 表示一个服务一个应用的容器,说白了,就是你想要跑的docker。它是写在servcies: 里面的。每一个都需要一个独一无二的名字。

项目 project: 表示,由多个服务构成,具有相同业务逻辑的单元。其实就是整个docker-compose.yml文件

2. 部分指令如下

image

指定 镜像名称或者镜像的ID。 如果镜像在本地不存在,comopse 将会尝试拉取这个镜像

image: ubuntu
image: orchardup/postgresql
image: abcdfe:v3
posts

暴露端口信息
使用 宿主机端口:容器端口(HOST:CONTAINER)格式,或者仅仅指定容器的端口(宿主机将会随机选择端口)都可以

ports:
  - "3000"
  - "8000:8000"
  - "49200:22"
  - "127.0.0.1:8001:8001"

*注意: 当使用 "HOST:CONTAINER"格式来映射端口的时候,如果你的端口号小于60,并且没有放到引号里面,可能会得到错误,因为yaml文件会自动解析’ “XX:YY” 这种格式为60进制。为了避免出现这种问题,建议将一组值,翻到引号中 *

volumes

数据卷所挂载的路径设置。可以设置成 宿主机路径(HOST:CONTAINER)或者数据卷名称(VOLUME:CONTAINER)两种格式。。。同时如果需要设置访问权限,就是说只能宿主机修改文件,并且影响到容器里面。不能进容器里面修改数据,从而影响到宿主机。意思就是说:本来双向的数据,现在改成了单向通道,只能宿主机影响容器。格式是:HOST:CONTANIER:ro -->注意这里的:ro 表示read only的意思。
注意: 这个指令支持相对路径

volumes: # 注意这里的复数
  - /var/lib/mysql
  - cache:/tmp/cache
  - ~/configs:/etc/configs/:ro

细节1---------> 如果路径是数据卷的名称,必须要文件中单独配置数据卷。这里就跟network 是一样的。

version: "3.0"

services:
  some-one-service:
    networks:
      - some-network
      - other-network
    volumes:
    - mysql-data:/var/lib/mysql
    - data-volume:/srv/data
    - /home/hello/:/apps/

volumes: # 注意这里的volumes 是复数,和services 平齐,需要把上面用数据卷的名字都写下来。
  mysql-data:
  data-volume:

进阶的细节2---------> 上面用数据卷中有一个系统指定的问题。就是我们虽然在底部单独定义了volumes: 然后也把上面用到的数据卷,在里面声明了。但是在系统中单独查找这个数据卷,却找不到。因为docker 给我们添加了一个前缀。。。这个前缀就是docker-compose.yml 所在文件的上层文件夹的名字。
比如我们的docker-compose.yml在hello 这个文件夹中。则我们的数据卷在系统中的完整的名字就是:hello_mysql-data 和hello_data-volume

修改 进阶的细节2---------> 上面我们已经在volumes中单独定义了数据卷,但是 系统给它加上了前缀和下划线。
有没有办法不要这个前缀和下划线哪? 办法是有的。如下:
不过你要确定如果系统里面的数据卷和network 不存在重名的问题,要不然出错。就是名字不要重复。

volumes:
  mysql-data:
    external: # 注意这里的external: 和true 
      true
  data-volume:
    external: # 表示 使用我们自定义的卷名
      true # 用true 表示 确认使用指定的卷名

但是这样,直接运行会出错。因为你用我们自定义的数据卷。但是系统在运行的时候,并不知道有这个数据卷,需要提前创建这个数据卷才可以,否则不能用,怎么创建?
在命令行手动创建

docker volume create mysql-data # 执行这个之后,系统里面才有我们上面定义的数据卷,才可用docker-compose.yml 否则会出错。
networks

配置容器连接的网络。
一个容器可以有多个网桥,就是一个容器可以同时用几个网桥,系统会给这个容器分配多个网卡,每一个网卡都绑定不同的IP
可以把一组服务(或者一个工程里面的所有服务,都用一个网桥。这样省的和其他的工程里面的服务产生关系,就是各自在一个独立的局域网里面运行。省的有干扰)

进阶的点------和volumes 一样,都需要单独拿出来定义,然后声明所用到的网桥名字。同时注意 是我们自定义用网桥名字,还是用 系统加前缀的网桥名字。
同时:如果我们用自己的网桥名字的话,需要提前创建,否则运行不通过

docker network create some-network
version: "3.0"

services:
  some-one-service:
    networks:
      - some-network
      - other-network
      
# 注意这里的networks 需要单独定义的,是和上面services 大类是齐平的,也就是说一个docker-compose.yml文件有一组service,那么就有为这一组service服务的网卡,还有为这一组service服务的挂载点volume
networks:
  some-network:
    external: # 注意这里使用我们自定义的网桥名字,就是some-network这个名字
      true
  other-network: # 注意这里我们使用系统给我们加前缀的网桥名字
  	
综合volumes 和networks 举例:
version: "3.2"

services:
  tomcat-1:
    image: tomcat:8.0-jre8
    ports:
      - "8080:8080"
    volumes:
      - appdata1:/usr/local/tomcat/webapps
      - /home:/home
    networks:
      - tomcat-net # 这里一样的网络
    
  tomcat-2:
    image: tomcat:8.0-jre8
    ports:
      - 8081:8080
    volumes:
      - appdate2:/usr/local/tomcat/webapps
    networks:
      - tomcat-net # 这里一样的网络
      - 
volumes:
  appdata1: # tomcat-1 里面的数据卷
  appdate2: # tomcat-2 里面的数据卷
    
networks:
  tomcat-net: # 两者公用一个网桥,也就是说tomcate1服务和tomcate2服务,在一个网段里面,可以互通。
    external:
      true
container_name

这个是容器的名字,先当于 命令行下面的 --name
重点: 如果设置了container_name那么如果几个容器在一个网桥内,可以使用http://container_name:port来代替http://127.0.0.1:port 来访问同局域网内的其它容器。

version: "3.2"

services:
  tomcat-1:
    container_name: tomcat-1_name # 这就是给运行的容器一个名字,先当于--name
    image: tomcat:8.0-jre8
    ports:
      - "8080:8080"
    volumes:
      - appdata1:/usr/local/tomcat/webapps
      - /home:/home
    networks:
      - tomcat-net # 这里一样的网络
volumes:
  appdata1:
networks:
  tomcat-net:
environment

设置环境变量。你可以使用数组或者字典两种格式。两种格式:字典用:不用-。。。。数组用-用=号

当只给定名称的变量,不赋值。则这个变量会自动获取运行compose主机上对应变量的值,可以用来防止泄露不必要的数据。

environment: # 字典格式,注意第二个变量没有赋值。 也不用 用 - 来开头
      RACK_ENV: development
      SESSION_SECRET:
    
    environment: # 数组格式,注意第二个变量没有赋值。 需要用 - 来开头
      - RACK_NEN=development
      - SESSION_SECRET

如果变量名称或者值中用到 true|alse, yes|no 等表达 ··布尔··含义的词汇,最好放到引号里面,避免yaml自动解析某些内容为对应的布尔语义。
这些词汇包括:
y Y yes Yes YES n N no No true True TRUE false False FALSE on On OFF off Off

实例:

  mysql:
    image: mysql:5.7.23
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - mysql_config:/etc/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "123456"   # 注意这里 用的是字典格式, :号 后面有空格,需要符合yaml格式
    
env_file

从文件中获取环境变量,可以是单独的文件路径或者列表。
如果通过docker-compose -f File的方式来指定compose模板文件, 则env_file中变量的路径会基于模板文件的路径。
如果有变量名称和environment 中的指令冲突,按照惯例,以后者为准

env_file: .env  # 指定一个env_file ,文件名字是 .env

或者:

env_file:   # 指定多个env_file, 文件名字各式各样,而且还有相对路径和绝对路径
  - ./common.env # 相对路径下的
  - ./apps/web.env # 相对路径下的
  - /app/secrets.env # 绝对路径下的
书写env_file 文件的格式:

环境变量文件中每一行必须符合格式,支持#开头的注释行。

# common.env Set development environment  # 这个是注释行
PROG_ENV=development # 这个是内容
command

覆盖容器启动后默认执行的命令。
相当于在命令行 run 镜像之后用来覆盖容器内部 默认的命令。

command: echo "hello world"

实例:

redis:
    image: redis:5.0.10
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: "redis-server --appendonly yes" # 原本的redis启动的命令是 redis-server 但是我们要这个是容器,而且要做数据持久化,所以需要覆盖原本的命令,新命令是 command: "redis-server --appendonly yes"

depends_on 比较重要的命令

解决容器的依赖,启动先后的问题。下面的例子会先启动redis db 然后在启动web
注意depends_on 里面写的是服务的名字,不是容器的名字

version: "3"

services:
  web:
  build: .
  depends_on:
    - db_container # 注意这里写的是服务名字
    - redis_container # 注意这里写的是服务名字,不是服务container_name里面的名字
  
  redis_container:
    image: redis
  db_container:
    image: mysql

注意:web 服务不会等待redis db 完全启动之后才启动,但是确实是晚启动

healthcheck

通过命令检查容器是否健康运行

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3
sysctls

配置容器内核参数。
有两种方式,一种数组,一种字典

用来修改容器内 系统内部参数, 但是这个命令并不是必须的。。有些服务启动的时候,会受到容器内参数的限制导致可能无法成功启动,则必须修改容器内参数才能让这个服务启动成功

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncooies=0
ulimits

用来指定容器中最大进程数。
指定容器的ulimits限制值。
例如,指定最大进程数为65535, 指定文件句柄数为20000(软限制,应用可以随时修改,不能超过硬限制)和40000(系统硬限制,只能root用户提高)。

ulimits:
  nproc: 65535
  nofile:
  sofe: 20000
  hard: 40000

至此,给一个例子,如下:

version: "3.2"

services:
  tomcat-1:
    container_name: tomcat-1_name
    image: tomcat:8.0-jre8
    ports:
      - "8080:8080"
    volumes:
      - appdata1:/usr/local/tomcat/webapps
      - /home:/home
    networks:
      - tomcat-net # 这里一样的网络
    depends_on:
      - tomcat-2
      - mysql
      - redis
    healthcheck: # 这个是官方给的案例,让系统每1分30秒向本机的docker 引擎发送curl -f http://localhost, 如果能反回,就说明这个tomcat-1的服务是在正常运行中。
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 1m30s
      timeout: 10s
      retries: 3
    sysctls: # 用来修改系统内部参数
      - net.core.somaxconn=1024 # 这里是例子
      - net.ipv4.tcp_syncookies=0
    ulimits: #用来修改系统内进程数限制,日后使用,可以根据当前容器运行服务要求,进行修改,用以满足容器的成功启动
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000

  tomcat-2:
    image: tomcat:8.0-jre8
    ports:
      - 8081:8080
    volumes:
      - appdate2:/usr/local/tomcat/webapps
    networks:
      - tomcat-net # 这里一样的网络
      - tomcat2-net

  mysql:
    image: mysql:5.7.23
    container_name: mysql
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - mysql_config:/etc/mysql
#    environment:
#      MYSQL_ROOT_PASSWORD: "123456"
#    第二种方法:用env_file
    env_file:
      - mysql.env
    networks:
      - tomcat-net

  redis:
    image: redis:5.0.10
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: "redis-server --appendonly yes" # 原本的redis启动的命令是 redis-server 但是我们要这个是容器,而且要做数据持久化,所以需要覆盖原本的命令,新命令是 command: "redis-server --appendonly yes"
    networks:
      - tomcat-net

volumes:
  appdata1:
  appdate2:
  mysql_data:
  mysql_config:
  redis_data:

networks:
  tomcat-net:
    external:
      true
  tomcat2-net:

最复杂的一个命令 build 指令

作用:用来将我们指定的自制的Dockerfile 打包成镜像, 然后再运行这个镜像。
build 用来指定Dockerfile 所在目录,现根据build中Dockerfile自动构建镜像,然后自动运行容器
过程就是:先用Dockerfile 生成image,然后在运行成容器。

  1. 注意:build 指令下面,要有Dockerfile所在的目录,就是Dockerfile的上下文环境。这里还要注意就是这个目录相对docker-compose.yml的路径
  2. 还有就是要指定Dockerfile 文件名
  3. 不要忘记把Dockefile中暴露的端口,在这里也写出来
  4. 不要忘记volume 挂载点
version: "3.2"

services:
  
  demo:
    build: # 启动服务时先将命令中指定dockerfile打包成镜像,然后运行该镜像
      context: ./demodir # Dockerfile 的上下文环境,就是Dockerfile所在的目录,里面存放生产镜像所需的文件。这里demodir目录和docker-compose.yaml同级
      dockerfile: Dockerfile # 指定Dockefile文件的名字
    container_name: demo # 生产容器的名字
    ports: # 暴露我们Dockerfile中expose 的端口
      - "8081:8081"
    depends_on: # 依赖下面的服务 启动之后,这个再启动
      - tomcat-1
    networks:
      - tomcat-net
      
  tomcat-1:
    container_name: tomcat-1_name
    image: tomcat:8.0-jre8
    ports:
      - "8080:8080"
    volumes:
      - appdata1:/usr/local/tomcat/webapps
      - /home:/home
    networks:
      - tomcat-net # 这里一样的网络
    depends_on:
      - tomcat-2
      - mysql
      - redis
    healthcheck: # 这个是官方给的案例,让系统每1分30秒向本机的docker 引擎发送curl -f http://localhost, 如果能反回,就说明这个tomcat-1的服务是在正常运行中。
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 1m30s
      timeout: 10s
      retries: 3
    sysctls: # 用来修改系统内部参数
      - net.core.somaxconn=1024 # 这里是例子
      - net.ipv4.tcp_syncookies=0
    ulimits: #用来修改系统内进程数限制,日后使用,可以根据当前容器运行服务要求,进行修改,用以满足容器的成功启动
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000

  tomcat-2:
    image: tomcat:8.0-jre8
    ports:
      - 8081:8080
    volumes:
      - appdate2:/usr/local/tomcat/webapps
    networks:
      - tomcat-net # 这里一样的网络
      - tomcat2-net

  mysql:
    image: mysql:5.7.23
    container_name: mysql
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - mysql_config:/etc/mysql
#    environment:
#      MYSQL_ROOT_PASSWORD: "123456"
#    第二种方法:用env_file
    env_file:
      - mysql.env
    networks:
      - tomcat-net

  redis:
    image: redis:5.0.10
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: "redis-server --appendonly yes" # 原本的redis启动的命令是 redis-server 但是我们要这个是容器,而且要做数据持久化,所以需要覆盖原本的命令,新命令是 command: "redis-server --appendonly yes"
    networks:
      - tomcat-net

volumes:
  appdata1:
  appdate2:
  mysql_data:
  mysql_config:
  redis_data:

networks:
  tomcat-net:
    external:
      true
  tomcat2-net:

三 docker-compose 命令行指令

up
down
exec
ps
.
.
.
.
翻文挡去吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值