Spring Boot + Vue 项目 ARM64 服务器 Portainer 部署指南

Spring Boot + Vue 项目 ARM64 服务器 Portainer 部署指南

目录


1. 概述

1.1 部署架构说明

本指南适用于将 Spring Boot 后端 + Vue 前端项目部署到 ARM64 架构服务器的场景。部署方案如下:

本地开发机 → 构建 ARM64 镜像 → 导出 tar 包 → Portainer 导入镜像 → 创建容器

1.2 系统组件

  • 后端服务: Spring Boot 应用 (Java)
  • 前端服务: Vue.js + Nginx
  • 数据库: PostgreSQL / MySQL(可选)
  • 缓存服务: Redis(可选)
  • 目标架构: linux/arm64
  • 部署工具: Portainer

1.3 技术要点

  • 使用 Docker Desktop + WSL2 进行本地开发
  • 使用 Docker Buildx 进行跨平台构建
  • 镜像导出为 tar 包离线传输
  • 通过 Portainer Web 界面完成镜像导入和容器部署

2. 本地环境准备

2.1 安装 Docker Desktop

2.1.1 下载 Docker Desktop
  1. 访问 Docker 官网: https://www.docker.com/products/docker-desktop
  2. 下载 Docker Desktop for Windows
  3. 运行安装程序 Docker Desktop Installer.exe
2.1.2 安装 Docker Desktop
# 运行安装程序,建议勾选以下选项:
# ☑ Use WSL 2 instead of Hyper-V (recommended)
# ☑ Add shortcut to desktop

安装完成后,需要重启计算机

2.1.3 安装 WSL 2 (Windows Subsystem for Linux)

重要提示:Docker Desktop 需要 WSL 2 才能正常运行。

方法 1: 自动安装(推荐)

以管理员身份打开 PowerShell,执行:

# 安装 WSL 2 和默认 Linux 发行版(Ubuntu)
wsl --install

# 重启计算机
Restart-Computer

方法 2: 手动安装

如果自动安装失败,请手动执行以下步骤:

# 1. 启用 WSL 功能
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

# 2. 启用虚拟机平台
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

# 3. 重启计算机
Restart-Computer

# 4. 下载并安装 WSL2 Linux 内核更新包
# 访问: https://aka.ms/wsl2kernel
# 下载并安装 wsl_update_x64.msi

# 5. 设置 WSL 2 为默认版本
wsl --set-default-version 2

# 6. 安装 Linux 发行版(Ubuntu)
wsl --install -d Ubuntu
2.1.4 验证安装
# 检查 WSL 版本
wsl --list --verbose
# 应该看到类似输出:
#   NAME      STATE           VERSION
# * Ubuntu    Running         2

# 检查 Docker 版本
docker --version
# 输出: Docker version 24.0.x, build xxxxx

# 检查 Docker 是否正常运行
docker ps
# 如果正常应该显示空列表(无错误)

2.2 配置 Docker Desktop

2.2.1 启动 Docker Desktop
  1. 双击桌面上的 Docker Desktop 图标
  2. 等待 Docker Engine 启动(系统托盘图标变为绿色)
2.2.2 配置 Docker Engine

打开 Docker Desktop → Settings → Docker Engine,建议配置加速镜像:

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://registry.docker-cn.com"
  ],
  "experimental": false
}

点击 Apply & Restart 应用配置。

2.3 启用 Docker Buildx

Docker Buildx 是 Docker 的多平台构建工具,支持交叉编译到 ARM64 架构。

# 检查 Buildx 是否可用
docker buildx version
# 输出: github.com/docker/buildx v0.x.x

# 创建并启用新的构建器实例
docker buildx create --name multiarch-builder --use

# 启动构建器
docker buildx inspect --bootstrap

# 查看支持的平台
docker buildx inspect multiarch-builder

预期输出应包含:

Name:   multiarch-builder
Driver: docker-container

Nodes:
Name:      multiarch-builder0
Endpoint:  npipe:////./pipe/docker_engine
Status:    running
Platforms: linux/amd64*, linux/arm64, linux/arm/v7, ...

确认支持 linux/arm64 平台,这是部署到 ARM64 服务器的关键。

2.4 其他开发工具(可选)

  • Git for Windows: 版本控制工具
  • VS Code: 代码编辑器(推荐安装 Docker 插件)
  • PowerShell 7: 现代化的命令行工具
  • Windows Terminal: 更好的终端体验

2.5 登录镜像仓库(重要!)

为什么需要登录镜像仓库

在构建 Docker 镜像时,Dockerfile 中的 FROM 指令需要从镜像仓库拉取基础镜像,例如:

  • Maven 构建镜像: maven:3.9.6-eclipse-temurin-11
  • Node.js 构建镜像: node:18-alpine
  • JRE 运行镜像: eclipse-temurin:11-jre
  • Nginx 镜像: nginx:1.25-alpine

这些镜像默认从 Docker Hub 拉取。在以下情况下需要登录:

  1. Docker Hub 匿名限额:未登录用户有拉取次数限制
  2. 网络速度慢:国内访问 Docker Hub 可能较慢,需要使用阿里云等国内镜像加速
  3. 私有镜像:如果使用私有镜像仓库
2.5.1 选项 1:登录 Docker Hub(推荐)

