Initial commit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
# ── RV50x Template Manager — Docker ignore ──────────────────────────────────
|
||||||
|
# Files and folders that should NOT be copied into the Docker image.
|
||||||
|
# Data directories are mounted as volumes instead.
|
||||||
|
|
||||||
|
# Virtual environment — dependencies are installed fresh in the image
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# Data directories — these are bind-mounted as named volumes
|
||||||
|
template_downloads/
|
||||||
|
template_uploads/
|
||||||
|
xml_templates/
|
||||||
|
|
||||||
|
# Legacy and backup scripts — not needed in the container
|
||||||
|
download_csv.py
|
||||||
|
upload_csv.py
|
||||||
|
rv50x_template_manager.py
|
||||||
|
modems.csv
|
||||||
|
|
||||||
|
# Standalone CLI scripts — the web app (app.py) replaces these in Docker
|
||||||
|
download.py
|
||||||
|
upload.py
|
||||||
|
|
||||||
|
# Reports — live in the volumes, not the image
|
||||||
|
report_*.txt
|
||||||
|
|
||||||
|
# Python cache
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
|
||||||
|
# Environment files — never bake secrets into the image
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
# Editor and OS files
|
||||||
|
.DS_Store
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# ── RV50x Template Manager — Environment Configuration ─────────────────────
|
||||||
|
#
|
||||||
|
# Copy this file to .env and fill in your values.
|
||||||
|
# Never commit .env to version control — it contains secrets.
|
||||||
|
#
|
||||||
|
# docker-compose reads this file automatically.
|
||||||
|
# For Portainer: paste these into the Environment Variables section of the stack.
|
||||||
|
# ───────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
# ── NocoDB connection ────────────────────────────────────────────────────────
|
||||||
|
#
|
||||||
|
# If using the built-in NocoDB from this stack:
|
||||||
|
# NOCODB_URL=http://nocodb:8080
|
||||||
|
#
|
||||||
|
# If pointing at an existing external NocoDB instance:
|
||||||
|
# NOCODB_URL=http://192.168.16.130:8080
|
||||||
|
#
|
||||||
|
# After spinning up the stack and importing your data, update the IDs below
|
||||||
|
# by reading them from the NocoDB browser URL:
|
||||||
|
# http://host/w98wg3nt/{NOCODB_BASE_ID}/{NOCODB_TABLE_ID}/{NOCODB_VIEW_ID}/...
|
||||||
|
|
||||||
|
NOCODB_URL=http://nocodb:8080
|
||||||
|
NOCODB_TOKEN=your-nocodb-api-token-here
|
||||||
|
NOCODB_BASE_ID=your-base-id-here
|
||||||
|
NOCODB_TABLE_ID=your-table-id-here
|
||||||
|
NOCODB_VIEW_ID=your-view-id-here
|
||||||
|
|
||||||
|
|
||||||
|
# ── PostgreSQL password ──────────────────────────────────────────────────────
|
||||||
|
# Used internally by NocoDB. Choose a strong password.
|
||||||
|
# You won't need to type this anywhere — it's only used container-to-container.
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=changeme_use_a_strong_password_here
|
||||||
|
|
||||||
|
|
||||||
|
# ── NocoDB JWT secret ────────────────────────────────────────────────────────
|
||||||
|
# Used to sign NocoDB auth tokens. Any long random string works.
|
||||||
|
# Generate one with: openssl rand -hex 32
|
||||||
|
|
||||||
|
NC_JWT_SECRET=changeme_use_a_long_random_string_here
|
||||||
|
|
||||||
|
|
||||||
|
# ── Playwright timeouts (optional — defaults shown) ──────────────────────────
|
||||||
|
# Increase these if your modems are slow to respond.
|
||||||
|
# Values are in milliseconds.
|
||||||
|
|
||||||
|
# PAGE_TIMEOUT=90000
|
||||||
|
# DOWNLOAD_TIMEOUT=120000
|
||||||
|
# UPLOAD_TIMEOUT=120000
|
||||||
|
# MAX_RETRIES=3
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
.env
|
||||||
|
certs/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
# ── RV50x Template Manager ─────────────────────────────────────────────────
|
||||||
|
# Uses the official Playwright Python image which has Chromium and all
|
||||||
|
# required system libraries pre-installed — no manual apt installs needed.
|
||||||
|
# ───────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/playwright/python:v1.44.0-jammy
|
||||||
|
|
||||||
|
# Set working directory inside the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# ── Install Python dependencies ─────────────────────────────────────────────
|
||||||
|
# Copy requirements first so Docker caches this layer — only rebuilds when
|
||||||
|
# requirements.txt changes, not every time app code changes.
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# ── Install Playwright's Chromium browser ───────────────────────────────────
|
||||||
|
# The base image has the system libs; this installs the actual browser binary.
|
||||||
|
RUN playwright install chromium
|
||||||
|
|
||||||
|
# ── Copy application files ──────────────────────────────────────────────────
|
||||||
|
COPY app.py .
|
||||||
|
COPY index.html .
|
||||||
|
|
||||||
|
# ── Create data directories ─────────────────────────────────────────────────
|
||||||
|
# These will be overridden by volume mounts in docker-compose, but we create
|
||||||
|
# them here so the app works even if volumes aren't configured.
|
||||||
|
RUN mkdir -p /data/template_downloads \
|
||||||
|
/data/template_uploads \
|
||||||
|
/data/xml_templates
|
||||||
|
|
||||||
|
# ── Environment defaults ────────────────────────────────────────────────────
|
||||||
|
# These are overridden by the .env file or docker-compose environment section.
|
||||||
|
ENV DOWNLOAD_DIR=/data/template_downloads
|
||||||
|
ENV UPLOAD_DIR=/data/template_uploads
|
||||||
|
ENV TEMPLATES_DIR=/data/xml_templates
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# ── Expose port ─────────────────────────────────────────────────────────────
|
||||||
|
# Change the left number in docker-compose.yml to remap to a different host port.
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# ── Start the application ───────────────────────────────────────────────────
|
||||||
|
# SSL_CERT and SSL_KEY env vars are optional — if set, uvicorn serves HTTPS.
|
||||||
|
# If not set, falls back to plain HTTP (useful for local dev).
|
||||||
|
CMD ["sh", "-c", "\
|
||||||
|
if [ -n \"$SSL_CERT\" ] && [ -n \"$SSL_KEY\" ]; then \
|
||||||
|
echo 'Starting with HTTPS'; \
|
||||||
|
python -m uvicorn app:app --host 0.0.0.0 --port 8000 \
|
||||||
|
--ssl-certfile \"$SSL_CERT\" --ssl-keyfile \"$SSL_KEY\"; \
|
||||||
|
else \
|
||||||
|
echo 'Starting with HTTP (no SSL vars set)'; \
|
||||||
|
python -m uvicorn app:app --host 0.0.0.0 --port 8000; \
|
||||||
|
fi"]
|
||||||
@@ -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 |
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
# ── RV50x Template Manager — Full Stack ────────────────────────────────────
|
||||||
|
#
|
||||||
|
# Services:
|
||||||
|
# rv50x-manager FastAPI web app + Playwright
|
||||||
|
# nocodb NocoDB UI and API
|
||||||
|
# postgres PostgreSQL database for NocoDB
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# Start: docker-compose up -d
|
||||||
|
# Stop: docker-compose stop
|
||||||
|
# Destroy: docker-compose down (data volumes preserved)
|
||||||
|
# Logs: docker-compose logs -f rv50x-manager
|
||||||
|
#
|
||||||
|
# Port mapping — change the LEFT number to use a different host port:
|
||||||
|
# rv50x-manager: http://host-ip:YOUR_PORT
|
||||||
|
# nocodb: http://host-ip:8090
|
||||||
|
# postgres: not exposed (internal only)
|
||||||
|
# ───────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
# ── RV50x Template Manager ────────────────────────────────────────────────
|
||||||
|
rv50x-manager:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rv50x-manager
|
||||||
|
restart: "no" # manual start only
|
||||||
|
ports:
|
||||||
|
- "8002:8000" # ← change YOUR_PORT to your chosen port
|
||||||
|
volumes:
|
||||||
|
# Bind mounts — files are directly accessible on the host at these paths.
|
||||||
|
# No sudo needed, no docker volume commands needed.
|
||||||
|
- /opt/rv50x-manager/template_downloads:/data/template_downloads
|
||||||
|
- /opt/rv50x-manager/template_uploads:/data/template_uploads
|
||||||
|
- /opt/rv50x-manager/xml_templates:/data/xml_templates
|
||||||
|
- /opt/rv50x-manager/certs:/certs:ro # SSL certificates (read-only)
|
||||||
|
environment:
|
||||||
|
# ── NocoDB connection ──────────────────────────────────────────────
|
||||||
|
# To use the built-in NocoDB from this stack, set NOCODB_URL to:
|
||||||
|
# http://nocodb:8080
|
||||||
|
# To use an external NocoDB instance, set it to that URL instead.
|
||||||
|
NOCODB_URL: ${NOCODB_URL}
|
||||||
|
NOCODB_TOKEN: ${NOCODB_TOKEN}
|
||||||
|
NOCODB_BASE_ID: ${NOCODB_BASE_ID}
|
||||||
|
NOCODB_TABLE_ID: ${NOCODB_TABLE_ID}
|
||||||
|
NOCODB_VIEW_ID: ${NOCODB_VIEW_ID}
|
||||||
|
# ── SSL certificate paths (inside the container) ───────────────────
|
||||||
|
SSL_CERT: /certs/cert.pem
|
||||||
|
SSL_KEY: /certs/key.pem
|
||||||
|
# ── Tunable timeouts (optional) ────────────────────────────────────
|
||||||
|
PAGE_TIMEOUT: ${PAGE_TIMEOUT:-90000}
|
||||||
|
DOWNLOAD_TIMEOUT: ${DOWNLOAD_TIMEOUT:-120000}
|
||||||
|
UPLOAD_TIMEOUT: ${UPLOAD_TIMEOUT:-120000}
|
||||||
|
MAX_RETRIES: ${MAX_RETRIES:-3}
|
||||||
|
APP_USERNAME: ${APP_USERNAME}
|
||||||
|
APP_PASSWORD: ${APP_PASSWORD}
|
||||||
|
SESSION_SECRET: ${SESSION_SECRET}
|
||||||
|
SESSION_HOURS: ${SESSION_HOURS:-8}
|
||||||
|
depends_on:
|
||||||
|
nocodb:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- rv50x-net
|
||||||
|
|
||||||
|
# ── NocoDB ───────────────────────────────────────────────────────────────
|
||||||
|
nocodb:
|
||||||
|
image: nocodb/nocodb:latest
|
||||||
|
container_name: rv50x-nocodb
|
||||||
|
restart: "no" # manual start only
|
||||||
|
ports:
|
||||||
|
- "8090:8080" # NocoDB UI on host port 8090
|
||||||
|
environment:
|
||||||
|
NC_DB: "pg://postgres:5432?u=nocodb&p=${POSTGRES_PASSWORD}&d=nocodb"
|
||||||
|
NC_AUTH_JWT_SECRET: ${NC_JWT_SECRET}
|
||||||
|
volumes:
|
||||||
|
- nocodb_data:/usr/app/data
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- rv50x-net
|
||||||
|
|
||||||
|
# ── PostgreSQL ───────────────────────────────────────────────────────────
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: rv50x-postgres
|
||||||
|
restart: "no" # manual start only
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: nocodb
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB: nocodb
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U nocodb"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 10
|
||||||
|
networks:
|
||||||
|
- rv50x-net
|
||||||
|
# Postgres is intentionally NOT exposed on a host port.
|
||||||
|
# Only NocoDB can reach it via the internal network.
|
||||||
|
|
||||||
|
# ── Named volumes — only postgres and nocodb use named volumes ───────────────
|
||||||
|
# template_downloads, template_uploads, and xml_templates use bind mounts
|
||||||
|
# above so files are directly accessible in /opt/rv50x-manager/ on the host.
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
nocodb_data:
|
||||||
|
|
||||||
|
# ── Internal network ────────────────────────────────────────────────────────
|
||||||
|
networks:
|
||||||
|
rv50x-net:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# This is the internal Docker service name — leave as-is if using the
|
||||||
|
# built-in NocoDB from the stack. Change to your external NocoDB IP
|
||||||
|
# if you want to point at your existing instance instead.
|
||||||
|
NOCODB_URL=http://nocodb:8080
|
||||||
|
|
||||||
|
# Your NocoDB API token — get this from:
|
||||||
|
# NocoDB → Profile (bottom left) → Team & Settings → API Tokens
|
||||||
|
NOCODB_TOKEN=eWU_ilelaCtNy1JzC7vf41DokkqFOovcLHM0zVml
|
||||||
|
|
||||||
|
# These three come from the NocoDB browser URL after you import your data.
|
||||||
|
# The URL looks like: http://host:8090/{org}/{BASE_ID}/{TABLE_ID}/{VIEW_ID}/...
|
||||||
|
NOCODB_BASE_ID=pdq96x915xt4a0m
|
||||||
|
NOCODB_TABLE_ID=mkewnr53ahqvnt9
|
||||||
|
NOCODB_VIEW_ID=vwl7qvxo1xclvawz
|
||||||
|
|
||||||
|
# Make up a strong password — you'll never type this manually,
|
||||||
|
# it's only used between the NocoDB and Postgres containers internally.
|
||||||
|
POSTGRES_PASSWORD=SomeLongStrongPassword123!
|
||||||
|
|
||||||
|
# Any long random string — used to sign NocoDB login tokens.
|
||||||
|
# Generate one with: openssl rand -hex 32
|
||||||
|
NC_JWT_SECRET=a1b2c3d4e5f6...
|
||||||
|
|
||||||
|
The order of operations for first setup:
|
||||||
|
|
||||||
|
Create .env with the passwords and secrets filled in — but leave the NocoDB IDs as placeholder values for now
|
||||||
|
Run docker-compose up -d to start the stack
|
||||||
|
Open NocoDB at http://host-ip:8090, create your account, import your CSV, recreate your views
|
||||||
|
Copy the real base/table/view IDs from the browser URL into .env
|
||||||
|
Run docker-compose restart rv50x-manager to pick up the new IDs
|
||||||
|
App is ready at http://host-ip:YOUR_PORT
|
||||||
+1672
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn[standard]
|
||||||
|
playwright
|
||||||
|
pandas
|
||||||
|
openpyxl
|
||||||
|
paramiko
|
||||||
|
itsdangerous
|
||||||
|
python-multipart
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user