
Vercel Too Slow? Build Your Own
2 min read
This page was translated by AI
1. Why I Did This
A few days ago, I got in touch with a developer. I really liked a theme from his earlier blog, but unfortunately it was not open source at the time.
He has now made the theme’s source code public on GitHub, so I immediately started deploying the blog with plans to replace my current one.
Taco is a Next.js project. I used the convenient Node.js Docker deployment environment provided by the 1Panel dashboard.
Unfortunately, every time I modified the source code, I had to package it into a ZIP file, upload it to the server, extract it, overwrite the existing files, compile it again, and run it. It was extremely tedious!
Later, the author suggested an edge-computing platform such as Vercel. I tried it and liked it, but access from China was unreliable. After tinkering with it for a while, I realized that I already had two servers and did not need to pay extra for an edge-computing service. So I decided to build my own “DevOps” setup.
2. Preparation
Because my code is on GitHub, I decided to use GitHub Actions. Let’s create the workflow file.
First, let’s model Vercel’s workflow: repository update → Vercel is triggered → the project is rebuilt.
We can turn that flow into a workflow:
- When the repository is updated, trigger an action.
- Connect to the server.
- Change to the project directory.
- Update the files with Git.
- Enter the Node.js Docker container.
- Build the project.
- Restart the container.
3. Configuration
Here are two workflow options:
- Connect to the server with an SSH key:
# workflow:name: Server Updateon:push:branches: - main
jobs: deploy:runs-on: self-hostedsteps: - name: Deploy using direct SSH with key run: |
# 创建SSH目录(如果不存在) mkdir -p ~/.ssh
# 将私钥保存到临时文件 echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa_deploy chmod 600 ~/.ssh/id_rsa_deploy
# 添加服务器到known_hosts以避免提示 ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
# 执行SSH命令 ssh -i ~/.ssh/id_rsa_deploy \ -o StrictHostKeyChecking=accept-new \ ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} \ -p ${{ secrets.SERVER_PORT }} \ ' echo "🚀 正在进入项目目录..." cd /opt/node/Taco || { echo "❌ 项目目录不存在,请检查路径"; exit 1; }
echo "🔄 正在拉取最新代码..." git fetch origin main && git reset --hard origin/main
echo "📦 正在进入 Docker 容器 [Taco] 并构建项目..." docker exec Taco sh -c "npm run build"
echo "🔁 正在重启容器 [Taco]..." docker restart Taco
echo "✅ 部署完成" '
# 清理临时密钥文件 rm -f ~/.ssh/id_rsa_deploy`- Connect with password authentication (requires
sshpass):
# workflow:name: Server Update
on: push:branches: - main
jobs: deploy:runs-on: self-hostedsteps: - name: Install sshpass if needed run: | if ! command -v sshpass &> /dev/null; then echo "sshpass not found, installing..." sudo apt-get update && sudo apt-get install -y sshpass fi
- name: Deploy using direct SSH with password run: | # 使用sshpass进行密码认证 sshpass -p "${{ secrets.SERVER_PASSWORD }}" \ ssh -o StrictHostKeyChecking=no \ ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} \ -p ${{ secrets.SERVER_PORT }} \ ' echo "🚀 正在进入项目目录..." cd /opt/node/Taco || { echo "❌ 项目目录不存在,请检查路径"; exit 1; }
echo "🔄 正在拉取最新代码..." git fetch origin main && git reset --hard origin/main
echo "📦 正在进入 Docker 容器 [Taco] 并构建项目..." docker exec Taco sh -c "npm run build"
echo "🔁 正在重启容器 [Taco]..." docker restart Taco
echo "✅ 部署完成" 'With that, the automated deployment setup is complete!
4. Summary
If, like me, you use 1Panel to deploy a Node.js project but do not want to upload everything again for every update, you can try this approach.
The workflow uses a local runner by default. If you need to use a GitHub-hosted runner, adjust it yourself.