docker-compose一鍵部署Springboot+Vue前后端分離項目

1. 背景說明

  • 后端使用JDK8,前端為普通Vue項目
  • 前端訪問后端接口,統一帶了前綴/api

2. 項目配置

2.1 后端

yml文件里配置統一訪問前綴/api
在這里插入圖片描述

2.2 前端

API路徑配置為相對路徑:

在這里插入圖片描述
說明:我這邊前后端應用都是部署在同一臺服務器上,所以用相對路徑更靈活省事,因為在相對路徑配置下,接口請求會基于當前前端頁面的域名和端口拼接基礎地址。

如果前后端應用需要分開部署在不同的服務器上,配置絕對路徑就好了,如下:
在這里插入圖片描述

3. 打包

前后端分別打包好,將后端的jar包前端的dist目錄上傳到服務器,我這邊的目錄結構如下,一個項目的前后端都放在一個文件夾下,用apiweb目錄區分

└── sa-admin├── api│   ├── Dockerfile│   └── sa-admin-prod-3.0.0.jar└── web│   ├── dist│   ├── Dockerfile│   ├── nginx.conf├── deploy.sh├── docker-compose.yml

4 編寫 Dockerfile 與 docker-compose.yml

后端jar包前端dist的目錄下分別創建一個Dockerfile文件

4.1 后端的Dockerfile

# 使用 OpenJDK 8 作為基礎鏡像
FROM openjdk:8-jdk# VOLUME 指定了臨時文件目錄為/tmp。
# 其效果是在主機 /var/lib/docker 目錄下創建了一個臨時文件,并鏈接到容器的/tmp
VOLUME /tmp#設置時區
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone# 復制jar包到容器內(注意jar包名稱與實際一致)
COPY sa-admin-prod-3.0.0.jar app.jar# 暴露后端服務端口(根據實際項目端口修改)
EXPOSE 9090# 容器啟動時執行的命令
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-jar","/app.jar"]

4.2 前端的Dockerfile

