Fix: integrera i befintlig nextcloud-node-red :1880, ingen ny container

This commit is contained in:
Hannes Ahlin
2026-08-22 15:23:33 +02:00
parent 971bc42469
commit 22157fe723
7 changed files with 302 additions and 283 deletions
+28 -34
View File
@@ -1,60 +1,54 @@
# nextcloud-collabora-nodered # nextcloud-collabora-nodered
Node-RED sidecar (port **1881**) med Collabora/Nextcloud Office-noder. Collabora/Nextcloud Office-noder för **befintlig** `nextcloud-node-red` på port **1880**.
**Version 1.0 — 22 augusti 2026** Skapar **ingen** ny Node-RED-container.
## Snabbaste installation (valfri VM) ## Installation (cloud / valfri VM)
```bash ```bash
curl -fsSL https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered/raw/branch/main/bootstrap-install.sh | bash curl -fsSL https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered/raw/branch/main/bootstrap-install.sh | sudo -u ncadmin bash
``` ```
Skriptet: Det skriptet:
- installerar git/curl/Docker om de saknas 1. Klonar detta repo till `/home/ncadmin/nextcloud-collabora-nodered`
- klonar från **Gitea** (`n3wk/nextcloud-collabora-nodered`) 2. Kopierar noder till `/home/ncadmin/nextcloud-node-red/nodes/nextcloud-collabora/`
- detekterar CODE-IP på Docker `bridge` 3. Patchar `Dockerfile` + `entrypoint.sh` i nextcloud-node-red
- bygger och startar Node-RED sidecar med alla noder 4. Bygger om **samma** `nextcloud-node-red`-image och startar om containern
- lämnar `:1880`, odds-scraper och CODE orörda 5. Ansluter `nextcloud-node-red` till Docker `bridge` så CODE (`172.17.0.2:9980`) nås
### Miljövariabler (valfritt) ## Uppdatera noder
```bash
GIT_REPO_URL=https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered.git \
INSTALL_DIR=/home/ncadmin/nextcloud-collabora-nodered \
NC_HOST=cloud.hannesahlin.se \
NC_HOST_IP=192.168.1.26 \
bash bootstrap-install.sh
```
## Manuell installation (repo redan klonat)
```bash ```bash
cd /home/ncadmin/nextcloud-collabora-nodered cd /home/ncadmin/nextcloud-collabora-nodered
git pull
./install.sh ./install.sh
``` ```
## Repo ## Manuell integration
- **Gitea:** https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered ```bash
- **SSH clone:** `ssh -p 2222 git@kode.hannesahlin.se:n3wk/nextcloud-collabora-nodered.git` cd /home/ncadmin/nextcloud-collabora-nodered
NODERED_DIR=/home/ncadmin/nextcloud-node-red ./scripts/integrate-into-nodered.sh
```
## Dokumentation ## Sidecar :1881 (ej rekommenderat)
- [docs/AGENT-MANUAL.md](docs/AGENT-MANUAL.md) Endast om du uttryckligen vill separat instans:
- [docs/INFRASTRUCTURE.md](docs/INFRASTRUCTURE.md)
```bash
INSTALL_MODE=sidecar docker compose --profile sidecar up -d --build
```
## Noder ## Noder
`nc-collab-config` · `collabora-bridge` · `nc-office` · `collabora-convert` · `collabora-extract` · `collabora-transform` · `collabora-wopi` `nc-collab-config` · `collabora-bridge` · `nc-office` · `collabora-convert` · `collabora-extract` · `collabora-transform` · `collabora-wopi`
## Utveckling / push ## Repo
```bash https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered
git remote add origin https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered.git
git push -u origin main
```
## Licens ## Dokumentation
MIT - [docs/AGENT-MANUAL.md](docs/AGENT-MANUAL.md)
- [docs/INFRASTRUCTURE.md](docs/INFRASTRUCTURE.md)
+50 -139
View File
@@ -1,207 +1,118 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# bootstrap-install.sh — full installation på valfri VM-variant # bootstrap-install.sh — klona från Gitea och integrera i befintlig nextcloud-node-red
# #
# Laddar ned från Gitea, installerar Docker vid behov, bygger Node-RED sidecar # Skapar INTE ny Node-RED-container. Patchar /home/ncadmin/nextcloud-node-red och bygger om.
# med alla Collabora-noder och startar på port 1881.
# #
# One-liner (efter repo finns på Gitea): # One-liner:
# curl -fsSL https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered/raw/branch/main/bootstrap-install.sh | bash # curl -fsSL https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered/raw/branch/main/bootstrap-install.sh | bash
# #
# Med miljövariabler: # Som ncadmin (rekommenderat):
# GIT_REPO_URL=https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered.git \ # curl -fsSL ... | sudo -u ncadmin bash
# INSTALL_DIR=/home/ncadmin/nextcloud-collabora-nodered \
# bash bootstrap-install.sh
# #
set -euo pipefail set -euo pipefail
VERSION="1.0.0" VERSION="1.0.0"
GIT_REPO_URL="${GIT_REPO_URL:-https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered.git}" GIT_REPO_URL="${GIT_REPO_URL:-https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered.git}"
GIT_BRANCH="${GIT_BRANCH:-main}" GIT_BRANCH="${GIT_BRANCH:-main}"
INSTALL_MODE="${INSTALL_MODE:-integrate}"
# Som root: använd ncadmin-sökvägar (inte /root)
if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncadmin" ]; then
INSTALL_DIR="${INSTALL_DIR:-/home/ncadmin/nextcloud-collabora-nodered}"
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
else
INSTALL_DIR="${INSTALL_DIR:-${HOME}/nextcloud-collabora-nodered}" INSTALL_DIR="${INSTALL_DIR:-${HOME}/nextcloud-collabora-nodered}"
NODERED_DIR="${NODERED_DIR:-${HOME}/nextcloud-node-red}"
fi
NC_HOST="${NC_HOST:-cloud.hannesahlin.se}" NC_HOST="${NC_HOST:-cloud.hannesahlin.se}"
NC_URL="${NC_URL:-https://${NC_HOST}}"
CODE_CONTAINER="${CODE_CONTAINER:-code}" CODE_CONTAINER="${CODE_CONTAINER:-code}"
CODE_PORT="${CODE_PORT:-9980}" NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1881}" NODERED_PORT="${NODERED_PORT:-1880}"
SKIP_APT="${SKIP_APT:-0}" SKIP_APT="${SKIP_APT:-0}"
SKIP_DOCKER_INSTALL="${SKIP_DOCKER_INSTALL:-0}" SKIP_DOCKER_INSTALL="${SKIP_DOCKER_INSTALL:-1}"
log() { printf '[bootstrap] %s\n' "$*"; } log() { printf '[bootstrap] %s\n' "$*"; }
warn() { printf '[bootstrap] VARNING: %s\n' "$*" >&2; } warn() { printf '[bootstrap] VARNING: %s\n' "$*" >&2; }
die() { printf '[bootstrap] FEL: %s\n' "$*" >&2; exit 1; } die() { printf '[bootstrap] FEL: %s\n' "$*" >&2; exit 1; }
run_as_root() { run_as_root() {
if [ "$(id -u)" -eq 0 ]; then if [ "$(id -u)" -eq 0 ]; then "$@"; elif command -v sudo >/dev/null 2>&1; then sudo "$@"; else die "sudo krävs"; fi
"$@"
elif command -v sudo >/dev/null 2>&1; then
sudo "$@"
else
die "Root/sudo krävs för: $*"
fi
}
detect_host_ip() {
if [ -n "${NC_HOST_IP:-}" ]; then
echo "${NC_HOST_IP}"
return
fi
local ip
ip="$(hostname -I 2>/dev/null | awk '{print $1}' || true)"
if [ -n "${ip}" ]; then
echo "${ip}"
return
fi
ip="$(ip -4 route get "${NC_HOST}" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' || true)"
if [ -n "${ip}" ]; then
echo "${ip}"
return
fi
echo "192.168.1.26"
}
detect_code_ip() {
if [ -n "${COLLABORA_IP:-}" ]; then
echo "${COLLABORA_IP}"
return
fi
if command -v docker >/dev/null 2>&1 && docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${CODE_CONTAINER}" 2>/dev/null | head -1
return
fi
echo "172.17.0.2"
} }
install_apt_packages() { install_apt_packages() {
[ "${SKIP_APT}" = "1" ] && return 0 [ "${SKIP_APT}" = "1" ] && return 0
if ! command -v apt-get >/dev/null 2>&1; then command -v apt-get >/dev/null 2>&1 || return 0
warn "apt-get saknas — installera git, curl och docker manuellt" log "Installerar git, curl, rsync..."
return 0
fi
log "Installerar grundpaket (git, curl, ca-certificates)..."
run_as_root apt-get update -qq run_as_root apt-get update -qq
run_as_root apt-get install -y -qq git curl ca-certificates rsync run_as_root apt-get install -y -qq git curl ca-certificates rsync
} }
install_docker() { install_docker() {
if [ "${SKIP_DOCKER_INSTALL}" = "1" ]; then [ "${SKIP_DOCKER_INSTALL}" = "1" ] && return 0
return 0 command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1 && return 0
fi
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
log "Docker finns redan"
return 0
fi
log "Installerar Docker..." log "Installerar Docker..."
if command -v apt-get >/dev/null 2>&1; then
run_as_root apt-get install -y -qq docker.io docker-compose-plugin 2>/dev/null || true
fi
if ! command -v docker >/dev/null 2>&1 || ! docker info >/dev/null 2>&1; then
log "Kör get.docker.com..."
curl -fsSL https://get.docker.com | run_as_root sh curl -fsSL https://get.docker.com | run_as_root sh
fi
local target_user="${SUDO_USER:-${USER}}"
if [ -n "${target_user}" ] && [ "${target_user}" != "root" ]; then
run_as_root usermod -aG docker "${target_user}" 2>/dev/null || true
warn "Användaren ${target_user} lades till i docker-gruppen — logga ut/in om 'permission denied'"
fi
} }
clone_or_update_repo() { clone_or_update_repo() {
if [ -d "${INSTALL_DIR}/.git" ]; then if [ -d "${INSTALL_DIR}/.git" ]; then
log "Uppdaterar befintlig klon i ${INSTALL_DIR}..." log "Uppdaterar ${INSTALL_DIR}..."
git -C "${INSTALL_DIR}" fetch origin git -C "${INSTALL_DIR}" fetch origin
git -C "${INSTALL_DIR}" checkout "${GIT_BRANCH}" git -C "${INSTALL_DIR}" checkout "${GIT_BRANCH}"
git -C "${INSTALL_DIR}" pull --ff-only origin "${GIT_BRANCH}" || warn "git pull misslyckades — fortsätter med lokalt innehåll" git -C "${INSTALL_DIR}" pull --ff-only origin "${GIT_BRANCH}" || warn "git pull misslyckades"
return 0 return 0
fi fi
if [ -d "${INSTALL_DIR}" ] && [ "$(ls -A "${INSTALL_DIR}" 2>/dev/null | wc -l)" -gt 0 ]; then
die "${INSTALL_DIR} finns men är inte en git-klon — flytta bort eller sätt INSTALL_DIR"
fi
log "Klonar ${GIT_REPO_URL} → ${INSTALL_DIR}" log "Klonar ${GIT_REPO_URL} → ${INSTALL_DIR}"
mkdir -p "$(dirname "${INSTALL_DIR}")" mkdir -p "$(dirname "${INSTALL_DIR}")"
git clone --branch "${GIT_BRANCH}" --depth 1 "${GIT_REPO_URL}" "${INSTALL_DIR}" git clone --branch "${GIT_BRANCH}" --depth 1 "${GIT_REPO_URL}" "${INSTALL_DIR}"
if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncadmin" ]; then
chown -R ncadmin:ncadmin "${INSTALL_DIR}" 2>/dev/null || true
fi
} }
write_env_file() { preflight() {
local host_ip code_ip collab_url command -v docker >/dev/null 2>&1 || die "Docker saknas"
host_ip="$(detect_host_ip)" docker ps --format '{{.Names}}' | grep -qx "${NODERED_CONTAINER}" \
code_ip="$(detect_code_ip)" || die "'${NODERED_CONTAINER}' körs inte — detta skript integrerar i befintlig Node-RED, skapar ingen ny"
collab_url="http://${code_ip}:${CODE_PORT}" docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}" \
|| die "'${CODE_CONTAINER}' (Collabora) körs inte"
log "VM host-IP för ${NC_HOST}: ${host_ip}" [ -d "${NODERED_DIR}" ] || die "nextcloud-node-red-katalog saknas: ${NODERED_DIR}"
log "CODE URL: ${collab_url} (container ${CODE_CONTAINER})" log "OK: ${NODERED_CONTAINER} + ${CODE_CONTAINER} körs"
cat > "${INSTALL_DIR}/.env" <<EOF
# Genererad av bootstrap-install.sh $(date -Iseconds)
NC_HOST=${NC_HOST}
NC_HOST_IP=${host_ip}
NEXTCLOUD_URL=${NC_URL}
COLLABORA_URL=${collab_url}
TZ=Europe/Stockholm
NODERED_CREDENTIAL_SECRET=${NODERED_CREDENTIAL_SECRET:-$(openssl rand -hex 24 2>/dev/null || echo "byt-den-här-hemligheten-vid-produktion")}
EOF
}
preflight_code() {
if ! command -v docker >/dev/null 2>&1; then
die "Docker saknas efter installation"
fi
if ! docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then
die "CODE-container '${CODE_CONTAINER}' körs inte på denna VM. Starta befintlig CODE — skapa inte ny via detta skript."
fi
local cap
cap="$(docker exec "${CODE_CONTAINER}" curl -sf "http://127.0.0.1:${CODE_PORT}/hosting/capabilities" 2>/dev/null | head -c 80 || true)"
if [ -z "${cap}" ]; then
warn "CODE svarar inte på capabilities inuti containern — kontrollera aliasgroup och post_allow"
else
log "CODE capabilities OK inuti container ${CODE_CONTAINER}"
fi
} }
main() { main() {
log "nextcloud-collabora-nodered bootstrap v${VERSION}" log "bootstrap v${VERSION} — läge: ${INSTALL_MODE} (befintlig Node-RED :${NODERED_PORT})"
log "Repo: ${GIT_REPO_URL} (${GIT_BRANCH})" log "Repo → ${INSTALL_DIR}"
log "Installationskatalog: ${INSTALL_DIR}" log "Integrera → ${NODERED_DIR}"
if [ "$(id -u)" -eq 0 ] && [ -z "${SUDO_USER:-}" ]; then if [ "$(id -u)" -eq 0 ] && [ -z "${SUDO_USER:-}" ]; then
warn "Körs som root — rekommenderat: ncadmin eller annan docker-användare" warn "Körs som root — rekommenderat: curl ... | sudo -u ncadmin bash"
fi fi
install_apt_packages install_apt_packages
install_docker install_docker
clone_or_update_repo clone_or_update_repo
write_env_file preflight
preflight_code
log "Kör lokal install.sh..." chmod +x "${INSTALL_DIR}/install.sh" "${INSTALL_DIR}/scripts/integrate-into-nodered.sh"
chmod +x "${INSTALL_DIR}/install.sh"
INSTALL_DIR="${INSTALL_DIR}" \ INSTALL_DIR="${INSTALL_DIR}" \
INSTALL_MODE="${INSTALL_MODE}" \
NODERED_DIR="${NODERED_DIR}" \
CODE_CONTAINER="${CODE_CONTAINER}" \ CODE_CONTAINER="${CODE_CONTAINER}" \
COLLABORA_IP="$(detect_code_ip)" \
bash "${INSTALL_DIR}/install.sh" bash "${INSTALL_DIR}/install.sh"
local host_ip nodered_url local host_ip
host_ip="$(detect_host_ip)" host_ip="$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")"
nodered_url="http://${host_ip}:${NODERED_PORT}"
cat <<EOF cat <<EOF
================================================================================ ================================================================================
Klart — nextcloud-collabora-nodered v${VERSION} Klart — Collabora-noder i befintlig nextcloud-node-red
================================================================================ ================================================================================
Node-RED UI: ${nodered_url} Node-RED: http://${host_ip}:${NODERED_PORT} (samma som förut)
Nextcloud: ${NC_URL} Repo: ${INSTALL_DIR}
Collabora: $(grep '^COLLABORA_URL=' "${INSTALL_DIR}/.env" | cut -d= -f2-) Patchad: ${NODERED_DIR}
Katalog: ${INSTALL_DIR}
Nästa steg i Node-RED:
1. Öppna ${nodered_url}
2. nc-collab-config → app-lösenord (inte kontolösen), verifyTls=false
3. Kör acceptansflödet: capabilities → ncFileToPdf → /Dokument/OfficeOut/
Orört på denna VM:
- nextcloud-node-red :1880
- odds-scraper / odds_network
- Gitea-databaslösen
Uppdatera senare: Uppdatera senare:
cd ${INSTALL_DIR} && git pull && ./install.sh cd ${INSTALL_DIR} && git pull && ./install.sh
+3 -9
View File
@@ -1,7 +1,8 @@
# Sidecar — port 1881. Rör INTE nextcloud-node-red (:1880) eller odds_network. # Sidecar — ENDAST med INSTALL_MODE=sidecar (ej standard)
# CODE (container "code") ligger på Docker bridge: 172.17.0.2:9980 # Normal installation integrerar i befintlig nextcloud-node-red :1880
services: services:
nextcloud-collabora-nodered: nextcloud-collabora-nodered:
profiles: ["sidecar"]
build: . build: .
image: nextcloud-collabora-nodered:latest image: nextcloud-collabora-nodered:latest
container_name: nextcloud-collabora-nodered container_name: nextcloud-collabora-nodered
@@ -13,7 +14,6 @@ services:
TZ: ${TZ:-Europe/Stockholm} TZ: ${TZ:-Europe/Stockholm}
NEXTCLOUD_URL: ${NEXTCLOUD_URL:-https://cloud.hannesahlin.se} NEXTCLOUD_URL: ${NEXTCLOUD_URL:-https://cloud.hannesahlin.se}
COLLABORA_URL: ${COLLABORA_URL:-http://172.17.0.2:9980} COLLABORA_URL: ${COLLABORA_URL:-http://172.17.0.2:9980}
NODERED_CREDENTIAL_SECRET: ${NODERED_CREDENTIAL_SECRET:-byt-den-här-hemligheten-vid-produktion}
extra_hosts: extra_hosts:
- "cloud.hannesahlin.se:${NC_HOST_IP:-192.168.1.26}" - "cloud.hannesahlin.se:${NC_HOST_IP:-192.168.1.26}"
volumes: volumes:
@@ -21,12 +21,6 @@ services:
networks: networks:
- collab_default - collab_default
- docker_bridge - docker_bridge
healthcheck:
test: ["CMD-SHELL", "curl -sf http://127.0.0.1:1881 >/dev/null || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks: networks:
collab_default: collab_default:
+2 -2
View File
@@ -25,8 +25,8 @@ Du är en **flödesagent**. Du skapar och modifierar Node-RED-flöden, inte Libr
|--------|-------| |--------|-------|
| Nextcloud | `https://cloud.hannesahlin.se` (host 192.168.1.26) | | Nextcloud | `https://cloud.hannesahlin.se` (host 192.168.1.26) |
| CODE | container `code`, `127.0.0.1:9980`, aliasgroup `https://cloud.hannesahlin.se:443` | | CODE | container `code`, `127.0.0.1:9980`, aliasgroup `https://cloud.hannesahlin.se:443` |
| Befintlig Node-RED | `nextcloud-node-red` `:1880` (OCS-noder) | | Befintlig Node-RED | `nextcloud-node-red` `:1880` — **Collabora-noder integreras här** |
| Ny sidecar | `nextcloud-collabora-nodered` `:1881` | | Sidecar :1881 | Endast med `INSTALL_MODE=sidecar` (ej standard) |
| Intern CODE-URL från sidecar | `http://172.17.0.2:9980` (Docker bridge, container `code`) | | Intern CODE-URL från sidecar | `http://172.17.0.2:9980` (Docker bridge, container `code`) |
| Auth | Basic + Nextcloud app-lösenord, header `OCS-APIRequest: true` | | Auth | Basic + Nextcloud app-lösenord, header `OCS-APIRequest: true` |
+5 -2
View File
@@ -8,14 +8,17 @@ Verifierad 2026-08-22. Sidecar ska passa in utan att röra befintliga tjänster.
|-----------|-------|------|---------|-----| |-----------|-------|------|---------|-----|
| `code` | collabora/code:latest (26.04.3.1) | 127.0.0.1:9980 | `bridge` | 172.17.0.2 | | `code` | collabora/code:latest (26.04.3.1) | 127.0.0.1:9980 | `bridge` | 172.17.0.2 |
| `nextcloud-node-red` | nextcloud-node-red:latest | 0.0.0.0:1880 | `nextcloud-node-red_odds_network` | 172.18.0.3 | | `nextcloud-node-red` | nextcloud-node-red:latest | 0.0.0.0:1880 | `nextcloud-node-red_odds_network` | 172.18.0.3 |
| `nextcloud-collabora-nodered` | nextcloud-collabora-nodered:latest | 0.0.0.0:1881 | `collab_default` + **`bridge`** | (dynamisk) | | `nextcloud-node-red` | nextcloud-node-red:latest | 0.0.0.0:1880 | odds_network + **bridge** (efter install) | 172.18.0.3 |
| ~~nextcloud-collabora-nodered~~ | — | — | **Används ej** — noder integreras i :1880 | — |
| `gitea_server` | gitea/gitea:latest | 127.0.0.1:3000 | (egen) | — | | `gitea_server` | gitea/gitea:latest | 127.0.0.1:3000 | (egen) | — |
| `odds-postgres` | postgres:16-alpine | 5433 | odds_network | — | | `odds-postgres` | postgres:16-alpine | 5433 | odds_network | — |
## Viktigt om nätverk ## Viktigt om nätverk
- **CODE** ligger på Docker **`bridge`** (172.17.0.0/16), inte på `odds_network`. - **CODE** ligger på Docker **`bridge`** (172.17.0.0/16), inte på `odds_network`.
- **Sidecar** ansluter till **`bridge`** för att nå CODE på `http://172.17.0.2:9980`. - **Collabora-noder** installeras i befintlig `nextcloud-node-red` — ingen ny container
- **`install.sh`** patchar `/home/ncadmin/nextcloud-node-red` och bygger om samma image
- Efter install: `docker network connect bridge nextcloud-node-red` (sker automatiskt)
- `127.0.0.1:9980` på host når CODE, men **inte** från en container utan bridge/host-mode. - `127.0.0.1:9980` på host når CODE, men **inte** från en container utan bridge/host-mode.
- `host.docker.internal` är opålitligt på Linux — använd **172.17.0.2**. - `host.docker.internal` är opålitligt på Linux — använd **172.17.0.2**.
- **nextcloud-node-red** (:1880) ska **inte** flyttas till bridge; den stannar på odds_network. - **nextcloud-node-red** (:1880) ska **inte** flyttas till bridge; den stannar på odds_network.
+24 -91
View File
@@ -1,115 +1,48 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# install.sh — nextcloud-collabora-nodered v1.0 # install.sh — integrera Collabora-noder i befintlig nextcloud-node-red (:1880)
# Kör på cloud (192.168.1.26): /home/ncadmin/nextcloud-collabora-nodered #
# Standard: INSTALL_MODE=integrate (ingen ny container, ingen port 1881)
# Sidecar (endast om du uttryckligen vill): INSTALL_MODE=sidecar
#
set -euo pipefail set -euo pipefail
VERSION="1.0.0" VERSION="1.0.0"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${INSTALL_DIR:-$SCRIPT_DIR}" INSTALL_DIR="${INSTALL_DIR:-$SCRIPT_DIR}"
COMPOSE="docker compose" INSTALL_MODE="${INSTALL_MODE:-integrate}"
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
CODE_CONTAINER="${CODE_CONTAINER:-code}" CODE_CONTAINER="${CODE_CONTAINER:-code}"
COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}" COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}"
log() { printf '[install] %s\n' "$*"; } log() { printf '[install] %s\n' "$*"; }
die() { printf '[install] FEL: %s\n' "$*" >&2; exit 1; } die() { printf '[install] FEL: %s\n' "$*" >&2; exit 1; }
require_cmd() { log "nextcloud-collabora-nodered v${VERSION} (läge: ${INSTALL_MODE})"
command -v "$1" >/dev/null 2>&1 || die "Saknar kommando: $1"
}
log "nextcloud-collabora-nodered v${VERSION}"
log "Installationskatalog: ${INSTALL_DIR}"
if [ "${INSTALL_MODE}" = "sidecar" ]; then
log "Sidecar-läge — varning: standard är integrate (befintlig :1880)"
require_cmd() { command -v "$1" >/dev/null 2>&1 || die "Saknar: $1"; }
require_cmd docker require_cmd docker
if docker compose version >/dev/null 2>&1; then
COMPOSE="docker compose" COMPOSE="docker compose"
elif command -v docker-compose >/dev/null 2>&1; then docker compose version >/dev/null 2>&1 || COMPOSE="docker-compose"
COMPOSE="docker-compose"
else
die "Docker Compose saknas"
fi
cd "${INSTALL_DIR}" cd "${INSTALL_DIR}"
[ -f docker-compose.yml ] || die "docker-compose.yml saknas"
if [ ! -f docker-compose.yml ]; then [ -f .env ] || cp .env.example .env
die "docker-compose.yml saknas i ${INSTALL_DIR}"
fi
if [ ! -f .env ]; then
log "Skapar .env från .env.example"
cp .env.example .env
fi
# Valfri tarball från Windows
if [ -n "${IMPORT_TARBALL:-}" ] && [ -f "${IMPORT_TARBALL}" ]; then
log "Extraherar ${IMPORT_TARBALL}"
tmpdir="$(mktemp -d)"
tar -xzf "${IMPORT_TARBALL}" -C "${tmpdir}"
src="$(find "${tmpdir}" -maxdepth 2 -name docker-compose.yml -printf '%h\n' | head -1)"
[ -n "${src}" ] || die "Ogiltig tarball"
rsync -a "${src}/" "${INSTALL_DIR}/"
rm -rf "${tmpdir}"
fi
# Verifiera att CODE redan kör (starta INTE ny)
if ! docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then if ! docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then
die "CODE-container '${CODE_CONTAINER}' körs inte. Starta inte ny CODE — fixa befintlig instans först." die "CODE-container '${CODE_CONTAINER}' körs inte"
fi fi
code_ip="$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${CODE_CONTAINER}" 2>/dev/null | head -1)"
if [ -n "${code_ip}" ] && [ "${code_ip}" != "${COLLABORA_IP}" ]; then
log "OBS: CODE IP är ${code_ip} (inte ${COLLABORA_IP}). Uppdaterar COLLABORA_URL i .env."
if grep -q '^COLLABORA_URL=' .env; then
sed -i "s|^COLLABORA_URL=.*|COLLABORA_URL=http://${code_ip}:9980|" .env
fi
fi
# extra_hosts: uppdatera NC_HOST_IP om vi kan detektera
if [ -f .env ] && grep -q '^NC_HOST_IP=' .env; then
host_ip="$(hostname -I 2>/dev/null | awk '{print $1}' || true)"
if [ -n "${host_ip}" ]; then
sed -i "s|^NC_HOST_IP=.*|NC_HOST_IP=${host_ip}|" .env
fi
fi
log "Bygger och startar sidecar (port 1881, nätverk bridge + collab_default)..."
if [ "${FORCE_REBUILD:-0}" = "1" ]; then
${COMPOSE} build --no-cache
else
${COMPOSE} build ${COMPOSE} build
fi
${COMPOSE} up -d ${COMPOSE} up -d
log "Sidecar startad på :1881 (ej rekommenderat om :1880 redan kör)"
log "Väntar på Node-RED..." exit 0
for i in $(seq 1 30); do
if curl -sf "http://127.0.0.1:1881" >/dev/null 2>&1; then
log "Node-RED svarar på http://127.0.0.1:1881"
break
fi
sleep 2
[ "$i" -eq 30 ] && log "Varning: Node-RED svarade inte inom 60 s"
done
log "Testar CODE capabilities från sidecar..."
collab_url="$(grep '^COLLABORA_URL=' .env | cut -d= -f2- || echo "http://${COLLABORA_IP}:9980")"
host_ip="$(grep '^NC_HOST_IP=' .env 2>/dev/null | cut -d= -f2- || hostname -I | awk '{print $1}')"
if docker exec nextcloud-collabora-nodered curl -sf "${collab_url}/hosting/capabilities" >/dev/null 2>&1; then
log "OK: CODE nås på ${collab_url}"
else
log "VARNING: Kunde inte nå ${collab_url}/hosting/capabilities från sidecar."
log " Kontrollera: docker network inspect bridge | grep -A2 ${CODE_CONTAINER}"
log " Alternativ: docker network connect bridge nextcloud-collabora-nodered"
fi fi
cat <<EOF # === integrate (default) ===
chmod +x "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
Nästa steg: PKG_SRC="${INSTALL_DIR}" \
1. Öppna http://${host_ip:-127.0.0.1}:1881 NODERED_DIR="${NODERED_DIR}" \
2. nc-collab-config: app-lösenord, collaboraUrl=${collab_url} CODE_CONTAINER="${CODE_CONTAINER}" \
3. Kör acceptansflödet (capabilities → ncFileToPdf) COLLABORA_IP="${COLLABORA_IP}" \
bash "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
Repo: https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered
Orört: nextcloud-node-red :1880, odds-scraper, Gitea-databaslösen.
EOF
log "Klart." log "Klart."
+184
View File
@@ -0,0 +1,184 @@
#!/usr/bin/env bash
# integrate-into-nodered.sh — lägg Collabora-noder i BEFINTLIG nextcloud-node-red (:1880)
# Anropas av install.sh / bootstrap-install.sh (standardläge).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PKG_SRC="${PKG_SRC:-$(cd "${SCRIPT_DIR}/.." && pwd)}"
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}"
COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}"
MARKER="nextcloud-collabora-nodered"
log() { printf '[integrate] %s\n' "$*"; }
warn() { printf '[integrate] VARNING: %s\n' "$*" >&2; }
die() { printf '[integrate] FEL: %s\n' "$*" >&2; exit 1; }
resolve_paths() {
if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncadmin/nextcloud-node-red" ]; then
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
PKG_SRC="${PKG_SRC:-/home/ncadmin/nextcloud-collabora-nodered}"
fi
}
stop_sidecar_if_any() {
if docker ps -a --format '{{.Names}}' | grep -qx "nextcloud-collabora-nodered"; then
warn "Stoppar felaktig sidecar-container nextcloud-collabora-nodered (skulle inte skapas)"
docker stop nextcloud-collabora-nodered 2>/dev/null || true
docker rm nextcloud-collabora-nodered 2>/dev/null || true
fi
}
preflight() {
[ -d "${PKG_SRC}" ] || die "Paketkälla saknas: ${PKG_SRC}"
[ -f "${PKG_SRC}/package.json" ] || die "package.json saknas i ${PKG_SRC}"
[ -d "${NODERED_DIR}" ] || die "nextcloud-node-red saknas: ${NODERED_DIR}"
[ -f "${NODERED_DIR}/Dockerfile" ] || die "Dockerfile saknas i ${NODERED_DIR}"
[ -f "${NODERED_DIR}/entrypoint.sh" ] || die "entrypoint.sh saknas i ${NODERED_DIR}"
if ! docker ps --format '{{.Names}}' | grep -qx "${NODERED_CONTAINER}"; then
die "Container '${NODERED_CONTAINER}' körs inte — starta befintlig nextcloud-node-red först"
fi
if ! docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then
die "CODE-container '${CODE_CONTAINER}' körs inte"
fi
}
copy_node_package() {
local dest="${NODERED_DIR}/nodes/nextcloud-collabora"
log "Kopierar noder → ${dest}"
mkdir -p "${dest}"
rsync -a --delete \
"${PKG_SRC}/package.json" \
"${PKG_SRC}/lib/" \
"${PKG_SRC}/nodes/" \
"${dest}/"
}
patch_dockerfile() {
local df="${NODERED_DIR}/Dockerfile"
if grep -q "${MARKER}" "${df}"; then
log "Dockerfile redan patchad"
return 0
fi
log "Patchar Dockerfile"
cat >> "${df}" <<'EOF'
# nextcloud-collabora-nodered — Collabora/Office-noder (WebDAV + CODE REST)
RUN mkdir -p /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora
COPY nodes/nextcloud-collabora/package.json /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora/
COPY nodes/nextcloud-collabora/lib /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora/lib
COPY nodes/nextcloud-collabora/nodes /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora/nodes
RUN cd /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora && npm install --omit=dev
EOF
}
patch_entrypoint() {
local ep="${NODERED_DIR}/entrypoint.sh"
if grep -q "node-red-contrib-nextcloud-collabora" "${ep}"; then
log "entrypoint.sh redan patchad"
return 0
fi
log "Patchar entrypoint.sh"
# Infoga före sista exec/npm start om möjligt, annars append
if grep -q "node-red-contrib-nextcloud-ocs" "${ep}"; then
sed -i '/node-red-contrib-nextcloud-ocs/a\
cp -a /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora /data/node_modules/' "${ep}"
else
cat >> "${ep}" <<'EOF'
# nextcloud-collabora-nodered
mkdir -p /data/node_modules
cp -a /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora /data/node_modules/
EOF
fi
}
connect_code_network() {
log "Ansluter ${NODERED_CONTAINER} till Docker bridge (CODE)"
if docker network inspect bridge --format '{{range .Containers}}{{.Name}} {{end}}' 2>/dev/null | grep -q "${NODERED_CONTAINER}"; then
log "Redan ansluten till bridge"
else
docker network connect bridge "${NODERED_CONTAINER}" 2>/dev/null || warn "Kunde inte ansluta bridge — kontrollera manuellt"
fi
}
rebuild_nodered() {
local compose="docker compose"
if ! docker compose version >/dev/null 2>&1; then
compose="docker-compose"
fi
log "Bygger om ${NODERED_CONTAINER} (samma instans, port ${NODERED_PORT})..."
cd "${NODERED_DIR}"
if [ "${FORCE_REBUILD:-0}" = "1" ]; then
${compose} build --no-cache
else
${compose} build
fi
${compose} up -d
}
wait_nodered() {
log "Väntar på Node-RED :${NODERED_PORT}..."
for i in $(seq 1 30); do
if curl -sf "http://127.0.0.1:${NODERED_PORT}" >/dev/null 2>&1; then
log "Node-RED svarar på http://127.0.0.1:${NODERED_PORT}"
return 0
fi
sleep 2
done
warn "Node-RED svarade inte inom 60 s"
}
verify_code_from_nodered() {
local code_ip
code_ip="$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${CODE_CONTAINER}" 2>/dev/null | head -1)"
[ -n "${code_ip}" ] || code_ip="${COLLABORA_IP}"
local url="http://${code_ip}:9980/hosting/capabilities"
log "Testar CODE från ${NODERED_CONTAINER}: ${url}"
if docker exec "${NODERED_CONTAINER}" curl -sf "${url}" >/dev/null 2>&1; then
log "OK: CODE nås från befintlig Node-RED-container"
else
warn "CODE nås inte — kör: docker network connect bridge ${NODERED_CONTAINER}"
warn "nc-collab-config collaboraUrl=http://${code_ip}:9980"
fi
}
main() {
resolve_paths
log "Integrerar Collabora-noder i befintlig nextcloud-node-red"
log "Paket: ${PKG_SRC}"
log "Node-RED: ${NODERED_DIR} (container ${NODERED_CONTAINER})"
stop_sidecar_if_any
preflight
copy_node_package
patch_dockerfile
patch_entrypoint
connect_code_network
rebuild_nodered
wait_nodered
verify_code_from_nodered
local host_ip
host_ip="$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")"
cat <<EOF
Integrering klar — samma Node-RED på port ${NODERED_PORT}
UI: http://${host_ip}:${NODERED_PORT}
Noder: nc-collab-config, collabora-bridge, nc-office, ...
Nästa steg:
1. nc-collab-config → app-lösenord, collaboraUrl=http://172.17.0.2:9980
2. Importera flows/example-flows.json från ${PKG_SRC} (valfritt)
3. Test: capabilities → ncFileToPdf
Ingen ny container skapad. odds-scraper orörd.
EOF
}
main "$@"