注册 Docker Hub 账号

  1. 访问 https://hub.docker.com/
  2. 点击 “Sign Up” 注册免费账号
  3. 验证邮箱并激活账号

登录命令

# 登录 Docker Hub
docker login

# 输入提示:
Username: <您的Docker Hub用户名>
Password: <您的密码>

# 成功登录后显示:
Login Succeeded

验证登录状态

# 查看登录信息
cat ~\.docker\config.json
# 应该看到 "auths" 中包含 "https://index.docker.io/v1/"
2.5.2 选项 2:使用阿里云镜像加速

为什么使用阿里云镜像

  • 国内访问速度快
  • 无需注册即可使用(公共镜像)
  • 支持 Docker Hub 的大部分镜像

配置阿里云镜像加速

  1. 打开 Docker Desktop
  2. 点击 Settings → Docker Engine
  3. 修改配置(已在 2.2.2 节中配置):
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://registry.docker-cn.com",
    "https://mirror.ccs.tencentyun.com"
  ]
}
  1. 点击 Apply & Restart

注意:配置镜像加速后,仍然建议登录 Docker Hub,以解除匿名拉取限制。

2.5.3 选项 3:登录阿里云容器镜像服务

注册阿里云账号

  1. 访问 https://cr.console.aliyun.com/
  2. 注册/登录阿里云账号
  3. 开通容器镜像服务
  4. 设置镜像仓库密码(不同于阿里云登录密码)

登录命令

# 登录阿里云杭州区域镜像仓库
docker login --username=<您的阿里云账号> registry.cn-hangzhou.aliyuncs.com

# 输入密码(镜像仓库密码,不是阿里云登录密码)
Password: <镜像仓库密码>

# 成功登录后显示:
Login Succeeded

其他区域镜像仓库

  • 上海:registry.cn-shanghai.aliyuncs.com
  • 北京:registry.cn-beijing.aliyuncs.com
  • 深圳:registry.cn-shenzhen.aliyuncs.com
2.5.4 预先拉取基础镜像(可选)

为了确保构建顺利,可以预先拉取所需的基础镜像:

# 拉取 ARM64 架构的基础镜像

# Maven 构建镜像
docker pull --platform linux/arm64 maven:3.9.6-eclipse-temurin-11

# JRE 运行镜像
docker pull --platform linux/arm64 eclipse-temurin:11-jre

# Node.js 构建镜像
docker pull --platform linux/arm64 node:18-alpine

# Nginx 镜像
docker pull --platform linux/arm64 nginx:1.25-alpine

# Redis 镜像(如果需要)
docker pull --platform linux/arm64 redis:7-alpine

# 查看已拉取的镜像
docker images

说明

  • --platform linux/arm64 参数确保拉取 ARM64 架构的镜像
  • 预先拉取可以加快后续构建速度
  • 如果网络不稳定,建议预先拉取
2.5.5 常见问题

问题 1:拉取镜像速度慢

解决方案:

# 1. 配置阿里云镜像加速(见 2.2.2 节)
# 2. 或使用代理

问题 2:Docker Hub 限额提示

Error response from daemon: toomanyrequests: You have reached your pull rate limit.

解决方案:

# 登录 Docker Hub
docker login
# 或使用阿里云镜像加速

问题 3:无法拉取 ARM64 镜像

no matching manifest for linux/arm64

解决方案:

  • 检查镜像是否支持 ARM64 架构
  • 使用支持多架构的镜像标签(如 alpine 标签通常支持)

3. 编写 Dockerfile

3.1 后端 Dockerfile 示例(Spring Boot)

在项目根目录创建 Dockerfile

# 多阶段构建 - 第一阶段:构建
FROM maven:3.9.6-eclipse-temurin-11 AS build

WORKDIR /app

# 复制 pom.xml 并下载依赖(利用 Docker 缓存)
COPY pom.xml .
COPY */pom.xml ./
RUN mvn dependency:go-offline -B

# 复制源代码并构建
COPY . .
RUN mvn clean package -DskipTests

# 多阶段构建 - 第二阶段:运行
FROM eclipse-temurin:11-jre

WORKDIR /app

