部署过程:
1 2 3
| 主项目:Hexo + Butterfly 访问: https://fcmmm.xyz/
|
最终部署结构:
1 2
| /www/wwwroot/fcmmm.xyz/ ├── main/ # Hexo 主站 public/ 目录里的内容
|
Hexo 的静态构建产物默认生成在 public/,部署时应同步 public/ 里的内容,而不是整个 Hexo 源码目录。(Hexo) GitHub Actions 里使用 actions/checkout 是为了把仓库代码检出到工作区,后续步骤才能构建或同步文件。(GitHub) GitHub Secrets 用于保存 SSH 私钥、服务器 IP 等敏感信息。(GitHub Docs)
一、服务器目录准备
先用 root 登录服务器:
进入服务器后执行:
1
| mkdir -p /www/wwwroot/fcmmm.xyz/main
|
确认目录:
1
| ls -la /www/wwwroot/fcmmm.xyz/
|
应该看到:
二、创建 deploy 部署用户
仍然在服务器里执行:
1
| id deploy || useradd -m -s /bin/bash deploy
|
创建 SSH 目录:
1 2 3 4 5
| mkdir -p /home/deploy/.ssh touch /home/deploy/.ssh/authorized_keys chown -R deploy:deploy /home/deploy/.ssh chmod 700 /home/deploy/.ssh chmod 600 /home/deploy/.ssh/authorized_keys
|
给网站目录权限:
1 2
| chown -R deploy:deploy /www/wwwroot/fcmmm.xyz chmod -R 755 /www/wwwroot/fcmmm.xyz
|
退出服务器:
三、Windows 本地生成 SSH 密钥
在你的 Windows CMD 中执行:
1
| ssh-keygen -t ed25519 -C "github-actions-deploy-xxx" -f github-actions-deploy-xxx
|
生成两个文件:
1 2
| github-actions-deploy-xxx # 私钥,放 GitHub Secrets github-actions-deploy-xxx.pub # 公钥,放服务器
|
四、把公钥写入服务器
你是 Windows CMD,不能用 cat,要用 type。
执行:
1
| type github-actions-deploy-xxx.pub | ssh root@114.215.125.28 "cat >> /home/deploy/.ssh/authorized_keys && chown -R deploy:deploy /home/deploy/.ssh && chmod 700 /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys"
|
然后测试:
1
| ssh -i github-actions-deploy-xxx deploy@114.215.125.28
|
如果成功,会进入服务器,例如:
如果还是:
1
| Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
|
说明密钥仍然没配置成功,需要检查:
1 2
| cat /home/deploy/.ssh/authorized_keys ls -la /home/deploy/.ssh
|
成功登录后退出:
五、宝塔 Nginx 配置
进入宝塔面板:
1
| 网站 → fcmmm.xyz → 设置 → 配置文件
|
使用下面这份配置。它适配:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| /www/wwwroot/fcmmm.xyz/main → 主站 server { listen 80; listen 443 ssl; listen 443 quic; http2 on; http3 on;
server_name fcmmm.xyz www.fcmmm.xyz;
# 主站根目录:Hexo + Butterfly 构建后的 public/ 内容 root /www/wwwroot/fcmmm.xyz/main; index index.html index.htm default.htm default.html;
# 宝塔扩展配置 include /www/server/panel/vhost/nginx/extension/fcmmm.xyz/*.conf;
# CERT-APPLY-CHECK--START include /www/server/panel/vhost/nginx/well-known/fcmmm.xyz.conf; # CERT-APPLY-CHECK--END
# SSL-START # error_page 404/404.html; ssl_certificate /www/server/panel/vhost/cert/fcmmm.xyz/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/fcmmm.xyz/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_tickets on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; add_header Alt-Svc 'quic=":443"; h3=":443"; h3-29=":443"; h3-27=":443"; h3-25=":443"; h3-T050=":443"; h3-Q050=":443"; h3-Q049=":443"; h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"'; quic_retry on; quic_gso on; ssl_early_data on; error_page 497 https://$host$request_uri; # SSL-END
# ERROR-PAGE-START # error_page 404 /404.html; # error_page 502 /502.html; # ERROR-PAGE-END
# REWRITE-START include /www/server/panel/vhost/rewrite/html_fcmmm.xyz.conf; # REWRITE-END
# Hexo 主站 location / { try_files $uri $uri/ /index.html; }
# 静态资源缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|webp|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public"; try_files $uri =404; }
# 禁止访问敏感文件 location ~* (\.user.ini|\.htaccess|\.htpasswd|\.env.*|\.project|\.bashrc|\.bash_profile|\.bash_logout|\.DS_Store|\.gitignore|\.gitattributes|LICENSE|README\.md|CLAUDE\.md|CHANGELOG\.md|CHANGELOG|CONTRIBUTING\.md|TODO\.md|FAQ\.md|composer\.json|composer\.lock|package(-lock)?\.json|yarn\.lock|pnpm-lock\.yaml|\.\w+~|\.swp|\.swo|\.bak(up)?|\.old|\.tmp|\.temp|\.log|\.sql(\.gz)?|docker-compose\.yml|docker\.env|Dockerfile|\.csproj|\.sln|Cargo\.toml|Cargo\.lock|go\.mod|go\.sum|phpunit\.xml|pom\.xml|build\.gradl|pyproject\.toml|requirements\.txt|application(-\w+)?\.(ya?ml|properties))$ { return 404; }
# 禁止访问敏感目录 location ~* /(\.git|\.svn|\.bzr|\.vscode|\.claude|\.idea|\.ssh|\.github|\.npm|\.yarn|\.pnpm|\.cache|\.husky|\.turbo|\.next|\.nuxt|node_modules|runtime)/ { return 404; }
# SSL 验证目录 location ~ \.well-known { allow all; }
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) { return 403; }
access_log /www/wwwlogs/fcmmm.xyz.log; error_log /www/wwwlogs/fcmmm.xyz.error.log; }
|
保存后 SSH 执行:
1 2
| nginx -t systemctl reload nginx
|
六、主项目 Hexo + Butterfly 配置
在 xxx.github.io 仓库的 _config.yml 中确认:
1 2
| url: https://fcmmm.xyz root: /
|
root: /fcmlove/
本地测试构建:
1 2 3
| npm install npx hexo clean npx hexo generate
|
构建后会生成:
服务器最终应该是:
1 2 3 4
| /www/wwwroot/fcmmm.xyz/main/index.html /www/wwwroot/fcmmm.xyz/main/archives/ /www/wwwroot/fcmmm.xyz/main/css/ /www/wwwroot/fcmmm.xyz/main/js/
|
七、GitHub Secrets 配置
仓库添加 Secrets:
进入仓库:
1
| Settings → Secrets and variables → Actions → New repository secret
|
添加:
1 2 3 4
| ALIYUN_HOST 114.215.125.28 ALIYUN_USER deploy ALIYUN_PORT 22 ALIYUN_SSH_KEY github-actions-deploy-xxx 私钥完整内容
|
注意:
ALIYUN_SSH_KEY 填的是私钥,不是 .pub 公钥。
在 Windows CMD 查看私钥内容:
1
| type github-actions-deploy-xxx
|
复制完整内容,包含:
1 2 3
| -----BEGIN OPENSSH PRIVATE KEY----- ... -----END OPENSSH PRIVATE KEY-----
|
八、主项目 xxx.github.io 的 GitHub Actions
在 xxx.github.io 仓库中新建:
1
| .github/workflows/deploy.yml
|
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| name: Deploy Hexo Main Site to Aliyun
on: push: branches: [main]
jobs: build-and-deploy: runs-on: ubuntu-latest
steps: - name: Checkout source uses: actions/checkout@v4 with: submodules: recursive
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20
- name: Install dependencies run: npm install
- name: Build Hexo run: | npx hexo clean npx hexo generate
- name: Configure SSH run: | mkdir -p ~/.ssh echo "${{ secrets.ALIYUN_SSH_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H -p "${{ secrets.ALIYUN_PORT }}" "${{ secrets.ALIYUN_HOST }}" >> ~/.ssh/known_hosts
- name: Deploy to Aliyun run: | rsync -az --delete \ -e "ssh -p ${{ secrets.ALIYUN_PORT }}" \ public/ \ ${{ secrets.ALIYUN_USER }}@${{ secrets.ALIYUN_HOST }}:/www/wwwroot/fcmmm.xyz/main/
|
如果你的主分支是 master,把:
改成:
九、手动测试部署是否成功
仓库 push 后,去 GitHub 仓库查看:
如果显示绿色成功,再登录服务器检查:
1
| ls -la /www/wwwroot/fcmmm.xyz/main/
|
必须看到:
1
| /www/wwwroot/fcmmm.xyz/main/index.html
|
然后测试 Nginx:
1 2
| nginx -t systemctl reload nginx
|
浏览器访问:
十、完整操作顺序
按这个顺序做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1. 宝塔创建 fcmmm.xyz 网站 2. 创建 /www/wwwroot/fcmmm.xyz/main/ 3. 配置宝塔 Nginx 4. nginx -t 5. systemctl reload nginx 6. 创建 deploy 用户 7. 配置 deploy 的 SSH 公钥 8. 本地确认 ssh -i github-actions-deploy-xxx deploy@114.215.125.28 能登录 9. 给 /www/wwwroot/fcmmm.xyz 授权给 deploy 10. 两个 GitHub 仓库分别添加 Secrets 11. xxx.github.io 添加 Hexo 部署 workflow 12. push 仓库 13. 检查 GitHub Actions 是否成功 14. 访问 fcmmm.xyz
|
十三、常见问题
1. deploy 密钥登录失败
如果:
1
| ssh -i github-actions-deploy-xxx deploy@114.215.125.28
|
报:
重新在服务器执行:
1 2 3 4 5
| mkdir -p /home/deploy/.ssh touch /home/deploy/.ssh/authorized_keys chown -R deploy:deploy /home/deploy/.ssh chmod 700 /home/deploy/.ssh chmod 600 /home/deploy/.ssh/authorized_keys
|
然后 Windows CMD 再执行:
1
| type github-actions-deploy-xxx.pub | ssh root@114.215.125.28 "cat >> /home/deploy/.ssh/authorized_keys && chown -R deploy:deploy /home/deploy/.ssh && chmod 700 /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys"
|
2. GitHub Actions 报 Permission denied
服务器执行:
1 2
| chown -R deploy:deploy /www/wwwroot/fcmmm.xyz chmod -R 755 /www/wwwroot/fcmmm.xyz
|
最终结果
1 2 3 4 5
| → GitHub Actions 构建 Hexo → public/ → /www/wwwroot/fcmmm.xyz/main/ → https://fcmmm.xyz/
|
只要 deploy 用户能用密钥登录,并且两个仓库的 Secrets 配置正确,之后每次 push 到 GitHub,都会自动部署到阿里云服务器。