Docker - tagyoureit/nodejs-poolController GitHub Wiki
Pre-built Docker images
Image channels (important)
latest is channel-specific. It does not mean latest code across all registries.
ghcr.io/tagyoureit/njspc- official controller image published from upstreamtagyoureit/nodejs-poolController.ghcr.io/sam2kb/njspc- fork-maintained controller image (may lag upstream).msmi/nodejs-poolcontroller- legacy Docker Hub controller image (may lag upstream).ghcr.io/sam2kb/njspc-dash- dashPanel image currently published separately.
Canonical docs and examples
Use these files in the main repo as the source of truth:
README.md(Docker section): https://github.com/tagyoureit/nodejs-poolController/blob/master/README.md- Local build compose example: https://github.com/tagyoureit/nodejs-poolController/blob/master/docker-compose.yml
This wiki page keeps quick-start examples, but repo files are authoritative.
Quick test (Linux host with /dev/ttyUSB0)
docker run --rm -it \
--group-add dialout \
-p 4200:4200 \
--device /dev/ttyUSB0 \
ghcr.io/tagyoureit/njspc:latest
Docker Compose examples
For a more permanent install, use Docker Compose.
Server-only minimal example
services:
njspc:
image: ${NJSPC_IMAGE:-ghcr.io/tagyoureit/njspc}
container_name: njspc
restart: unless-stopped
group_add:
- dialout
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
ports:
- "4200:4200"
Server-only with persisted config/state
services:
njspc:
image: ${NJSPC_IMAGE:-ghcr.io/tagyoureit/njspc}
container_name: njspc
restart: unless-stopped
group_add:
- dialout
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
ports:
- "4200:4200"
volumes:
- /data/poolcontroller/data:/app/data
- /data/poolcontroller/logs:/app/logs
- /data/poolcontroller/backups:/app/backups
- type: bind
source: /data/poolcontroller/config.json
target: /app/config.json
Server plus optional dashPanel
services:
njspc:
image: ${NJSPC_IMAGE:-ghcr.io/tagyoureit/njspc}
container_name: njspc
restart: unless-stopped
group_add:
- dialout
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
ports:
- "4200:4200"
volumes:
- /data/poolcontroller/data:/app/data
- type: bind
source: /data/poolcontroller/config.json
target: /app/config.json
njspc-dash:
image: ${NJSPC_DASH_IMAGE:-ghcr.io/sam2kb/njspc-dash}
container_name: njspc-dash
restart: unless-stopped
depends_on:
- njspc
ports:
- "5150:5150"
volumes:
- type: bind
source: /data/poolcontroller-dashpanel/config.json
target: /app/config.json
Docker socat example (serial-to-TCP bridge)
services:
njspc:
image: ${NJSPC_IMAGE:-ghcr.io/tagyoureit/njspc}
container_name: njspc
restart: unless-stopped
ports:
- "4200:4200"
environment:
- POOL_NET_CONNECT=true
- POOL_NET_HOST=socat
- POOL_NET_PORT=9801
volumes:
- /data/poolcontroller/data:/app/data
- type: bind
source: /data/poolcontroller/config.json
target: /app/config.json
socat:
image: alpine/socat
command: tcp-listen:9801,fork,reuseaddr file:/dev/ttyUSB0,b9600,raw,echo=0
container_name: socat
restart: unless-stopped
ports:
- "9801:9801"
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
Socat is useful when you want to run controller and serial access separately or remotely.
Docker serial port access
You must specify the serial device in Compose or with docker run.
For Linux hosts, adding the container user to dialout is usually safest:
group_add:
- dialout
Avoid running as root unless needed. If using root, ensure /app/data mounts are writable or poolConfig.json/poolState.json updates may fail.
Example fix:
sudo chown -R 1000:1000 /data/poolcontroller/data
sudo chmod -R u+rw /data/poolcontroller/data
For Docker Desktop on macOS/Windows, raw /dev/tty* passthrough differs from native Linux and may not work the same way. Use a TCP bridge (socat) when direct mapping is unavailable.
Notes
Update to the latest tags in your selected channel:
docker compose pull && docker compose up -d
If running without mounted config and you need a copy:
docker cp njspc:/app/config.json ./config.json
Connect to a running container:
docker exec -it njspc sh
Verify the code revision in your image:
docker image inspect ghcr.io/tagyoureit/njspc:latest --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}'
docker image inspect ghcr.io/sam2kb/njspc:latest --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}'
docker image inspect msmi/nodejs-poolcontroller:latest --format '{{ index .Config.Labels "git-commit" }}'
Build a customized Docker image
If you want to add packages or build for a specific environment, use the repo Dockerfile as a template.
git clone https://github.com/tagyoureit/nodejs-poolController
cd nodejs-poolController
cp Dockerfile ../Dockerfile.mine
Example add-ons (alpine runtime):
FROM node:20-alpine AS build
RUN apk add --no-cache make gcc g++ python3 linux-headers udev tzdata
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
RUN npm prune --production
FROM node:20-alpine AS prod
RUN apk add --no-cache bash bash-completion
WORKDIR /app
COPY --from=build /app .
USER node
ENV NODE_ENV=production
ENTRYPOINT ["node", "dist/app.js"]
Build and run:
docker build --tag mynjspc --file ../Dockerfile.mine .
docker compose up -d