Install Docs
This commit is contained in:
@@ -15,6 +15,7 @@ JWT_SECRET="change-me-in-production"
|
|||||||
|
|
||||||
# ── Stripe ────────────────────────────────────────────────────────────────────
|
# ── Stripe ────────────────────────────────────────────────────────────────────
|
||||||
STRIPE_SECRET_KEY="sk_test_..."
|
STRIPE_SECRET_KEY="sk_test_..."
|
||||||
|
STRIPE_PUBLISHABLE_KEY="pk_test_..."
|
||||||
STRIPE_WEBHOOK_SECRET="whsec_..."
|
STRIPE_WEBHOOK_SECRET="whsec_..."
|
||||||
|
|
||||||
# ── Twilio Verify (SMS OTP) ───────────────────────────────────────────────────
|
# ── Twilio Verify (SMS OTP) ───────────────────────────────────────────────────
|
||||||
|
|||||||
+4
-4
@@ -47,10 +47,10 @@ Prisma Studio: `npm run db:studio`
|
|||||||
|
|
||||||
## Unraid Deployment
|
## Unraid Deployment
|
||||||
|
|
||||||
1. Place the repo in `/mnt/user/appdata/storybid/`.
|
See the full step-by-step guide: [unraid-install.md](./unraid-install.md)
|
||||||
2. Copy `.env.example` → `.env` and fill in all values.
|
|
||||||
3. From the Unraid terminal: `docker compose up -d`
|
Covers CLI (SSH) and GUI (Compose Manager plugin) methods, all environment variable
|
||||||
4. Optionally add a **Community Applications** custom app pointing to `docker-compose.yml`.
|
paths, reverse proxy setup, Stripe webhook registration, and troubleshooting.
|
||||||
|
|
||||||
## UniFi Event-Network Setup
|
## UniFi Event-Network Setup
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,558 @@
|
|||||||
|
# Unraid Installation Guide
|
||||||
|
|
||||||
|
Storybid runs as four Docker containers (PostgreSQL, Redis, server, client) managed
|
||||||
|
by a single `docker-compose.yml`. This guide covers two installation paths:
|
||||||
|
|
||||||
|
- **CLI** — SSH into Unraid and use the terminal directly. Recommended; always works.
|
||||||
|
- **GUI** — Use the Community Applications *Compose Manager* plugin to manage the
|
||||||
|
stack from the Unraid web interface.
|
||||||
|
|
||||||
|
Both methods produce an identical running system.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
| Requirement | Notes |
|
||||||
|
|---|---|
|
||||||
|
| Unraid 6.12 or later | Earlier versions lack the built-in Compose support CLI needs |
|
||||||
|
| Community Applications plugin | Required for GUI method; install from CA store |
|
||||||
|
| Docker enabled | Unraid → Settings → Docker → Enable Docker = Yes |
|
||||||
|
| At least 2 GB free RAM | PostgreSQL + Redis + Node API + Nginx |
|
||||||
|
| A user share for appdata | Default: `/mnt/user/appdata/` |
|
||||||
|
| A public domain name | For Stripe webhooks and the public bidder URL |
|
||||||
|
| Stripe account | Live or test; publishable + secret key + webhook secret |
|
||||||
|
| Twilio Verify service | For SMS OTP login (optional but recommended) |
|
||||||
|
| SMTP relay | Any transactional email provider (Gmail, Postmark, Mailgun…) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Directory Layout
|
||||||
|
|
||||||
|
All persistent data lives under a single appdata directory. The recommended path is:
|
||||||
|
|
||||||
|
```
|
||||||
|
/mnt/user/appdata/storybid/
|
||||||
|
├── repo/ ← cloned source code + docker-compose.yml
|
||||||
|
│ ├── .env ← your live config (never commit this file)
|
||||||
|
│ └── docker-compose.yml
|
||||||
|
├── postgres/ ← PostgreSQL data volume (managed by Docker)
|
||||||
|
├── redis/ ← Redis data volume (managed by Docker)
|
||||||
|
└── uploads/ ← uploaded item media (mapped from media_data volume)
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Tip:** Keep `repo/` on a cache-backed share so builds are fast, but ensure the
|
||||||
|
> share has `Use Cache: Prefer` or `Only` so data doesn't move to array disks mid-event.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Variables Reference
|
||||||
|
|
||||||
|
Copy `.env.example` to `.env` and fill in every value before starting the stack.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp /mnt/user/appdata/storybid/repo/.env.example \
|
||||||
|
/mnt/user/appdata/storybid/repo/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Core app
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `NODE_ENV` | `production` | Must be `production` for live deployments |
|
||||||
|
| `PORT` | `3001` | Internal port the API server listens on |
|
||||||
|
| `PUBLIC_URL` | `https://bid.example.org` | Externally reachable HTTPS URL. Used in magic-link emails and as the first-choice socket endpoint |
|
||||||
|
| `LOCAL_HOSTNAME` | `auction.event.lan` | LAN hostname for event-night failover (see [unifi-dns.md](./unifi-dns.md)). Must resolve on the event Wi-Fi. |
|
||||||
|
| `JWT_SECRET` | `64-char random string` | Signs all auth tokens. Generate with `openssl rand -hex 32` |
|
||||||
|
| `CLIENT_URL` | `https://bid.example.org` | Allowed CORS origin for the client; usually same as `PUBLIC_URL` |
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `DATABASE_URL` | `postgresql://storybid:PASS@db:5432/storybid` | Postgres connection string. The hostname is `db` (the Docker service name) in production |
|
||||||
|
|
||||||
|
> **Change the password** in both `DATABASE_URL` and the `docker-compose.yml`
|
||||||
|
> `POSTGRES_PASSWORD` entry before first boot.
|
||||||
|
|
||||||
|
### Redis
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `REDIS_URL` | `redis://redis:6379` | Redis connection string. The hostname is `redis` inside the compose network |
|
||||||
|
|
||||||
|
### Stripe
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `STRIPE_SECRET_KEY` | `sk_live_…` | Stripe secret key from Dashboard → Developers → API keys |
|
||||||
|
| `STRIPE_PUBLISHABLE_KEY` | `pk_live_…` | Stripe publishable key — returned to bidder browsers to initialise payment forms |
|
||||||
|
| `STRIPE_WEBHOOK_SECRET` | `whsec_…` | Signing secret for `POST /api/webhooks/stripe`. Created when you register the webhook endpoint in Stripe Dashboard |
|
||||||
|
|
||||||
|
### Twilio Verify (SMS OTP)
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `TWILIO_ACCOUNT_SID` | `ACxxxx…` | Found on your Twilio Console dashboard |
|
||||||
|
| `TWILIO_AUTH_TOKEN` | `xxxx…` | Found on your Twilio Console dashboard |
|
||||||
|
| `TWILIO_VERIFY_SERVICE_SID` | `VAxxxx…` | Create a Verify service in Twilio Console → Verify → Services |
|
||||||
|
|
||||||
|
Leave all three blank to disable SMS login (email magic links still work).
|
||||||
|
|
||||||
|
### Email
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `SMTP_HOST` | `smtp.postmarkapp.com` | Outbound SMTP server |
|
||||||
|
| `SMTP_PORT` | `587` | SMTP port (587 = STARTTLS, 465 = SSL) |
|
||||||
|
| `SMTP_USER` | `noreply@example.org` | SMTP username / sender address |
|
||||||
|
| `SMTP_PASS` | `…` | SMTP password or API key |
|
||||||
|
| `EMAIL_FROM` | `Storybid <noreply@example.org>` | Display name + address in the From header |
|
||||||
|
|
||||||
|
### Media storage
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `UPLOAD_DIR` | `/app/uploads` | Absolute path inside the server container where media files are written. Maps to `media_data` Docker volume |
|
||||||
|
| `MEDIA_BASE_URL` | `/media` | URL prefix the server uses to serve media. Change to an absolute URL if you front uploads with a CDN |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Method 1 — CLI via SSH
|
||||||
|
|
||||||
|
### 1. Enable SSH on Unraid
|
||||||
|
|
||||||
|
**Unraid web UI → Settings → Management Access → SSH → Enable SSH = Yes**
|
||||||
|
|
||||||
|
Connect from your workstation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh root@192.168.1.X # replace with your Unraid IP
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Clone the repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/user/appdata/storybid
|
||||||
|
cd /mnt/user/appdata/storybid
|
||||||
|
git clone https://github.com/YOUR_ORG/storybid.git repo
|
||||||
|
cd repo
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't have `git` on Unraid, install it via the **NerdTools** Community
|
||||||
|
Applications plugin, or transfer a zip via SCP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From your workstation
|
||||||
|
scp storybid.zip root@192.168.1.X:/mnt/user/appdata/storybid/
|
||||||
|
# On Unraid
|
||||||
|
cd /mnt/user/appdata/storybid && unzip storybid.zip && mv storybid repo
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure the environment file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/user/appdata/storybid/repo
|
||||||
|
cp .env.example .env
|
||||||
|
nano .env # or vi .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Minimum required edits:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
NODE_ENV=production
|
||||||
|
PUBLIC_URL=https://bid.example.org
|
||||||
|
JWT_SECRET=$(openssl rand -hex 32) # paste output, don't run inline in .env
|
||||||
|
|
||||||
|
DATABASE_URL=postgresql://storybid:CHANGE_ME@db:5432/storybid
|
||||||
|
STRIPE_SECRET_KEY=sk_live_...
|
||||||
|
STRIPE_PUBLISHABLE_KEY=pk_live_...
|
||||||
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
||||||
|
SMTP_HOST=smtp.example.com
|
||||||
|
SMTP_USER=noreply@example.org
|
||||||
|
SMTP_PASS=...
|
||||||
|
EMAIL_FROM=Storybid <noreply@example.org>
|
||||||
|
```
|
||||||
|
|
||||||
|
Also update `docker-compose.yml` to match the Postgres password you set above:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In docker-compose.yml, under the db service:
|
||||||
|
POSTGRES_PASSWORD: CHANGE_ME
|
||||||
|
# And in the server service environment:
|
||||||
|
DATABASE_URL: postgresql://storybid:CHANGE_ME@db:5432/storybid
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Update volume paths (optional — recommended)
|
||||||
|
|
||||||
|
By default Docker manages named volumes internally. To make them visible in the
|
||||||
|
Unraid GUI and ensure they survive array changes, pin them to explicit paths:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# In docker-compose.yml, replace the volumes block at the bottom:
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/postgres
|
||||||
|
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/redis
|
||||||
|
|
||||||
|
media_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/uploads
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the directories first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/user/appdata/storybid/{postgres,redis,uploads}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Build and start the stack
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/user/appdata/storybid/repo
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
First build downloads base images and compiles the TypeScript source — allow 3–5
|
||||||
|
minutes. Watch progress:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
All four containers should reach **Up** state:
|
||||||
|
|
||||||
|
```
|
||||||
|
NAME STATUS
|
||||||
|
storybid-db-1 Up (healthy)
|
||||||
|
storybid-redis-1 Up (healthy)
|
||||||
|
storybid-server-1 Up
|
||||||
|
storybid-client-1 Up
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Run database migrations
|
||||||
|
|
||||||
|
Run once after the first boot, and again after any update that includes schema changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec server npx prisma migrate deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Create the first admin user
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec server node -e "
|
||||||
|
const { prisma } = await import('./dist/lib/prisma.js');
|
||||||
|
await prisma.organization.create({
|
||||||
|
data: {
|
||||||
|
name: 'My Charity',
|
||||||
|
staffUsers: {
|
||||||
|
create: {
|
||||||
|
name: 'Admin',
|
||||||
|
email: 'admin@example.org',
|
||||||
|
role: 'admin',
|
||||||
|
passwordHash: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('Done');
|
||||||
|
await prisma.\$disconnect();
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then use the magic-link login flow at `http://UNRAID-IP:8080` to sign in with
|
||||||
|
`admin@example.org`. The magic link will arrive at the SMTP address you configured.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Method 2 — GUI via Compose Manager Plugin
|
||||||
|
|
||||||
|
The **Docker Compose Manager** plugin lets you manage compose stacks entirely from
|
||||||
|
the Unraid web interface without touching the terminal.
|
||||||
|
|
||||||
|
### 1. Install the plugin
|
||||||
|
|
||||||
|
1. Open **Unraid web UI → Apps** (Community Applications).
|
||||||
|
2. Search for **"Compose Manager"**.
|
||||||
|
3. Click **Install** on the result by *dcflachs*.
|
||||||
|
4. After installation, a new **Compose** tab appears in the Docker section.
|
||||||
|
|
||||||
|
### 2. Upload the source files
|
||||||
|
|
||||||
|
The plugin reads compose files from `/boot/config/plugins/compose.manager/projects/`.
|
||||||
|
Each project is a subdirectory containing `docker-compose.yml` and optionally a `.env`.
|
||||||
|
|
||||||
|
**Option A — File Manager plugin (easiest)**
|
||||||
|
|
||||||
|
1. Install **Unraid File Manager** from Community Applications.
|
||||||
|
2. Navigate to `/boot/config/plugins/compose.manager/projects/`.
|
||||||
|
3. Create a folder named `storybid`.
|
||||||
|
4. Upload `docker-compose.yml` and your completed `.env` into that folder.
|
||||||
|
|
||||||
|
**Option B — SCP from your workstation**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From your workstation
|
||||||
|
scp docker-compose.yml root@192.168.1.X:/boot/config/plugins/compose.manager/projects/storybid/
|
||||||
|
scp .env root@192.168.1.X:/boot/config/plugins/compose.manager/projects/storybid/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Set explicit volume bind mounts
|
||||||
|
|
||||||
|
Before starting, edit `docker-compose.yml` to replace Docker-managed volumes with
|
||||||
|
explicit host paths so Unraid can show them in the GUI (same change as step 4 of the
|
||||||
|
CLI method above):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/postgres
|
||||||
|
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/redis
|
||||||
|
|
||||||
|
media_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/storybid/uploads
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the host directories via **Unraid → Tools → New Terminal**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/user/appdata/storybid/{postgres,redis,uploads}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Configure environment variables in the GUI
|
||||||
|
|
||||||
|
1. In the **Compose** tab, click the **storybid** project row.
|
||||||
|
2. Click **Edit** to open the compose file editor — verify paths look correct.
|
||||||
|
3. Click the **⚙ Environment** button (or edit the `.env` file directly via File
|
||||||
|
Manager).
|
||||||
|
4. Set every variable listed in the [Environment Variables Reference](#environment-variables-reference)
|
||||||
|
above. At minimum:
|
||||||
|
|
||||||
|
| Key | Value |
|
||||||
|
|---|---|
|
||||||
|
| `NODE_ENV` | `production` |
|
||||||
|
| `PUBLIC_URL` | `https://bid.example.org` |
|
||||||
|
| `JWT_SECRET` | *(64-char random string — generate in Terminal with `openssl rand -hex 32`)* |
|
||||||
|
| `DATABASE_URL` | `postgresql://storybid:CHANGE_ME@db:5432/storybid` |
|
||||||
|
| `STRIPE_SECRET_KEY` | `sk_live_…` |
|
||||||
|
| `STRIPE_PUBLISHABLE_KEY` | `pk_live_…` |
|
||||||
|
| `STRIPE_WEBHOOK_SECRET` | `whsec_…` |
|
||||||
|
| `SMTP_HOST` | your SMTP server |
|
||||||
|
| `SMTP_USER` | sender address |
|
||||||
|
| `SMTP_PASS` | SMTP password |
|
||||||
|
| `EMAIL_FROM` | `Storybid <noreply@example.org>` |
|
||||||
|
|
||||||
|
5. Click **Save**.
|
||||||
|
|
||||||
|
### 5. Build and start the stack
|
||||||
|
|
||||||
|
1. In the **Compose** tab, click **Up** (▶) next to **storybid**.
|
||||||
|
2. The compose manager opens a build log window. First build takes 3–5 minutes.
|
||||||
|
3. When all containers show **Running**, close the log.
|
||||||
|
|
||||||
|
### 6. Run migrations via the terminal
|
||||||
|
|
||||||
|
The GUI plugin does not yet have a built-in `exec` interface, so open a terminal for
|
||||||
|
this one step:
|
||||||
|
|
||||||
|
**Unraid → Tools → New Terminal**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec storybid-server-1 npx prisma migrate deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
> The container name format is `<project>-<service>-1`. If yours differs, run
|
||||||
|
> `docker ps` to find the exact name.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reverse Proxy (Nginx Proxy Manager)
|
||||||
|
|
||||||
|
Storybid needs HTTPS for Stripe webhooks, PWA installation, and the camera API used
|
||||||
|
by the check-in page. **Nginx Proxy Manager** is the easiest option on Unraid.
|
||||||
|
|
||||||
|
### Install Nginx Proxy Manager
|
||||||
|
|
||||||
|
Search **"Nginx Proxy Manager"** in Community Applications and install it. Default
|
||||||
|
ports: HTTP 80, HTTPS 443, Admin UI 81.
|
||||||
|
|
||||||
|
### Add a proxy host for the client
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|---|---|
|
||||||
|
| Domain Names | `bid.example.org` |
|
||||||
|
| Scheme | `http` |
|
||||||
|
| Forward Hostname / IP | Unraid LAN IP (e.g. `192.168.1.50`) |
|
||||||
|
| Forward Port | `8080` |
|
||||||
|
| SSL Certificate | Request via Let's Encrypt (built into the GUI) |
|
||||||
|
| Force SSL | ✅ |
|
||||||
|
| HTTP/2 Support | ✅ |
|
||||||
|
|
||||||
|
### Add a proxy host for the API + WebSocket
|
||||||
|
|
||||||
|
Create a **second** proxy host (or add a location block) if your client and server are
|
||||||
|
on different subdomains, otherwise the single `bid.example.org` host handles both
|
||||||
|
because the Nginx config inside the client container already proxies `/api` and
|
||||||
|
`/socket.io` to `server:3001`.
|
||||||
|
|
||||||
|
If you prefer separate subdomains:
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|---|---|
|
||||||
|
| Domain Names | `api.example.org` |
|
||||||
|
| Scheme | `http` |
|
||||||
|
| Forward Hostname / IP | `192.168.1.50` |
|
||||||
|
| Forward Port | `3001` |
|
||||||
|
| SSL | Let's Encrypt |
|
||||||
|
| WebSockets Support | ✅ |
|
||||||
|
|
||||||
|
Then update `PUBLIC_URL` and `CLIENT_URL` in `.env` accordingly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Register the Stripe Webhook
|
||||||
|
|
||||||
|
1. Go to **Stripe Dashboard → Developers → Webhooks → Add endpoint**.
|
||||||
|
2. Endpoint URL: `https://bid.example.org/api/webhooks/stripe`
|
||||||
|
3. Events to listen for:
|
||||||
|
- `payment_intent.succeeded`
|
||||||
|
- `payment_intent.payment_failed`
|
||||||
|
4. Click **Add endpoint**.
|
||||||
|
5. Copy the **Signing secret** (`whsec_…`) into `STRIPE_WEBHOOK_SECRET` in `.env`.
|
||||||
|
6. Restart the server container to pick up the new value:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# CLI
|
||||||
|
docker compose restart server
|
||||||
|
|
||||||
|
# GUI — Compose tab → storybid → Restart
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Updating Storybid
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/user/appdata/storybid/repo
|
||||||
|
git pull
|
||||||
|
docker compose up -d --build
|
||||||
|
docker compose exec server npx prisma migrate deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### GUI
|
||||||
|
|
||||||
|
1. Transfer the updated `docker-compose.yml` to the project folder (same path as
|
||||||
|
installation).
|
||||||
|
2. **Compose tab → storybid → Pull + Up** — this rebuilds images and restarts containers.
|
||||||
|
3. Open **Unraid → Tools → New Terminal** and run:
|
||||||
|
```bash
|
||||||
|
docker exec storybid-server-1 npx prisma migrate deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Port Reference
|
||||||
|
|
||||||
|
| Port | Service | Exposed to |
|
||||||
|
|---|---|---|
|
||||||
|
| `3001` | API server | Reverse proxy / LAN |
|
||||||
|
| `8080` | Client (Nginx) | Reverse proxy / LAN |
|
||||||
|
| `5432` | PostgreSQL | LAN only (close in production if not needed) |
|
||||||
|
| `6379` | Redis | LAN only (close in production if not needed) |
|
||||||
|
|
||||||
|
To restrict Postgres and Redis to the Docker internal network only (recommended for
|
||||||
|
production), remove their `ports:` entries from `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Remove or comment out these blocks:
|
||||||
|
db:
|
||||||
|
ports:
|
||||||
|
- "5432:5432" # ← remove
|
||||||
|
|
||||||
|
redis:
|
||||||
|
ports:
|
||||||
|
- "6379:6379" # ← remove
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Containers restart immediately
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose logs server # check for DATABASE_URL or JWT_SECRET errors
|
||||||
|
docker compose logs db # check for volume permission issues
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migration fails with "relation already exists"
|
||||||
|
|
||||||
|
The database was already migrated. This is safe to ignore, or run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec server npx prisma migrate status
|
||||||
|
```
|
||||||
|
|
||||||
|
### `STRIPE_SECRET_KEY is not configured` error in logs
|
||||||
|
|
||||||
|
The `.env` file is not being loaded. Verify:
|
||||||
|
|
||||||
|
- `.env` is in the same directory as `docker-compose.yml`.
|
||||||
|
- The `server` service in `docker-compose.yml` has `env_file: .env`.
|
||||||
|
- No trailing whitespace or Windows line endings in `.env`
|
||||||
|
(`dos2unix .env` fixes CRLF issues).
|
||||||
|
|
||||||
|
### Media uploads return 404
|
||||||
|
|
||||||
|
Check that the `uploads` bind-mount directory exists and is writable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -la /mnt/user/appdata/storybid/uploads
|
||||||
|
chmod 755 /mnt/user/appdata/storybid/uploads
|
||||||
|
docker compose restart server
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bidders can't connect via local LAN hostname
|
||||||
|
|
||||||
|
1. Verify the DNS record resolves from a device on the event Wi-Fi:
|
||||||
|
```bash
|
||||||
|
nslookup auction.event.lan
|
||||||
|
```
|
||||||
|
2. Confirm `LOCAL_HOSTNAME` in `.env` matches the DNS record exactly.
|
||||||
|
3. See [unifi-dns.md](./unifi-dns.md) for full UniFi DNS setup steps.
|
||||||
|
|
||||||
|
### Compose Manager shows "project not found"
|
||||||
|
|
||||||
|
The project directory must be inside `/boot/config/plugins/compose.manager/projects/`.
|
||||||
|
Files on `/mnt/user/` shares are not read by the plugin. Use SCP or File Manager to
|
||||||
|
place files in the correct location on `/boot`.
|
||||||
Reference in New Issue
Block a user