前言
最近了解到公司里面都是用Docker以容器化的形式部署应用,所以想在实习之前自己学一下Docker,并且自己尝试部署一下Web应用,本文不包含Docker的基础知识,只是一个Docker部署Web应用的实践记录,一方面是作为自己的学习笔记,另外如果可以帮助大家解决学习过程中遇到的一些问题就更好了。
一、本地编写Springboot代码
创建一个新的Springboot工程,随便写一个样例demo,服务端口设置为8081,下面是一个测试用的样例HelloController.java
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "Hello";
}
}
在本地idea中运行无误后,将工程打包,这里为了方便,直接使用idea中的maven快捷操作
首先双击clean,清除旧的包
然后双击package,将工程打包
可以从demo/target目录下找到对应的jar包, demo是项目根目录
将该jar包上传到linux服务器,使用命令java -jar 运行,如果能正常运行,说明打包无误。当然运行这个命令之前本地必须安装好jdk1.8的环境,可以参考 www.cnblogs.com/coloz/p/111…
二、编写Dockerfile
在linux服务器上创建一个空的文件夹/webapp,创建Dockerfile文件,并将刚才的jar包导入这个文件夹中,为了方便这里可以简单将jar包重命名一下。
其中,Dockerfile文件内容如下
FROM openjdk:8
MAINTAINER [作者] [邮箱]
COPY qbank.jar qbank.jar
EXPOSE 8081
CMD ["java","-jar","qbank.jar"]
- FROM:指明当前镜像继承的基础镜像,编译当前镜像时候会自动下载基镜像
- 因为本文部署的是java服务,所以使用jdk作为基础镜像环境
- MAINTAINER:当前镜像的作者和邮箱,使用空格隔开
- COPY:从当前工作目录复制文件到镜像目录中并重新命名
- 非常重要,这个的作用是把当前本机中的jar包文件拷贝到docker容器中,没有这个容器找不到jar包
- EXPOSE:暴露监听的端口号,这个只是声明作用,并不会完成端口应声
- CMD:用来指定启动容器时默认执行的命令
- 注意这里一定要跟COPY后的文件名一致,并且不能使用大写字母
三、创建镜像
执行命令
$ docker build -t qbank .
其中参数 -t [镜像名] [Dockerfile所在路径],这里镜像名为qbank, 路径为当前目录
执行这个命令之后,会出现上图的结果,如果本地没有openjdk镜像,会自动pull该镜像,这里如果镜像pull的过程很慢,可以设置使用国内镜像源加速,参考 www.runoob.com/docker/dock…
创建image完成后,可以查看本地是否有该镜像
$ docker images
四、利用镜像创建并运行容器
执行命令:
$ docker run -d -p 8081:8081 --name qbank qbank
- -d:表示后台运行
- -p:端口映射,第一个8081表示机器的8081端口, 第二个8081表示docker的8081端口,这样我们访问机器的8081端口就会自动映射到docker的8081端口
- --name:为容器取名
- 最后的qbank:使用的镜像名
查看容器日志,看看是否成功运行
$ docker logs qbank
可以看到服务正常启动
最后查看能否正常访问, 使用本地浏览器访问,可以看到可以返回正确的结果
五、将镜像文件上传到docker服务器
当我们制作好一个docker镜像文件时,可以把它上传到docker服务器上,当我们想要在另一台新机器上部署该服务时,只需要讲镜像pull下来,就可以使用了
这里使用docker官方提供的仓库,如果没有账号的话可以创建一个hub.docker.com/
可以在远程创建仓库
创建成功后,右侧会有push提示
回到本地,在本地登录刚才创建的账号, 根据提示输入用户名和密码
$ docker login
将本地创建的镜像上传到docker中心仓库
$ docker tag [本地镜像名]:[tag] [用户名]/[仓库名]:[远程仓库tag]
$ docker push [用户名]/[仓库名]:[远程仓库tag]
在机器上重新拉取制作好的镜像,码掉的部分是刚才创建的用户名, 后面的qbank是创建的仓库名
查看本地镜像,第一个是刚才拉取的自己制作的镜像
然后按照前面的流程,利用这个镜像创建并运行容器,就可以正常使用了。
排雷
- 如果服务中涉及到数据库访问的问题,可能会遇到报错com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure,这个问题是服务不能正确访问数据库,检查一下对应数据库连接的信息是否正确,如果正确无误的话,再检查一下数据库ip地址是不是写的具体的ip,即使是使用的本机数据库也要写本机的ip,因为服务是在docker中运行,如果使用localhost的话会默认访问的docker中的数据库
- docker镜像pull速度过慢,可以使用国内镜像源加速,正文部分也提到了
- Dockerfile编写的时候一定要注意 写COPY或者ADD(建议使用COPY)将jar包从本机拷贝到docker环境中,否则可能会报错 Error: Unable to access jarfile, COPY后的文件名不能含有大写字母,否则也会报错