# 静态托管

> 从任意静态托管平台提供构建目录——nginx、S3 + CloudFront、Caddy 等。

Htmlpress 的构建结果就是一个由 `.html`、`.css`、 `.js` 和资源文件组成的普通目录。任何能提供文件目录服务的东西都可以使用。本指南介绍几种常见方式。

## 构建站点

```sh
htmlpress build
```

输出位于 `.htmlpress/build/`。把该目录作为文档根目录。`htmlpress preview` 会在本地以托管平台的方式提供同一份构建。

## 预渲染与 SPA 回退

每个页面都是一个真实的文件，即以其源文件命名的文件夹中的一个 `index.html`： `guides/build.html` 写入 `guides/build/index.html`，在 `/guides/build/` 提供，就像任何静态托管平台响应文件夹 URL 那样。没有客户端路由，因此任何托管平台都不需要 SPA 回退。

值得配置的是未找到页面。每次构建都会在根目录写出一个 `404.html`（项目自己的，或内置的）；把托管平台的错误页面指向它，这样未知路径会显示站点的布局，而不是托管平台默认的错误页。

## nginx

```
server {
  listen 80;
  server_name docs.example.com;
  root /var/www/docs;
  index index.html;

  # Try the exact file, then a folder's index.html, else the site's 404 page.
  location / {
    try_files $uri $uri/ =404;
  }
  error_page 404 /404.html;
}
```

每次发布时将 `.htmlpress/build/*` 复制到 `/var/www/docs/`。

## Caddy

```
docs.example.com {
  root * /var/www/docs
  file_server
  encode gzip zstd
  handle_errors {
    rewrite * /404.html
    file_server
  }
}
```

当域名解析到 Caddy 时，它会自动签发 Let's Encrypt 证书。

## AWS S3 + CloudFront

标准做法是以 S3 存储桶为源站，前面放 CloudFront：

1. 将 `.htmlpress/build/` 上传到 S3 存储桶（`aws s3 sync .htmlpress/build/ s3://my-docs --delete`）。
2. 将 **Static website hosting → Index document** 设为 `index.html`，**Error document** 设为 `404.html`。
3. 创建一个指向该存储桶网站端点的 CloudFront 分配。
4. 在 CloudFront 中添加一条 **Custom error response**，将 `404` 映射到 `/404.html`，并保持响应码为 `404`。
5. 将该分配的默认根对象设为 `index.html`。

`_htmlpress/` 下的文件在每次构建之间保持文件名不变，因此请只做短时间缓存，或在每次发布时使其失效。

## Apache

```
DirectoryIndex index.html
ErrorDocument 404 /404.html
```

把这些写入文档根目录下的 `.htaccess`，并将构建放在那里。真实存在的文件和文件夹会被直接提供；其他请求都会得到站点的 404 页面。

> **Warning**
>
> Htmlpress 复制项目时会跳过点文件，因此请把 `.htaccess` 保留在服务器上，或在构建后再复制进去。

## 其他托管平台

同样的做法适用于 Render Static、Surge、Fly Static、Bunny，或任何带 CDN 的对象存储：上传目录，把域名指向它，并为未知路径提供 `404.html`。

## 使用 GitHub Actions 部署

一个最简的 nginx/SSH 示例：

```yaml
name: deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npx gethtmlpress build
      - uses: easingthemes/ssh-deploy@v5
        with:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
          REMOTE_HOST: ${{ secrets.SSH_HOST }}
          REMOTE_USER: ${{ secrets.SSH_USER }}
          SOURCE: .htmlpress/build/
          TARGET: /var/www/docs/
          ARGS: -avzr --delete
```

对于 S3，把部署步骤换成 `aws-actions/configure-aws-credentials` + `aws s3 sync`。

## 另请参阅

- [站点元数据](/zh/customization/site-metadata/)：`site` 用于生成绝对 URL 和 sitemap。
- [部署](/zh/deployment/)：返回托管平台索引。
