我为什么躺平?因为代码自己会“飞”呀!

跟哥们儿撸串吹牛聊聊怎么让SpringBoot自己"跑"上服务器


SpringBoot自动化部署:让代码自己"飞"上服务器,我躺平!

兄弟,你是不是也这样:代码写爽了,一打包部署就头大?mvn clean package,找那个该死的jar包,scp上传,ssh连上去,ps -ef | grep java找老进程,kill -9送走它,在nohup java -jar...一套组合拳下来,咖啡都凉了!烦不烦? 今天教你用GitHub的免费劳动力(GitHub Actions),让代码自己打包、自己上传、自己重启 !你只需要干一件事:git push!然后?然后你就可以刷会儿短视频等结果了,贼香!

为啥要搞自动化?懒是第一生产力!

  1. 省事儿! 告别重复劳动,你的时间很值钱(至少比咖啡值钱吧?)。
  2. 少犯错! 手滑输错个命令、传错个文件?不存在的!机器比你靠谱(在重复劳动上)。
  3. 稳如老狗! 每次部署的步骤、环境一模一样,再也不会出现"在我机器上好好的"这种玄学问题。
  4. 心里有谱! 推完代码,立马就能在GitHub上看到是成了还是挂了,挂了也能马上知道为啥,不用抓瞎。

神器登场:GitHub Actions(免费的!)

这玩意儿是GitHub自带的,跟你代码仓库天生一对。简单说,就是你写个"菜谱"(YAML配置文件),告诉它:"嘿,哥们,当我往main分支推代码时,你按这个步骤帮我跑一下"。它就乖乖地在GitHub提供的"厨房"(虚拟机)里给你干活儿,干完还能告诉你结果。重点是,个人小项目用,免费!

实战开整!让你的SpringBoot App自己"飞"

场景: 你有个贼拉酷的SpringBoot项目(叫awesome-app吧),用Maven管的,最终要部署到你那台吃灰的Linux服务器(假设IP是111.222.333.444,用户叫deployer)。

