Initial commit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,730 @@
|
||||
# RV50x Template Manager — Docker Edition
|
||||
|
||||
A containerized web-based tool for managing configuration templates on Sierra Wireless AirLink RV50x modems. Runs as a full Docker stack including the web application, NocoDB, and PostgreSQL — start and stop the entire thing with a single command.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Stack Overview](#stack-overview)
|
||||
2. [Requirements](#requirements)
|
||||
3. [Project Structure](#project-structure)
|
||||
4. [First-Time Setup](#first-time-setup)
|
||||
5. [The .env File](#the-env-file)
|
||||
6. [Building and Starting](#building-and-starting)
|
||||
7. [NocoDB Setup](#nocodb-setup)
|
||||
8. [Updating the App](#updating-the-app)
|
||||
9. [Managing the Stack](#managing-the-stack)
|
||||
10. [Using Portainer](#using-portainer)
|
||||
11. [Migrating to a New Machine](#migrating-to-a-new-machine)
|
||||
12. [Reconnecting to a New NocoDB Instance](#reconnecting-to-a-new-nocodb-instance)
|
||||
13. [Data and Volumes](#data-and-volumes)
|
||||
14. [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Stack Overview
|
||||
|
||||
The stack runs three containers:
|
||||
|
||||
| Container | Image | Purpose | Default Port |
|
||||
|---|---|---|---|
|
||||
| `rv50x-manager` | Built from `Dockerfile` | FastAPI web app + Playwright | Your choice |
|
||||
| `rv50x-nocodb` | `nocodb/nocodb:latest` | NocoDB UI and API | 8090 |
|
||||
| `rv50x-postgres` | `postgres:16-alpine` | PostgreSQL database for NocoDB | Internal only |
|
||||
|
||||
All three containers communicate over a private internal Docker network. PostgreSQL is never exposed to the host — only NocoDB can reach it. The web app talks to NocoDB via the internal hostname `nocodb`.
|
||||
|
||||
```
|
||||
Your Browser
|
||||
│
|
||||
▼
|
||||
rv50x-manager (YOUR_PORT) ──→ nocodb (8090) ──→ postgres (internal)
|
||||
│
|
||||
▼
|
||||
Your Modems (port 443, via Playwright)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker Engine 24+ or Docker Desktop
|
||||
- Docker Compose v2 (`docker compose` or `docker-compose`)
|
||||
- Network access from the Docker host to your modems on port 443
|
||||
- Portainer (optional, but recommended for easy management)
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
/opt/rv50x-manager/
|
||||
├── app.py ← FastAPI backend
|
||||
├── index.html ← Web UI
|
||||
├── requirements.txt ← Python dependencies
|
||||
├── Dockerfile ← Container build instructions
|
||||
├── docker-compose.yml ← Stack definition
|
||||
├── .env ← Your secrets and config (never commit this)
|
||||
├── .env.example ← Template for .env
|
||||
└── .dockerignore ← Files excluded from the Docker image
|
||||
```
|
||||
|
||||
**Not needed in the Docker folder** (kept separately if you want CLI access):
|
||||
- `download.py` / `upload.py` — standalone CLI scripts
|
||||
- `modems.csv` — legacy device list
|
||||
- `.venv/` — Python virtual environment
|
||||
|
||||
---
|
||||
|
||||
## First-Time Setup
|
||||
|
||||
### Step 1 — Install Docker
|
||||
|
||||
**Fedora / RHEL / Rocky:**
|
||||
```bash
|
||||
sudo dnf install -y docker docker-compose-plugin
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
sudo usermod -aG docker $USER # log out and back in after this
|
||||
```
|
||||
|
||||
**Debian / Ubuntu:**
|
||||
```bash
|
||||
sudo apt-get install -y docker.io docker-compose-plugin
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
Verify Docker is working:
|
||||
```bash
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
### Step 2 — Copy project files to the host machine
|
||||
|
||||
Create the install directory and set permissions, then copy your files:
|
||||
|
||||
```bash
|
||||
# Create the directory and give your user ownership
|
||||
sudo mkdir -p /opt/rv50x-manager
|
||||
sudo chown $USER:$USER /opt/rv50x-manager
|
||||
|
||||
# Copy all project files into it
|
||||
cp app.py index.html requirements.txt Dockerfile \
|
||||
docker-compose.yml .env.example .dockerignore \
|
||||
/opt/rv50x-manager/
|
||||
|
||||
cd /opt/rv50x-manager
|
||||
```
|
||||
|
||||
### Step 3 — Create your .env file
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
cp .env.example .env
|
||||
nano .env # or use any text editor
|
||||
```
|
||||
|
||||
See [The .env File](#the-env-file) section below for what to put in each field.
|
||||
|
||||
### Step 4 — Set your port
|
||||
|
||||
Open `/opt/rv50x-manager/docker-compose.yml` and find this line under `rv50x-manager`:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "YOUR_PORT:8000"
|
||||
```
|
||||
|
||||
Replace `YOUR_PORT` with the port number you want to use on the host machine. For example:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "8001:8000"
|
||||
```
|
||||
|
||||
The app will then be accessible at `http://host-ip:8001`.
|
||||
|
||||
### Step 5 — Build and start
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This builds the `rv50x-manager` image and starts all three containers. The first build takes a few minutes because it downloads the Playwright base image and installs Chromium.
|
||||
|
||||
### Step 6 — Set up NocoDB
|
||||
|
||||
See [NocoDB Setup](#nocodb-setup) below.
|
||||
|
||||
### Step 7 — Update .env with NocoDB IDs
|
||||
|
||||
After importing your data into NocoDB, update `.env` with the real IDs and restart the manager:
|
||||
|
||||
```bash
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
### Step 8 — Open the app
|
||||
|
||||
```
|
||||
http://your-docker-host-ip:YOUR_PORT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The .env File
|
||||
|
||||
Create this file by copying `.env.example` and filling in your values. It is read automatically by `docker-compose`. **Never commit this file to version control** — it contains passwords and API tokens.
|
||||
|
||||
```bash
|
||||
# ── NocoDB connection ──────────────────────────────────────────────────────
|
||||
#
|
||||
# Use "http://nocodb:8080" to connect to the NocoDB container in this stack.
|
||||
# Use your external NocoDB URL if you prefer to point at an existing instance.
|
||||
NOCODB_URL=http://nocodb:8080
|
||||
|
||||
# Your NocoDB API token.
|
||||
# Get it from: NocoDB → Profile (bottom-left) → Team & Settings → API Tokens
|
||||
# Tokens look like: eWU_ilelaCtNy1JzC7vf41DokkqFOovcLHM0zVml
|
||||
NOCODB_TOKEN=your-api-token-here
|
||||
|
||||
# These three IDs come from the NocoDB browser URL after you import your data.
|
||||
# The URL structure is:
|
||||
# http://host:8090/{org_id}/{BASE_ID}/{TABLE_ID}/{VIEW_ID}/table-name
|
||||
# Leave as placeholder for now — update after NocoDB setup (Step 6 above).
|
||||
NOCODB_BASE_ID=your-base-id-here
|
||||
NOCODB_TABLE_ID=your-table-id-here
|
||||
NOCODB_VIEW_ID=your-view-id-here
|
||||
|
||||
# ── PostgreSQL ─────────────────────────────────────────────────────────────
|
||||
# Internal password used between NocoDB and PostgreSQL containers only.
|
||||
# You will never need to type this manually — make it long and strong.
|
||||
POSTGRES_PASSWORD=SomeLongStrongPassword123!
|
||||
|
||||
# ── NocoDB JWT secret ──────────────────────────────────────────────────────
|
||||
# Any long random string used to sign NocoDB authentication tokens.
|
||||
# Generate one with: openssl rand -hex 32
|
||||
NC_JWT_SECRET=paste-a-long-random-string-here
|
||||
|
||||
# ── Playwright timeouts (optional) ────────────────────────────────────────
|
||||
# Uncomment and adjust if your modems are slow to respond. Values in ms.
|
||||
# PAGE_TIMEOUT=90000
|
||||
# DOWNLOAD_TIMEOUT=120000
|
||||
# UPLOAD_TIMEOUT=120000
|
||||
# MAX_RETRIES=3
|
||||
```
|
||||
|
||||
### Generating secrets
|
||||
|
||||
```bash
|
||||
# Generate a strong JWT secret
|
||||
openssl rand -hex 32
|
||||
|
||||
# Generate a strong password
|
||||
openssl rand -base64 24
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Building and Starting
|
||||
|
||||
### Build the image
|
||||
|
||||
```bash
|
||||
docker-compose build
|
||||
```
|
||||
|
||||
Only needed when `app.py`, `index.html`, or `requirements.txt` change. Skipped automatically if you just change `.env`.
|
||||
|
||||
### Start the stack
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
The `-d` flag runs containers in the background (detached mode). Without it the logs stream to your terminal and the stack stops when you close the terminal.
|
||||
|
||||
### Check that everything is running
|
||||
|
||||
```bash
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
You should see all three containers with status `running` or `healthy`.
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
# All containers
|
||||
docker-compose logs -f
|
||||
|
||||
# Just the web app
|
||||
docker-compose logs -f rv50x-manager
|
||||
|
||||
# Just NocoDB
|
||||
docker-compose logs -f rv50x-nocodb
|
||||
```
|
||||
|
||||
### Stop the stack
|
||||
|
||||
```bash
|
||||
docker-compose stop
|
||||
```
|
||||
|
||||
Stops all containers. Data is preserved in volumes. Start again with `docker-compose up -d`.
|
||||
|
||||
### Remove containers (keep data)
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
Removes containers but keeps all named volumes (your modem data, templates, downloads). Safe to run before a rebuild.
|
||||
|
||||
### Remove everything including data ⚠
|
||||
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
**This deletes all volumes** including your NocoDB database and all template files. Only use this if you want a completely clean slate.
|
||||
|
||||
---
|
||||
|
||||
## NocoDB Setup
|
||||
|
||||
After starting the stack for the first time, NocoDB needs to be configured before the web app can use it.
|
||||
|
||||
### Step 1 — Open NocoDB
|
||||
|
||||
```
|
||||
http://your-docker-host-ip:8090
|
||||
```
|
||||
|
||||
### Step 2 — Create your account
|
||||
|
||||
On first launch NocoDB will prompt you to create an admin account. Use a strong password and note the credentials.
|
||||
|
||||
### Step 3 — Create a new base
|
||||
|
||||
Click **+ New Base** and name it something like `Cell Modems`.
|
||||
|
||||
### Step 4 — Import your modem data from CSV
|
||||
|
||||
1. Export your current modem data from your existing NocoDB instance: **toolbar → Download → CSV**
|
||||
2. In the new NocoDB, click **+ Add or import** → **Import from CSV**
|
||||
3. Upload the CSV file
|
||||
4. NocoDB will auto-detect all columns including `hostname`, `ip_address`, `dept`, `password`, etc.
|
||||
5. Confirm the import
|
||||
|
||||
### Step 5 — Recreate filtered views
|
||||
|
||||
The CSV import brings the data but not the views. Recreate them manually:
|
||||
|
||||
**Electric view:**
|
||||
1. In the left sidebar, click **+ Add View** → **Grid**
|
||||
2. Name it `Electric`
|
||||
3. Click **Filter** → **+ Add Filter**
|
||||
4. Set: `dept` `is` `ELEC`
|
||||
|
||||
**Gas & Water view:**
|
||||
1. Click **+ Add View** → **Grid**
|
||||
2. Name it `Gas & Water`
|
||||
3. Click **Filter** → **+ Add Filter**
|
||||
4. Set: `dept` `is` `GW`
|
||||
|
||||
### Step 6 — Get the IDs from the browser URL
|
||||
|
||||
Navigate to your Cell Modems table. The URL will look like:
|
||||
|
||||
```
|
||||
http://host:8090/abc123def/BASE_ID_HERE/TABLE_ID_HERE/VIEW_ID_HERE/cell-modems
|
||||
```
|
||||
|
||||
Copy `BASE_ID_HERE`, `TABLE_ID_HERE`, and `VIEW_ID_HERE` (use the All view ID).
|
||||
|
||||
### Step 7 — Generate an API token
|
||||
|
||||
1. Click your profile avatar (bottom-left)
|
||||
2. Go to **Team & Settings → API Tokens**
|
||||
3. Click **Add Token**, give it a name like `rv50x-manager`
|
||||
4. Copy the token
|
||||
|
||||
### Step 8 — Update .env and restart
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
nano .env
|
||||
# Update NOCODB_TOKEN, NOCODB_BASE_ID, NOCODB_TABLE_ID, NOCODB_VIEW_ID
|
||||
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
### Step 9 — Verify the connection
|
||||
|
||||
Open the web app and check that the device groups show the correct counts. If devices appear, the connection is working.
|
||||
|
||||
---
|
||||
|
||||
## Updating the App
|
||||
|
||||
When `app.py` or `index.html` change:
|
||||
|
||||
```bash
|
||||
# Stop the stack
|
||||
docker-compose stop
|
||||
|
||||
# Rebuild the manager image (NocoDB and Postgres don't need rebuilding)
|
||||
docker-compose build rv50x-manager
|
||||
|
||||
# Start everything back up
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
When only `.env` changes (NocoDB IDs, token, timeouts):
|
||||
|
||||
```bash
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
When `requirements.txt` changes (new Python packages):
|
||||
|
||||
```bash
|
||||
docker-compose build rv50x-manager
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Managing the Stack
|
||||
|
||||
### Start individual services
|
||||
|
||||
```bash
|
||||
docker-compose up -d postgres # start just postgres
|
||||
docker-compose up -d nocodb # start just nocodb
|
||||
docker-compose up -d rv50x-manager # start just the web app
|
||||
```
|
||||
|
||||
### Restart a single service
|
||||
|
||||
```bash
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
### Rebuild and restart a single service
|
||||
|
||||
```bash
|
||||
docker-compose up -d --build rv50x-manager
|
||||
```
|
||||
|
||||
### Execute a command inside a running container
|
||||
|
||||
```bash
|
||||
# Open a shell in the web app container
|
||||
docker exec -it rv50x-manager bash
|
||||
|
||||
# Check Python packages installed
|
||||
docker exec rv50x-manager pip list
|
||||
|
||||
# Test NocoDB connection from inside the container
|
||||
docker exec rv50x-manager curl -s http://nocodb:8080/api/v1/health
|
||||
```
|
||||
|
||||
### Access the PostgreSQL database directly
|
||||
|
||||
```bash
|
||||
docker exec -it rv50x-postgres psql -U nocodb -d nocodb
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using Portainer
|
||||
|
||||
Portainer gives you a browser-based UI to manage the entire stack without needing SSH.
|
||||
|
||||
### Install Portainer (if not already installed)
|
||||
|
||||
```bash
|
||||
docker volume create portainer_data
|
||||
docker run -d \
|
||||
-p 9000:9000 \
|
||||
--name portainer \
|
||||
--restart=always \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v portainer_data:/data \
|
||||
portainer/portainer-ce:latest
|
||||
```
|
||||
|
||||
Then open `http://host-ip:9000` and create your admin account.
|
||||
|
||||
### Deploy the stack via Portainer
|
||||
|
||||
1. Go to **Stacks → + Add Stack**
|
||||
2. Name it `rv50x`
|
||||
3. Paste the contents of `docker-compose.yml` into the editor
|
||||
4. Scroll down to **Environment Variables**
|
||||
5. Click **+ Add an environment variable** for each line in your `.env` file:
|
||||
|
||||
| Name | Value |
|
||||
|---|---|
|
||||
| `NOCODB_URL` | `http://nocodb:8080` |
|
||||
| `NOCODB_TOKEN` | your token |
|
||||
| `NOCODB_BASE_ID` | your base ID |
|
||||
| `NOCODB_TABLE_ID` | your table ID |
|
||||
| `NOCODB_VIEW_ID` | your view ID |
|
||||
| `POSTGRES_PASSWORD` | your password |
|
||||
| `NC_JWT_SECRET` | your secret |
|
||||
|
||||
6. Click **Deploy the stack**
|
||||
|
||||
### Start and stop via Portainer
|
||||
|
||||
- **Stacks → rv50x → Start** — starts all containers
|
||||
- **Stacks → rv50x → Stop** — stops all containers
|
||||
- Individual containers: **Containers** list → click the start/stop icons
|
||||
|
||||
### Update the stack via Portainer
|
||||
|
||||
1. **Stacks → rv50x → Editor**
|
||||
2. Paste updated `docker-compose.yml`
|
||||
3. Click **Update the stack**
|
||||
|
||||
For code changes (`app.py`, `index.html`), you need to rebuild the image first from the command line:
|
||||
|
||||
```bash
|
||||
docker-compose build rv50x-manager
|
||||
```
|
||||
|
||||
Then update the stack in Portainer to pick up the new image.
|
||||
|
||||
---
|
||||
|
||||
## Migrating to a New Machine
|
||||
|
||||
### Step 1 — Export your NocoDB data
|
||||
|
||||
Before migrating, export your modem data as CSV from the current NocoDB instance so you can reimport it on the new machine.
|
||||
|
||||
In NocoDB: **Cell Modems table → toolbar → Download → CSV**
|
||||
|
||||
### Step 2 — Copy project files
|
||||
|
||||
From the old machine:
|
||||
|
||||
```bash
|
||||
scp app.py index.html requirements.txt Dockerfile docker-compose.yml \
|
||||
.env.example .dockerignore youruser@new-host:/tmp/rv50x-transfer/
|
||||
```
|
||||
|
||||
**Do not copy `.env`** over an insecure connection — recreate it manually on the new machine.
|
||||
|
||||
On the new machine, move files into place:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/rv50x-manager
|
||||
sudo chown $USER:$USER /opt/rv50x-manager
|
||||
cp /tmp/rv50x-transfer/* /opt/rv50x-manager/
|
||||
```
|
||||
|
||||
### Step 3 — Copy template files (optional)
|
||||
|
||||
If you want to keep your existing XML templates, downloaded configs, and upload files:
|
||||
|
||||
```bash
|
||||
# Export volumes from the old machine
|
||||
cd /opt/rv50x-manager
|
||||
|
||||
docker run --rm \
|
||||
-v rv50x-manager_xml_templates:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar czf /backup/xml_templates.tar.gz -C /data .
|
||||
|
||||
docker run --rm \
|
||||
-v rv50x-manager_template_downloads:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar czf /backup/template_downloads.tar.gz -C /data .
|
||||
|
||||
docker run --rm \
|
||||
-v rv50x-manager_template_uploads:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar czf /backup/template_uploads.tar.gz -C /data .
|
||||
|
||||
# Copy archives to new machine
|
||||
scp xml_templates.tar.gz template_downloads.tar.gz template_uploads.tar.gz \
|
||||
youruser@new-host:/opt/rv50x-manager/
|
||||
```
|
||||
|
||||
### Step 4 — Set up the new machine
|
||||
|
||||
```bash
|
||||
# Install Docker (see First-Time Setup above)
|
||||
|
||||
# Files should already be in /opt/rv50x-manager from Step 2
|
||||
cd /opt/rv50x-manager
|
||||
|
||||
# Create fresh .env with new passwords and secrets
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
|
||||
# Set your port
|
||||
nano docker-compose.yml
|
||||
|
||||
# Build and start
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Step 5 — Restore template files (if copied)
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
|
||||
# Restore xml_templates
|
||||
docker run --rm \
|
||||
-v rv50x-manager_xml_templates:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar xzf /backup/xml_templates.tar.gz -C /data
|
||||
|
||||
# Restore template_downloads
|
||||
docker run --rm \
|
||||
-v rv50x-manager_template_downloads:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar xzf /backup/template_downloads.tar.gz -C /data
|
||||
|
||||
# Restore template_uploads
|
||||
docker run --rm \
|
||||
-v rv50x-manager_template_uploads:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar xzf /backup/template_uploads.tar.gz -C /data
|
||||
```
|
||||
|
||||
### Step 6 — Set up NocoDB on the new machine
|
||||
|
||||
Follow the [NocoDB Setup](#nocodb-setup) section — import your CSV, recreate views, get new IDs.
|
||||
|
||||
### Step 7 — Update .env with new NocoDB IDs
|
||||
|
||||
```bash
|
||||
nano .env
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reconnecting to a New NocoDB Instance
|
||||
|
||||
If your NocoDB database is corrupted, rebuilt, or moved to a new server:
|
||||
|
||||
### Step 1 — Get the new connection details
|
||||
|
||||
1. Open the new NocoDB in your browser
|
||||
2. Import your modem data from CSV
|
||||
3. Recreate the Electric and Gas & Water filtered views
|
||||
4. Go to **Profile → Team & Settings → API Tokens** → create a new token
|
||||
5. Copy the base ID, table ID, and view ID from the browser URL
|
||||
|
||||
### Step 2 — Test the connection
|
||||
|
||||
```bash
|
||||
curl -H "xc-token: YOUR_NEW_TOKEN" \
|
||||
"http://new-nocodb-host:8090/api/v1/db/data/noco/BASE_ID/TABLE_ID?limit=1"
|
||||
```
|
||||
|
||||
A successful response returns JSON with a `list` array containing your first modem row.
|
||||
|
||||
### Step 3 — Update .env
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
nano .env
|
||||
```
|
||||
|
||||
Update these values:
|
||||
|
||||
```bash
|
||||
NOCODB_URL=http://new-host:8090 # or http://nocodb:8080 if using the stack
|
||||
NOCODB_TOKEN=your-new-token
|
||||
NOCODB_BASE_ID=your-new-base-id
|
||||
NOCODB_TABLE_ID=your-new-table-id
|
||||
NOCODB_VIEW_ID=your-new-view-id
|
||||
```
|
||||
|
||||
### Step 4 — Restart the manager
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
docker-compose restart rv50x-manager
|
||||
```
|
||||
|
||||
Or in Portainer: **Stacks → rv50x → rv50x-manager → Restart**
|
||||
|
||||
---
|
||||
|
||||
## Data and Volumes
|
||||
|
||||
All persistent data lives in Docker named volumes. They survive `docker-compose down` and rebuilds, and are only deleted with `docker-compose down -v`.
|
||||
|
||||
| Volume | Contents | Maps to container path |
|
||||
|---|---|---|
|
||||
| `rv50x_template_manager_postgres_data` | NocoDB database | `/var/lib/postgresql/data` |
|
||||
| `rv50x_template_manager_nocodb_data` | NocoDB config and uploads | `/usr/app/data` |
|
||||
| `rv50x_template_manager_template_downloads` | Downloaded modem configs + reports | `/data/template_downloads` |
|
||||
| `rv50x_template_manager_template_uploads` | Staged XML files for upload + reports | `/data/template_uploads` |
|
||||
| `rv50x_template_manager_xml_templates` | Your XML builder templates | `/data/xml_templates` |
|
||||
|
||||
### List all volumes
|
||||
|
||||
```bash
|
||||
docker volume ls | grep rv50x
|
||||
```
|
||||
|
||||
### Back up a volume
|
||||
|
||||
```bash
|
||||
# Backs up the xml_templates volume to a tar file in the current directory
|
||||
docker run --rm \
|
||||
-v rv50x_template_manager_xml_templates:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar czf /backup/xml_templates_backup.tar.gz -C /data .
|
||||
```
|
||||
|
||||
### Back up the NocoDB database
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
docker exec rv50x-postgres \
|
||||
pg_dump -U nocodb nocodb > nocodb_backup_$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
### Restore the NocoDB database
|
||||
|
||||
```bash
|
||||
cd /opt/rv50x-manager
|
||||
docker exec -i rv50x-postgres \
|
||||
psql -U nocodb nocodb < nocodb_backup_20260413.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
|---|---|---|
|
||||
| `docker-compose: command not found` | Using older Docker without compose plugin | Use `docker compose` (space not hyphen) or install `docker-compose-plugin` |
|
||||
| Build fails with "no space left on device" | Docker image cache full | Run `docker system prune` to free space |
|
||||
| `rv50x-manager` exits immediately after start | App crash on startup — bad .env values | Run `docker-compose logs rv50x-manager` to see the error |
|
||||
| NocoDB shows "Service Unavailable" | Postgres not ready yet | Wait 30s and refresh — healthcheck retries handle this automatically |
|
||||
| Web app shows 0 devices | NocoDB IDs wrong or token invalid | Test with curl (see Reconnecting section), update .env, restart manager |
|
||||
| `ERR_BASE_NOT_FOUND` in curl test | Wrong NOCODB_BASE_ID | Re-read the ID from the NocoDB browser URL |
|
||||
| `ERR_AUTHENTICATION_REQUIRED` | Wrong or expired token | Regenerate token in NocoDB → API Tokens |
|
||||
| Modems show in All but not Electric/Gas & Water | Wrong dept field values | Check actual `dept` values in NocoDB — must be exactly `ELEC` and `GW` |
|
||||
| Playwright / Chromium crashes | Missing system library | The Playwright base image should have everything — check `docker-compose logs rv50x-manager` |
|
||||
| Template upload times out | Modem slow or unreachable | Increase `UPLOAD_TIMEOUT` in `.env`, restart manager |
|
||||
| Can't reach NocoDB at port 8090 | Port conflict or firewall | Change the left port in `docker-compose.yml` under `nocodb:` ports |
|
||||
| Can't reach web app | Port conflict or firewall | Change `YOUR_PORT` in `docker-compose.yml` |
|
||||
| `permission denied` on docker commands | User not in docker group | Run `sudo usermod -aG docker $USER` then log out and back in |
|
||||
| Volume data missing after `docker-compose down` | Used `down -v` by mistake | Data is gone — restore from backup or re-import CSV |
|
||||
Reference in New Issue
Block a user