Docker部署前后端分離項目的三種方式小結(jié)
方式一:通過兩個容器部署
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本地創(chuàng)建default.conf和Dockerfile
1、default.conf:linux本機創(chuàng)建的配置文件,用于覆蓋nginx內(nèi)部的配置文件
server { listen 80; server_name 10.61.4.42; # 修改為docker服務(wù)宿主機的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,該端口是容器內(nèi)端口,也是nginx監(jiān)聽的端口,是默認(rèn)的)
# 鏡像nginx FROM nginx # 作者 MAINTAINER ZhangSH<xxx@163.com> # 將前端dist文件中的內(nèi)容復(fù)制到nginx目錄 ENV TimeZone=Asia/Shanghai # 將前端dist文件中的內(nèi)容復(fù)制到nginx目錄 COPY dist /usr/share/nginx/html/ # 用本地的nginx配置文件覆蓋鏡像的Nginx配置 COPY default.conf /etc/nginx/conf.d EXPOSE 80
1.4、將dist文件夾和以上兩個文件同級放置
1.5、打包鏡像
在Dockerfile目錄執(zhí)行build打包鏡像。
docker build -t 鏡像名 . # -t指明鏡像名 # .不能丟
1.6、啟動容器實例
docker run -d -p 8088:80 --name 容器實例名 鏡像名 # 8088為linux本地端口,也是瀏覽器地址欄中輸入的端口(可任意設(shè)置),docker會將其映射到容器實例中的80端口,然后nginx會監(jiān)聽到該端口
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、創(chuàng)建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是當(dāng)前目錄下的jar包
docker build -t 鏡像名 . # -t指明鏡像名 # .不能丟
2.6、啟動容器實例
docker run -d -p 7777:80 --name 容器實例名 鏡像名 # 7777為linux本地端口,也是前端的BASE_URL中指定的端口號,docker會將7777映射到容器實例中的80端口,然后nginx會監(jiān)聽到該端口
方式二:通過compose編排容器自動部署
通過compose編排可以自動化部署前后端項目(包括中間件等)
文件目錄結(jié)構(gòu):
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: . # 執(zhí)行當(dāng)前目錄下的Dockerfile文件打包鏡像 ports: - "7777:80" depends_on: - mysql networks: data_security: ipv4_address: 192.128.0.4 # 容器內(nèi)部網(wǎng)絡(luò)組 networks: data_security: driver: bridge ipam: config: - subnet: 192.128.0.0/16
方式三:將前后端項目打成一個鏡像部署
將前后端打成一個docker鏡像并作為容器啟動,同時通過反向代理對接另一個服務(wù)端。即:一個客戶端,兩個服務(wù)端。
服務(wù)結(jié)構(gòu): 共三個容器實例
- 前端A、后端A(一個容器實例)
- 后端B(一個容器實例)
- 數(shù)據(jù)庫MySQL(一個容器實例)
目標(biāo):
- 將前端A、后端B打包成一個鏡像并作為容器實例啟動
- 將后端B作為其他服務(wù),以nginx反向代理的方式為前端A提供服務(wù)
步驟:
1、打包前后端項目
前端A: 2xx.xx.xx.xx9:6868(ip和端口,用于發(fā)送請求的BASE_URL,?也是nginx的ip和監(jiān)聽端口)
后端A: 2xx.xx.xx.xx9:7777(容器啟動時以本地7777端口啟動)
后端B: 2xx.xx.xx.xx9:7777(容器啟動時以本地6666端口啟動)
分別得到:前端A的dist文件夾、后端A的jar包、后端B的jar包
2、編寫nginx.conf文件
該文件會在Dockerfile文件中使用,**作用:**覆蓋服務(wù)器中nginx的配置文件,使用該nginx.conf文件。
該文件中通過location指定了url中包含/roadSection
的請求轉(zhuǎn)發(fā)到后端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監(jiān)聽的端口,需要在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發(fā)送到nginx,由nginx根據(jù)location規(guī)則匹配做對應(yīng)的轉(zhuǎn)發(fā) location ~ /roadSection { # ?反向代理重寫url,正則表達(dá)式拼接 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文件
該文件用于構(gòu)建一個鏡像,其中包括nginx、jdk環(huán)境,以及前端A包dist、后端Ajar包。(mysql數(shù)據(jù)庫是單獨起了一個容器實例)
FROM centos:7 MAINTAINER ZhangSH<xxx@163.com> # 當(dāng)前目錄掛載到容器內(nèi)的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默認(rèn)的資源目錄里 COPY dist /usr/share/nginx/html # 將自己的nginx.conf 配置文件放到docker里nginx默認(rèn)的配置文件位置 COPY nginx.conf /etc/nginx/nginx.conf # 將nginx監(jiān)聽的端口6868暴露出來,啟動容器實例時通過--net=host不用指定端口映射,會默認(rèn)使用這個端口 EXPOSE 6868 # 運行jar包,ENTRYPOINT這條命令只能出現(xiàn)一次,如有多條,則只執(zhí)行最后一條。該命令只有容器啟動時才執(zhí)行 ENTRYPOINT ["java","-jar","/app.jar"]
4、將文件放到服務(wù)器
5、將前端A和后端B打成一個鏡像
在/usr/zsh/dockerOneImage
目錄下執(zhí)行命令:docker build -t 鏡像名 .
,這里是test
6、啟動該鏡像容器實例
命令:docker run -d --name 容器名 --net=host 鏡像名
-d: 后臺運行容器,并返回容器ID;
–net=host: 指定容器的網(wǎng)絡(luò)連接類型,四種類型:bridge/host/none/container;
通過docker ps
查看:
通過postman測試,發(fā)現(xiàn)**后端A(端口7777)**正常啟動了:
7、啟動該容器里的nginx服務(wù)器
通過docker exec -it 剛剛的容器名 nginx
來啟動nginx,此時會使用之前Dockerfile中暴露出來的端口6868,也是nginx.conf中監(jiān)聽的端口。
8、啟動后端B
9、查看已啟動服務(wù)
通過netstat -ntlp
可查看已啟動服務(wù)的端口信息:
10、測試
已啟動容器:
后端A:正常
后端B:正常
網(wǎng)頁:
1)關(guān)閉后端B的容器實例時,反向代理轉(zhuǎn)發(fā)失敗。
2)開啟后端B的容器實例時,反向代理轉(zhuǎn)發(fā)成功。
到此這篇關(guān)于Docker部署前后端分離項目的三種方式小結(jié)的文章就介紹到這了,更多相關(guān)Docker部署前后端分離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在docker中執(zhí)行l(wèi)inux shell命令的操作
這篇文章主要介紹了在docker中執(zhí)行l(wèi)inux shell命令的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03解決Docker之mysql容器數(shù)據(jù)庫更改不生效的問題
這篇文章主要介紹了解決Docker之mysql容器數(shù)據(jù)庫更改不生效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11docker Nginx PHP-FPM單機多站點布署的方法
這篇文章主要介紹了docker Nginx PHP-FPM單機多站點布署的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07docker鏡像與傳統(tǒng)vm虛擬機區(qū)別及分析
這篇文章主要是內(nèi)容分享系列,為大家用大白話通俗的講解docker鏡像與傳統(tǒng)vm虛擬機區(qū)別以及分析,有需要的朋友可以借鑒參考想,希望能夠有所幫助2022-03-03