Docker部署前后端分离项目的三种方式小结
作者:sh顺其自然
方式一:通过两个容器部署
1、部署前端
1.1、指定前端向后端请求的BASE_URL
比如:http://10.61.4.42:7777/traffic,这里的7777是Docker部署后端时linux的本地端口,即7777:80,80是后端配置文件中指定的端口。
export const BASE_URL = 'http://10.61.4.42:7777/traffic'
1.2、打包前端项目生成dist文件夹
1.3、linux本地创建default.conf和Dockerfile
1、default.conf:linux本机创建的配置文件,用于覆盖nginx内部的配置文件
server { listen 80; server_name 10.61.4.42; # 修改为docker服务宿主机的ip location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html =404; } location /traffic { proxy_pass http://10.61.4.42:7777/traffic; } error_page 500 502 503 504 /404; location = /50x.html { root html; } }
2、Dockerfile:打包镜像。(default.conf和Dockerfile中端口都为80,该端口是容器内端口,也是nginx监听的端口,是默认的)
# 镜像nginx FROM nginx # 作者 MAINTAINER ZhangSH<xxx@163.com> # 将前端dist文件中的内容复制到nginx目录 ENV TimeZone=Asia/Shanghai # 将前端dist文件中的内容复制到nginx目录 COPY dist /usr/share/nginx/html/ # 用本地的nginx配置文件覆盖镜像的Nginx配置 COPY default.conf /etc/nginx/conf.d EXPOSE 80
1.4、将dist文件夹和以上两个文件同级放置
1.5、打包镜像
在Dockerfile目录执行build打包镜像。
docker build -t 镜像名 . # -t指明镜像名 # .不能丢
1.6、启动容器实例
docker run -d -p 8088:80 --name 容器实例名 镜像名 # 8088为linux本地端口,也是浏览器地址栏中输入的端口(可任意设置),docker会将其映射到容器实例中的80端口,然后nginx会监听到该端口
2、部署后端
2.1、指定端口和context-path
server: port: 80 servlet: context-path: /traffic
2.2、处理跨域问题
@Configuration @EnableWebMvc public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedHeaders("*") .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH") .maxAge(3600); } }
2.3、打jar包
2.4、创建Dockerfile文件
# 镜像jdk1.8 FROM openjdk:8-jre-alpine # 作者 MAINTAINER ZhangSH<xxx@163.com> RUN echo "Asia/Shanghai" > /etc/timezone # 拷贝并取别名 COPY *.jar /app.jar EXPOSE 80 ENTRYPOINT ["java","-jar","app.jar"]
2.5、打包镜像
Dockerfile文件要和jar包在同一目录下,因为Dockerfile文件的COPY是当前目录下的jar包
docker build -t 镜像名 . # -t指明镜像名 # .不能丢
2.6、启动容器实例
docker run -d -p 7777:80 --name 容器实例名 镜像名 # 7777为linux本地端口,也是前端的BASE_URL中指定的端口号,docker会将7777映射到容器实例中的80端口,然后nginx会监听到该端口
方式二:通过compose编排容器自动部署
通过compose编排可以自动化部署前后端项目(包括中间件等)
文件目录结构:
nginx.conf
server { listen 80; server_name 2xxxxxxxxx9; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html last; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
Dockerfile(后端)
# 镜像jdk1.8 FROM openjdk:8-jre-alpine # 作者 MAINTAINER ZhangSH<xxx@163.com> RUN echo "Asia/Shanghai" > /etc/timezone # 拷贝并取别名 COPY *.jar /app.jar EXPOSE 80 ENTRYPOINT ["java","-jar","app.jar"]
docker-compose.yaml
version: '3' services: nginx: image: nginx:latest container_name: nginx restart: always volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./html/dist:/usr/share/nginx/html/ ports: - "8080:80" networks: data_security: ipv4_address: 192.128.0.8 privileged: true mysql: image: mysql:8.0.26 container_name: mysql security_opt: # 忽略安全性检查 - seccomp:unconfined cap_add: - SYS_NICE restart: always environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=Root123! - MYSQL_DATABASE=traffic # - MYSQL_USER: 'root' # - MYSQL_PASSWORD: 'password' # - MYSQL_ROOT_HOST: '%' volumes: # 挂载sql文件 - ./mysql/init/:/docker-entrypoint-initdb.d/ ports: - "3306:3306" networks: data_security: ipv4_address: 192.128.0.2 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --sql-mode='' --interactive_timeout=259200 --wait_timeout=259200 myweb: image: web/test1 build: . # 执行当前目录下的Dockerfile文件打包镜像 ports: - "7777:80" depends_on: - mysql networks: data_security: ipv4_address: 192.128.0.4 # 容器内部网络组 networks: data_security: driver: bridge ipam: config: - subnet: 192.128.0.0/16
方式三:将前后端项目打成一个镜像部署
将前后端打成一个docker镜像并作为容器启动,同时通过反向代理对接另一个服务端。即:一个客户端,两个服务端。
服务结构: 共三个容器实例
- 前端A、后端A(一个容器实例)
- 后端B(一个容器实例)
- 数据库MySQL(一个容器实例)
目标:
- 将前端A、后端B打包成一个镜像并作为容器实例启动
- 将后端B作为其他服务,以nginx反向代理的方式为前端A提供服务
步骤:
1、打包前后端项目
前端A: 2xx.xx.xx.xx9:6868(ip和端口,用于发送请求的BASE_URL,❗也是nginx的ip和监听端口)
后端A: 2xx.xx.xx.xx9:7777(容器启动时以本地7777端口启动)
后端B: 2xx.xx.xx.xx9:7777(容器启动时以本地6666端口启动)
分别得到:前端A的dist文件夹、后端A的jar包、后端B的jar包
2、编写nginx.conf文件
该文件会在Dockerfile文件中使用,**作用:**覆盖服务器中nginx的配置文件,使用该nginx.conf文件。
该文件中通过location指定了url中包含/roadSection
的请求转发到后端B。
user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; # ❗nginx监听的端口,需要在Dockerfile中暴露出来 server { listen 6868 default_server; listen [::]:6868 default_server; server_name 2xx.xx.xx.xx9; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; # ❗反向代理,前端请求的url发送到nginx,由nginx根据location规则匹配做对应的转发 location ~ /roadSection { # ❗反向代理重写url,正则表达式拼接 rewrite ^/(.*)$ /$1 break; # ❗后端B的ip和端口 proxy_pass http://2xx.xx.xx.xx9:6666; } location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html last; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } }
3、编写Dockerfile文件
该文件用于构建一个镜像,其中包括nginx、jdk环境,以及前端A包dist、后端Ajar包。(mysql数据库是单独起了一个容器实例)
FROM centos:7 MAINTAINER ZhangSH<xxx@163.com> # 当前目录挂载到容器内的tmp VOLUME /tmp # 安装java RUN yum -y install java # 安装epel源 RUN yum -y install epel-release # 安装nginx RUN yum -y install nginx # 将jar包添加到容器中并更名为app.jar ADD traffic-backend-0.0.1-SNAPSHOT.jar app.jar # 把自己本地的html里放的前端项目,放入nginx默认的资源目录里 COPY dist /usr/share/nginx/html # 将自己的nginx.conf 配置文件放到docker里nginx默认的配置文件位置 COPY nginx.conf /etc/nginx/nginx.conf # 将nginx监听的端口6868暴露出来,启动容器实例时通过--net=host不用指定端口映射,会默认使用这个端口 EXPOSE 6868 # 运行jar包,ENTRYPOINT这条命令只能出现一次,如有多条,则只执行最后一条。该命令只有容器启动时才执行 ENTRYPOINT ["java","-jar","/app.jar"]
4、将文件放到服务器
5、将前端A和后端B打成一个镜像
在/usr/zsh/dockerOneImage
目录下执行命令:docker build -t 镜像名 .
,这里是test
6、启动该镜像容器实例
命令:docker run -d --name 容器名 --net=host 镜像名
-d: 后台运行容器,并返回容器ID;
–net=host: 指定容器的网络连接类型,四种类型:bridge/host/none/container;
通过docker ps
查看:
通过postman测试,发现**后端A(端口7777)**正常启动了:
7、启动该容器里的nginx服务器
通过docker exec -it 刚刚的容器名 nginx
来启动nginx,此时会使用之前Dockerfile中暴露出来的端口6868,也是nginx.conf中监听的端口。
8、启动后端B
9、查看已启动服务
通过netstat -ntlp
可查看已启动服务的端口信息:
10、测试
已启动容器:
后端A:正常
后端B:正常
网页:
1)关闭后端B的容器实例时,反向代理转发失败。
2)开启后端B的容器实例时,反向代理转发成功。
到此这篇关于Docker部署前后端分离项目的三种方式小结的文章就介绍到这了,更多相关Docker部署前后端分离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!