FROM nginx# 刪除nginx默認配置、默認靜態文件
RUN rm -rf /usr/share/nginx/html/*
# 刪除禁用nginx默認配置(為避免沖突,使自定義的sa-admin-web-nginx.conf生效)
RUN mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak# 復制自定義的配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf# 復制前端dist目錄到nginx靜態文件目錄
COPY dist/ /usr/share/nginx/html/# 暴露80端口(nginx默認端口)
EXPOSE 80CMD ["nginx", "-g", "daemon off;"]

4.3 前端的nginx配置文件

server {listen 80;server_name localhost;  # 可替換為實際域名# 前端靜態文件目錄(對應Dockerfile中復制的dist目錄)root /usr/share/nginx/html;index index.html index.htm;# 支持前端路由(history模式),刷新頁面不404location / {try_files $uri $uri/ /index.html;}# 反向代理到后端服務(核心配置)# 假設前端請求后端的API路徑以 /api 開頭(需與前端代碼一致)location /api/ {# 后端容器名+端口(docker內部可直接用服務名訪問,無需映射到宿主機)proxy_pass http://sa-admin-api:9090/api/;  # 注意結尾的斜杠與后端一致# 代理相關的頭信息(解決跨域和后端獲取真實IP等問題)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;}# 跨域配置(如果需要更寬松的跨域規則)add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';add_header Access-Control-Allow-Headers 'Origin, Content-Type, Authorization';}

這一行配置:proxy_pass http://sa-admin-api:9090/api/;
為什么地址寫的是sa-admin-api,看下面的配置說明 (關鍵)

4.4 docker-compose.yml

回到apiweb的根目錄下(項目目錄/sa-admin),創建docker-compose.yml文件:

version: '3.8'  # 兼容主流Docker版本services:# 后端服務sa-admin-api:build:context: ./api  # 后端Dockerfile所在目錄image: sa-admin-api  # 鏡像名container_name: sa-admin-api  # 容器名ports:- "9090:9090"  # 宿主機端口:容器端口(根據后端實際端口調整)restart: unless-stopped  # 異常退出時自動重啟environment:- SPRING_PROFILES_ACTIVE=prod  # 指定環境配置networks:- sa-admin-network  # 加入自定義網絡(前后端可通過服務名通信)volumes:- /docker/sa-admin/log:/home/smart-admin  # 使用命名卷# 前端服務sa-admin-web:build:context: ./web  # 前端Dockerfile所在目錄image: sa-admin-web  # 鏡像名container_name: sa-admin-web  # 容器名ports:- "9091:80"  # 宿主機80端口映射到容器80(可自定義宿主機端口)restart: unless-stoppednetworks:- sa-admin-networkdepends_on:- sa-admin-api  # 確保后端先啟動volumes:- ./web/dist/:/usr/share/nginx/html/# 自定義網絡(避免端口沖突,支持服務名訪問)
networks:sa-admin-network:driver: bridge

4.4.1 配置說明:

networks: 創建docker網絡
網絡連接不通的問題

在docker中,容器的網絡不等于宿主機的網絡。

比如:按正常思維,前后端部署在一臺機器上,前端訪問后端地址配置為http://localhost:9090是肯定可以訪問到的,但在docker中不行。

因為docker容器內的localhost不等于宿主機的localhost,Docker 容器有獨立的網絡命名空間,容器內部的localhost(127.0.0.1)僅指向容器自身,而非宿主機或其他容器。

若前端 Nginx 配置中用localhost:后端端口代理后端服務(例如proxy_pass http://localhost:9090),Nginx 會嘗試訪問當前前端容器內部的 9090端口,但后端服務通常運行在另一個容器或宿主機上,因此會出現 “連接拒絕”。

解決方案

要解決這個問題,就需要將前后端容器處于同一網絡下。分為兩步:

  1. 創建自定義網絡(上面前端nginx配置文件中的sa-admin-api),將前端、后端容器加入同一網絡
  2. 修正 Nginx 代理配置,用后端容器名作為代理目標(同一網絡內可直接訪問):http://sa-admin-api:9090/api/,http后面直接接上后端的容器名

4.5 一鍵部署腳本

docker-compose.yml同目錄下創建deploy.sh文件:

#!/bin/bash# 定義顏色變量,用于美化輸出
GREEN="\033[0;32m"
RED="\033[0;31m"
NC="\033[0m" # 無顏色echo -e "${GREEN}開始部署sa-admin項目...${NC}"# 停止并刪除所有相關容器、網絡,同時刪除關聯鏡像
echo -e "${GREEN}正在停止并清理舊容器和鏡像...${NC}"
docker-compose down --rmi all# 檢查上一條命令是否執行成功
if [ $? -ne 0 ]; thenecho -e "${RED}清理舊容器和鏡像失敗!${NC}"exit 1
fi# 重新構建鏡像并啟動容器
echo -e "${GREEN}正在構建新鏡像并啟動容器...${NC}"
docker-compose up --build -d# 檢查部署是否成功
if [ $? -eq 0 ]; thenecho -e "${GREEN}部署成功!${NC}"echo -e "${GREEN}正在運行的容器:${NC}"docker ps --filter "name=sa-admin"
elseecho -e "${RED}部署失敗!${NC}"exit 1
fi

腳本執行順序說明:

  1. 刪除舊的鏡像、容器
  2. 構建新鏡像
  3. 創建容器并啟動

給腳本添加可執行權限:chmod +x deploy.sh

5. 一鍵部署

進入deploy.sh文件目錄下,執行命令:./deploy.sh

6. 執行效果

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91798.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91798.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91798.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity_數據持久化_XML基礎

Unity數據持久化 三、XML數據持久化 3.1 XML基礎概念 3.1.1 什么是XML XML(eXtensible Markup Language)**是一種可擴展的標記語言,用于存儲和傳輸數據。它具有以下特點: 結構化:數據以層次結構組織可讀性:…

大語言模型的解碼策略:貪婪解碼與波束搜索

在自然語言生成任務(如機器翻譯、文本摘要、圖像描述等)中,語言模型通常會輸出一個詞的概率分布,但模型本身并不會自動告訴你應該選哪些詞作為最終的輸出句子。因此,我們需要設計一個“解碼策略”來從這些概率中生成可…

智慧園區:中小企業的 “減壓閥” 與數字化招商革命

在當前的經濟環境下,中小企業的生存發展面臨著諸多挑戰,其中選址成本儼然成為了創業路上的 “第一道坎”。傳統招商模式中,信息不對稱的問題尤為突出,初創企業常常因此陷入選址失誤的困境。有的企業選在交通不便的地方&#xff0c…

從零開始配置pytorch環境

總結了一下幾篇熱門文章和自己的經驗,方便以后換設備配置環境 一、安裝Anaconda 這一步是為了不污染全局環境,很有必要。 直接清華源鏡像下載:Index of /anaconda/archive/ | 清華大學開源軟件鏡像站 | Tsinghua Open Source Mirror 根據自…

離線錄像文件視頻AI分析解決方案

前言 在安防領域,視頻的價值不言而喻,尤其是錄像文件的價值顯得更是尤為重要。在一個安防項目上視頻錄像一般存儲1個月、3個月甚至更長時間,這就形成了海量的離線錄像文件數據。傳統安防項目對錄像文件的處理還有一定的局限性: 事…

人工智能與金融:金融服務的重塑

1. AI 驅動金融變革:從 “標準化” 到 “智能化”1.1 傳統金融的痛點與 AI 的破局傳統金融行業長期面臨三大瓶頸:服務效率低下:銀行柜臺辦理一筆貸款需 3-5 個工作日,人工審核流程繁瑣,客戶等待時間長;風險…

Qwen大模型關鍵參數解析:緩存與滑動窗口

QwenLLM "use_cache": true Qwen "use_sliding_window": false 在大語言模型(如Qwen系列)的生成配置中,"use_cache": true 和 "use_sliding_window": false 是兩個與模型推理效率和長文本處理相關的重要參數,具體含義如下: 1. …

Flask 框架全面詳解

Flask 是一個輕量級的 Python Web 框架,以其簡潔、靈活和易擴展的特性廣受歡迎。接下來我將從多個維度詳細介紹 Flask 框架。 1. Flask 核心特性 微框架設計 輕量級:核心功能精簡,只包含基本組件可擴展:通過擴展添加所需功能無…

概率 多維隨機變量與分布

一、二維1、二維隨機變量及其分布假設E是隨機試驗,Ω是樣本空間,X、Y是Ω的兩個變量;(X,Y)就叫做二維隨機變量或二維隨機向量。X、Y來自同一個樣本空間。聯合分布函數 F(x,y)P(X≤x,Y≤y),即F(x,y)表示求(x,y)左下方的面積。 F(x,…

Spring AI MCP:解鎖大模型應用開發新姿勢

一、AI 浪潮下的新利器 ——Spring AI MCP 登場在當今數字化時代,人工智能(AI)無疑是最耀眼的技術明星,正以前所未有的速度滲透到各個領域,深刻改變著我們的生活和工作方式。從智能語音助手到圖像識別技術,…

ThinkPHP5x,struts2等框架靶場復現

ThinkphpThinkphp5x遠程命令執行及getshell首先我們先找一個環境,或者自己搭建一個環境fofa:body"ThinkPHP V5"搭建:vulhub/thinkphp/5-rcedocker-compose up -d然后去訪問我們的環境遠程命令執行/?sindex/think\app/invokefuncti…

Hyperliquid:揭秘高性能區塊鏈共識引擎HyperBFT

大家好,今天我們一起探討Hyperliquid這個高性能區塊鏈項目以及它背后的共識引擎。Hyperliquid能在擁擠的去中心化交易賽道(DEX)中脫穎而出,很大程度上要歸功于其高效的共識機制——HyperBFT。 為了徹底搞懂HyperBFT,我…

大模型開發框架LangChain之構建知識庫

1.前言 為了避免 llm正確的廢話和幻覺,知識庫可以說是現在開發 agent的必備了。同時,作為 rag中的 r,知識庫召回的成功率會極大的影響 llm的最終回復效果。一般,會把知識庫召回的內容作為背景知識給到 llm,并在 prompt…

NPM打包時,報reason: getaddrinfo ENOTFOUND registry.nlark.com

先說解決方法:將 package-lock.json 文件中的 registry.nlark.com 改為 registry.npmmirror.com現象:npm ERR! code ENOTFOUND npm ERR! syscall getaddrinfo npm ERR! errno ENOTFOUND npm ERR! network request to https://registry.nlark.com/url-too…

python內置庫os與sys的區別是什么?分別能實現什么功能?

Python 的 os 和 sys 是兩個功能截然不同但都非常重要的內置庫,它們分別服務于不同的交互場景:前者專注于與操作系統交互,后者專注于與 Python 解釋器本身交互。以下是詳細解析: 一、os 庫:操作系統交互接口 os 庫&…

【云計算】云主機的親和性策略(一):快樂旅行團

《云主機的親和性策略》系列,共包含以下文章: 1?? 云主機的親和性策略(一):快樂旅行團2?? 云主機的親和性策略(二):集群節點組3?? 云主機的親和性策略(三&#xf…

USRP捕獲手機/路由器數據傳輸信號波形(下)

目錄: USRP捕獲手機/路由器數據傳輸信號波形(上) USRP捕獲手機/路由器數據傳輸信號波形(中) USRP捕獲手機/路由器數據傳輸信號波形(下) 四、路由器MIMO-OFDM系統 本文深入分析采集手機與路由…

位運算在權限授權中的應用及Vue3實踐

在現代前端應用中,權限管理是一個至關重要的功能模塊。隨著應用復雜度的提示功能,權限細粒度越來越精細,如何高效地管理和判斷權限成為前端開發的一大挑戰。位運算作為一種高效的運算方式,在權限管理領域有著獨特的優勢。本文將詳…

面試實戰,問題二十二,Java JDK 17 有哪些新特性,怎么回答

Java JDK 17 新特性面試回答指南 作為一名Java開發者,了解JDK 17的新特性是面試中的關鍵點。JDK 17(Java SE 17)于2021年9月發布,是一個長期支持(LTS)版本,引入了多項改進以提升開發效率、安全性…

【MySQL安全】什么是SQL注入,怎么避免這種攻擊:前端防護、后端orm框架、數據庫白名單

基本概念SQL注入是OWASP Top 10安全風險之一,它利用了應用程序對用戶輸入數據的不當處理。當應用程序直接將用戶輸入拼接到SQL查詢中而沒有進行適當的過濾或轉義時,就可能發生SQL注入攻擊。攻擊原理假設有一個登錄表單的SQL查詢:SELECT * FRO…