虽然知道如何部署war包到服务器上了,但是docker这么火,不学习学习装装逼怎么行呢,今天就来尝尝鲜。
注:阿里云上选的系统是centos,下面是具体的安装步骤都是在centos系统下完成的。
docker环境搭建
sudo yum update // 如果需要,对yum进行更新
yum -y install docker-io // 使用yum 安装docker
service docker start // 安装成功后启动docker
docker run hello-world // 从官网下个hello-world的镜像,启动容器打印hello-world,说明启动成功
docker部署mysql镜像
如果我们直接创建一个空的数据库,那直接下载mysql镜像就行了。
docker pull hub.c.163.com/library/mysql:5.7 // 使用网易的仓库下载mysql镜像
docker tag hub.c.163.com/library/mysql:5.7 mysql:5.7 // 重命名mysql镜像名
由于要把本地数据库的数据也迁移到阿里云上,为此,需要对mysql镜像进行定制化,我事先将本地的数据库脚本导出到为此创建dockerfile如下:
FROM mysql:5.7
#设置免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
#将所需文件放到容器中
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql
#设置容器启动时执行的命令
CMD ["sh", "/mysql/setup.sh"]
其中setup.sh为启动执行脚本,内容如下:
#!/bin/bash
set -e
#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`
echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`
echo '2.开始导入数据....'
#导入数据
mysql < /mysql/schema.sql
echo '3.导入数据完毕....'
sleep 3
echo `service mysql status`
#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /mysql/privileges.sql
echo '5.修改密码完毕....'
#sleep 3
echo `service mysql status`
echo 'mysql容器启动完毕,且数据导入成功'
tail -f /dev/null
具体的sql语句放在schema.sql文件中,这样启动后就会自动创建表结构,插数据。另外要注意的是这里是先导入数据,然后才是设置用户和权限,是因为mysql容器一开始为免密登录,Dockerfile中有如下设置:ENV MYSQL_ALLOW_EMPTY_PASSWORD yes,此时执行导入数据命令不需要登录验证操作,如果是先执行权限操作,那么导入数据则需要登录验证,整个过程就麻烦了许多。
设置数据库权限的脚步privileges.sql文件内容如下:
use mysql;
select host, user from user;
-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user docker identified by '123456';
-- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
grant all on docker_mysql.* to docker@'%' identified by '123456' with grant option;
-- 这一条命令一定要有:
flush privileges;
安装mongodb镜像
docker pull hub.c.163.com/public/mongodb:3.2.0
安装elasticsearch镜像
docker pull hub.c.163.com/library/elasticsearch:2.4.1
使用docker插件build spring boot工程
首先在mac系统上安装并启动docker,这里就不再阐述了。
下面要部署的是我的个人博客网站。应用分为博客应用和文件服务器应用。其中博客应用需要连接mysql进行数据持久化,elasticsearch进行全文索引,而文件服务器需要用到mongodb进行非结构化存储。为此下面要编译出两个个人镜像,以及对下载的mysql,es镜像进行相关配置,下面就详细介绍这些内容:
- 首先是博客应用的配置
在pom.xml文件中添加配置,这样idea会自动下载docker的编译插件。
yunsblog
compile
com.spotify
docker-maven-plugin
0.4.11
${docker.image.prefix}/${project.artifactId}
${project.basedir}/src/main/docker
/
${project.build.directory}
${project.build.finalName}.jar
接着在项目的pom.xml同级目录下创建dockerfile文件,作为docker编译生成镜像的依据。dockerfile内容如下:
FROM java:8-jre
ADD demo-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/demo-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080
第一句表示此镜像依赖jdk镜像,编译时会先下载jdk镜像。
第二句表示会将maven编译后的jar包拷贝到镜像的/app/目录下。
第三句表示启动镜像对应的容器的时候,会执行java -jar /app/demo-0.0.1-SNAPSHOT.jar
命令 ,即启动应用。
第四句表示暴露容器的8080端口,因为应用也是默认暴露的8080端口,这样部署后应用才能被访问。
上述几步都完成后,就可以在pom.xml文件目录下执行下面的命令去编译生成应用的jar包和镜像:
mvn package -Dmaven.test.skip=true docker:build
如果mvn配了有时候没生效,需要执行下:
source ~/.bash_profile
编译后,我们使用docker image ls命令就可以看到我们新生成的镜像了:
REPOSITORY TAG IMAGE ID CREATED SIZE
yunsblog/demo latest 63b7e4d9b807 22 minutes ago 381MB
如果我们在本地直接启动容器,也就直接启动应用了:
- 接着是文件服务器应用的配置
文件服务器的docker配置大部分都和博客应用的配置相同,唯一不同的就是dockerfile:
FROM java:8-jre
ADD demo-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/demo-0.0.1-SNAPSHOT.jar"]
EXPOSE 8081
因为应用服务器在application.properties属性文件中暴露的是8081端口,所以容器也要相应暴露8081端口。
使用mvn package -Dmaven.test.skip=true docker:build
命令编译后生成了文件服务器的镜像:
REPOSITORY TAG IMAGE ID CREATED SIZE
fileserver/demo latest 554845dd9ca9 About a minute ago 336MB
现在问题来了,由于我们直接在本地mac系统上编译生成了镜像文件,那这个镜像文件在哪呢?百度后发现位置为:
/Users/{YourUserName}/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2
问题又来了,镜像的格式是qcow2格式,这怎么导入到阿里云上生成镜像呢?这回百度不出来办法了,于是想到了另外一个办法,那就是拿着生成的jar包和dockerfile一起上传到阿里云上,在阿里云上使用docker来生成镜像。其实这样也有好处,毕竟上传一个镜像速度肯定也是要比上传jar包慢很多的。
下面我们将jar包和对应的dokerfile上传到阿里云上后,在dockerfile目录下执行:
docker build -t yubuyun/blog .
这样就开始生成镜像了。生成的过程有点慢,可能是下载依赖的时候网速有点慢。
生成好镜像后,最后一步就是将这几个容器连接起来。
- 启动mysql容器:
首先先编译镜像:
docker build -t yubuyun/mysql .
然后启动容器:
docker run -d -p 3306:3306 --name docker-mysql yubuyun/mysql
注意,这里的镜像是我之前自定义dockerfile的镜像。启动容器的时候,将容器的3306端口映射到阿里云主机的3306端口上。
- 启动mongodb容器
docker run -d -p 27017:27017 hub.c.163.com/public/mongodb:3.2.0
- 启动elasticsearch容器
docker run -d -p 9200:9200 -p 9300:9300 hub.c.163.com/library/elasticsearch:2.4.1
- 启动文件服务器应用
docker run -d -p 8081:8081 --name fileserver --link docker-mongoldb fcfd7f...
- 启动博客应用
docker run -d -p 8080:8080 --name blog --link docker-elasticsearch --link docker-mysql fcfd7f...
结果启动后,连接mysql失败了,进入mysql容器登陆成功了,说明账号密码对的,问题就在容器间的连接上,问了下同事,使用docker-compose可以实现容器互通,但是上面这个方法到底哪里有问题,还得再查查,顺便再学习一下docker-compose和docker三剑客了。
写到这本来要告一断落,但是还是不死心,感觉用上面这种方法是可以实现的,一定是配置问题,于是百度了许久,发现有篇博文也遇到了相同的问题,于是照着这篇文章再来了一遍,终于成功了,下面再分享一下过程,参考日志为:https://www.jb51.net/article/126278.htm
修改要修改下应用的数据库连接:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_activiti?useUnicode=yes&serverTimezone=GMT
spring.datasource.url=jdbc:mysql://mysql:3306/db_activiti?useUnicode=yes&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=abc123
spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
file.server.url=http://localhost:8081/upload
spring.http.multipart.max-file-size=30Mb
spring.http.multipart.max-request-size=30Mb
可以看出修改了mysql的连接信息,原来localhost肯定是有问题的,其中localhost替换为mysql,这个是后面link数据库的别名。
修改后重新部署blog容器,运行命令为:
docker run -p 8080:8080 --name blog --link docker-mysql:mysql b3cb50328ee8
按照上述办法最终真的可以连接上mysql,但是新的问题了,在照着这种办法连接elasticsearch的时候,发现es容器启动一会就会报错,百度了一下说这是由于es占用内存较大,其默认配置为需要1g内存,而我的ecs只有1g的内存 ,所以导致es启动失败,为此需要修改es的配置文件,在/config/jvm.options文件中,但是由于我使用的es是低版本的2.4.1(为什么使用这个版本呢,这是因为使用的spring data jpa只支持2.4.1以下的版本),这个低版本没有这个配置文件,那可以在哪个地方改下这个呢?
百度一下,有两种方法可以修改这个内存,一个是设置es的环境变量
export ES_HEAP_SIZE=512m
另一个是在启动命令中加上:
./bin/elasticsearch -Xmx512m -Xms512m
第二种方法我试了不行,找不到参数-X,下面就试下第一种方法行不行。
设置如上环境变量后,es启动后坚持2个小时左右还是挂了,而且当应用连接后马上就挂,问了下搞运维的同学,证实了es对内存的要求比较高,阿里云1g的乞丐版怕是玩不了了,用一句话来结束云上的es体验:从入门到放弃。
docker run -p 8080:8080 --name blog --link docker-mysql:mysql --link fileserver:fileserver c8bcf97ebf15
show dis
db.runoob.insert({"name":"菜鸟教程"})
sudo docker logs -f -t --tail 行数 容器名