Skip to content

Commit 56e9b18

Browse files
committed
docs(web): align deployment and operator guidance
1 parent 8ed2055 commit 56e9b18

11 files changed

Lines changed: 210 additions & 126 deletions

File tree

src/components/docs/DockerComposeSnippet.astro

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@ const snippets: Record<Props["variant"], string> = {
1515
restart: unless-stopped
1616
ports:
1717
- "127.0.0.1:4000:4000"
18+
env_file:
19+
- path: .env
20+
required: false
1821
environment:
1922
RACK_ENV: production
2023
PORT: 4000
21-
HTML2RSS_SECRET_KEY: your-generated-secret-key
22-
HEALTH_CHECK_TOKEN: your-health-check-token
24+
BUILD_TAG: \${BUILD_TAG:?set BUILD_TAG}
25+
GIT_SHA: \${GIT_SHA:?set GIT_SHA}
26+
HTML2RSS_SECRET_KEY: \${HTML2RSS_SECRET_KEY:?set HTML2RSS_SECRET_KEY}
27+
HEALTH_CHECK_TOKEN: \${HEALTH_CHECK_TOKEN:?set HEALTH_CHECK_TOKEN}
28+
SENTRY_DSN: \${SENTRY_DSN:-}
2329
BROWSERLESS_IO_WEBSOCKET_URL: ws://browserless:4002
24-
BROWSERLESS_IO_API_TOKEN: your-browserless-token
30+
BROWSERLESS_IO_API_TOKEN: \${BROWSERLESS_IO_API_TOKEN:?set BROWSERLESS_IO_API_TOKEN}
2531
2632
browserless:
2733
image: "${browserlessImage}"
@@ -35,6 +41,7 @@ const snippets: Record<Props["variant"], string> = {
3541
productionCaddy: `services:
3642
caddy:
3743
image: ${caddyImage}
44+
restart: unless-stopped
3845
ports:
3946
- "80:80"
4047
- "443:443"
@@ -46,39 +53,70 @@ const snippets: Record<Props["variant"], string> = {
4653
- --from
4754
- \${CADDY_HOST}
4855
- --to
49-
- html2rss:3000
50-
html2rss:
56+
- html2rss-web:4000
57+
58+
html2rss-web:
5159
image: ${webImage}
52-
env_file: .env
60+
restart: unless-stopped
61+
env_file:
62+
- path: .env
63+
required: false
64+
environment:
65+
RACK_ENV: production
66+
PORT: 4000
67+
BUILD_TAG: \${BUILD_TAG:?set BUILD_TAG}
68+
GIT_SHA: \${GIT_SHA:?set GIT_SHA}
69+
HTML2RSS_SECRET_KEY: \${HTML2RSS_SECRET_KEY:?set HTML2RSS_SECRET_KEY}
70+
HEALTH_CHECK_TOKEN: \${HEALTH_CHECK_TOKEN:?set HEALTH_CHECK_TOKEN}
71+
SENTRY_DSN: \${SENTRY_DSN:-}
72+
BROWSERLESS_IO_WEBSOCKET_URL: ws://browserless:4002
73+
BROWSERLESS_IO_API_TOKEN: \${BROWSERLESS_IO_API_TOKEN:?set BROWSERLESS_IO_API_TOKEN}
74+
75+
browserless:
76+
image: "${browserlessImage}"
77+
restart: unless-stopped
78+
environment:
79+
PORT: 4002
80+
CONCURRENT: 10
81+
TOKEN: \${BROWSERLESS_IO_API_TOKEN:?set BROWSERLESS_IO_API_TOKEN}
5382
5483
volumes:
5584
caddy_data:`,
5685
secure: `services:
57-
html2rss:
86+
html2rss-web:
5887
image: ${webImage}
88+
restart: unless-stopped
89+
env_file:
90+
- path: .env
91+
required: false
5992
environment:
6093
RACK_ENV: production
61-
LOG_LEVEL: warn
62-
HEALTH_CHECK_USERNAME: your-secure-username
63-
HEALTH_CHECK_PASSWORD: your-very-secure-password
64-
BASE_URL: https://yourdomain.com`,
94+
PORT: 4000
95+
BUILD_TAG: \${BUILD_TAG:?set BUILD_TAG}
96+
GIT_SHA: \${GIT_SHA:?set GIT_SHA}
97+
HTML2RSS_SECRET_KEY: \${HTML2RSS_SECRET_KEY:?set HTML2RSS_SECRET_KEY}
98+
HEALTH_CHECK_TOKEN: \${HEALTH_CHECK_TOKEN:?set HEALTH_CHECK_TOKEN}
99+
SENTRY_DSN: \${SENTRY_DSN:-}
100+
BROWSERLESS_IO_WEBSOCKET_URL: ws://browserless:4002
101+
BROWSERLESS_IO_API_TOKEN: \${BROWSERLESS_IO_API_TOKEN:?set BROWSERLESS_IO_API_TOKEN}
102+
103+
browserless:
104+
image: "${browserlessImage}"
105+
restart: unless-stopped
106+
environment:
107+
PORT: 4002
108+
CONCURRENT: 10
109+
TOKEN: \${BROWSERLESS_IO_API_TOKEN:?set BROWSERLESS_IO_API_TOKEN}`,
65110
watchtower: `services:
66111
watchtower:
67112
image: ${watchtowerImage}
68-
depends_on:
69-
- html2rss
70-
- caddy
71-
command:
72-
- --cleanup
73-
- --interval
74-
- "300"
75-
- html2rss
76-
- caddy
113+
restart: unless-stopped
77114
volumes:
78-
- /var/run/docker.sock:/var/run/docker.sock:ro
79-
restart: unless-stopped`,
115+
- /var/run/docker.sock:/var/run/docker.sock
116+
- "\${HOME}/.docker/config.json:/config.json"
117+
command: --cleanup --interval 7200`,
80118
resourceGuardrails: `services:
81-
html2rss:
119+
html2rss-web:
82120
image: ${webImage}
83121
deploy:
84122
resources:
Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,28 @@
11
---
22
title: "Self-Host Your Own Instance"
3-
description: "Take control of your information diet. Host your own html2rss instance and join the decentralized web movement."
3+
description: "Start self-hosting with the current html2rss-web setup and deployment docs."
44
sidebar:
55
order: 3
66
---
77

8-
Turn any website into an RSS feed. Self-host your own instance to take back control of your information diet and help the html2rss ecosystem grow for everyone.
8+
This page is the short routing point for self-hosting. The current setup and deployment instructions live under the `html2rss-web` docs so the Docker, token, and Browserless guidance only exists in one place.
99

10-
## Before You Begin
10+
## Recommended Path
1111

12-
This guide walks you through running a production-ready instance that friends, teams, or communities can rely on. You'll need:
12+
1. **[Run html2rss-web locally](/web-application/getting-started/)** to verify your own instance with an included feed first.
13+
2. **[Deploy html2rss-web to production](/web-application/how-to/deployment/)** when you are ready to expose or operate it.
14+
3. **[Use automatic feed generation](/web-application/how-to/use-automatic-feed-generation/)** only if you want the token-gated page-URL workflow.
1315

14-
- A server you control (a VPS, home lab, or cloud instance) with Docker support.
15-
- Comfort running a few terminal commands and editing configuration files.
16+
## What To Expect
1617

17-
If that feels new, start with the [Getting Started guide](/web-application/getting-started/) for a friendly local install. It introduces the same concepts at a slower pace. When you're ready to go live, come back here and review the full [Deployment & Production guide](/web-application/how-to/deployment) for sizing tips, proxy examples, and hardening advice.
18-
19-
Before you deploy, double-check this quick checklist:
20-
21-
- Docker Engine and Docker Compose Plugin are installed on the host.
22-
- Ports 80/443 (or the ports used by your TLS terminator) are open to the internet if you plan to serve other users.
23-
- You can publish DNS for your chosen domain.
24-
25-
## Deployment Overview
26-
27-
1. Generate your `docker-compose.yml` and `config/feeds.yml` by following [Step 2 of the Getting Started guide](/web-application/getting-started/#step-2-create-the-configuration-file), then copy the resulting files into your deployment directory.
28-
2. Create an `.env` file with production credentials and the values documented in the [environment reference](/web-application/reference/env-variables). Generate new secrets (`openssl rand -hex 32`) and avoid reusing the samples from local testing.
29-
3. Adjust the compose file to match your host (volumes, proxy service, watchtower, resource limits). The [deployment guide](/web-application/how-to/deployment) shows complete examples for Caddy, health-check protection, and automatic updates.
30-
4. Start the stack with `docker compose up -d` and verify the application is reachable at your chosen domain or internal endpoint.
31-
32-
For extra reliability, integrate the instance with your existing reverse proxy, DNS, or platform tooling rather than running it ad hoc on a laptop. Treat it like any other production service so readers can trust it.
33-
34-
## Harden & Secure
35-
36-
- Follow the [Secure Your Instance](/web-application/how-to/deployment#secure-your-instance) checklist to lock down credentials, TLS, and network access.
37-
- Enforce HTTPS by configuring a reverse proxy (see [Option A: Caddy](/web-application/how-to/deployment#option-a-caddy-automatic-https)) or your preferred terminator. If you manage certificates separately, document the renewal procedure alongside your deployment scripts.
38-
- Review the [production preparation guidelines](/web-application/how-to/deployment#prepare-for-production) and keep secrets outside of version control.
39-
40-
## Monitor & Maintain
41-
42-
- Point your uptime monitor at `/health_check.txt` and review container logs regularly. The [Operate & Monitor](/web-application/how-to/deployment#operate--monitor) section outlines suggested thresholds.
43-
- Automate updates with Watchtower (a Docker container that updates running containers) or your container management platform to receive the latest html2rss-web releases quickly.
44-
- Track storage usage for feed cache volumes and prune unused images. Schedule periodic configuration reviews so feeds and credentials remain accurate.
18+
- `html2rss-web` is the recommended self-hosted product surface.
19+
- Included feeds are the lowest-maintenance way to prove a deployment.
20+
- Automatic feed generation is disabled by default in production.
21+
- The generated API contract is published as OpenAPI at `/openapi.yaml`.
22+
- Custom config work belongs in the core `html2rss` docs and JSON Schema.
4523

4624
## Share Your Instance
4725

4826
Running a reliable deployment benefits the broader community. Share your server with the broader community by adding it to the [community instance list](https://github.com/html2rss/html2rss-web/wiki/Instances) once it is stable and you are ready for other readers. Include details such as uptime expectations, moderation policy, and contact information so people know what to expect.
4927

5028
Thanks for investing the time to share html2rss with others. Each new instance expands the open web and helps readers stay in control of the stories they follow.
51-
52-
## License
53-
54-
[MIT](https://github.com/html2rss/html2rss/blob/main/LICENSE)

src/content/docs/ruby-gem/index.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ sidebar:
77

88
This section provides comprehensive documentation for the `html2rss` Ruby gem.
99

10+
If you are looking for the stable machine-readable contract for config authoring, use the JSON Schema exported by the core repo:
11+
12+
- Repository file: [`schema/html2rss-config.schema.json`](https://github.com/html2rss/html2rss/blob/master/schema/html2rss-config.schema.json)
13+
- CLI export: `html2rss schema`
14+
- Runtime validation: `html2rss validate config.yml`
15+
1016
## Getting Started
1117

1218
If you are getting started with `html2rss`, we recommend starting with the [tutorials](/ruby-gem/tutorials).

src/content/docs/troubleshooting/troubleshooting.mdx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ If you are getting a "command not found" error, try the following:
7070
```bash
7171
docker compose logs
7272
```
73-
- Ensure the port (default: 3000) isn’t already in use:
73+
- Ensure the app port (default compose binding: 4000) isn’t already in use:
7474
```bash
75-
netstat -tulpn | grep :3000
75+
lsof -i :4000
7676
```
77+
- If the app exits immediately in production, check that `HTML2RSS_SECRET_KEY`, `BUILD_TAG`, and `GIT_SHA` are set.
7778

7879
### Can’t Access the Web Interface
7980

80-
- Confirm your firewall allows traffic on port 3000 (or the port you configured)
81+
- Confirm your firewall allows traffic on port 4000 or your reverse-proxy ports
8182
- Try accessing via the server’s IP instead of a domain name
8283
- Double-check that containers are running:
8384
```bash
@@ -86,10 +87,10 @@ If you are getting a "command not found" error, try the following:
8687

8788
### Authentication Errors
8889

89-
- **401 Unauthorized:** Check your `AUTO_SOURCE_USERNAME` and `AUTO_SOURCE_PASSWORD` environment variables.
90-
- **403 Forbidden:** The URL is not in the `AUTO_SOURCE_ALLOWED_URLS` list, or the origin is not in `AUTO_SOURCE_ALLOWED_ORIGINS`.
90+
- **401 Unauthorized when creating feeds:** The create-feed API expects a bearer token. Re-enter a valid access token in the UI or send `Authorization: Bearer ...` to `POST /api/v1/feeds`.
91+
- **403 Forbidden when creating feeds:** Automatic feed generation may be disabled (`AUTO_SOURCE_ENABLED=false`) or the requested URL may not be allowed for the authenticated account.
9192
- **500 Internal Server Error:** Check the application logs for detailed error information.
92-
- **Health check failures:** Use the `/health_check.txt` endpoint to identify which specific feed configurations are broken.
93+
- **Health endpoint failures:** Use `GET /api/v1/health/live`, `GET /api/v1/health/ready`, or authenticated `GET /api/v1/health` depending on which probe you are testing.
9394

9495
### Feed Problems
9596

src/content/docs/web-application/getting-started.mdx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sidebar:
88
import AutoGenerationOptional from "../../../components/docs/AutoGenerationOptional.astro";
99
import MinimalDockerCompose from "../../../components/docs/MinimalDockerCompose.astro";
1010

11-
Run `html2rss-web` locally with Docker, open the web interface, and verify that your instance can serve a working included feed.
11+
Run `html2rss-web` locally with Docker, open the web interface, and verify that your instance can serve a working included feed before you enable direct feed generation.
1212

1313
## What You Will Have When This Works
1414

@@ -17,7 +17,7 @@ After this guide, you should have:
1717
- `html2rss-web` running at `http://localhost:4000`
1818
- the web interface loading correctly
1919
- a first included feed URL you can copy into your reader
20-
- a clear path to either custom configs or more advanced setup
20+
- a clear path to either token-gated feed generation or custom configs
2121

2222
## Installation Guide
2323

@@ -45,7 +45,7 @@ Create a file called `docker-compose.yml` in that folder and start with the mini
4545

4646
<MinimalDockerCompose />
4747

48-
Add update automation later, after the first run works.
48+
This minimal stack intentionally proves the included-feed path first. Add automatic updates, reverse proxying, or your own config file only after this first run works.
4949

5050
### Step 3: Start html2rss-web
5151

@@ -68,7 +68,7 @@ At this point, `html2rss-web` should be running.
6868
4. Confirm the feed opens
6969
5. Copy that feed URL into your reader
7070

71-
If that works, the deployment, static feed path, and reader subscription path are working together.
71+
If that works, the deployment, included-config path, and reader subscription path are working together.
7272

7373
## What To Do First
7474

@@ -78,7 +78,18 @@ Start with an included config from your own instance:
7878
2. copy that feed URL into your reader
7979
3. confirm your reader can subscribe successfully
8080

81-
That proves the core path before you invest in automatic generation or custom configs.
81+
That proves the lowest-friction path before you invest in automatic generation or custom configs.
82+
83+
## What Changes If You Enable Feed Generation
84+
85+
Automatic feed generation is off by default in production. When you enable it later:
86+
87+
- the web app creates feeds through `POST /api/v1/feeds`
88+
- that API requires a bearer token
89+
- the UI starts with `faraday` and automatically retries once with `browserless` when appropriate
90+
- Browserless still needs to be configured for JavaScript-heavy pages
91+
92+
If you are integrating this flow programmatically, the generated OpenAPI is available at `/openapi.yaml`.
8293

8394
<AutoGenerationOptional />
8495

0 commit comments

Comments
 (0)