docs: make clone + docker compose the preferred deployment path

The deployment page led with a third-party all-in-one Docker Hub image
(`9qeklajc/routstr`) that is not published by this repo's release workflow,
while the Tor and pre-config examples pulled `ghcr.io/routstr/proxy` and
built from source — three different starting points for the same node.

Lead with the supported path instead: clone the repo at a release tag, copy
`.env.example` to `.env`, and `docker compose up -d`, which builds the node
and dashboard from source.

- Drop the all-in-one image section and its compose snippet.
- Add the clone/release checkout steps, including `cp .env.example .env`
  (compose declares `env_file: .env`, so `up` fails without it).
- Fold the duplicate Tor compose example into a pointer to `tor.md`, since
  the default `compose.yml` already runs Tor.
- Correct the persistence table: with `.:/app` mounted, state lives in the
  clone (`keys.db`, `routstr_secret.key`, `.wallet/`), not `/app/data`.
- Document `--build` on updates and the first-start build time.
- README quick start: add the missing clone step to match.
This commit is contained in:
redshift
2026-09-22 14:03:49 +03:00
parent 03e0fea15f
commit fd0b379d7b
2 changed files with 102 additions and 154 deletions
+23 -5
View File
@@ -51,9 +51,25 @@ curl https://api.routstr.com/v1/chat/completions \
## Quick Start (Docker) ## Quick Start (Docker)
If you are a node runner, start a Routstr Core instance using Docker Compose: If you are a node runner, the recommended way to start Routstr Core is to clone
the repository at the latest release and run it with Docker Compose:
1. **Prepare your `.env`**: 1. **Clone the latest release**:
```bash
git clone https://github.com/Routstr/routstr-core.git
cd routstr-core
git checkout v0.4.7 # current release — see https://github.com/Routstr/routstr-core/releases/latest
```
Docker Compose builds the node and the admin dashboard from source, so there
is no image to pull.
2. **Prepare your `.env`**:
```bash
cp .env.example .env
```
Then edit it with your details:
```bash ```bash
# Optional: encrypts node secrets at rest. If unset, the node generates a key # Optional: encrypts node secrets at rest. If unset, the node generates a key
# on first start, writes it to routstr_secret.key, and prints it once — back # on first start, writes it to routstr_secret.key, and prints it once — back
@@ -76,12 +92,14 @@ If you are a node runner, start a Routstr Core instance using Docker Compose:
uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
``` ```
2. **Start the services**: 3. **Start the services**:
```bash ```bash
docker compose up -d docker compose up -d
``` ```
3. **Get your admin password**: The first start builds both images (the dashboard build takes a few minutes).
4. **Get your admin password**:
On first start the node generates an admin password and logs it once with the On first start the node generates an admin password and logs it once with the
`/admin` URL. Read it from the logs: `/admin` URL. Read it from the logs:
```bash ```bash
@@ -89,7 +107,7 @@ If you are a node runner, start a Routstr Core instance using Docker Compose:
``` ```
(Lost it? Reset with `docker compose exec routstr /.venv/bin/python scripts/reset_admin_password.py --regenerate`.) (Lost it? Reset with `docker compose exec routstr /.venv/bin/python scripts/reset_admin_password.py --regenerate`.)
4. **Configure**: 5. **Configure**:
Open [http://localhost:8000/admin/](http://localhost:8000/admin/) to connect your AI providers and set pricing. Open [http://localhost:8000/admin/](http://localhost:8000/admin/) to connect your AI providers and set pricing.
For full instructions, see the **[Provider Quick Start Guide](https://docs.routstr.com/provider/quickstart/)**. For full instructions, see the **[Provider Quick Start Guide](https://docs.routstr.com/provider/quickstart/)**.
+79 -149
View File
@@ -2,179 +2,97 @@
Production deployment guide for Routstr Provider nodes. Production deployment guide for Routstr Provider nodes.
## All-in-One Docker Image (Preferred) ## Quick Start (Recommended)
The easiest way to deploy Routstr is using the all-in-one Docker image from Docker Hub, which includes both the FastAPI backend and the Next.js admin dashboard in a single container. The recommended way to run a provider node is to clone the repository at the
**latest release** and start the stack with Docker Compose. Compose builds both
### Quick Start the node and the admin dashboard from source, so there is no image to pull and no
dashboard build to keep in sync with the node.
```bash ```bash
docker run -d \ git clone https://github.com/Routstr/routstr-core.git
--name routstr \ cd routstr-core
-p 8000:8000 \
-v routstr-data:/app/data \
-e DATABASE_URL="sqlite:////app/data/routstr.db" \
9qeklajc/routstr:latest
```
Access your node: # Check out a release (v0.4.7 is current — see the releases page for the newest tag)
- **API & Admin Dashboard**: http://localhost:8000 git checkout v0.4.7
### Docker Compose Setup # Compose reads its configuration from .env
cp .env.example .env
Create `docker-compose.yml`:
```yaml
version: '3.8'
services:
routstr:
image: 9qeklajc/routstr:latest
container_name: routstr
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- routstr-data:/app/data
environment:
DATABASE_URL: "sqlite:////app/data/routstr.db"
LOG_LEVEL: "info"
volumes:
routstr-data:
```
Start it:
```bash
docker compose up -d docker compose up -d
``` ```
--- Then open your node:
- **API & Admin Dashboard**: <http://localhost:8000>
## Docker Compose (Recommended) - **Admin login**: the password is generated and logged once on first start
For production, use Docker Compose with persistent storage and optional Tor support.
Use the included `compose.yml` for a flexible setup that handles both the UI and the node execution. This is useful for development or when you want to manage Tor as a separate service.
```bash ```bash
docker compose up -d docker compose logs routstr | grep -i admin
``` ```
This will: !!! note "The first start takes a few minutes"
1. **Build the UI**: Compiles the frontend and copies it to a shared volume. `docker compose up` builds both images locally, and the Next.js dashboard
2. **Start Routstr**: Runs the Python node, mounting the built UI. build is the slow part. Later starts reuse the built images.
3. **Start Tor**: Provides anonymous access via a `.onion` address.
!!! tip "Always tracking the newest release"
To check out whatever `releases/latest` currently points at, use:
```bash
git clone https://github.com/Routstr/routstr-core.git
cd routstr-core
git checkout "$(curl -sSL -o /dev/null -w '%{url_effective}' \
https://github.com/Routstr/routstr-core/releases/latest | sed 's|.*/tag/||')"
```
Omitting the `git checkout` entirely leaves you on `main` — newer, but not a
tested release.
--- ---
## With Tor (Anonymous Access) ## What Docker Compose Starts
Add Tor to serve your node as a hidden service—no port forwarding needed. `compose.yml` brings up three services:
```yaml 1. **ui** — builds the Next.js admin dashboard and copies the result into the
services: shared `./ui_out` volume.
routstr: 2. **routstr** — the Python node, serving the API and the dashboard built above.
image: ghcr.io/routstr/proxy:latest 3. **tor** — serves the node as a `.onion` hidden service, so no port forwarding
container_name: routstr is needed. See [Tor Support](tor.md) for how to read your `.onion` address.
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- ./data:/app/data
- ./logs:/app/logs
environment:
- TOR_PROXY_URL=socks5://tor:9050
# Keep the database (and the key file generated beside it) on the volume.
- DATABASE_URL=sqlite:////app/data/routstr.db
depends_on:
- tor
tor:
image: ghcr.io/hundehausen/tor-hidden-service:latest
container_name: tor
restart: unless-stopped
volumes:
- ./tor-data:/var/lib/tor
environment:
- HS_ROUTER=routstr:8000:80
```
After starting, find your `.onion` address:
```bash
docker exec tor cat /var/lib/tor/hidden_service/hostname
```
See [Tor Support](tor.md) for details.
--- ---
## Pre-Configuration (Optional) ## Pre-Configuration (Optional)
While everything can be configured via the dashboard, you can pre-configure settings with environment variables for automated deployments. Everything can be configured from the dashboard after first start, but you can
pre-configure a deployment by editing the `.env` file you created above:
### Using Environment Variables
```yaml
services:
routstr:
image: ghcr.io/routstr/proxy:latest
environment:
# Pre-configure upstream (optional)
- UPSTREAM_BASE_URL=https://api.openai.com/v1
- UPSTREAM_API_KEY=sk-proj-...
# The admin password is generated and logged once on first start; set
# ADMIN_PASSWORD here only as a legacy seed for an existing deployment.
# Node identity
- NAME=My Provider Node
- DESCRIPTION=Fast GPT-4 access via Lightning
# Lightning withdrawals
- RECEIVE_LN_ADDRESS=me@walletofsatoshi.com
# Keep the database (and the key file generated beside it) on the volume.
- DATABASE_URL=sqlite:////app/data/routstr.db
volumes:
- ./data:/app/data
```
### Using an .env File
```yaml
services:
routstr:
image: ghcr.io/routstr/proxy:latest
env_file:
- .env
volumes:
- ./data:/app/data
```
Example `.env`:
```bash ```bash
# Upstream (optional — can also be set from the dashboard)
UPSTREAM_BASE_URL=https://api.openai.com/v1 UPSTREAM_BASE_URL=https://api.openai.com/v1
UPSTREAM_API_KEY=sk-proj-... UPSTREAM_API_KEY=sk-proj-...
# Keep the database (and the key file generated beside it) on the mounted volume.
DATABASE_URL=sqlite:////app/data/routstr.db
# Encrypts node secrets at rest. Optional — if unset, a key is generated next to # Encrypts node secrets at rest. Optional — if unset, a key is generated next to
# your database (on the same volume) and its file is named once for backup. Set # your database (on the same volume) and its file is named once for backup. Set
# it explicitly to manage the key yourself. # it explicitly to manage the key yourself.
ROUTSTR_SECRET_KEY= ROUTSTR_SECRET_KEY=
# Node identity
NAME=My Provider Node NAME=My Provider Node
DESCRIPTION=Fast GPT-4 access via Lightning
# Lightning withdrawals
RECEIVE_LN_ADDRESS=me@walletofsatoshi.com RECEIVE_LN_ADDRESS=me@walletofsatoshi.com
``` ```
The admin password is generated and logged once on first start; set
`ADMIN_PASSWORD` only as a legacy seed for an existing deployment.
!!! note "Secret key persistence" !!! note "Secret key persistence"
If you leave `ROUTSTR_SECRET_KEY` unset, the node generates one and stores it If you leave `ROUTSTR_SECRET_KEY` unset, the node generates one and stores it
as `routstr_secret.key` **next to your database**, so it persists on the same as `routstr_secret.key` **next to your database**, so it persists alongside
volume as your data — just include that volume in your backups. For stronger your data — just include that in your backups. For stronger isolation
isolation (keeping the key off the data volume), set `ROUTSTR_SECRET_KEY` from (keeping the key off the data volume), set `ROUTSTR_SECRET_KEY` from a
a secrets manager instead. secrets manager instead.
See [Configuration](configuration.md) for all available options. See [Configuration](configuration.md) for all available options.
@@ -182,17 +100,21 @@ See [Configuration](configuration.md) for all available options.
## Persistence ## Persistence
Point `DATABASE_URL` inside `/app/data` (as the examples above do) so everything With the default `compose.yml` the repository directory is mounted into the
Routstr persists lands on the mounted volume: container, so everything Routstr persists stays in the directory you cloned:
| Path | Contents | | Path | Contents |
|------|----------| |------|----------|
| `routstr.db` | SQLite database (settings, API keys, sessions) | | `keys.db` | SQLite database (settings, API keys, sessions) |
| `routstr_secret.key` | Auto-generated master key, written beside the database when `ROUTSTR_SECRET_KEY` is unset | | `routstr_secret.key` | Auto-generated master key, written beside the database when `ROUTSTR_SECRET_KEY` is unset |
| `.wallet/` | Cashu wallet data (your Bitcoin!) | | `.wallet/` | Cashu wallet data (your Bitcoin!) |
| `logs/` | Node logs |
!!! warning "Back Up Your Data" !!! warning "Back Up Your Data"
The `./data` volume contains your wallet. Losing it means losing funds. Back up regularly. Your cloned directory holds your wallet and your master key. Losing it means
losing funds. Back it up regularly — and don't delete the checkout to
"start fresh" without copying `keys.db`, `routstr_secret.key` and `.wallet/`
first.
--- ---
@@ -233,27 +155,35 @@ server {
## Updates ## Updates
Pull the latest image and restart: Check out the new release and rebuild:
```bash ```bash
docker compose pull git fetch --tags
docker compose up -d git checkout v0.4.7 # or the tag you are moving to
docker compose up -d --build
``` ```
`--build` is required: Compose reuses an existing image for a service unless you
ask it to rebuild.
!!! warning "Back up first"
Copy `keys.db`, `routstr_secret.key` and `.wallet/` before updating, and read
the release notes for the version you are moving to.
--- ---
## Building from Source ## Building Without Starting
### Using Docker Compose `docker compose up -d` already builds from source. To build the images
The easiest way to build everything from source: explicitly without starting them:
```bash ```bash
docker compose build docker compose build
``` ```
### Individual Components To build only the node image (the dashboard must already be built into
If you prefer building the node only (requires manual UI build first): `./ui_out`):
```bash ```bash
docker build -t routstr-node . docker build -t routstr-node .
``` ```