Add Unraid deployment via the Portainer API
ops/deploy.py ships each service's build context to the remote Docker daemon's /build endpoint and pushes docker-compose.prod.yml as a Portainer stack — there is no docker CLI in WSL and Unraid's SSH is closed. The prod compose file drops the dev bind mounts and uvicorn --reload, publishes only the frontend port (8000 is taken by Portainer's Edge tunnel), and pins bms_net to 172.31.42.0/24 because the host's default address pools are fully subnetted. Mosquitto's config is baked into an image since the repo is not checked out on the host. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d4a104be9d
commit
de9b8c51bd
5 changed files with 510 additions and 22 deletions
55
README.md
55
README.md
|
|
@ -43,14 +43,12 @@ cd bms
|
|||
|
||||
### 2. Create the environment files
|
||||
|
||||
Copy the example files and fill in your values:
|
||||
|
||||
```bash
|
||||
cp backend/.env.example backend/.env
|
||||
cp frontend/.env.local.example frontend/.env.local
|
||||
```
|
||||
|
||||
Open each file and follow the inline comments. At minimum you need to set the Clerk keys (see [Environment Variables](#environment-variables) below).
|
||||
The defaults work as-is — they already match the service names in `docker-compose.yml`. **The app runs in demo mode with authentication disabled**, so there are no keys to obtain before the first run. See [Environment Variables](#environment-variables) below.
|
||||
|
||||
### 3. Start all services
|
||||
|
||||
|
|
@ -72,6 +70,14 @@ Open your browser at **http://your-server:5646**
|
|||
|
||||
## Environment Variables
|
||||
|
||||
> **Authentication is disabled.** The app runs in demo mode: `frontend/proxy.ts` passes every
|
||||
> request through and there is no auth provider in `app/layout.tsx`. Deploy it on a trusted
|
||||
> network (LAN, VPN, or behind an authenticating reverse proxy) — every route is open.
|
||||
>
|
||||
> To turn auth back on: reinstall `@clerk/nextjs`, wrap the tree in `<ClerkProvider>` in
|
||||
> `app/layout.tsx`, restore `<UserButton />` in `components/layout/topbar.tsx`, re-add the
|
||||
> `sign-in` / `sign-up` route groups, and swap `proxy.ts` for `clerkMiddleware`.
|
||||
|
||||
### `backend/.env`
|
||||
|
||||
```env
|
||||
|
|
@ -82,11 +88,6 @@ DATABASE_URL=postgresql+asyncpg://dcim:dcim_pass@db:5432/dcim
|
|||
MQTT_HOST=mqtt
|
||||
MQTT_PORT=1883
|
||||
|
||||
# Clerk authentication
|
||||
# Get these from https://dashboard.clerk.com → Your App → API Keys
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
CLERK_JWKS_URL=https://YOUR_APP.clerk.accounts.dev/.well-known/jwks.json
|
||||
|
||||
# CORS — add your frontend origin if you expose the backend directly
|
||||
# Leave empty when using the built-in Next.js proxy (recommended)
|
||||
CORS_ORIGINS=[]
|
||||
|
|
@ -97,23 +98,13 @@ DEBUG=true
|
|||
### `frontend/.env.local`
|
||||
|
||||
```env
|
||||
# Clerk authentication (same app as above)
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_REPLACE_ME
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
|
||||
# Clerk redirect paths — no need to change these
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
|
||||
|
||||
# API path — leave as-is, Next.js proxies /api/backend/* to the backend internally
|
||||
NEXT_PUBLIC_API_URL=/api/backend
|
||||
```
|
||||
|
||||
> **Where do I get Clerk keys?**
|
||||
> Sign up free at https://clerk.com → create an application → go to **API Keys**.
|
||||
> Copy the **Publishable key** and **Secret key** into both files above.
|
||||
# Backend internal URL (used by the Next.js server-side proxy, not sent to the browser)
|
||||
# In Docker: http://backend:8000 In local dev: http://localhost:8000
|
||||
BACKEND_INTERNAL_URL=http://backend:8000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -181,6 +172,26 @@ Browser → Reverse Proxy → :5646 (Next.js)
|
|||
|
||||
---
|
||||
|
||||
## Deploying to the Unraid Server
|
||||
|
||||
The live instance runs on the Unraid Docker host at `192.168.1.249` as the Portainer stack
|
||||
**`bms`** — reachable at **http://192.168.1.249:5646/dashboard**.
|
||||
|
||||
```bash
|
||||
python3 ops/deploy.py # build all four images + deploy/update the stack
|
||||
python3 ops/deploy.py --no-build # redeploy the stack using the existing images
|
||||
```
|
||||
|
||||
There is no `docker` CLI in WSL and no SSH to the Unraid box, so `ops/deploy.py` ships each
|
||||
service's build context to the remote daemon's `/build` endpoint over the Portainer API
|
||||
(token at `~/.portainer-token`), then pushes `docker-compose.prod.yml` as a Portainer stack.
|
||||
The script is idempotent — rerun it after any code change.
|
||||
|
||||
`docker-compose.prod.yml` differs from the dev `docker-compose.yml`: images instead of build
|
||||
contexts, no source bind mounts, no `--reload`, and only the frontend publishes a host port.
|
||||
Postgres data is bind-mounted to `/mnt/user/appdata/bms/db` so it lands on the Unraid array
|
||||
instead of growing inside `docker.img`, and it survives redeploys.
|
||||
|
||||
## Local Development (without Docker)
|
||||
|
||||
Useful if you want hot-reload on the frontend or backend without rebuilding containers.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue