为什么选择自有服务器部署?
🎯 GitHub Pages 的限制
-
路径问题:必须使用
/仓库名作为基础路径 -
域名限制:只能使用
username.github.io或自定义域名 -
功能限制:只支持静态文件,无法运行服务端代码
-
存储限制:仓库大小和带宽有限制
✅ 自有服务器的优势
-
完全控制:自由配置域名、路径、服务器环境
-
性能优化:可以配置 CDN、缓存、压缩等
-
功能扩展:支持 API、数据库、动态功能
-
无限制:存储、带宽根据服务器配置而定
准备工作
🛠️ 必需的资源
1. 服务器环境
- 操作系统:Debian 12 (本文以此系统为例)
2. 软件环境
-
Web 服务器:Nginx
-
Node.js:18+ 版本(如果需要服务端功能)
-
Git:版本控制
-
PM2:进程管理(可选)
服务器环境配置
🐧 Debian 服务器配置
1. 连接服务器
# 使用 SSH 连接服务器
ssh root@your-server-ip
# 或使用非 root 用户
ssh username@your-server-ip
2. 更新系统
# 更新包列表
sudo apt update
# 升级已安装的包
sudo apt upgrade -y
# 安装基础工具
sudo apt install -y curl wget git unzip
3. 安装 Nginx
# 安装 Nginx
sudo apt install -y nginx
# 启动 Nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
# 检查状态
sudo systemctl status nginx
4. 安装 Node.js(可选)
# 安装 Node.js 18.x
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# 验证安装
node --version
npm --version
SSH 密钥配置
🔐 生成和配置 SSH 密钥
1. 在本地生成 SSH 密钥对
# 生成新的 SSH 密钥对
ssh-keygen -t ed25519 -C "github-actions@yourdomain.com" -f ~/.ssh/deploy_key
# 查看公钥
cat ~/.ssh/deploy_key.pub
2. 配置服务器
# 连接到服务器
ssh root@your-server-ip
# 创建部署用户(推荐)
sudo adduser deploy
sudo usermod -aG sudo deploy
# 切换到部署用户
sudo su - deploy
# 创建 .ssh 目录
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 添加公钥到授权文件
echo "你的公钥内容" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 创建网站目录
sudo mkdir -p /var/www/your-website
sudo chown deploy:deploy /var/www/your-website
3. 配置 GitHub Secrets
在 GitHub 仓库中添加以下 Secrets:
-
进入仓库 → Settings → Secrets and variables → Actions
-
添加以下 secrets:
HOST: your-server-ip
USERNAME: deploy
SSH_PRIVATE_KEY: (私钥内容,即 ~/.ssh/deploy_key 文件的内容)
GitHub Actions 工作流配置
🤖 创建部署工作流
创建 .github/workflows/deploy.yml:
name: 🚀 部署到自有服务器
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build-and-deploy:
name: 构建并部署到服务器
runs-on: ubuntu-latest
steps:
- name: 📥 检出代码
uses: actions/checkout@v4
- name: 🟢 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: 📦 安装依赖
run: npm ci
- name: 🔨 构建项目
run: npm run build
env:
NODE_ENV: production
- name: 🚚 准备服务器
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script_stop: true
script: |
# 确保目标目录存在并设置权限
sudo mkdir -p /var/www/my-website
sudo chown -R deploy:www-data /var/www/my-website
# 清理目标目录
sudo rm -rf /var/www/my-website/*
# 清理临时文件(如果有)
rm -rf /tmp/dist
- name: 📤 直接上传构建文件到目标目录
uses: appleboy/scp-action@v0.1.4
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: 'dist/*'
target: '/var/www/my-website/'
strip_components: 1
- name: 🔧 设置权限
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script_stop: true
script: |
# 设置正确的权限
chmod -R 755 /var/www/my-website
sudo chown -R deploy:www-data /var/www/my-website
echo "✅ 部署完成!"
- name: 🔄 重载 Nginx
if: success()
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
echo "🔄 重载 Nginx..."
if sudo nginx -t; then
sudo systemctl reload nginx
echo "✅ Nginx 重载成功"
else
echo "❌ Nginx 配置测试失败"
exit 1
fi
- name: 🎉 部署成功通知
if: success()
run: |
echo "🎉 网站已成功部署到服务器!"
echo "🌐 访问地址: http://${{ secrets.HOST }}"
- name: ❌ 部署失败处理
if: failure()
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
echo "❌ 部署失败,清理临时文件..."
# 清理临时文件
rm -rf /tmp/website-build /tmp/my-website_deploy.sh /tmp/dist
echo "⚠️ 请检查部署日志并手动处理"
Astro 项目配置优化
⚙️ 优化 astro.config.mjs
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
// 配置为你的域名或服务器 IP
site: 'https://your-domain.com', // 或 'http://your-server-ip'
// 输出目录
outDir: './dist',
// 静态资源配置
build: {
assets: 'assets',
inlineStylesheets: 'auto',
},
// 集成插件
integrations: [
mdx(),
sitemap(),
],
// 开发服务器配置
server: {
port: 4321,
host: true
},
// Vite 配置
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[hash][extname]',
chunkFileNames: 'assets/[name].[hash].js',
entryFileNames: 'assets/[name].[hash].js',
},
},
},
},
});
安全性配置
🔐 Nginx 安全配置
创建 /etc/nginx/sites-available/your-website:
# Nginx 配置文件
server {
listen 80;
server_name your-domain.com www.your-domain.com; # 替换为你的域名
# 重定向到 HTTPS(如果配置了 SSL)
# return 301 https://$server_name$request_uri;
root /var/www/your-website/current;
index index.html index.htm;
# 安全头部
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# 缓存静态资源
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 主要路由
location / {
try_files $uri $uri/ /index.html;
}
# 隐藏 Nginx 版本
server_tokens off;
# 防止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
激活配置:
# 创建软链接
sudo ln -s /etc/nginx/sites-available/your-website /etc/nginx/sites-enabled/
# 删除默认配置(可选)
sudo rm -f /etc/nginx/sites-enabled/default
# 测试配置
sudo nginx -t
# 重新加载
sudo systemctl reload nginx
配置完成了,去 GitHub 提交代码就可以了。
🎉 总结
部署流程回顾
代码推送 → GitHub Actions → 构建项目 → 上传到服务器 → 自动部署 → 完成