赞
踩
version: "3.0" # 表示使用的版本,必写
services: # 注意这里写的是复数,表示多个的意思
tomcat: # 这个就是服务了,这里写的是付的名称,就是这个服务叫啥,注意这个开头用了2个空格缩进
image: tomcat:8.0-jre8 # 表示创建当前这个服务所使用的镜像是那个, 注意这个开头也用了2个空格缩进
ports: # 注意这个是端口,是复数
- "8000:8000"
- "4456:4456"
服务 service: 表示一个服务一个应用的容器,说白了,就是你想要跑的docker。它是写在servcies: 里面的。每一个都需要一个独一无二的名字。
项目 project: 表示,由多个服务构成,具有相同业务逻辑的单元。其实就是整个docker-compose.yml文件
指定 镜像名称或者镜像的ID。 如果镜像在本地不存在,comopse 将会尝试拉取这个镜像
image: ubuntu
image: orchardup/postgresql
image: abcdfe:v3
暴露端口信息
使用 宿主机端口:容器端口(HOST:CONTAINER)格式,或者仅仅指定容器的端口(宿主机将会随机选择端口)都可以
ports:
- "3000"
- "8000:8000"
- "49200:22"
- "127.0.0.1:8001:8001"
*注意: 当使用 "HOST:CONTAINER"格式来映射端口的时候,如果你的端口号小于60,并且没有放到引号里面,可能会得到错误,因为yaml文件会自动解析’ “XX:YY” 这种格式为60进制。为了避免出现这种问题,建议将一组值,翻到引号中 *
数据卷所挂载的路径设置。可以设置成 宿主机路径(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 否则会出错。
配置容器连接的网络。
一个容器可以有多个网桥,就是一个容器可以同时用几个网桥,系统会给这个容器分配多个网卡,每一个网卡都绑定不同的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: # 注意这里我们使用系统给我们加前缀的网桥名字
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
这个是容器的名字,先当于 命令行下面的 --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:
设置环境变量。你可以使用数组或者字典两种格式。两种格式:字典用:不用-。。。。数组用-用=号
当只给定名称的变量,不赋值。则这个变量会自动获取运行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格式
从文件中获取环境变量,可以是单独的文件路径或者列表。
如果通过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 # 绝对路径下的
环境变量文件中每一行必须符合格式,支持#
开头的注释行。
# common.env Set development environment # 这个是注释行
PROG_ENV=development # 这个是内容
覆盖容器启动后默认执行的命令。
相当于在命令行 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"
解决容器的依赖,启动先后的问题。下面的例子会先启动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:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
配置容器内核参数。
有两种方式,一种数组,一种字典
用来修改容器内 系统内部参数, 但是这个命令并不是必须的。。有些服务启动的时候,会受到容器内参数的限制导致可能无法成功启动,则必须修改容器内参数才能让这个服务启动成功
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncooies=0
用来指定容器中最大进程数。
指定容器的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:
作用:用来将我们指定的自制的Dockerfile 打包成镜像, 然后再运行这个镜像。
build 用来指定Dockerfile 所在目录,现根据build中Dockerfile自动构建镜像,然后自动运行容器
过程就是:先用Dockerfile 生成image,然后在运行成容器。
注意:build 指令下面,要有Dockerfile所在的目录,就是Dockerfile的上下文环境。这里还要注意就是这个目录相对docker-compose.yml的路径
还有就是要指定Dockerfile 文件名
不要忘记把Dockefile中暴露的端口,在这里也写出来
不要忘记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:
up
down
exec
ps
.
.
.
.
翻文挡去吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。