docker-compose build、gradlew build、docker-compose up的个人理解

陈渊
2023-12-01
利用docker搭建一个mysql + java service + nginx,总共4个docker容器,如果采用docker run的方式一个一个容器去创建十分麻烦。为了能更高效的批量创建容器,docker推出了docker-compose工具,只需要定义一个docker-compose.yml文件即可快速搞定一组容器的创建.
docker-compose.yml文件格式如下:
mysql:
  image: daocloud.io/yjmyzz/mysql-osx:latest
  volumes:
    - ./mysql/db:/var/lib/mysql
  ports:
    - 3306:3306
  environment:
    - MYSQL_ROOT_PASSWORD=123456
  
service1:
  image: java:latest
  volumes:
    - ./java:/opt/app
  expose:
    - 8080
  #ports:
  #  - 9081:8080
  links:
    - mysql: default
  command: java -jar /opt/app/spring-boot-rest-framework-1.0.0.jar
  
service2:
  image: java:latest
  volumes:
    - ./java:/opt/app
  expose:
    - 8080
  #ports:
  #  - 9082:8080
  links:
    - mysql: default
  command: java -jar /opt/app/spring-boot-rest-framework-1.0.0.jar
  
nginx1:
   image: nginx:latest
   volumes:
    - ./nginx/html:/usr/share/nginx/html:ro
    - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    - ./nginx/conf.d:/etc/nginx/conf.d:ro
   #expose:
   #  - 80
   ports:
    - "80:80"
   links:
    - service1:service1
    - service2:service2


每一个定义在docker-compose.yml中的服务必须明确指定一个image或者build选项,这与 docker run 命令行中输入的是对应相同的,对于 docker run ,在Dockerfile文件中指定的选项(比如CMD、EXPOSE、VOLUME、ENV)是默认的,因此不必在docker-compose.yml中再指定一次
image 
标明image的ID,这个image ID可以是本地也可以是远程的,如果本地不存在,Compose会尝试去pull下来
image: ubuntu image: orchardup/postgresql image: a4bc65fd

build 
该参数指定Dockerfile文件的路径,该目录也是发送到守护进程的构建环境(这句有点),Compose将会以一个已存在的名称进行构建并标记,并随后使用这个image
build: /path/to/build/dir

command 
重写默认的命令
command: bundle exec thin -p 3000

links 
连接到其他服务中的容器,可以指定服务名称和这个链接的别名,或者只指定服务名称
links: - db - db: database - redis

此时,在容器内部,会在 /etc/hosts 文件中用别名创建一个条目,就像这样:
172.17.2.186 db 172.17.2.186 database 172.17.2.186 redis


环境变量也会被创建,关于环境变量的参数,会在后面讲到
external_links 
连接到在这个docker-compose.yml文件或者Compose外部启动的容器,特别是对于提供共享和公共服务的容器。在指定容器名称和别名时, external_links 遵循着和 links 相同的语义用法
external_links: - redis_1 - project_db_1: mysql - project_db_1: postgresql

ports 
暴露端口,指定两者的端口(主机:容器),或者只是容器的端口(主机会被随机分配一个端口)
注:当以 主机:容器 的形式来映射端口时,如果使容器的端口小于60,那可能会出现错误,因为YAML会将 xx:yy这样格式的数据解析为六十进制的数据,基于这个原因,时刻记得要将端口映射明确指定为字符串
ports: - "3000" - "8000:8000" - "49100:22" - "127.0.0.1:8001:8001"

expose 
暴露端口而不必向主机发布它们,而只是会向链接的服务(linked service)提供,只有内部端口可以被指定
expose: - "3000" - "8000"

volumes 
挂载路径最为卷,可以选择性的指定一个主机上的路径(主机:容器),或是一种可使用的模式(主机:容器:ro)
volumes_from: - service_name - container_name

environment 
加入环境变量,可以使用数组或者字典,只有一个key的环境变量可以在运行Compose的机器上找到对应的值,这有助于加密的或者特殊主机的值
environment: RACK_ENV: development SESSION_SECRET: environments: - RACK_ENV =development - SESSION_SECRET

env_file 
从一个文件中加入环境变量,该文件可以是一个单独的值或者一张列表,在 environment 中指定的环境变量将会重写这些值
env_file: - .env RACK_ENV: development

net 
网络模式,可以在docker客户端的 --net 参数中指定这些值
net: "bridge" net: "none" net: "container:[name or id]" net: "host"

dns 
自定义DNS服务,可以是一个单独的值或者一张列表
dns: 8.8.8.8 dns: - 8.8 . 8.8 - 9.9 . 9.9

cap_add,cap_drop 
加入或者去掉容器能力,查看 man 7 capabilities  可以有一张完整的列表
cap_add: - ALL cap_drop: - NET_ADMIN - SYS_ADMIN

dns_search 
自定义DNS搜索范围,可以是单独的值或者一张列表
dns_search: example .com dns_search: - dc1 .example.com - dc2 .example.com

working_dir,entrypoint,user,hostname,domainname,mem_limit,privileged,restart,stdin_open,tty,cpu_shares 
上述的每一个都只是一个单独的值,和 docker run 中对应的参数是一样的
cpu_shares: 73 working_dir: /code entrypoint: /code/entrypoint.sh user: postgresql hostname: foo domainname: foo.com mem_limit: 1000000000 privileged: true restart: always stdin_open: true tty: true
****************************************************************************************
好,终于把yml文件中的一些参数进行了说明,下面根据个人理解来说一下docker-compose build、docker-compose up、以及gradle构建的项目下 ./gradlew clean build 三者之间的关系。
./gradlew clean build是基于gradle构建项目时的打包指令,会将所有的文件打成一个项目名命名的jar包。
docker-compose build是基于docker compose的指令,在 Dockerfile文件基础上 会将项目打成一个app.jar并将jar包制作成镜像,并且结合yml文件可以批量build。
docker-compose up 是基于docker和yml文件的一种批量启动方式,与其相对应的单个docker image启动方式是 docker run 方式,这种方式要设定参数配置IP 端口号 image名称,当项目包含多个docker时会十分繁琐。
镜像除了可以build出来也可以从远端pull,使用docker pull image名的方式把镜像pull下来之后可以直接使用docker run 将其运行。
 类似资料: