1 file changed
+25
-5
@@ -45,7 +45,7 @@ echo "MANAGER_SETTINGS_ENCRYPTION_KEY=$(openssl rand -hex 32)"
|
||||
# so this works with nothing but Docker installed on the host.
|
||||
docker run --rm node:22-alpine sh -c \
|
||||
"mkdir -p /tmp/gen && cd /tmp/gen && npm install bcryptjs --no-audit --no-fund >/dev/null 2>&1 && \
|
||||
node -e \"console.log('MANAGER_PASSWORD_HASH=' + require('/tmp/gen/node_modules/bcryptjs').hashSync('your-password', 12))\""
|
||||
node -e \"const h=require('/tmp/gen/node_modules/bcryptjs').hashSync('your-password',12); console.log('MANAGER_PASSWORD_HASH=\\\"'+h.replace(/\\$/g,'\\$\\$')+'\\\"')\""
|
||||
```
|
||||
|
||||
### 1. Shared infrastructure — network, MySQL, Caddy, Dockge
|
||||
@@ -58,6 +58,7 @@ cp .env.infra.example stacks/infra/.env
|
||||
|
||||
Edit `stacks/infra/.env`:
|
||||
- `MYSQL_ROOT_PASSWORD` — the first secret you generated above.
|
||||
- `MYSQL_HOST_PORT` — set this to `127.0.0.1:3306` so MySQL is only exposed on the VPS loopback interface, not publicly. You can still connect to it remotely through an SSH tunnel.
|
||||
- `ACME_EMAIL` — a real address you check (Let's Encrypt renewal notices).
|
||||
- `STACKS_DIR` — the absolute clone path, e.g. `/opt/nextchair/stacks`.
|
||||
|
||||
@@ -140,11 +141,29 @@ Repeat this step for each additional business, whenever you want one.
|
||||
|
||||
## Updating after a code change
|
||||
|
||||
For an existing NextChair server, **do not re-run the fresh VPS setup above** and do not overwrite your production `.env` files.
|
||||
|
||||
First pull the latest code:
|
||||
|
||||
```bash
|
||||
cd /opt/nextchair
|
||||
git pull
|
||||
```
|
||||
|
||||
# Rebuild the one shared image every business uses.
|
||||
Before rebuilding, check whether either example environment file has gained new settings since your last deployment:
|
||||
|
||||
```bash
|
||||
# Review only — do not copy these files over your existing production .env files.
|
||||
diff -u stacks/infra/.env .env.infra.example || true
|
||||
diff -u stacks/manager/.env manager/.env.example || true
|
||||
```
|
||||
|
||||
If a new variable has been added, copy **only that variable** into the corresponding production `.env` and give it an appropriate value. Keep all existing passwords, secrets and generated values unchanged.
|
||||
|
||||
Then rebuild the one shared image every business uses:
|
||||
|
||||
```bash
|
||||
cd /opt/nextchair
|
||||
docker build -t nextchair-app:latest .
|
||||
```
|
||||
|
||||
@@ -152,7 +171,7 @@ Then, for **each** business: use its **Update** button in the Manager UI,
|
||||
or run this directly:
|
||||
|
||||
```bash
|
||||
cd stacks/<slug>
|
||||
cd /opt/nextchair/stacks/<slug>
|
||||
docker compose --env-file .env up -d --force-recreate
|
||||
```
|
||||
|
||||
@@ -162,10 +181,11 @@ built image — and its own startup automatically runs
|
||||
same step. No separate migration command needed.
|
||||
|
||||
If the code change touched the **Manager app itself** (anything under
|
||||
`manager/`), update it the same way — this one does rebuild, since unlike
|
||||
a business it doesn't share a prebuilt image:
|
||||
`manager/`), rebuild/recreate the Manager too:
|
||||
|
||||
```bash
|
||||
cd /opt/nextchair
|
||||
docker compose -f stacks/manager/compose.yaml --env-file stacks/manager/.env up -d --build
|
||||
```
|
||||
|
||||
If both the business app and Manager changed, do both update steps.
|
||||
Reference in new issue
Block a user