Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions blume.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ export default defineConfig({
},
agents: {
llmsTxt: { details: llmsDetails },
// The WP Cloud footer, written out as Markdown for .md pages, llms-full.txt
// and MCP: without this the component ships as raw JSX.
markdownComponents: {
WpCloudDocs: ({ props }) =>
`Spacefast is built on Automattic's [WP Cloud](https://wp.cloud/). Using the [Partner API](${deploymentBase}/platforms/partner-api)? See [${String(props.title)}](${String(props.href)}) on WP Cloud Docs.`,
},
// The Website publishes Spacefast's agent skill at the site root; a second,
// generated Docs skill would compete with it.
skillMd: false,
Expand Down
10 changes: 2 additions & 8 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { defineComponents } from "blume";
import Breadcrumbs from "./components/Breadcrumbs.astro";
import Pagination from "./components/Pagination.astro";
import Sidebar from "./components/Sidebar.astro";
import WpCloudDocs from "./components/WpCloudDocs.astro";

export default defineComponents({
layout: { Breadcrumbs, Pagination, Sidebar },
mdx: { WpCloudDocs },
Comment thread
batuhan marked this conversation as resolved.
Resolved
});
16 changes: 16 additions & 0 deletions components/WpCloudDocs.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
import { contentHref } from "blume/components/content/base-href.ts";

interface Props {
title: string;
href: string;
}

const { title, href } = Astro.props;
---

<aside class="not-prose mt-10 border-border border-t pt-4 text-muted-foreground text-sm leading-6 [&_a]:underline [&_a]:decoration-current/50 hover:[&_a]:text-foreground" data-wp-cloud-docs>
<p>
Spacefast is built on Automattic's <a href="https://wp.cloud/">WP Cloud</a>. Using the <a href={contentHref("/platforms/partner-api")}>Partner API</a>? See <a href={href}>{title}</a> on WP Cloud Docs.
</p>
</aside>
12 changes: 7 additions & 5 deletions content/(dynamic)/logs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ sidebar:

Use `sf logs` for requests, `sf logs runtime` for your code's output, and `sf builds logs` for build failures.

## Three streams
## Four streams

| Stream | What it holds | How to read it |
| --- | --- | --- |
| Access | Every request the edge served | `sf logs`, dashboard **Logs** with source **Access** |
| Access | Requests that reached the origin | `sf logs`, dashboard **Logs** with source **Access** |
| Edge | Requests handled by the edge, including cache hits and challenges | [`sf logs edge`](/infrastructure/edge-request-logs), dashboard **Logs** with source **Edge Logs** |
| Runtime | Lines your own code wrote | `sf logs runtime`, dashboard **Logs** with source **App** |
| Build | A build runner's output | `sf builds logs <bld_...>` |

Access and runtime are per Space. Build logs belong to one build.
Access, edge, and runtime are per Space. Build logs belong to one build.

## Read them

Expand All @@ -27,7 +28,7 @@ sf logs https://example.com access
sf logs runtime --follow
```

The first positional is a target, which can be a Space id, slug, live URL, or custom domain. The second is the kind. The command shifts a bare kind out of the first slot, so `sf logs runtime` and `sf logs docs runtime` both work. The kind defaults to `access`, and anything other than `access` or `runtime` is refused.
The first positional is a target, which can be a Space id, slug, live URL, or custom domain. The second is the kind. The command shifts a bare kind out of the first slot, so `sf logs runtime` and `sf logs docs runtime` both work. The kind defaults to `access`. Use `edge` for requests handled by the edge, including cache hits and security challenges. See [Edge request logs](/infrastructure/edge-request-logs) for its filters and query limits.
Comment thread
batuhan marked this conversation as resolved.
Resolved

| Flag | Default | What it does |
| --- | --- | --- |
Expand Down Expand Up @@ -77,7 +78,7 @@ A record is written on the origin, shipped off the box, and indexed before it ca

`--request-id` and `--handler` are applied over pages already fetched, because the provider indexes neither. That makes them precise but not free, so give a `--limit` that covers the window you care about.

The `since` and `until` window exists on the API query, but the CLI exposes no flags for it.
Use `--since` and `--until` for an ISO 8601 time window. Edge logs have their own [window and retention limits](/infrastructure/edge-request-logs#filters-and-time-windows).

## Retention

Expand All @@ -99,5 +100,6 @@ sf builds logs bld_123 --follow
| Operation | Route |
| --- | --- |
| [`listSpaceAccessLogs`](/api/reference/activity/listspaceaccesslogs) | `GET /v1/spaces/{spaceId}/logs/access` |
| [`listSpaceEdgeLogs`](/api/reference/activity/listspaceedgelogs) | `GET /v1/spaces/{spaceId}/logs/edge` |
| [`listSpaceRuntimeLogs`](/api/reference/activity/listspaceruntimelogs) | `GET /v1/spaces/{spaceId}/logs/runtime` |
| [`listBuildLogs`](/api/reference/builds/listbuildlogs) | `GET /v1/builds/{buildId}/logs` |
6 changes: 4 additions & 2 deletions content/(serve)/domains.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,15 @@ Every observed `A` record has to point at Spacefast. A leftover record from your

### When a TXT record shows up

Most domains need no TXT record. One appears only when the hostname is already in use elsewhere and you have to prove it is yours:
Most domains need no TXT record. One appears only when the hostname is already in use elsewhere and you have to prove it is yours (see [Domain verification records](/infrastructure/domain-verification-records) for how they interact with older proofs):

- **Another host still holds it.** The record is named for the hostname, its value starts with `atomic-domain-`, and the domain waits until it is published. Remove any CNAME at that name first; a TXT record cannot sit beside one.
- **Another Space serves it.** Adding it here creates a claim instead of failing, and returns a `_spacefast-claim.<domain>` TXT record. If you can also manage the Space that holds it, verify with move and the domain moves without the record. Otherwise publish the record at your DNS host and verify: once Spacefast sees it, the domain moves to this Space and the old Space stops serving it. Either way, a claim expires 24 hours after it was created; add the domain again for a new one.

Keep exactly one `atomic-domain-` record per hostname. Two of them, even when one is correct, make the claim fail.

Certificates are provisioned and renewed automatically once the hostname can be validated. See [TLS certificates](/infrastructure/tls-certificates) for issuance checks and retries, and [IP ranges](/infrastructure/ip-ranges) for inbound and outbound address behavior.

## Apex and www travel together

If the hostname you add is the registrable apex or its `www` twin, both hostnames get set up. `example.com` pulls in `www.example.com`, and `www.example.com` pulls in `example.com`. Any other subdomain, like `app.example.com`, is connected on its own.
Expand Down Expand Up @@ -209,7 +211,7 @@ www.example.com purpose=www dns=not_configured txt=missing ssl=missing
| `verification_required` | The hostname needs proof of DNS control to keep serving. | Add the verification TXT record. |
| `domain_ownership_required` | Another Space serves this hostname. | Publish the claim's TXT record, then verify to move it here. |
| `ssl_pending` | Certificate issuance is in progress. | Wait. |
| `ssl_renewal_blocked` | A DNS record, usually CAA, is blocking issuance. | Fix the record, then retry SSL. |
| `ssl_renewal_blocked` | A DNS record, usually CAA, is blocking issuance. | Fix the record, then retry HTTPS. |
| `provider_pending` | The edge has not observed the hostname yet. | Wait. |
| `provider_rejected` | The hostname claim was rejected. | Contact support. |
| `provider_error` | Attaching or detaching the hostname failed. | Contact support. |
Expand Down
2 changes: 2 additions & 0 deletions content/(serve)/routing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Two more tokens can appear on a line. Query matchers sit between the source and

## `_headers`

For a security policy example and browser checks, see [HTTP and security headers](/infrastructure/http-security-headers).

An unindented line starts a matcher block. Indented lines under it are operations. `!Name` removes a header.

```text _headers
Expand Down
8 changes: 4 additions & 4 deletions content/cli/storage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sidebar:
order: 23
---

List your app's stored objects and read access or runtime logs within your plan's retention window. Runtime lines take time to appear, and static Spaces have no runtime logs.
List your app's stored objects and read access, edge, or runtime logs within your plan's retention window. Runtime lines take time to appear, and static Spaces have no runtime logs.

Every command here takes the global flags (`--api-url`, `--profile`, `--token`, `-y`/`--yes`, `--json`) and the space selection flags (`--space`, `-o`/`--team`, `--claim-token`). See [the CLI overview](/cli).

Expand Down Expand Up @@ -84,7 +84,7 @@ With `--json`, `data` carries `deleted`.

Read a Space's logs.

`access` is every request the edge served. `runtime` is what your code logged, with the request id and handler for each line. A static Space has no runtime lines.
`access` covers requests that reached your Space's origin. `edge` covers requests handled at the edge, cache hits included. Each edge query reads one hostname (the primary unless you pass `--hostname`), and a busy window can be truncated; see [Edge request logs](/infrastructure/edge-request-logs) for its filters and limits. With `runtime` you get what your code logged, with the request id and handler for each line. A static Space has no runtime lines.

A line you just triggered takes a while to appear — it's written on the origin, shipped, and indexed before it can be read back. **An empty page means not yet, not broken.** Keep paging while the cursor is there: a page can come back empty while there's still more to read.

Expand All @@ -98,7 +98,7 @@ sf logs [target] [kind] [--space <value>] [--limit <n>] [-f] [--cursor <value>]
| Argument | What it is |
| --- | --- |
| `[target]` | Space ID, slug, live URL, or domain. Defaults to the linked Space |
| `[kind]` | `access` or `runtime`. Defaults to `access` |
| `[kind]` | `access`, `edge`, or `runtime`. Defaults to `access` |

A bare kind in the first slot works: `sf logs runtime` is the same as `sf logs --space <linked> runtime`.

Expand Down Expand Up @@ -136,5 +136,5 @@ Log history is a plan limit. A request that reaches past your retention window i

| Code | Exit | When |
| --- | --- | --- |
| `validation_error` | 2 | `kind` is not `access` or `runtime` |
| `validation_error` | 2 | `kind` is not `access`, `edge`, or `runtime` |
| `validation_error` | 2 | `--request-id` or `--handler` passed with the access log |
26 changes: 26 additions & 0 deletions content/infrastructure/automated-failover.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Automated failover
description: How regional replicas keep Spacefast sites available when an origin fails.
---

Spacefast sites run on infra with primary and secondary origin servers in different geographic data centers. WP Cloud continuously replicates site data between them and can move traffic when the primary server or its data center becomes unavailable.

## What happens during failover

WP Cloud monitors origin health and performance. When a failure requires a switch, it redirects traffic to the secondary origin. Once the primary is restored, traffic returns to it automatically.

You do not need to republish your Space or change its DNS records. The public address reaches the [edge network](/infrastructure/origin-edge-servers), which routes requests to the active origin.

The active origin location and outbound IP address can change during a switch. Do not use either as a permanent identifier for your Space. See [IP ranges](/infrastructure/ip-ranges) before connecting an external service that requires an IP allowlist.

## Cached responses during an origin error

Graceful failover is a separate protection. If an origin returns an HTTP 5xx error, the edge may serve an eligible cached response instead. It can keep an already cached page available while the origin has a problem.

This does not repair application errors or create cached copies of responses that were never stored. Personalized pages, API calls that bypass the cache, and writes still depend on a working origin. See [Caching](/caching) for what Spacefast caches.

## Data location

The redundant copy lives in another region. An origin preference is not a guarantee that all site data stays in one geographic location. WP Cloud can store site data in both the United States and the European Union.

<WpCloudDocs title="Automated failover" href="https://wp.cloud/docs/infrastructure/automated-failover/" />
28 changes: 28 additions & 0 deletions content/infrastructure/ddos-protection.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: DDoS protection
description: How edge routing, caching, and traffic classification protect your Space.
---

Spacefast sites inherit WP Cloud's platform-level protection against denial-of-service and distributed denial-of-service attacks. It operates without a setup step or a plugin in your Space.

## Before traffic reaches your application

Anycast routing distributes inbound requests across the edge network. The edge can serve eligible cached responses, classify suspicious traffic, and apply [rate limits](/infrastructure/rate-limiting) before requests consume origin resources.

WP Cloud monitors the network and adjusts protections as traffic changes. Caching and filtering can absorb repeated or unwanted requests, but they do not guarantee that every application remains available under every attack.

## Browser challenges

[Defensive Mode](/infrastructure/defensive-mode) adds browser challenges during suspected bot or DDoS activity. Certain suspicious traffic can also receive a challenge independently of Defensive Mode.

A challenge normally returns HTTP `403`. A rate limit normally returns `429`. Inspect [edge request logs](/infrastructure/edge-request-logs) to distinguish them before changing your application.

For a known unwanted pattern, Spacefast also supports traffic rules through `sf rules`. A firewall rule can block a request or ask for a browser challenge. The [CLI reference](/cli/reference#sf-rules) lists the supported matches and actions.

## During an incident

Check whether legitimate visitors or integrations are failing, then preserve request samples. Include the affected hostname, UTC timestamp, URL, source IP address, complete `User-Agent`, and the response status when contacting Spacefast support.

Send traffic directly to Spacefast's supplied DNS addresses where possible. An extra proxy can hide classification signals and change how visitors reach the edge. If you use one, include that detail in the incident report.

<WpCloudDocs title="DDoS protection" href="https://wp.cloud/docs/security/traffic-protection/ddos-protection/" />
Loading
Loading