1Panel+Vercel部署前后端分离博客Mix Space

3 天前(已编辑)

1Panel+Vercel部署前后端分离博客Mix Space

准备

  • 云服务器(笔者为腾讯云轻量应用服务器2核内存2GB,重装系统为 Debian 12)
  • 后端和前端两个域名,后端域名必须 ICP 备案否则无法访问
  • github 账号和 vercel 账号

docker容器构建

用本地终端 ssh 服务器,如果重装过操作系统,需要在本地终端先清除服务器的 ssh 指纹

ssh-keygen -R 服务器公网IP
ssh root@服务器公网IP

使用docker部署,构建docker环境并拉取mix space构建文件

apt update && apt upgrade -y # 更新包管理器
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # 国内镜像源安装docker
docker -v
cd && mkdir -p mx-space/core && cd $_ # 拉取 docker-compose.yml 文件
wget https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml

编辑 docker-compose.yml 字段

- JWT_SECRET=... # JWT密钥
- ALLOWED_ORIGINS=akatsuki033896.asia # 域名
- ENCRYPT_ENABLE=false # 不加密

接下来配置docker的国内镜像源否则无法pull,建立并编辑 /etc/docker/daemon.json

mkdir -p /etc/docker
vim /etc/docker/daemon.json
docker info | grep cd -A 5 "Registry" # 应返回镜像列表
{
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}

启动docker并pull

systemctl start docker
docker compose up -d # pull
docker compose ps

1Panel 配置网页反向代理

经查阅发现宝塔面板部署反代存在问题,使用1Panel部署配置反向代理,不建议手写反代

在根目录下安装1Panel

bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)"

根据终端提示操作,记住以下配置 1Panel在27978端口,外部地址即管理页面为 http://服务器公网IP:27978

请使用您的浏览器访问面板:  
[1Panel 2026-01-05 02:57:04 install Log]: 外部地址:  
[1Panel 2026-01-05 02:57:04 install Log]: 内部地址:  
[1Panel 2026-01-05 02:57:04 install Log]: 面板用户:  
[1Panel 2026-01-05 02:57:04 install Log]: 面板密码: 

接下来在本机浏览器访问外部地址通过1Panel提供的GUI操作

Let's Encrypt 证书申请

准备工作

  1. 在应用中心安装OpenResty(基于 NGINX 和 LuaJIT 的 Web 平台)
  2. 在页面中注册Acme账号用于申请 Let's Encrypt
  3. 在购买域名的运营商获取 accesskey 和 secretkey 用于申请DNS账号,阿里云的情况需要创建RAM子账号,RAM子账号权限管理添加权限,打开 AliyunDNSFullAccess 否则解析不到地址
  4. 记住获取的 accesskey 和 secretkey,生成后只显示一次,离开页面失效

申请过程

选择注册的Acme账号和DNS账号,勾选自动续签

反向代理

在左侧网站中创建网站,选择静态网站,启用https导入证书

编辑配置文件,在 server 块最后加入以下内容

# WebSocket 地址
location /socket.io {
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "Upgrade"; 
    proxy_buffering off; 
    proxy_set_header Host $host; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_pass http://127.0.0.1:2333/socket.io; 
}
# API 地址
location /api/v2 {
    proxy_pass http://127.0.0.1:2333/api/v2; 
}
# 简读 render 地址
location /render {
    proxy_pass http://127.0.0.1:2333/render; 
}
# Shiro 地址
location / {
    proxy_pass http://127.0.0.1:2323; 
}
# 后端管理页面地址
location /proxy {
    proxy_pass http://127.0.0.1:2333/proxy; 
}
location /qaqdmin {
    proxy_pass http://127.0.0.1:2333/proxy/qaqdmin; 
}

后端管理页面配置

