使用docker 部署应用

虽然知道如何部署war包到服务器上了,但是docker这么火,不学习学习装装逼怎么行呢,今天就来尝尝鲜。


201806291530261215908089.jpg

注:阿里云上选的系统是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的编译插件。
    <properties>
        <docker.image.prefix>yunsblog</docker.image.prefix>
    </properties>
    <build>
        <defaultGoal>compile</defaultGoal>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.4.11</version>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
    </plugins>
    </build>

接着在项目的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

如果我们在本地直接启动容器,也就直接启动应用了:


屏幕快照 2018-07-21 上午10.48.29.png
  • 接着是文件服务器应用的配置
    文件服务器的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 行数 容器名

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容