方案实现

通过Github Actions实现git push后自动部署到云服务器。

第一步:云服务器准备工作

1.1 创建专门部署用户

为github actions创建一个专门的SSH用户。

# 在服务器上执行
sudo adduser deploy
sudo usermod -aG sudo deploy

1.2 生成SSH密钥对

在本地生成一对 SSH 密钥,专门给 GitHub Actions 使用:

ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/github_actions_deploy

这会生成两个文件:

  • github_actions_deploy —— 私钥(存到 GitHub Secrets)
  • github_actions_deploy.pub —— 公钥(放到服务器)

1.3 将公钥添加到服务器

# 在服务器上执行
mkdir -p /home/deploy/.ssh
echo "公钥内容" >> /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh

1.4 将cp权限给deploy用户

visudo
%wheel ALL=(ALL)       ALL
deploy  ALL=(ALL)       NOPASSWD: /usr/bin/lsof, /usr/bin/kill, /usr/bin/cp

1.5 测试SSH连接

ssh -i ~/.ssh/github_actions_deploy deploy@你的服务器IP

能成功登录即表示配置正确

第二步:Github仓库配置Secrets

在 GitHub 仓库中依次进入:Settings → Secrets and variables → Actions,点击 New repository secret,添加以下四个 Secrets:

Secret名称 说明 示例值
SERVER_HOST 服务器 IP 或域名 123.123.123.123
SERVER_USER SSH 登录用户名 deploy
SSH_PRIVATE_KEY 私钥完整内容(含 —–BEGIN 和 —–END) 粘贴 github_actions_deploy 文件内容
SERVER_PORT SSH 端口(默认 22) 22

第三步:创建GitHub Actons工作流

在项目根目录创建.github/workflows/deploy.yml文件

3.1 基础版本(适用于静态网站/前端项目)

name: Deploy to Server

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: 拉取代码
        uses: actions/checkout@v4

      - name: 安装 Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '24'

      - name: 安装依赖
        run: npm install pnpm@latest -g && pnpm install

      - name: 构建项目
        run: pnpm run build

      - name: 部署到服务器 
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SERVER_PORT || 22 }}
          command_timeout: 30m
          script: |
            export NVM_DIR="$HOME/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
            cd /home/deploy/yourproject
            # 强制同步远程 master 分支
            git fetch origin master
            git reset --hard origin/master
            
            # 安装依赖并构建
            pnpm run build
            cp -rf /home/deploy/your-projects/dist/* /var/www/html/your-project/

第四步:安装配置nginx

yum install nginx -y

切换到deploy用户安装nvm和nodejs

# 安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
# 加入到
\. "$HOME/.nvm/nvm.sh"
# 安装nodejs
nvm install 24
# 验证
node -v # Should print "v24.18.1".
npm -v # Should print "12.0.2".
#创建网站目录
mkdir -p /var/www/html/yourproject
ls -la /var/www/html/yourproject

sudo chown -R nginx:nginx /var/www/html/yourproject
sudo chmod -R 755 /var/www/html/yourproject

su - deploy
sudo find /var/www/html/yourproject/ -type d -exec chomod 755 {} \;
sudo find /var/www/html/yourproject/ -type d -exec chmod 755 {} \;
sudo find /var/www/html/yourproject/ -type f -exec chmod 644 {} \;

nginx.conf

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;


}

yousite.conf

# --- HTTP 服务器块:强制跳转到 HTTPS ---
server {
    listen 80;
    listen [::]:80;
    server_name example.com; # 替换为你的实际域名

    # 将所有 HTTP 请求永久重定向到 HTTPS
    return 301 https://$host$request_uri;
}

# --- HTTPS 服务器块:主要服务配置 ---
server {
    listen 443 ssl;      # 启用 SSL 和 HTTP/2
    listen [::]:443 ssl; # IPv6 支持


    #请填写绑定证书的域名
    server_name example.com;
    #请填写证书文件的相对路径或绝对路径
    ssl_certificate example.com_bundle.crt;
    #请填写私钥文件的相对路径或绝对路径
    ssl_certificate_key example.com.key;
    ssl_session_timeout 5m;
    #请按照以下协议配置
    ssl_protocols TLSv1.2 TLSv1.3;
    #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;


    # --- 网站根目录 ---
    root /var/www/html/example.com;
    index index.html;

    # --- 核心配置:处理前端路由 ---
    location / {
        try_files $uri $uri/ /index.html;
    }

    # --- 静态资源缓存优化 ---
    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location = /robots.txt {
        add_header Content-Type "text/plain; charset=UTF-8";
        return 200 "User-agent: *\nDisallow:\n\nSitemap: https://example.com/sitemap-index.xml";
    }

    # --- 安全配置:禁止访问隐藏文件 ---
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
}

总结

完整的自动化部署流程如下:

  1. 服务器端:创建部署用户 → 生成 SSH 密钥 → 添加公钥到服务器

  2. GitHub端:配置 Secrets(主机、用户、私钥)

  3. 代码库:创建 .github/workflows/deploy.yml 工作流文件

  4. 触发:git push 到 main 分支 → Actions 自动执行 → 代码部署到服务器

整个方案的核心就是 SSH 密钥认证 + GitHub Actions 工作流,一次配置,永久受益。