1. 介绍
Docker Compose
是一个用于定义和运行多容器 Docker
应用程序的工具。使用 Compose
,我们可以使用 YAML
文件来配置我们自己应用程序。最终我们从配置中创建并启动所有服务。
官方推荐用 Compose
基本上是一个三步过程:
- 使用
Dockerfile
定义应用程序的环境,方便在任何地方复制它 - 在
docker-compose.yml
中定义构成应用程序的服务,可以在隔离环境中一起运行 - 运行
docker compose up
命令启动并运行整个应用程序.
2. docker-compose.yml结构
YAML
为 Docker
应用程序定义服务、网络和卷的 YAML
文件。 docker-compose.yml
应该包含: version
、 services
、 networks
、 volumes
、 configs
、 secrets
六大部分。
2.1. 示例
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
- logvolume01:/var/log
depends_on:
- redis
redis:
image: redis
volumes:
logvolume01: {}
2.2. 常用字段
字段 | 描述 |
---|---|
build | 指定 Dockerfile 文件名,要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定 |
dockerfile | 构建镜像上下文路 |
context | 可以是 dockerfile 的路径,或者是指向 git 仓库的 url 地址 |
image | 指定镜像 |
command | 执行命令,覆盖默认命令 |
container name | 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法 scale |
deploy | 指定部署和运行服务相关配置,只能在 Swarm 模式使用 |
environment | 添加环境变量 |
networks | 加入网络 |
ports | 暴露容器端口,与 -p 相同,但端口不能低于 60 |
volumes | 挂载宿主机路径或命令卷 |
hostname | 容器主机名 |
restart | 重启策略,默认 no,always,no-failure,unless-stoped |
3. 安装
3.1. 下载
目前 Docker Compose
有两种下载路径,一种是通过 Github
下载,另外一种通过 daocloud
。
第一种 Github
在国内受制于网速,速度很慢,还不容易成功。所以推荐使用第二种。
使用 curl
命令,并且制定了下载后输出路径。
3.1.1. daocloud下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
3.1.2. Github下载-不推荐
curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
3.2. 赋可执行权
chmod +x /usr/local/bin/docker-compose
3.3. 检查安装
cd /docker-compose version
4. 使用示例
在 docker-compose.yml
结构 章节中,我们知道 docker-compose.yml
由 version
、 services
、 networks
、 volumes
、 configs
、 secrets
六大部分组成。 这里我们围绕这六大部分如何使用,我们通过一个样例来说明。
演示样例分为三个步骤:
- 准备一个可被启动的应用服务,比如常见的
Redis
、Tomcat
、Nginx
都可以。 - 定义
Dockerfile
文件,这是我们对应用服务的定义 - 定义
docker-compose
4.1. 准备应用服务
这是一个基于 SpringBoot Web
的服务,定义 Controller
层,详细如下:
@Slf4j
@RequestMapping("/demo")
@RestController
public class AntiReptileController {
@Autowired
private AsynService asynService;
@RequestMapping("")
public String demo(){
return "demo";
}
@RequestMapping("/asyn")
public String asyn(){
String selector = asynService.selector();
asynService.update(selector);
log.warn("阅读执行完毕");
return selector;
}
}
这个 Web 服务,我们定义一个资源,在浏览器被访问(地址:http://ip:port/demo/asyn ) ,可以观察到响应内容如下:
{
"code": 0,
"data": "Selector http-nio-9090-exec-1",
"message": "SUCCESS"
}
如果服务不能正常启动,则展示的非上述内容。
接下来将样例通过 Maven
打包,形成的 Jar
包,名称为 demo-will.jar
,这个 Jar
包就是我们要启动的服务,下一步,我们要开始编写 Dockerfile
。
4.2. 编写Dockerfile
FROM openjdk:8
ADD demo-will.jar /demo.jar
ENTRYPOINT ["java", "-jar", "demo.jar"]
- FROM: 定制的镜像都是基于 FROM 的镜像,这里的 openjdk 就是定制需要的基础镜像
- ADD: 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。 和
COPY
的使用格类似,官方推荐使用COPY
。 - ENTRYPOINT: 同
CMD
4.3. 编写docker-compose
version: "3.9"
services:
myapp:
container_name: boot-app
build: .
ports:
- "9090:9090"
- version: 指定 yml 版本
- myapp: 服务的名称,可自定义,此处为了特殊说明,叫做
myapp
- container_name: 容器的名字,也可以自定义
- build: 构建所依赖的 Dockerfile 的路径,此处 . 说明在当前路径下,也可以使用相对路径如 ../src/ 等
- ports: 说明宿主机和容器之间的端口映射,,这里可指定多个端口映射,此处定义 容器端口
9090
映射到宿主机端口9090
。
4.4. 启动
在含有 docker-compose.yml
文件的路径下,执行操作 docker-compose up
后服务将完成下载依赖并启动 docker-compose.yml
中定义所有的容器。
docker-compose up
启动日志如下:
Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/
Creating boot-app ... done
Attaching to boot-app
boot-app | 13:29:00,582 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
boot-app | 13:29:00,582 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/demo.jar!/BOOT-INF/classes!/logback.xml]
boot-app | 13:29:00,601 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@2d8e6db6 - URL [jar:file:/demo.jar!/BOOT-INF/classes!/logback.xml] is not of type file
boot-app | 13:29:00,667 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
boot-app | 13:29:00,675 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:117 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
boot-app | 13:29:00,679 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word clr with class [org.springframework.boot.logging.logback.ColorConverter]
boot-app | 13:29:00,679 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wex with class [org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter]
boot-app | 13:29:00,679 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wEx with class [org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter]
boot-app | 13:29:00,679 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
boot-app | 13:29:00,683 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [console]
boot-app | 13:29:00,686 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
boot-app | 13:29:00,742 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
boot-app | 13:29:00,747 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [debug]
boot-app | 13:29:00,758 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@598446861 - Archive files will be limited to [50 MB] each.
boot-app | 13:29:00,762 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@598446861 - No compression will be used
boot-app | 13:29:00,764 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@598446861 - Will use the pattern logs/spring.application.name_IS_UNDEFINED/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log for the active file
boot-app | 13:29:00,774 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@4534b60d - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/spring.application.name_IS_UNDEFINED/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log'.
boot-app | 13:29:00,774 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@4534b60d - Roll-over at midnight.
boot-app | 13:29:00,776 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@4534b60d - Setting initial period to Sat Aug 20 13:29:00 UTC 2022
boot-app | 13:29:00,778 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
boot-app | 13:29:00,781 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[debug] - Active log file name: logs/spring.application.name_IS_UNDEFINED/debug.log
boot-app | 13:29:00,781 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[debug] - File property is set to [logs/spring.application.name_IS_UNDEFINED/debug.log]
boot-app | 13:29:00,782 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
boot-app | 13:29:00,782 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [error]
boot-app | 13:29:00,783 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@1067938912 - Archive files will be limited to [50 MB] each.
boot-app | 13:29:00,783 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@1067938912 - No compression will be used
boot-app | 13:29:00,783 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@1067938912 - Will use the pattern logs/spring.application.name_IS_UNDEFINED/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log for the active file
boot-app | 13:29:00,789 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@619a5dff - The date pattern is 'yyyy-MM' from file name pattern 'logs/spring.application.name_IS_UNDEFINED/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log'.
boot-app | 13:29:00,789 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@619a5dff - Rollover at start of every month.
boot-app | 13:29:00,789 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@619a5dff - Setting initial period to Sat Aug 20 13:29:00 UTC 2022
boot-app | 13:29:00,789 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
boot-app | 13:29:00,792 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[error] - Active log file name: logs/spring.application.name_IS_UNDEFINED/error.log
boot-app | 13:29:00,792 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[error] - File property is set to [logs/spring.application.name_IS_UNDEFINED/error.log]
boot-app | 13:29:00,792 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
boot-app | 13:29:00,792 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [console] to Logger[ROOT]
boot-app | 13:29:00,793 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [debug] to Logger[ROOT]
boot-app | 13:29:00,793 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [error] to Logger[ROOT]
boot-app | 13:29:00,793 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [io.github.rothschil] to INFO
boot-app | 13:29:00,793 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
boot-app | 13:29:00,794 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@1ed6993a - Registering current configuration as safe fallback point
boot-app |
boot-app |
boot-app | . ____ _ __ _ _
boot-app | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
boot-app | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
boot-app | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
boot-app | ' |____| .__|_| |_|_| |_\__, | / / / /
boot-app | =========|_|==============|___/=/_/_/_/
boot-app | :: Spring Boot :: (v2.6.8)
boot-app |
boot-app | 2022-08-20 13:29:01.443 INFO 1 --- [ main] io.github.rothschil.WillApplication : Starting WillApplication using Java 1.8.0_312 on 5f0d3b19101b with PID 1 (/demo.jar started by root in /)
boot-app | 2022-08-20 13:29:01.447 INFO 1 --- [ main] io.github.rothschil.WillApplication : No active profile set, falling back to 1 default profile: "default"
boot-app | 2022-08-20 13:29:03.099 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9090 (http)
boot-app | 2022-08-20 13:29:03.116 INFO 1 --- [ main] o.a.coyote.http11.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-9090"]
boot-app | 2022-08-20 13:29:03.118 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
boot-app | 2022-08-20 13:29:03.118 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.63]
boot-app | 2022-08-20 13:29:03.214 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
boot-app | 2022-08-20 13:29:03.215 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1668 ms
boot-app | 2022-08-20 13:29:04.253 WARN 1 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
boot-app | 2022-08-20 13:29:04.487 INFO 1 --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-9090"]
boot-app | 2022-08-20 13:29:04.655 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
boot-app | 2022-08-20 13:29:04.655 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
boot-app | 2022-08-20 13:29:04.659 INFO 1 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms
boot-app | 2022-08-20 13:29:04.667 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9090 (http) with context path ''
boot-app | 2022-08-20 13:29:04.689 INFO 1 --- [ main] io.github.rothschil.WillApplication : Started WillApplication in 3.718 seconds (JVM running for 4.397)
4.5. 验证
我们打开容器所在宿主机端口 http://192.168.147.128:9090/demo/asyn
{
"code": 0,
"data": "Selector http-nio-9090-exec-1",
"message": "SUCCESS"
}
5. 常用命令
字段 | 描述 |
---|---|
up | 创建和启动容器 |
build | 重新构建服务 |
docker-compose ls | 列出容器 |
exec | 在容器里面执行命令 |
scale | 指定一个服务容器启动数量 |
top | 显示容器进程 |
docker-compose logs | 查看容器输出 |
docker-compose port | 查看容器宿主机端口 |
down | 删除容器、网络、数据卷和镜像 |
stop/start/restart | 停止/启动/重启服务 |
5.1. 查看所有运行的容器
docker-compose ps
5.2. 查看容器端口
docker-compose port myapp 9090