74 lines
2.0 KiB
Markdown
74 lines
2.0 KiB
Markdown
# Local Page Archiver
|
|
|
|
This project saves self-contained HTML archives. It opens the input with Playwright, captures the rendered HTML, and inlines external resources as `data:` URLs.
|
|
|
|
## CLI
|
|
|
|
```sh
|
|
npm install
|
|
npm run install-browsers
|
|
node src/cli.mjs archive "https://example.com/article"
|
|
```
|
|
|
|
For an existing HTML file:
|
|
|
|
```sh
|
|
node src/cli.mjs archive ./page.html
|
|
```
|
|
|
|
Archives are written to `ARCHIVE_PATH`, or to a development directory under the system temp directory when `ARCHIVE_PATH` is not set.
|
|
|
|
## Ephemeral container worker
|
|
|
|
The host-facing container boundary is `src/container-runner.mjs`. It starts a short-lived Docker/Podman worker container, mounts the host archive directory at `/archives`, sends one archive request, reads a JSON result, and exits.
|
|
|
|
Build the worker image:
|
|
|
|
```sh
|
|
podman build -t local-page-archiver:latest .
|
|
```
|
|
|
|
Archive through the worker on macOS with Podman:
|
|
|
|
```sh
|
|
node src/container-runner.mjs archive "https://example.com/article" \
|
|
--runtime podman \
|
|
--image local-page-archiver:latest \
|
|
--archive-path ./archives
|
|
```
|
|
|
|
The convenience wrapper does the same thing and builds the image if missing:
|
|
|
|
```sh
|
|
./podman-run.sh archive "https://example.com/article"
|
|
```
|
|
|
|
For visual debugging, expose VNC from the worker:
|
|
|
|
```sh
|
|
./podman-run.sh vnc-archive "https://example.com/article"
|
|
# Then open vnc://localhost:5901
|
|
```
|
|
|
|
The worker image starts Xvfb internally, so callers do not need to mount the host X11 socket or override the entrypoint.
|
|
|
|
## Web UI
|
|
|
|
The web path is split into three roles:
|
|
|
|
- `src/frontend-server.mjs` serves the static UI and proxies `/api/*` and `/archives/*` to the backend.
|
|
- `src/backend-server.mjs` manages archive lookup, job state, and the archive index.
|
|
- `src/worker-server.mjs` runs inside the browser worker container and wraps `archivePage()` over HTTP.
|
|
|
|
Run the full stack with:
|
|
|
|
```sh
|
|
docker compose -f docker-compose.example.yml up --build
|
|
```
|
|
|
|
Then open `http://localhost:5731`. Direct path archival is supported, for example:
|
|
|
|
```text
|
|
http://localhost:5731/https://example.com
|
|
```
|