# 创建非 root 用户
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 复制构建产物
COPY --from=build /app/target/*.jar app.jar

# 如果有系统级依赖(如 GaussDB 驱动)
COPY --from=build /app/lib /app/lib

# 设置文件所有者
RUN chown -R appuser:appuser /app

USER appuser

EXPOSE 8080

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

说明

  • 使用多阶段构建减小镜像体积
  • Maven 构建阶段利用 Docker 层缓存优化构建速度
  • 运行阶段仅包含 JRE 和 jar 包

3.2 前端 Dockerfile 示例(Vue + Nginx)

front/ 目录下创建 Dockerfile

# 多阶段构建 - 第一阶段:构建
FROM node:18-alpine AS build

WORKDIR /app

# 复制 package.json 并安装依赖
COPY package*.json ./
RUN npm install

# 复制源代码并构建
COPY . .
RUN npm run build

# 多阶段构建 - 第二阶段:Nginx 提供静态文件
FROM nginx:1.25-alpine

# 复制构建产物到 Nginx 目录
COPY --from=build /app/dist /usr/share/nginx/html

# 复制 Nginx 配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

3.3 前端 Nginx 配置示例

front/ 目录下创建 nginx.conf

server {
    listen 80;
    server_name localhost;
    
    # 静态文件目录
    root /usr/share/nginx/html;
    index index.html;
    
    # Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json;
    
    # SPA 路由配置
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # API 代理(将前端 API 请求代理到后端)
    location /api/ {
        proxy_pass http://backend:8080;
        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;
    }
    
    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

重要说明

  • proxy_pass http://backend:8080; 中的 backend 是后端容器名称
  • 如果前后端分离部署,需要将后端容器名改为实际名称

3.4 项目结构示例

project/
├── Dockerfile                 # 后端 Dockerfile
├── pom.xml                    # Maven 配置
├── src/                       # 后端源代码
├── front/
│   ├── Dockerfile             # 前端 Dockerfile
│   ├── nginx.conf             # Nginx 配置
│   ├── package.json
│   ├── src/                   # 前端源代码
│   └── dist/                  # 构建产物(构建后生成)
└── docker-compose.yml         # (可选)Docker Compose 配置

4. 本地构建与打包镜像

4.1 构建前的测试(重要!)

在构建 Docker 镜像之前,必须先在本地测试项目构建,确保构建成功。

4.1.1 后端项目测试
# 进入项目目录
cd C:\your-project

# Maven 清理并构建(跳过测试)
mvn clean package -DskipTests

# 检查构建产物
dir target\*.jar
# 应该看到 xxx-1.0.0.jar 文件

# (可选)运行测试
mvn test

常见错误处理

  • 如果构建失败,检查 pom.xml 配置
  • 如果依赖下载失败,检查 Maven 镜像源配置
  • 确保 JDK 版本与项目要求一致
4.1.2 前端项目测试
# 进入前端目录
cd front

# 安装依赖
npm install

# 构建项目
npm run build

# 检查构建产物
dir dist
# 应该看到 index.html 和其他静态资源

常见错误处理

  • 如果 npm install 失败,尝试清理缓存:npm cache clean --force
  • 检查 Node.js 版本是否符合要求
  • 确保 .env 文件配置正确

4.2 构建 ARM64 镜像

4.2.1 设置镜像名称和版本
# 设置变量
$PROJECT_NAME = "myproject"        # 项目名称
$VERSION = "1.0.0"                 # 版本号

# 镜像名称
$BACKEND_IMAGE = "${PROJECT_NAME}-backend"
$FRONTEND_IMAGE = "${PROJECT_NAME}-frontend"
4.2.2 构建后端镜像
# 返回项目根目录
cd C:\your-project

# 构建 ARM64 后端镜像(注意:不使用 --push,而是 --load)
docker buildx build `
  --platform linux/arm64 `
  --tag ${BACKEND_IMAGE}:${VERSION} `
  --tag ${BACKEND_IMAGE}:latest `
  --file Dockerfile `
  --load `
  .

重要参数说明

  • --platform linux/arm64:指定目标平台为 ARM64
  • --tag:为镜像打标签
  • --load:将构建的镜像加载到本地 Docker(不推送到仓库)
  • .:构建上下文为当前目录

注意:如果构建过程中出现错误,检查是否是 Dockerfile 路径或依赖问题。

4.2.3 构建前端镜像
# 构建 ARM64 前端镜像
docker buildx build `
  --platform linux/arm64 `
  --tag ${FRONTEND_IMAGE}:${VERSION} `
  --tag ${FRONTEND_IMAGE}:latest `
  --file front/Dockerfile `
  --load `
  front/

说明

  • 构建上下文为 front/ 目录
  • Dockerfile 路径为 front/Dockerfile

4.3 验证镜像构建

# 查看本地镜像列表
docker images | Select-String "${PROJECT_NAME}"

# 应该看到类似输出:
# myproject-backend    1.0.0    xxxxx    2 minutes ago    500MB
# myproject-backend    latest   xxxxx    2 minutes ago    500MB
# myproject-frontend   1.0.0    xxxxx    1 minute ago     50MB
# myproject-frontend   latest   xxxxx    1 minute ago     50MB

4.4 导出镜像为 tar 包

这是关键步骤:将构建好的镜像导出为 tar 文件,用于上传到 Portainer。

4.4.1 创建导出目录
# 创建目录存放 tar 包
mkdir -Force C:\docker-images
4.4.2 导出后端镜像
# 导出后端镜像
docker save -o C:\docker-images\${PROJECT_NAME}-backend-${VERSION}.tar ${BACKEND_IMAGE}:${VERSION}

# 检查文件是否生成
dir C:\docker-images\*.tar
4.4.3 导出前端镜像
# 导出前端镜像
docker save -o C:\docker-images\${PROJECT_NAME}-frontend-${VERSION}.tar ${FRONTEND_IMAGE}:${VERSION}

命令说明

  • docker save:导出镜像为 tar 文件
  • -o:指定输出文件路径
  • 最后的参数是镜像名称和标签
4.4.4 查看 tar 包大小
# 查看文件信息
Get-ChildItem C:\docker-images\*.tar | Select-Object Name, @{Name="SizeMB";Expression={[math]::Round($_.Length/1MB,2)}}

# 输出示例:
# Name                                    SizeMB
# ----                                    ------
# myproject-backend-1.0.0.tar             485.23
# myproject-frontend-1.0.0.tar             48.56

4.5 一键构建脚本(推荐)

创建一个 PowerShell 脚本 build-images.ps1 实现自动化构建:

# build-images.ps1
param(
    [string]$ProjectName = "myproject",
    [string]$Version = "1.0.0",
    [string]$OutputDir = "C:\docker-images"
)

$ErrorActionPreference = "Stop"

Write-Host "======================================" -ForegroundColor Cyan
Write-Host "开始构建 Docker 镜像" -ForegroundColor Cyan
Write-Host "项目名称: $ProjectName" -ForegroundColor Yellow
Write-Host "版本号: $Version" -ForegroundColor Yellow
Write-Host "======================================" -ForegroundColor Cyan

# 1. 测试后端构建
Write-Host "`n[1/6] 测试后端项目构建..." -ForegroundColor Green
mvn clean package -DskipTests
if ($LASTEXITCODE -ne 0) { throw "后端项目构建失败" }

# 2. 测试前端构建
Write-Host "`n[2/6] 测试前端项目构建..." -ForegroundColor Green
Set-Location front
npm run build
if ($LASTEXITCODE -ne 0) { throw "前端项目构建失败" }
Set-Location ..

# 3. 构建后端镜像
Write-Host "`n[3/6] 构建后端 Docker 镜像..." -ForegroundColor Green
$BackendImage = "$ProjectName-backend"
docker buildx build --platform linux/arm64 --tag ${BackendImage}:${Version} --tag ${BackendImage}:latest --load .
if ($LASTEXITCODE -ne 0) { throw "后端镜像构建失败" }

# 4. 构建前端镜像
Write-Host "`n[4/6] 构建前端 Docker 镜像..." -ForegroundColor Green
$FrontendImage = "$ProjectName-frontend"
docker buildx build --platform linux/arm64 --tag ${FrontendImage}:${Version} --tag ${FrontendImage}:latest --file front/Dockerfile --load front/
if ($LASTEXITCODE -ne 0) { throw "前端镜像构建失败" }

# 5. 创建输出目录
Write-Host "`n[5/6] 导出镜像为 tar 包..." -ForegroundColor Green
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null

# 6. 导出镜像
Write-Host "导出后端镜像..." -ForegroundColor Yellow
docker save -o "$OutputDir\$ProjectName-backend-$Version.tar" ${BackendImage}:${Version}

Write-Host "导出前端镜像..." -ForegroundColor Yellow
docker save -o "$OutputDir\$ProjectName-frontend-$Version.tar" ${FrontendImage}:${Version}

Write-Host "`n[6/6] 验证输出文件..." -ForegroundColor Green
$Files = Get-ChildItem "$OutputDir\*.tar" | Select-Object Name, @{Name="SizeMB";Expression={[math]::Round($_.Length/1MB,2)}}
$Files | Format-Table -AutoSize

Write-Host "`n======================================" -ForegroundColor Cyan
Write-Host "构建完成!" -ForegroundColor Green
Write-Host "输出目录: $OutputDir" -ForegroundColor Yellow
Write-Host "======================================" -ForegroundColor Cyan

使用方法

# 默认参数
.\build-images.ps1

# 自定义参数
.\build-images.ps1 -ProjectName "myapp" -Version "2.0.0" -OutputDir "D:\images"

5. Portainer 镜像导入

5.1.1 打开 Portainer 管理界面
  1. 打开浏览器,访问 Portainer 地址:

    • HTTP: http://<服务器IP>:9000
    • HTTPS: https://<服务器IP>:9443
  2. 使用管理员账号登录

  3. 选择目标 Docker 环境(通常为 “local” 或远程服务器名称)

5.2 导入后端镜像

5.2.1 进入 Images 页面
  1. 点击左侧菜单 Images(镜像)
  2. 点击 Import 按钮(导入)

在这里插入图片描述

5.2.2 上传 tar 文件
  1. 点击 Select file 按钮
  2. 浏览并选择后端 tar 文件:myproject-backend-1.0.0.tar
  3. (多节点环境)选择目标节点(Deployment)

支持的文件格式.tar.tar.gz.tar.bz2.tar.xz

5.2.3 配置镜像标签

方式 1:基本模式(推荐)

直接使用镜像原有标签,不需额外配置。

方式 2:高级模式

如果需要重新命名镜像:

  1. 点击 Advanced mode 切换到高级模式
  2. 输入镜像名称和标签:
    • Image name: myproject-backend
    • Tag: 1.0.0
      在这里插入图片描述

示例

Image: myproject-backend:1.0.0
5.2.4 上传镜像

在这里插入图片描述

  1. 点击 Upload 按钮开始上传
  2. 等待上传完成(根据文件大小和网络速度,可能需要几分钟)
  3. 上传成功后,会显示成功消息

注意

  • 大型镜像(>500MB)上传可能较慢,请耐心等待
  • 确保网络连接稳定,避免上传中断

5.3 导入前端镜像

重复上述步骤,导入前端镜像:

  1. 点击 ImagesImport
  2. 选择 myproject-frontend-1.0.0.tar
  3. (可选)配置镜像标签:myproject-frontend:1.0.0
  4. 点击 Upload 上传

5.4 验证镜像导入

5.4.1 查看镜像列表
  1. Images 页面查看镜像列表

  2. 应该能看到刚才导入的两个镜像:

    • myproject-backend:1.0.0
    • myproject-frontend:1.0.0
  3. 检查镜像信息:

    • Size:镜像大小
    • Created:创建时间
    • Architecture:应该显示 arm64
5.4.2 查看镜像详情
  1. 点击镜像名称进入详情页
  2. 查看 Layers(层)信息
  3. 查看 Environment variables(环境变量)
  4. 确认镜像架构为 linux/arm64

5.5 导入其他基础镜像(可选)

如果服务器无法访问公网,需要预先导入 Redis 等基础镜像:

6. Portainer 容器部署

6.1 创建 Docker 网络

为什么需要自定义网络

  • 允许容器间通过容器名称相互访问
  • 前端可以通过容器名访问后端(如 http://backend:8080
  • 提供网络隔离和安全性
6.1.1 创建网络步骤

在这里插入图片描述
在这里插入图片描述

  1. 点击左侧菜单 Networks(网络)
  2. 点击 Add network(添加网络)
  3. 填写配置:
    • Name: myproject-network(网络名称)
    • Driver: bridge(默认)
    • IPv4 Subnet: (可选)留空使用默认
    • IPv4 Gateway: (可选)留空使用默认
  4. 点击 Create the network(创建网络)

6.2 创建数据卷

为什么需要数据卷

  • 数据持久化:即使删除容器,数据也不会丢失
  • 常用于数据库、日志文件等需要持久化的数据
6.2.1 创建 Redis 数据卷(示例)

在这里插入图片描述
在这里插入图片描述

  1. 点击左侧菜单 Volumes(数据卷)
  2. 点击 Add volume(添加数据卷)
  3. 填写配置:
    • Name: redis_data
    • Driver: local
  4. 点击 Create the volume(创建数据卷)
6.2.2 创建后端日志数据卷(可选)

重复上述步骤,创建:

  • Name: backend_logs

6.3 部署 Redis 容器(可选)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 点击左侧菜单 "Containers" (容器)
2. 点击 "Add container" (添加容器)
3. 配置容器:
   - **Name**: `myproject-redis`
   - **Image**: `redis:7-alpine`
   - **Command**: `redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru`
   - **Ports**:
     - **Host**: `6379`
     - **Container**: `6379`
   - **Volumes**:
     - **Container**: `/data`
     - **Volume**: `redis_data`
   - **Networks**:
     - **Network**: `myproject-network`
   - **Restart policy**:
     - **Restart policy**: `Unless stopped`
4. 点击 **Deploy the container**(部署容器)

基本设置:
- Name: decoction-redis
- Image: redis:7-alpine

网络端口:
- 点击 "publish a new network port"
- host: 6379
- container: 6379

高级设置 - Command & logging:
- Command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru

高级设置 - Volumes:
- 点击 "map additional volume"
- container: /data
- volume: redis_data

高级设置 - Network:
- Network: decoction-network

高级设置 - Restart policy:
- Restart policy: Unless stopped

4. 点击 "Deploy the container" (部署容器)
5. 等待容器启动完成 (状态显示为 running)

5.6 部署后端容器

1. 点击 "Add container" (添加容器)
2. 配置容器:

基本设置:
- Name: decoction-backend
- Image: your-registry/decoction-backend:1.0.0
- Registry: 选择之前配置的私有仓库 (如果使用)

网络端口:
- 点击 "publish a new network port"
- host: 8080
- container: 8080

高级设置 - Env (环境变量):
点击 "add environment variable" 添加以下变量:
- SPRING_PROFILES_ACTIVE = dev
- SPRING_REDIS_HOST = decoction-redis
- SPRING_REDIS_PORT = 6379
- JAVA_OPTS = -Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom

高级设置 - Network:
- Network: decoction-network

高级设置 - Restart policy:
- Restart policy: Unless stopped

高级设置 - Runtime & Resources (可选):
- Memory limit: 1024 MB
- CPU limit: 1.0

3. 点击 "Deploy the container" (部署容器)
4. 等待容器启动完成 (约 30-60 秒)

5.7 部署前端容器

1. 点击 "Add container" (添加容器)
2. 配置容器:

基本设置:
- Name: decoction-frontend
- Image: your-registry/decoction-frontend:1.0.0
- Registry: 选择之前配置的私有仓库 (如果使用)

网络端口:
- 点击 "publish a new network port"
- host: 80
- container: 80

高级设置 - Network:
- Network: decoction-network

高级设置 - Restart policy:
- Restart policy: Unless stopped

3. 点击 "Deploy the container" (部署容器)
4. 等待容器启动完成

5.8 使用 Docker Compose Stack 部署 (推荐)

Portainer 支持使用 Docker Compose 格式的 Stack 进行批量部署,这是更高效的方式。

5.8.1 创建 Stack
1. 点击左侧菜单 "Stacks" (堆栈)
2. 点击 "Add stack" (添加堆栈)
3. 配置堆栈:
   - Name: decoction-system
   - Build method: Web editor
5.8.2 编写 Stack 配置

在这里插入图片描述

在 Web editor 中粘贴以下内容 (根据实际情况修改镜像地址):

version: '3.8'

services:
  backend:
    image: your-registry/decoction-backend:1.0.0
    container_name: decoction-backend
    environment:
      SPRING_PROFILES_ACTIVE: dev
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PORT: 6379
      JAVA_OPTS: "-Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom"
    ports:
      - "8080:8080"
    depends_on:
      - redis
    restart: unless-stopped
    networks:
      - decoction-network
    deploy:
      resources:
        limits:
          memory: 1024M
          cpus: '1.0'

  frontend:
    image: your-registry/decoction-frontend:1.0.0
    container_name: decoction-frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    restart: unless-stopped
    networks:
      - decoction-network
    deploy:
      resources:
        limits:
          memory: 256M
          cpus: '0.5'

  redis:
    image: redis:7-alpine
    container_name: decoction-redis
    command: ["redis-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - decoction-network
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'

networks:
  decoction-network:
    driver: bridge

volumes:
  redis_data:
    driver: local
5.8.3 配置环境变量 (可选)

如果需要使用环境变量,可以在 “Environment variables” 部分添加:

IMAGE_PREFIX=your-registry
VERSION=1.0.0

然后在 Stack 配置中使用:

services:
  backend:
    image: ${IMAGE_PREFIX}/decoction-backend:${VERSION}
5.8.4 部署 Stack
1. 检查配置无误后,点击 "Deploy the stack" (部署堆栈)
2. 等待所有容器启动完成
3. 在 Stack 详情页面可以看到所有服务的状态

5.9 配置私有仓库认证 (Stack 方式)

如果使用私有镜像仓库,需要额外配置:

1. 在 Stack 编辑页面,展开 "Advanced mode"
2. 启用 "Use registry authentication"
3. 选择之前配置的 Registry

6. 验证与测试

6.1 检查容器状态

在 Portainer 中检查:

1. 进入 "Containers" 页面
2. 确认以下容器状态为 "running":
   - decoction-backend
   - decoction-frontend
   - decoction-redis
3. 检查容器的 "Uptime" (运行时间)

6.2 查看容器日志

在这里插入图片描述

1. 点击容器名称进入详情页
2. 点击 "Logs" 标签
3. 检查日志输出:

后端日志应包含:
- Started DecoctionAdminApplication in xxx seconds
- Tomcat started on port(s): 8080

前端日志应包含:
- Nginx 启动信息

Redis 日志应包含:
- Ready to accept connections

6.3 测试服务可用性

方法 1: 在 Portainer 中执行命令
1. 进入后端容器详情页
2. 点击 "Console" 标签
3. 点击 "Connect" 连接到容器
4. 执行测试命令:

# 测试后端健康检查
wget -qO- http://localhost:8080/actuator/health

# 测试 Redis 连接
ping decoction-redis
方法 2: 使用浏览器访问
1. 访问前端页面:
   http://your-server-ip

2. 访问后端 API:
   http://your-server-ip:8080/actuator/health

3. 访问 API 文档:
   http://your-server-ip:8080/doc.html

6.4 检查容器资源使用

1. 在 Portainer 主页查看 "Container stats"
2. 或进入容器详情页查看 "Stats" 标签
3. 监控:
   - CPU 使用率
   - 内存使用量
   - 网络流量

6.5 测试容器间网络连通性

1. 进入后端容器 Console
2. 测试 Redis 连接:

# 安装网络工具 (如果需要)
apt-get update && apt-get install -y iputils-ping curl

# Ping Redis 容器
ping decoction-redis

# 测试 Redis 端口
curl -v telnet://decoction-redis:6379

7. 故障排除

7.1 镜像拉取失败

问题: 容器创建时提示 “Failed to pull image”

解决方案:

1. 检查镜像名称是否正确
2. 确认镜像已成功推送到仓库
3. 验证 Portainer 中的 Registry 配置
4. 检查服务器网络连接

测试镜像可访问性:
- 在本地执行: docker pull your-registry/decoction-backend:1.0.0
- 检查是否能成功拉取

7.2 容器启动失败

问题: 容器状态显示 “Exited” 或不断重启

解决方案:

1. 查看容器日志:
   - 在 Portainer 中进入容器详情
   - 查看 Logs 标签
   - 查找错误信息

2. 常见错误:
   
   错误: "Cannot connect to Redis"
   解决: 检查 Redis 容器是否运行,网络配置是否正确
   
   错误: "Port 8080 already in use"
   解决: 修改主机端口映射
   
   错误: "Out of memory"
   解决: 增加容器内存限制或调整 JAVA_OPTS

7.3 网络连接问题

问题: 容器间无法通信

解决方案:

1. 确认所有容器都连接到同一网络 (decoction-network)
2. 检查网络配置:
   - 进入 "Networks" 页面
   - 点击 decoction-network
   - 查看 "Connected containers"
3. 重新连接容器到网络:
   - 进入容器详情
   - 点击 "Duplicate/Edit"
   - 修改 Network 设置
   - 重新部署

7.4 数据持久化问题

问题: Redis 数据丢失

解决方案:

1. 检查数据卷是否正确挂载:
   - 进入 Redis 容器详情
   - 查看 "Volumes" 标签
   - 确认 /data 已挂载到 redis_data

2. 验证数据持久化:
   - 进入 Redis 容器 Console
   - 执行: ls -la /data
   - 应该看到 appendonly.aof 文件

3. 备份数据卷:
   - 进入 "Volumes" 页面
   - 选择 redis_data
   - 使用 "Browse" 功能查看数据

7.5 性能问题

问题: 应用响应缓慢

解决方案:

1. 检查资源使用情况:
   - 查看容器 Stats
   - 确认 CPU 和内存是否充足

2. 调整资源限制:
   - 编辑容器配置
   - 增加 Memory limit 和 CPU limit

3. 优化 JVM 参数:
   - 修改 JAVA_OPTS 环境变量
   - 推荐配置: -Xms512m -Xmx1024m -XX:+UseG1GC

4. 检查日志大小:
   - 日志过大可能影响性能
   - 配置日志轮转

7.6 更新镜像

问题: 需要更新应用版本

解决方案:

方法 1: 通过 Portainer 更新
1. 构建并推送新版本镜像到仓库
2. 在 Portainer 中进入容器详情
3. 点击 "Recreate" 按钮
4. 启用 "Pull latest image" 选项
5. 点击 "Recreate" 确认
方法 2: 通过 Stack 更新
1. 进入 "Stacks" 页面
2. 点击 stack 名称
3. 点击 "Editor" 标签
4. 修改镜像版本号
5. 点击 "Update the stack"
6. 启用 "Re-pull image and redeploy"
7. 点击 "Update" 确认

7.7 回滚操作

问题: 新版本有问题,需要回滚

解决方案:

1. 停止当前容器:
   - 选择容器
   - 点击 "Stop"

2. 修改镜像版本:
   - 点击 "Duplicate/Edit"
   - 修改 Image 为旧版本
   - 例如: your-registry/decoction-backend:1.0.0

3. 重新部署:
   - 点击 "Deploy the container"

7.8 完全重置

问题: 需要完全重新部署

解决方案:

1. 删除 Stack (如果使用):
   - 进入 "Stacks" 页面
   - 选择 stack
   - 点击 "Delete this stack"

2. 或删除所有容器:
   - 进入 "Containers" 页面
   - 选择所有相关容器
   - 点击 "Remove"

3. 清理数据卷 (可选):
   - 进入 "Volumes" 页面
   - 选择 redis_data
   - 点击 "Remove"

4. 重新按照部署步骤操作

8. 生产环境配置建议

8.1 环境变量配置

生产环境建议配置:

environment:
  # Spring 配置
  SPRING_PROFILES_ACTIVE: prod
  
  # 数据库配置 (使用外部数据库)
  SPRING_DATASOURCE_URL: jdbc:postgresql://db-host:5432/decoction_db
  SPRING_DATASOURCE_USERNAME: prod_user
  SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}  # 使用 Portainer 的环境变量
  
  # Redis 配置
  SPRING_REDIS_HOST: decoction-redis
  SPRING_REDIS_PORT: 6379
  SPRING_REDIS_PASSWORD: ${REDIS_PASSWORD}
  
  # JVM 配置
  JAVA_OPTS: "-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/logs"
  
  # 日志配置
  LOGGING_LEVEL_ROOT: INFO
  LOGGING_LEVEL_COM_PROJECT: INFO

8.2 资源限制

deploy:
  resources:
    limits:
      memory: 1024M      # 最大内存
      cpus: '1.0'        # 最大 CPU
    reservations:
      memory: 512M       # 预留内存
      cpus: '0.5'        # 预留 CPU

8.3 健康检查

在 Portainer 中配置健康检查:

进入容器 "Duplicate/Edit" 页面
展开 "Advanced container settings"
找到 "Healthcheck" 部分

配置:
- Test command: CMD-SHELL wget -qO- http://localhost:8080/actuator/health || exit 1
- Interval: 30s
- Timeout: 10s
- Retries: 3
- Start period: 60s

8.4 日志管理

配置日志驱动:

logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

8.5 安全建议

  1. 使用私有镜像仓库
  2. 配置防火墙规则,仅开放必要端口
  3. 使用环境变量管理敏感信息
  4. 定期更新基础镜像
  5. 启用 Portainer 的 RBAC 权限控制

9. 备份与恢复

9.1 备份数据卷

1. 进入 "Volumes" 页面
2. 选择 redis_data
3. 点击 "Browse" 查看数据
4. 使用 Portainer 的文件管理功能下载数据

9.2 导出容器配置

1. 进入容器详情页
2. 点击 "Inspect" 标签
3. 复制 JSON 配置保存

9.3 导出 Stack 配置

1. 进入 "Stacks" 页面
2. 点击 stack 名称
3. 点击 "Editor" 标签
4. 复制 YAML 配置保存

10. 监控与维护

10.1 日常监控检查项

  • 容器运行状态 (所有容器应为 running)
  • CPU 使用率 (应低于 80%)
  • 内存使用率 (应低于 80%)
  • 磁盘空间 (应有足够剩余空间)
  • 日志大小 (定期清理)
  • 应用响应时间

10.2 定期维护任务

每周:

  • 检查容器日志是否有异常
  • 检查资源使用趋势
  • 备份重要数据

每月:

  • 更新基础镜像 (redis, nginx 等)
  • 清理未使用的镜像和容器
  • 检查安全更新

每季度:

  • 审查资源配置是否合理
  • 优化性能瓶颈
  • 更新依赖版本

11. 快速参考

11.1 镜像构建命令速查

# 构建 ARM64 后端镜像
docker buildx build --platform linux/arm64 -t your-registry/decoction-backend:1.0.0 --push .

# 构建 ARM64 前端镜像
docker buildx build --platform linux/arm64 -t your-registry/decoction-frontend:1.0.0 --push front/

# 构建多架构镜像
docker buildx build --platform linux/amd64,linux/arm64 -t your-registry/decoction-backend:1.0.0 --push .

# 查看镜像信息
docker buildx imagetools inspect your-registry/decoction-backend:1.0.0

11.2 Portainer 操作速查

操作路径
添加容器Containers → Add container
创建网络Networks → Add network
创建数据卷Volumes → Add volume
部署 StackStacks → Add stack
配置仓库Registries → Add registry
查看日志容器详情 → Logs
进入终端容器详情 → Console
查看统计容器详情 → Stats

11.3 常用端口

服务端口说明
前端80Web 界面
后端8080API 接口
Redis6379缓存服务
Portainer9443管理界面 (HTTPS)
Portainer9000管理界面 (HTTP)

11.4 环境变量速查

变量名说明示例值
SPRING_PROFILES_ACTIVESpring 配置文件dev / prod
SPRING_REDIS_HOSTRedis 主机decoction-redis
SPRING_DATASOURCE_URL数据库连接jdbc:postgresql://host:5432/db
JAVA_OPTSJVM 参数-Xms512m -Xmx1024m

12. 附录

12.1 完整部署 Stack 模板

version: '3.8'

services:
  backend:
    image: ${IMAGE_PREFIX}/decoction-backend:${VERSION:-latest}
    container_name: decoction-backend
    environment:
      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILE:-dev}
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PORT: 6379
      SPRING_DATASOURCE_URL: ${DB_URL}
      SPRING_DATASOURCE_USERNAME: ${DB_USER}
      SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
      JAVA_OPTS: "-Xms${JAVA_MIN_MEM:-512m} -Xmx${JAVA_MAX_MEM:-1024m} -XX:+UseG1GC"
    ports:
      - "${BACKEND_PORT:-8080}:8080"
    depends_on:
      - redis
    restart: unless-stopped
    networks:
      - decoction-network
    volumes:
      - backend_logs:/app/logs
    deploy:
      resources:
        limits:
          memory: ${BACKEND_MEM_LIMIT:-1024M}
          cpus: ${BACKEND_CPU_LIMIT:-1.0}
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8080/actuator/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  frontend:
    image: ${IMAGE_PREFIX}/decoction-frontend:${VERSION:-latest}
    container_name: decoction-frontend
    ports:
      - "${FRONTEND_PORT:-80}:80"
    depends_on:
      - backend
    restart: unless-stopped
    networks:
      - decoction-network
    deploy:
      resources:
        limits:
          memory: ${FRONTEND_MEM_LIMIT:-256M}
          cpus: ${FRONTEND_CPU_LIMIT:-0.5}
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "3"

  redis:
    image: redis:7-alpine
    container_name: decoction-redis
    command: 
      - redis-server
      - --appendonly yes
      - --maxmemory ${REDIS_MAX_MEM:-256mb}
      - --maxmemory-policy allkeys-lru
    ports:
      - "${REDIS_PORT:-6379}:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - decoction-network
    deploy:
      resources:
        limits:
          memory: ${REDIS_MEM_LIMIT:-512M}
          cpus: ${REDIS_CPU_LIMIT:-0.5}
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
        max-file: "3"

networks:
  decoction-network:
    driver: bridge

volumes:
  redis_data:
    driver: local
  backend_logs:
    driver: local

12.2 环境变量配置示例

在 Portainer Stack 部署时,可以配置以下环境变量:

# 镜像配置
IMAGE_PREFIX=registry.cn-hangzhou.aliyuncs.com/myapp
VERSION=1.0.0

# 环境配置
SPRING_PROFILE=prod

# 数据库配置
DB_URL=jdbc:postgresql://your-db-host:5432/decoction_db
DB_USER=decoction_user
DB_PASSWORD=your-secure-password

# 端口配置
BACKEND_PORT=8080
FRONTEND_PORT=80
REDIS_PORT=6379

# JVM 配置
JAVA_MIN_MEM=512m
JAVA_MAX_MEM=1024m

# 资源限制
BACKEND_MEM_LIMIT=1024M
BACKEND_CPU_LIMIT=1.0
FRONTEND_MEM_LIMIT=256M
FRONTEND_CPU_LIMIT=0.5
REDIS_MEM_LIMIT=512M
REDIS_CPU_LIMIT=0.5
REDIS_MAX_MEM=256mb

12.3 故障排查清单

遇到问题时,按以下顺序检查:

  • 1. 检查容器状态是否为 running
  • 2. 查看容器日志是否有错误信息
  • 3. 检查网络配置是否正确
  • 4. 验证环境变量是否设置正确
  • 5. 确认镜像版本是否正确
  • 6. 检查端口是否被占用
  • 7. 验证数据卷是否正确挂载
  • 8. 检查资源使用是否超限
  • 9. 测试容器间网络连通性
  • 10. 检查防火墙规则

联系与支持

如有问题,请检查:

  1. 容器日志
  2. Portainer 事件日志
  3. 服务器系统日志

部署完成后访问地址:

  • 前端界面: http://your-server-ip
  • 后端 API: http://your-server-ip:8080
  • API 文档: http://your-server-ip:8080/doc.html
  • Portainer: https://your-server-ip:9443

文档版本: 1.0.0
适用架构: ARM64 (linux/arm64)
部署工具: Portainer CE/EE

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值