如何用Docker|如何用Docker Compose部署项目()
[TOC]
前言
之前我们用docker
部署了springboot
,redis
,mysql
的项目,但是是部署在三个不同的容器里,还需要先知道redis
和mysql
的ip
地址,手动配置到springboot
应用容器里,我只是想快速在本地进行测试啊,这样成本太高了,有没有什么办法,把他们集中管理呢?比如把它构建成为一个镜像。
办法总是有的,那就是Docker Compose
。
之前的项目地址:https://github.com/Damaer/Dem...
Docker Compose
1. Docker Compose是什么?
Docker Compose
其实就是用来定义和运行复杂应用的Docker
工具,什么叫复杂应用,比如前面写的springboot
+redis
+mysql
,里面就有三个容器,这种多个容器的,用一个工具来管理,它不香么?
docker compose 通过配置文件来管理多个2. Docker Compose 的具体步骤Docker
容器,在配置文件中,所有的容器通过service
来进行定义,然后使用docker-compose
脚本来启动、停止、重启应用以及应用中的服务和所依赖的容器等。
一般是三个步骤:
- 使用
Dockerfile
来定义应用程序的环境 - 在
docker-compose.yml
定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。 - 执行
docker-compose up
命令来启动并运行整个应用程序。
Mac OS
,装Docker
的时候已经把Docker Compose
也安装好了,不需要单独安装。3. 如何在IDEA项目里面使用Docker Compose
首先
pom.xml
文件中需要注意配置小写的artifactId
:com.aphysia
dockerdemo
0.0.1-SNAPSHOT
dockerdemo jar
除此之外还需要配置插件:
org.springframework.boot
spring-boot-maven-plugin
com.spotify
docker-maven-plugin
1.0.0
build-image package
build
${docker.image.prefix}/${project.artifactId}
src/main/docker
/
${project.build.directory}
${project.build.finalName}.jar
除此之外,
Dockerfile
是必要的,上面的插件中已经配置了我们dockerFile
需要放在src/main/docker
这个位置,DockerFile
里面配置如下:FROM openjdk:8-jdk-alpine
EXPOSE 8081
VOLUME /tmp
# 重写命名为app.jar
ADD dockerdemo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
理论上到这个时候,我们使用
mvn clean package
就会生成对应的jar
包:文章图片
docker compose
最重要的是配置docker-compose.yml
,这个文件我们放在项目的根目录就可以,和pom.xml
平级:version: "3"services:
redis:
image: redis:latest
restart: always
ports:
- "6389:6379"
volumes:
- /tmp/redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.confmysql:
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_USER: 'root'
MYSQL_PASS: '123456'
ports:
- "3306:3306"
volumes:
- "./db:/var/lib/mysql"
- "./conf/my.cnf:/etc/my.cnf"
- "./init:/docker-entrypoint-initdb.d/"
# 指定服务名称
webapp:
# 指定服务使用的镜像
image: aphysia/dockerdemo
# 指定容器名称
container_name: dockerdemo
# 指定服务运行的端口
ports:
- 8081:8081
# 指定容器中需要挂载的文件
volumes:
- /etc/localtime:/etc/localtime
- /tmp/dockerdemo/logs:/var/logs
值得注意的点:
- service里面就是我们配置的镜像,包含了
redis
,mysql
,webapp
,webapp
其实就是我们的应用。 "6389:6379"
中6389
其实是我们主机的端口,也就是我的Mac
连接redis
容器需要使用6389
,而容器之间连接需要使用6379
,这是容器的端口。/tmp/redis.conf:/etc/redis/redis.conf
中/tmp/redis.conf
是主机的目录,而这个目录需要在docker里面配置才可以,要不就会报错(执行记得加管理员权限):
docker ERROR: * start service *: Mounts denied
文章图片
mysql
8.0 可能会报错java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed
,这个是因为url
链接少了一个参数:allowPublicKeyRetrieval=true
mysql
或者redis
,但是看容器运行情况又是正常的:DockerCompose % docker container ps
CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
32fd6ce598baaphysia/dockerdemo"java -jar /app.jar"7 minutes agoUp 7 minutes0.0.0.0:8081->8081/tcp, :::8081->8081/tcpdockerdemo
585b9b6bd71dredis:latest"docker-entrypoint.s…"10 minutes agoUp 7 minutes0.0.0.0:6379->6379/tcp, :::6379->6379/tcpdockercompose_redis_1
d96ba57941d9mysql:latest"docker-entrypoint.s…"16 minutes agoUp 7 minutes0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcpdockercompose_mysql_1
执行
docker-compose up
没有报错,请求的时候报错: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /127.0.0.1:6379
这是因为容器之间的请求不能用
127.0.0.1
,必须用mysql
,redis
代表容器的网络,比如:jdbc:mysql://mysql:3306/test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
完整的
application.yml
:server:
port: 8081
spring:
#数据库连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 123456
redis:
host: redis## redis所在的服务器IP
port: 6379
##密码,我这里没有设置,所以不填
password:
## 设置最大连接数,0为无限
pool:
max-active: 8
min-idle: 0
max-idle: 8
max-wait: -1
#mybatis的相关配置
mybatis:
#mapper配置文件
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.aphysia.springdocker.model
#开启驼峰命名
configuration:
map-underscore-to-camel-case: true
logging:
level:
root: debug
还有一个问题,就是
docker-compose.yml
里面配置的镜像名字一定要对,要不docker-compose up
执行的时候,就会出现:Pulling xxxx...
ERROR: The image for the service you're trying to recreate has been removed. If you continue, volume data could be lost. Consider backing up your data before continuing.Continue with the new image? [yN]y
Pulling xxxx...
ERROR: pull access denied for postgresql, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
我还以为是登录的原因,本来是本地镜像,应该直接
create
而不是pull
,如果不知道名字,可以通过以下命令查看,REPOSITORY
就是名字:DockerCompose % docker images
REPOSITORYTAGIMAGE IDCREATEDSIZE
aphysia/dockerdemolatest1429aa26790a54 minutes ago137MB
ceb493583d7c57 minutes ago137MB
dffcc47602a2About an hour ago137MB
a695cf2cd2dfAbout an hour ago137MB
209ce4f96d342 hours ago137MB
redislatest40c68ed3a4d210 days ago113MB
mysqllateste1d7dc9731da14 months ago544MB
openjdk8-jdk-alpinea3562aa0b9912 years ago105MB
最后启动命令:
sudo docker-compose up
成功启动:
文章图片
启动之后记得初始化一下数据库数据表!!!
drop database IF EXISTS test;
CREATE DATABASE test;
use test;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT "",
`age` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES (1, '李四', 11);
INSERT INTO `user` VALUES (2, '王五', 11);
【如何用Docker|如何用Docker Compose部署项目()】
文章图片
至此,大功告成,看似简单的命令,其实还是有不少坑点。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:
Java源码解析
,JDBC
,Mybatis
,Spring
,redis
,分布式
,剑指Offer
,LeetCode
等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。剑指Offer全部题解PDF
2020年我写了什么?
开源编程笔记
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- 任时光绽放成六月繁花
- 我从来不做坏事
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 樱花雨
- 如何寻找情感问答App的分析切入点
- 拍照一年啦,如果你想了解我,那就请先看看这篇文章
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- 人如果没梦想,和咸鱼有什么区别(自媒体时代把握住就能咸鱼翻身)