第一步:服务器上给GitHub Actions发个"接头暗号"(SSH密钥)

  1. 登服务器,搞密钥:

    bash 复制代码
    ssh deployer@111.222.333.444  # 连上你的宝刀服务器
    ssh-keygen -t rsa -b 4096 -C "github-actions-deploy" -f ~/.ssh/github-actions

    回车回车再回车(别设密码,省事儿)。生成了俩文件:github-actions(私钥,宝贝!)和github-actions.pub(公钥)。

  2. 告诉服务器:"这公钥是好人!":

    bash 复制代码
    cat ~/.ssh/github-actions.pub >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys  # 权限很重要!

    这就相当于把公钥加进了服务器的"VIP通行证"名单。

  3. 把私钥"藏"进GitHub(千万别泄露!):

    • 打开你项目的GitHub页面。
    • Settings -> Secrets and variables -> Actions -> New repository secret
    • Name: SERVER_SSH_KEY (名字好记就行)
    • Value: github-actions文件里的所有内容(从-----BEGIN OPENSSH PRIVATE KEY----------END OPENSSH PRIVATE KEY----- 全选、复制、粘贴进去!一点别落!
    • 再新建两个Secret:
      • SERVER_IP: 111.222.333.444 (你服务器的IP)
      • SERVER_USER: deployer (你登录服务器的用户名)

第二步:项目里放"菜谱"(Workflow配置文件)

  1. 在你SpringBoot项目的根目录 下,新建文件夹:.github/workflows/ (注意前面有个点!)。
  2. 在这个文件夹里,新建一个文件,比如叫deploy-awesome-app.yml
  3. 核心"菜谱"来了! 把下面的代码复制进去,记得看注释按你的情况改:
yaml 复制代码
name: 自动构建部署Awesome App # 名字可以随便取

on:
  push:
    branches: [ "main" ] # 重点!只有推送到main分支才触发。用master的改成master

jobs:
  build-deploy:
    runs-on: ubuntu-latest # GitHub提供的Ubuntu厨房

    steps:
    # 1. 把代码从冰箱(仓库)里拿出来
    - name: 检出代码
      uses: actions/checkout@v4

    # 2. 准备好Java环境(JDK 17示例)
    - name: 装JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin' # 或者 'corretto', 'zulu' 都行

    # 3. Maven打包!(跳过测试,赶时间!生产记得去掉 -DskipTests!)
    - name: Maven 打包
      run: mvn -B clean package -DskipTests # -B 意思"别啰嗦,安静打包"

    # 4. 让GitHub Actions "厨房" 连上你的服务器,把jar包传过去并启动!
    - name: SSH 部署到服务器
      uses: appleboy/ssh-action@v1.0.0 # 这是一个SSH插件,挺好用
      with:
        host: ${{ secrets.SERVER_IP }}    # 用之前藏的服务器IP
        username: ${{ secrets.SERVER_USER }} # 用之前藏的用户名
        key: ${{ secrets.SERVER_SSH_KEY }}  # 用之前藏的私钥(接头暗号)
        script: | # 在服务器上执行的一连串命令,看好了!
          # 找到刚打好的jar包(名字根据你的项目变!)
          # 打开你本地的 target 文件夹,看看jar包叫啥!这是最容易翻车的地方!
          JAR_PATH="/home/github/workspace/target/awesome-app-*.jar" # GitHub Actions 里项目的工作路径
          APP_NAME="awesome-app" # 给你的应用起个名,方便管理
          DEPLOY_DIR="/home/deployer/apps/$APP_NAME" # 服务器上放app的目录,自己定!

          echo "===== 准备起飞! ====="
          # 1. 在服务器上创建部署目录(没有就建)
          mkdir -p $DEPLOY_DIR
          echo "创建/确认目录: $DEPLOY_DIR !"

          # 2. 停掉老服务 (粗暴版,生产建议用systemd)
          echo "寻找并干掉老进程..."
          pkill -f "java -jar $DEPLOY_DIR/$APP_NAME.jar" || echo "没找到老进程,可能是第一次?问题不大!"

          # 3. 把新鲜出炉的jar包从GitHub厨房复制到服务器
          echo "正在空投jar包..."
          scp -o StrictHostKeyChecking=no $JAR_PATH $DEPLOY_DIR/$APP_NAME.jar
          echo "jar包空投成功!落点: $DEPLOY_DIR/$APP_NAME.jar"

          # 4. 启动新服务!(后台运行,日志输出到文件)
          echo "点火!启动新服务..."
          cd $DEPLOY_DIR
          nohup java -jar $APP_NAME.jar > $APP_NAME.log 2>&1 &

          # 5. 喘口气,等几秒看看启动没
          echo "等5秒,看看发动机转起来没..."
          sleep 5
          if pgrep -f "java -jar $APP_NAME.jar" > /dev/null; then
            echo "启动成功!进程活着呢!可以去访问了!"
            echo "日志文件在这: $DEPLOY_DIR/$APP_NAME.log (万一抽风了记得看这里)"
          else
            echo "启动好像失败了!赶紧看日志救命: $DEPLOY_DIR/$APP_NAME.log"
            exit 1 # 告诉GitHub Actions这一步失败了
          fi
          echo "===== 部署完成!! ====="

重点盯防区(最容易翻车的地方!)

  • branches: [ "main" ]: 你开发用哪个分支?main还是master?改成你用的!
  • java-version: '17': 你项目用啥JDK?8?11?17?21?必须一致!
  • mvn ... -DskipTests: -DskipTests跳过了测试!正式上线前务必去掉它,让测试跑起来! 这是为了演示快。
  • JAR_PATHAPP_NAME: 重中之重!
    • 打开你本地项目打完包后的target文件夹,看清楚生成的jar包全名是啥!awesome-app-0.0.1-SNAPSHOT.jar?还是awesome-app.jar?把/home/github/workspace/target/awesome-app-*.jar 里的 awesome-app-*.jar 替换成你实际 的jar包名字模式。可以用*通配符匹配版本号。
    • APP_NAME 起个简短好记的名字,比如你的项目名,后面停进程、看日志都用它。
  • DEPLOY_DIR: 在服务器上你想把应用放哪儿?/home/deployer/apps/ 只是个例子,确保deployer用户对这个目录有读写执行 权限!mkdir -p会帮你建目录。
  • 启停服务 (pkill & nohup): 这是最简单粗暴的方式。生产环境强烈建议用systemd写个服务文件! (sudo systemctl restart yourapp.service 多优雅多稳!) 这里先用nohup顶一下。

见证奇迹的时刻:推代码,看它飞!

  1. 把你改好的代码(特别是那个.github/workflows/deploy-awesome-app.yml文件)git add .git commit -m "加上了自动部署!",然后 git push origin main (或者你的分支名)。
  2. 立马上GitHub,进你的项目,点顶上的 Actions 标签。
  3. 你会看到一个叫"自动构建部署Awesome App"的任务跑起来了!点进去可以实时围观日志输出,跟看直播似的。
  4. 如果满屏绿勾并且看到 "部署完成!": 恭喜!你的代码已经自己"飞"上去跑起来了!赶紧打开浏览器访问你的服务试试!
  5. 如果出现了刺眼的红叉: 莫慌!点开失败的任务,仔细看日志! 翻车点通常就那几个:
    • 私钥格式不对/复制少了: 检查GitHub Secrets里SERVER_SSH_KEY是不是复制了完整的 私钥内容(包括-----BEGIN...-----END...)。
    • 服务器路径权限不足: 检查DEPLOY_DIR,确保SERVER_USER用户能读写执行。mkdir -p报错多半是这。
    • Jar包路径/名字不对!: 老生常谈!100%确认 JAR_PATH设置对了!看日志里scp那一步报的啥错。
    • 端口冲突/启动失败: 看服务器上$DEPLOY_DIR/$APP_NAME.log日志文件!是不是端口被占了?数据库连不上?依赖缺失?
    • 服务器防火墙/安全组: 确保服务器开放了你的应用端口和SSH端口(22)!

搞定了基础版?还能更骚!

  • 分环境部署:dev分支自动部署到测试环境,打v1.0标签部署到生产环境。配置不同的workflow文件或者用if条件判断分支/tag就行。
  • 通知小能手: 部署成功/失败,自动给你发个邮件、Slack消息或者钉钉通知。Action市场有现成的插件。
  • 玩Docker: 在Action里docker build + docker push 把你的应用打成镜像,推到Docker Hub或者私仓。服务器上docker pull + docker run。更现代!
  • 数据库迁移: 部署前,在服务器上自动跑Flyway或Liquibase脚本更新数据库。

安全提示: 那个SERVER_SSH_KEY权限很大!管好你的GitHub仓库权限,别随便给人写权限。定期换换密钥更安全。生产环境强烈建议用权限更小的专用部署用户,并且用systemd管理服务!

相关推荐
程序员爱钓鱼23 分钟前
Rust 开发环境安装(Windows|macOS|Linux)
后端·rust
爱勇宝9 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
IT_陈寒13 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码14 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo14 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志15 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..15 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects15 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰15 小时前
一些基础和问题解决
后端
陈随易16 小时前
前端项目部署只要30秒
前端·后端·程序员