docker部署前后端分离项目实战
1.docker容器之间的通讯方式
方案1:容器之间默认可以使用容器的ip进行通信,但是重启docker,ip会变化。查看ip如下:
docker inspect --format=’{{.NetworkSettings.IPAddress}}’ mycentos1
方案2:端口映射 把docker暴露到外部,这种方式不安全,只有暴露到外部需要访问才用 如: nginx pethome fastdfs ,对于: redis ,mysql就不应该暴露,但是为了操作方便也可以暴露,方便导入sql
方案3:
启动容器的时候,给要通信的目标容器使用link指定一个“链接名”,在容器中就可以使用“链接名”和目标容器通信。格式: --link 目标容器:别名 ,例如: 容器pethome 想要链接 pethome_mysql 如下配置:
创建Mysql容器,名字为: pethome_mysql
Docker run -id --name=pethome_mysql -p=3306:3306 mysql:5.7
创建项目容器,名字为:pethome ,通过link链接pethome_mysql容器,链接名为pethome_mysql
docker run -di --name=pethome --link pethome_mysql:pethome_mysql pethome:1.0-SNAPSHOT
2.后端部署
2.1.1 Redis部署
docker run -di --name pethome_redis redis --requirepass "123456"
2.1.2 Mysql部署
两个数据库对应两个容器,一个是pethome的库,一个是quartz的库。
docker run -di --name=pethome_mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
docker run -di --name=quartz_mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
“Mysql开放端口是方便导入SQL , 使用Navicat链接Mysql,导入SQL”
2.1.3. 构建Pethome后端镜像
- 修改项目
我们的项目Pethome采用link的方式去链接Mysql和Redis,所以需要把项目中的地址进行修改,先预定mysql的link别名为:pethome_mysql和 quartz_mysql , Redis的link别名为: pethome_redis , 那么项目修改如下:
特别注意:我们的后端配置了跨域,在部署环境我们使用nginx对后端进行反向代理,所以跨域的工作交给Ningx去实现,我们需要注释掉后端的跨域代码。
2. 打包镜像`
- 在工程pom.xml 增加插件:
<build>
<finalName>pethome</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--docker的maven插件,官网: https://github.com/spotify/docker‐maven‐plugin-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<!--镜像名 PetHome:1.0-->
<imageName>${project.artifactId}:${project.version}</imageName>
<!--基础镜像-->
<baseImage>jdk1.8</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}
</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<!--docker远程主机-->
<dockerHost>http://ip:2375</dockerHost>
</configuration>
</plugin>
</plugins>
</build>
- 进入Pethome所在的目录,输入以下命令,进行打包和上传镜像
mvn clean package -Dmaven.test.skip=true docker:build
- 基于pethome镜像运行容器
docker run -id --name=pethome -p 8082:8082 --link pethome_redis:pethome_redis --link pethome_mysql:pethome_mysql --link quartz_mysql:quartz_mysql pethome:1.0-SNAPSHOT
3.1.1 前端部署
前端使用Nginx进行部署,首先我们需要把前段项目打包成静态资源 , 然后使用Dockerfile自动构建一个Ningx镜像,Docerfile脚本构建镜像时需要把前段代码自动拷贝到容器中。
后台代码可以通过Docker的maven插件进行自动构建,而前段不是Maven项目,需要我们手动编写Dockerfile进行项目构建。
我们需要在Window电脑上准备前段项目并打包,准备好Dockerfile和nginx.config配置等,待会儿直接打包上传到Linux执行镜像构建即可。
3.2.1 前端项目打包
- 修改前端
注意:这里的地址应该是指向后端服务,但是我们后端服务使Nignx进行反向代理,所以这里应该指向反向代理的地址:
2. 把前端进行打包
PetHome_Admin使用 “npm run build” ,见:dist目录
Pethome_front 直接拷贝项目接口
注意:我们把前段准备好之后需要使用压缩工具(7z2000-x64.exe)把前段打包成 tar.gz格式,因为这种格式在构建Dockerfile镜像的时候可以自动解压。
压缩成tar之后,再压缩一次,改一下名字,变成 pethome_admin.tar.gz
两个前端最终打包如下:
3. 编写Dockerfile脚本
编写Dockerfile脚本,构建Nginx镜像,同时拷贝前段到Nginx镜像中。
FROM nginx:1.15
RUN mkdir /usr/share/nginx/pethome_admin
RUN mkdir /usr/share/nginx/pethome_front
ADD ./pethome_admin.tar.gz /usr/share/nginx/pethome_admin
ADD ./pethome_front.tar.gz /usr/share/nginx/pethome_front
ADD ./nginx.conf /etc/nginx/conf.d/
WORKDIR /usr/share/nginx
RUN chmod -R a+rx * pethome_admin
RUN chmod -R a+rx * pethome_front
- 编写Nginx配置文件
编写nginx.conf,配置三个虚拟主机,2个前端的主机需要执行Dockerfile中指定的站点目录。
server {
listen 80;
server_name www.wolfboy.xyz;
location / {
root /usr/share/nginx/pethome_front;
index index.html;
}
}
server {
listen 80;
server_name admin.wolfboy.xyz;
location / {
root /usr/share/nginx/pethome_admin;
index index.html;
}
}
server {
listen 80;
server_name api.wolfboy.xyz;
location / {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE,PUT,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,U-TOKEN,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE,PUT,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,U-TOKEN,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
root html;
index index.html index.htm;
proxy_pass http://pethome_service:8082; #这里跟后端服务的link名字
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5;
}
}
特别注意:这个nginx.cnf只需要有上面的内容即可
最终准备好的目录结构如下:`
5. 上传代码到Linux
6. 构建镜像
cd到 项目上传的目录,执行镜像构建命令,下面构建的镜像名字为: pethome-nginx
docker pull nginx:1.15
[root@VM_0_15_centos pethome-web]# docker build -t="pethome-nginx" ./
7. 创建容器
docker run -di --name=pethome_web -p 80:80 --link pethome:pethome pethome-nginx
注意:这里一定要是“–link pethome:pethome” ,因为在nginx.conf中使用了这个link名字来反向代理到后端服务
启动测试