后端管理页面地址为 https://域名/qaqdmin,根据指示设置好,API 地址网关地址等会自动读取生成 在附加功能 - 配置与云函数中黏贴默认配置

  • 名称:shiro
  • 引用:theme
  • 数据类型:JSON
{
  "footer": {
    "otherInfo": {
      "date": "2020-{{now}}",
      "icp": {
        "text": "萌 ICP 备 20236136 号",
        "link": "https://icp.gov.moe/?keyword=20236136"
      }
    },
    "linkSections": [
      {
        "name": "关于",
        "links": [
          {
            "name": "关于本站",
            "href": "/about-site"
          },
          {
            "name": "关于我",
            "href": "/about"
          },
          {
            "name": "关于此项目",
            "href": "https://github.com/innei/Shiro",
            "external": true
          }
        ]
      },
      {
        "name": "更多",
        "links": [
          {
            "name": "时间线",
            "href": "/timeline"
          },
          {
            "name": "友链",
            "href": "/friends"
          },
          {
            "name": "监控",
            "href": "https://status.innei.in/status/main",
            "external": true
          }
        ]
      },
      {
        "name": "联系",
        "links": [
          {
            "name": "写留言",
            "href": "/message"
          },
          {
            "name": "发邮件",
            "href": "mailto:i@innei.ren",
            "external": true
          },
          {
            "name": "GitHub",
            "href": "https://github.com/innei",
            "external": true
          }
        ]
      }
    ]
  },
  "config": {
    "color": {
      "light": [
        "#33A6B8",
        "#FF6666",
        "#26A69A",
        "#fb7287",
        "#69a6cc",
        "#F11A7B",
        "#78C1F3",
        "#FF6666",
        "#7ACDF6"
      ],
      "dark": [
        "#F596AA",
        "#A0A7D4",
        "#ff7b7b",
        "#99D8CF",
        "#838BC6",
        "#FFE5AD",
        "#9BE8D8",
        "#A1CCD1",
        "#EAAEBA"
      ]
    },
 
    "bg": [
      "/static/images/F0q8mwwaIAEtird.jpeg",
      "/static/images/IMG_2111.jpeg.webp.jpg"
    ],
    "custom": {
      "css": [],
      "styles": [],
      "js": [],
      "scripts": []
    },
    "site": {
      "favicon": "/innei.svg",
      "faviconDark": "/innei-dark.svg"
    },
    "hero": {
      "title": {
        "template": [
          {
            "type": "h1",
            "text": "Hi, I'm ",
            "class": "font-light text-4xl"
          },
          {
            "type": "h1",
            "text": "Innei",
            "class": "font-medium mx-2 text-4xl"
          },
          {
            "type": "h1",
            "text": "👋。",
            "class": "font-light text-4xl"
          },
          {
            "type": "br"
          },
          {
            "type": "h1",
            "text": "A NodeJS Full Stack ",
            "class": "font-light text-4xl"
          },
          {
            "type": "code",
            "text": "<Developer />",
            "class": "font-medium mx-2 text-3xl rounded p-1 bg-gray-200 dark:bg-gray-800/0 hover:dark:bg-gray-800/100 bg-opacity-0 hover:bg-opacity-100 transition-background duration-200"
          },
          {
            "type": "span",
            "class": "inline-block w-[1px] h-8 -bottom-2 relative bg-gray-800/80 dark:bg-gray-200/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 group-hover:animation-blink"
          }
        ]
      },
      "description": "An independent developer coding with love."
    },
    "module": {
      "activity": {
        "enable": true,
        "endpoint": "/fn/ps/update"
      },
      "donate": {
        "enable": true,
        "link": "https://afdian.net/@Innei",
        "qrcode": [
          "/static/images/20191211132347.png",
          "/static/images/0424213144.png"
        ]
      },
      "bilibili": {
        "liveId": 1434499
      }
    }
  }
}

使用vercel部署shiro前端

笔者的服务器太垃圾了无法在服务器内编译

  1. 根据提示填写前端的github仓库,项目创建后vercel会自动帮你fork一个新仓库,之后仓库有更新vercel都会自己deploy
  1. 此时前端在 build 的时候尝试访问后端 API 会报错找不到,deploy后显示错误,这是正常的
  2. 在 Settings 的 Environment Variable 配置环境变量
NEXT_PUBLIC_API_URL=https://域名/api/v2 # 后端api
NEXT_PUBLIC_GATEWAY_URL=https://域名 # 网关
ENABLE_EXPERIMENTAL_COREPACK=1 # 部署时启用corepack 取默认值
  1. 在一开始deploy的production上redeploy
  2. 完成部署,接下来可根据文档修改云函数来配置,注意不会立刻生效

前端的域名添加

由 vercel 构建的项目会使用 vercel.app 的免费域名,申请一个新的域名用于前端

  1. 在 settings - domain 中添加你的域名,勾选重定向www,此时是 Invalid 状态
  2. 根据 vercel 的指示在购买域名的运营商设置 dns 解析,回到网页并 refresh,vercel 会帮你申请 ssl 证书,valid 即可使用你的域名访问构建好的项目

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...