利用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 将其运行。