部署项目是一件很麻烦的事,尤其是当同一个项目部署到很多服务器的时候,这种麻烦变得更加让人难受。
在我刚到公司的时候,公司之前的先项目采用的就是使用Web服务器Tomcat部署项目,但是后来的新项目是微服务的架构,所以部署十几个服务变得比较麻烦,后来技术经理想到了使用Docker,现在也来学习如何快捷的部署自己的项目。
刚开始学习当然是先安装了,这里使用的macOS,安装和其他的软件没有什么区别,就是下载完毕后直接拖到application里面就完成安装了。
安装完毕后需要修改镜像加速地址。
具体的安装在下面的网站也有详细的步骤。http://www.runoob.com/docker/docker-tutorial.html
安装完毕后在终端输入:docker --version。显示如下界面表示成功。
安装完毕就要介绍一些部署的流程,顺便介绍一下Docker的一些结构。
Docker的一些简单介绍这里就不在累述了。具体的一些信息可以在下面的网站了解:http://www.runoob.com/docker/docker-tutorial.html
Docker是一个虚拟化的容器引擎,具体的服务可以在虚拟机中运行,和宿主主机分开,达到了不依赖宿主环境的效果,这也是Docker可以简化部署的原因,Docker的优点还有很多。这里也不再详细介绍。
Docker具体的部署分为三步:
1.将项目变为一个镜像。
2.将厂库中的镜像pull下来并且实例化为容器。
3.将容器启动,完成部署。
这里的镜像和Java中的类差不多,容器和Java中的对象差不多,一个镜像可以实例化为好多的对象,一个镜像也可以在其他镜像的基础上面进行修改。而厂库的概念又有点想git,一个镜像也好像git里面的代码,代码也是有着名字和地址的,同时版本还拥有版本号,这些镜像都有。
因为自己的具体Docker实现是将一个SpringBoot项目打包到Docker中完成部署,但是一些中间件还是使用宿主机器的。这就是大致的一个思路。
下面就说说具体的实现:
先是将项目添加Docker的插件和Dockerfile文件。
在pom.xml文件中添加插件如下:
<!-- 加入maven插件 docker-maven-plugin --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <configuration> <imageName>${docker.image.prefix}/${project.artifactId}</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin>
这里要注意几个路径的参数,修改到自己的项目中时要发生一些变化。
Dockerfile文件里的内容如下:
# Usage: FROM [image name] FROM java:8 # Usage: MAINTAINER [name] MAINTAINER yanyu VOLUME /tmp ADD spring-boot-train-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] # Usage: EXPOSE [port] EXPOSE 8080
这些添加完毕,项目就可以打包成镜像了。
先cd到项目到根目录下,在执行打包命令,打包命令是:
mvn clean package docker:build
上面到命令是打包和build一起执行到,在命令不报错到情况下,会直接生成一个镜像,后面运行镜像就可以了。运行命令如下:
docker run --name nginx_web -d -p 8080:80 name
上面到参数有些可以看懂,--name就是指定容器name,-d是后台运行,-p是指定端口映射,最后的name就是镜像的名字。
如果这个地方不报错,就可以直接访问你到项目了。部署项目到Docker就是完成了。
下面就讲一下自己踩到的坑。
在最开始尝试到时候建立了很多的容器,想删除镜像时却无法删除,这里的原因就是在删除镜像之前一定要先删除容器(不是停止容器,是删除容器),然后才能删除镜像。
打包的时候出错非常多了,这里面的问题也是有很多,大部分都是配置的问题,下面就说几个点:项目的名字最好不要用大写字母,因为Docker会报错。项目一定写上打包的地址在哪里,同时在Docker插件的添加中也要声明Dockerfile文件的位置。
打包完成后并不是代表你的项目就部署完毕了,因为项目是部署在虚拟机上面,所以在你机器上面测试通过的代码可能就会有问题。比如MySQL的URL问题,因为Docker容器和宿主主机不是同一个ip,所以代码中localhost可能就会出问题,上面的端口映射讲的就是这个问题,就是将宿主主机上面对于8080端口的请求都映射到虚拟机上面,至于MySQL的问题为这里也是有一个不是解决办法的解决办法,就是使用电脑的ip地址,比如10.168。55.123。网络的问题还是比较复杂的,自己对于一些具体的细节还是没有深入了解。
下面就说说Dockerfile文件内参数的意思:
ADD
ADD命令有两个参数,源和目标。它的基本作用是从源系统的文件系统上复制文件到目标容器的文件系统。如果源是一个URL,那该URL的内容将被下载并复制到容器中。
CMD
和RUN命令相似,CMD可以用于执行特定的命令。和RUN不同的是,这些命令不是在镜像构建的过程中执行的,而是在用镜像构建容器后被调用。
ENTRYPOINT
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
ENTRYPOINT 帮助你配置一个容器使之可执行化,如果你结合CMD命令和ENTRYPOINT命令,你可以从CMD命令中移除“application”而仅仅保留参数,参数将传递给ENTRYPOINT命令。
ENV
ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。
EXPOSE
EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。
FROM
FROM命令可能是最重要的Dockerfile命令。改命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜 像。如果基础镜像没有被发现,Docker将试图从Docker image index来查找该镜像。FROM命令必须是Dockerfile的首个命令。
FROM ubuntu
MAINTAINER
我建议这个命令放在Dockerfile的起始部分,虽然理论上它可以放置于Dockerfile的任意位置。这个命令用于声明作者,并应该放在FROM的后面。
RUN
RUN命令是Dockerfile执行命令的核心部分。它接受命令作为参数并用于创建镜像。不像CMD命令,RUN命令用于创建镜像(在之前commit的层之上形成新的层)。
USER
USER命令用于设置运行容器的UID。
VOLUME
VOLUME命令用于让你的容器访问宿主机上的目录。
WORKDIR
WORKDIR命令用于设置CMD指明的命令的运行目录。
上面关于参数的解释参考了一些博客。
下面在说说Docker常用的命令。上面使用到不再累述。
查看容器日志:docker logs name
删除容器: docker rm id
删除镜像: docker rmi id
删除所有的容器: docker rm $(docker ps -a -q)
查看所有的容器: docker ps -a
查看正在运行的容器: docker ps
剩下就没有什么问题了,在贴上具体的一些参考的博客。
Docker的详解和具体实现:https://www.cnblogs.com/ECJTUACM-873284962/p/9789130.html#autoid-0-0-0
Docker的网络问题解析:https://zhuanlan.zhihu.com/p/26418829?utm_medium=social&utm_source=weibo
就这样吧,结束。