docker compose 基本使用 概述 docker compose 是一个工具,轻松和高效管理多个容器;批量容器编排;方便一次性管理多个容器
compose 是docker官方的开源项目,需要单独安装;
docker compose 可以集中的管理整个服务的运行环境和依赖关系,方便的上线和下线操作。
您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,您可以从您的配置中创建并启动所有服务。
官方地址: https://docs.docker.com/compose/
使用docker compose 三个步骤
定义应用的可以运行的dockerfile 通过 docker-compose.yml 定义服务运行的环境,使其能够在隔离的容器中运行 使用 docker compose up 快速运行环境 docker compose 整个生命周期
启动,停止和构建服务 查看服务的状态 流动输出服务的运行日志 在服务上运行一次性命令 安装docker compose 安装步骤: https://docs.docker.com/compose/install/
以linux为例说明
首先需要安装docker 服务
github 下载二进制文件
1 curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
赋予文件执行权限
1 chmod +x /usr/local/bin/docker-compose
验证
1 2 3 4 5 docker-compose version 1.29.2, build 5becea4c docker-py version: 5.0.0 CPython version: 3.7.10 OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
基本概念 服务 对应compose 中定义的一个一个的容器实例,就称为是一个服务。比如mysql容器 比如web服务容器。
工程 由一组容器组成的一个整体,可以认为一个docker-compose.yml 组成的整个服务为一个工程。
docker compose 常用命令 需要在docker-compose.yml 相同目录下执行
docker-compose -h 帮助 docker-compose up [-d] 启动所有服务 docker-compose down 停止并删除容器和网络 docker-compose restart 重启 docker-compose start 启动 docker-compose stop 停止 docker-compose config [-q有问题才输出] 检查配置 docker-compose logs 日志信息 docker-compose exec 进人容器内部 docker compose 文件编写简单说明 文件格式可以使用yml 或yaml 文件名称必须为 docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml 中的一个文件名
文件需要执行版本,目前基本上都是用3.x 版本,不同的版本选择和docker版本有对应关系
详细配置文档 https://docs.docker.com/compose/compose-file/compose-file-v3/
常用配置说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 version: "xx" 首先需要定义版本号,固定写法,表示当前的文件的版本号说明 services: 配置多个服务 webapp: 名字未 webapp的服务 build: 配置通过dockerFile进行构建 context: ./dir 对应的路径,比如dockerfile的路径 dockerfile: Dockerfile-alternate dockerfile的名称 container_name: 自定义容器名称,如果不定义 默认为目录名称 + service 名称 image: mysql 基于那个镜像构建 volumes: 容器卷配置 - db-data:/var/lib/mysql/data networks: 网络配置 - overlay depends_on: //依赖那些服务,这些服务先起来后,本服务再启动,用来定义服务的启动顺序 - db - redis environment: //添加容器的环境变量设置 xx:xx expose: //对外暴露端口 -"3001" labels: 添加docker镜像的label network_mode: networks: 定义网络相关配置
spring boot 使用docker compose 部署服务 使用一个测试的springboot 项目,外部服务依赖 mysql和redis
数据访问使用spring-data-jpa redisTemplate
基本依赖配置
demo springboot项目 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
实体类和配置信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 =====entity @Data @Entity @Table(name = "t_user", uniqueConstraints= @UniqueConstraint(columnNames={"id"})) public class User implements Serializable { @Id @GeneratedValue private Long id; private String userName; private int sex; } =======dao @Repository public interface UserRepositoryImpl extends CrudRepository<User,Long> { } =======boot @EnableJpaRepositories @SpringBootApplication public class ComposeDemoApplication { public static void main(String[] args) { SpringApplication.run(ComposeDemoApplication.class, args); } @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); template.setValueSerializer(jackson2JsonRedisSerializer); template.setKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } } =====yml server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: 123456 redis: host: 127.0.0.1 database: 0 jpa: database-platform: org.hibernate.dialect.MySQL5InnoDBDialect show-sql: true hibernate: ddl-auto: update
定义了4个web接口,用来访问数据库和redis测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 @RequestMapping("/user") @RestController public class UserController { @Resource private UserRepositoryImpl userRepositoryImpl; private static AtomicInteger count = new AtomicInteger(0); @Resource private RedisTemplate<String,User> redisTemplate; private static final String USER_KEY = "cache_user"; @RequestMapping("/insert") public Boolean insert(){ User user = new User(); user.setUserName("张三"+count.incrementAndGet()); user.setSex(count.get() % 2); userRepositoryImpl.save(user); return Boolean.TRUE; } @RequestMapping("/getAll") public List<User> getAll(){ Iterable<User> allUser = userRepositoryImpl.findAll(); Iterator<User> iterator = allUser.iterator(); List<User> users = new ArrayList<>(); while (iterator.hasNext()){ users.add(iterator.next()); } return users; } @RequestMapping("/toCache/{id}") public Boolean toCache(@PathVariable(value = "id") Long id){ Optional<User> userOptional = userRepositoryImpl.findById(id); if(userOptional.isPresent()){ ValueOperations<String, User> stringObjectValueOperations = redisTemplate.opsForValue(); stringObjectValueOperations.set(USER_KEY+":"+id,userOptional.get()); return Boolean.TRUE; } return Boolean.FALSE; } @RequestMapping("/getFromCache/{id}") public User getFromCache(@PathVariable(value = "id") Long id){ ValueOperations<String, User> stringObjectValueOperations = redisTemplate.opsForValue(); Object obj = stringObjectValueOperations.get(USER_KEY + ":" + id); if(obj != null){ return (User)obj; } return null; } }
http://localhost:8080/user/insert 插入一个新数据
http://localhost:8080/user/getAll 获取所有数据
http://localhost:8080/user/toCache/1 id 为1 放入redis
http://localhost:8080/user/getFromCache/1 获取id 为1 从redis中获取
修改配置中的服务请求地址,这里的请求的host 名称 需要是 dockercompose的服务名称一致。和微服务中根据服务名称调用的做法类似。 修改文件,在docker-compose中统一部署服务,对应的服务的地址不写死,而使用对应的服务名进行访问,所以
配置文件修改为
打包和上传
使用maven 打包数据jar包放到服务器上
1 mvn package -DskipTests=true
获取springboot jar包传到服务器的指定目录
编写服务的dockerFile文件
1 2 3 4 5 6 FROM openjdk:8 RUN mkdir -p /usr/src/app COPY ./compose-0.0.1-SNAPSHOT.jar /usr/src/app/app.jar WORKDIR /usr/src/app EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
创建redis 和mysql的外部配置 和数据目录 。
对于容器内的数据和配置,不要放到容器内,通过数据卷的方式映射外部路径
1 2 3 4 [root@localhost boot-server]# mkdir -p redis/conf [root@localhost boot-server]# mkdir -p redis/data [root@localhost boot-server]# mkdir -p mysql/data [root@localhost boot-server]# mkdir -p mysql/conf
编写docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 version: '3.6' services: web_server: build: context: . dockerfile: serverDockerFile ports: - "8080:8080" depends_on: - mysql - redis networks: - my_server_network container_name: webServer redis: image: redis:5.0.14 volumes: - /usr/local/boot-server/redis/conf:/usr/local/etc/redis - /usr/local/boot-server/redis/data:/data ports: - "6379:6379" networks: - my_server_network container_name: redis mysql: image: mysql:5.7 volumes: - /usr/local/boot-server/mysql/conf:/etc/mysql - /usr/local/boot-server/mysql/data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=123456 privileged: true ports: - "3306:3306" networks: - my_server_network container_name: mysql networks: my_server_network: name: server_network
启动服务
docker-compose up
测试服务,通过调用接口的方式测试服务的正常访问
当需要停止服务的时候
docker-compose stop 全部停止
docker-compose start 全部开启
docker-compose logs 查看日志输出