From 961045d6bcf65b8dad9ceae9f59296cacfe79e45 Mon Sep 17 00:00:00 2001 From: 3bsalam-1 <3bsalam0@gmail.com> Date: Mon, 18 May 2026 12:13:03 +0300 Subject: [PATCH 1/4] fix(docker): add Podman compatibility and fix Node 22 healthcheck - Prefix all FROM directives with docker.io/ to resolve unqualified image name errors in Podman (node:22-slim, node:20-alpine, nginx:alpine) - Replace node -e healthcheck with curl -f to fix Node 22 TypeScript evaluator crash and Podman whitespace-splitting issue - Add curl to production stage apt-get install - Update CHANGELOG.md with [0.2.1] release entry - Update version badges to 0.2.1 in README.md and docs/README.md - Add Podman troubleshooting section to docs/12-troubleshooting-faq.md --- CHANGELOG.md | 25 +++++++++++ Dockerfile | 7 +-- README.md | 13 +++++- dashboard/Dockerfile | 4 +- docker-compose.dev.yml | 8 +--- docs/12-troubleshooting-faq.md | 80 +++++++++++++++++++++++++++++++++- docs/README.md | 4 +- 7 files changed, 125 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba12a70..56491c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.1] - 2026-05-18 + +### Fixed + +- **Podman compatibility — Docker socket**: `docker compose` failed with `FileNotFoundError` because the + Podman socket (`/run/user//podman/podman.sock`) was inactive. Fix: enable and start + `systemctl --user start podman.socket` and export + `DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock`. +- **Podman compatibility — unqualified image names**: Podman rootless mode does not resolve short image + names without a registry prefix. Updated all `FROM` directives in `Dockerfile` and + `dashboard/Dockerfile` to use fully-qualified names (`docker.io/node:22-slim`, + `docker.io/node:20-alpine`, `docker.io/nginx:alpine`). +- **Healthcheck crash on Node 22**: `node -e "require('http').get(..., (r) => ...)"` failed inside the + container because Node 22 routes `node -e` through its TypeScript evaluator (`evalTypeScript`) which + rejects arrow-function syntax, and Podman further splits the quoted shell command on whitespace causing + `SyntaxError: Unexpected end of input`. Fixed by installing `curl` in the production stage and + replacing both the `Dockerfile` `HEALTHCHECK` and the `docker-compose.dev.yml` `test` with + `curl -f http://localhost:2785/api/health`. + +### Changed + +- **Dockerfile** (`production` stage): Added `curl` to `apt-get install` for use by the healthcheck. +- **docker-compose.dev.yml**: Simplified healthcheck `test` from a multi-token `node -e` array to + `['CMD', 'curl', '-f', 'http://localhost:2785/api/health']`. + ## [0.1.6] - 2026-05-17 ### Fixed diff --git a/Dockerfile b/Dockerfile index 2a67936..e7d5c58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # Multi-stage build for production-ready image # ===== Stage 1: Builder ===== -FROM node:22-slim AS builder +FROM docker.io/node:22-slim AS builder WORKDIR /app @@ -26,7 +26,7 @@ COPY . . RUN npm run build # ===== Stage 2: Production ===== -FROM node:22-slim AS production +FROM docker.io/node:22-slim AS production # Install Chrome/Chromium and required dependencies RUN apt-get update && apt-get install -y \ @@ -49,6 +49,7 @@ RUN apt-get update && apt-get install -y \ libxrandr2 \ xdg-utils \ dumb-init \ + curl \ && rm -rf /var/lib/apt/lists/* # Set Chrome executable path for Puppeteer @@ -82,7 +83,7 @@ EXPOSE 2785 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD node -e "require('http').get('http://localhost:2785/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))" + CMD curl -f http://localhost:2785/api/health || exit 1 # Start with dumb-init to handle signals properly ENTRYPOINT ["dumb-init", "--"] diff --git a/README.md b/README.md index 3bcea7e..7f2478a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@

- Version + Version License Node NestJS @@ -108,6 +108,17 @@ docker compose -f docker-compose.dev.yml up -d # Swagger: http://localhost:2785/api/docs ``` +> **Using Podman instead of Docker?** +> Podman rootless mode requires the socket to be running and `DOCKER_HOST` to be set: +> +> ```bash +> systemctl --user start podman.socket +> systemctl --user enable podman.socket +> export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock +> ``` +> +> Add the `export` line to your `~/.bashrc` to make it permanent. + ### Option B: Local Development ```bash diff --git a/dashboard/Dockerfile b/dashboard/Dockerfile index 37486f2..4b6e1f4 100644 --- a/dashboard/Dockerfile +++ b/dashboard/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine AS builder +FROM docker.io/node:20-alpine AS builder WORKDIR /app @@ -15,7 +15,7 @@ COPY . . RUN npm run build # Production stage with nginx -FROM nginx:alpine +FROM docker.io/nginx:alpine # Copy built files COPY --from=builder /app/dist /usr/share/nginx/html diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index c258bad..a59cb48 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -29,13 +29,7 @@ services: - ./data:/app/data restart: unless-stopped healthcheck: - test: - [ - 'CMD', - 'node', - '-e', - "require('http').get('http://localhost:2785/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))", - ] + test: ['CMD', 'curl', '-f', 'http://localhost:2785/api/health'] interval: 30s timeout: 10s retries: 3 diff --git a/docs/12-troubleshooting-faq.md b/docs/12-troubleshooting-faq.md index 16d5caa..e988010 100644 --- a/docs/12-troubleshooting-faq.md +++ b/docs/12-troubleshooting-faq.md @@ -49,7 +49,85 @@ flowchart TD A3 -->|No| A3a[Check message format] ``` -## 12.2 Connection Issues +## 12.2 Podman Compatibility + +### Issue: `FileNotFoundError` / Docker socket missing + +**Symptoms:** + +```text +docker.errors.DockerException: Error while fetching server API version: + ('Connection aborted.', FileNotFoundError(2, 'No such file or directory')) +``` + +**Cause:** The system uses Podman (not Docker Engine). Podman's rootless socket is inactive by default. + +**Fix:** + +```bash +systemctl --user start podman.socket +systemctl --user enable podman.socket +export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock +``` + +Add the `export` to `~/.bashrc` to make it permanent. + +--- + +### Issue: `short-name did not resolve to an alias` + +**Symptoms:** + +```text +Error: creating build container: short-name "nginx:alpine" did not resolve to an alias +and no unqualified-search registries are defined +``` + +**Cause:** Podman rootless mode does not fall back to Docker Hub for unqualified image names. + +**Fix:** All `FROM` directives in `Dockerfile` and `dashboard/Dockerfile` must use fully-qualified names: + +```dockerfile +FROM docker.io/node:22-slim +FROM docker.io/nginx:alpine +``` + +--- + +### Issue: Healthcheck always `unhealthy` on Node 22 + Podman + +**Symptoms:** Container starts successfully but stays `unhealthy`; logs show: + +```text +SyntaxError: Unexpected end of input +at evalTypeScript (node:internal/process/execution:256:22) +``` + +**Cause:** Node 22 routes `node -e` through its TypeScript evaluator which rejects arrow-function +syntax. Podman also splits quoted shell commands on whitespace, truncating the `-e` argument. + +**Fix:** Use `curl` for the healthcheck instead of `node -e`: + +```dockerfile +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ + CMD curl -f http://localhost:2785/api/health || exit 1 +``` + +```yaml +# docker-compose.dev.yml +healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:2785/api/health'] +``` + +Ensure `curl` is installed in the production stage: + +```dockerfile +RUN apt-get install -y ... curl ... +``` + +--- + +## 12.3 Connection Issues ### Issue: Container Won't Start diff --git a/docs/README.md b/docs/README.md index f6d95ba..b425f63 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,9 +16,9 @@

- Version + Version License - Node + Node NestJS Docker TypeScript From c9d728d207d1aa1b20fc2ef0c873de12fbf51fc6 Mon Sep 17 00:00:00 2001 From: 3bsalam-1 <3bsalam0@gmail.com> Date: Mon, 18 May 2026 15:42:54 +0300 Subject: [PATCH 2/4] docs: add Docker Hub install option with pre-built images - Add Option A (Docker Hub) to Quick Start with pull instructions and docker run one-liners for 3bsalam/openwa-api and 3bsalam/openwa-dashboard images - Add docker-compose.hub.yml for zero-clone deployment - Rename existing options to B (build from source) and C (local dev) - Add Docker Hub badge to README header - Update clone URLs to point to 3bsalam-1/OpenWA fork --- README.md | 54 ++++++++++++++++++++++++++++++++++++++---- docker-compose.hub.yml | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 docker-compose.hub.yml diff --git a/README.md b/README.md index 7f2478a..9c15e42 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ NestJS Docker TypeScript + Docker Hub

--- @@ -94,11 +95,56 @@ Built on a **pluggable architecture**, OpenWA lets you swap database engines (SQ ## 🚀 Quick Start -### Option A: Docker (Recommended) +### Option A: Docker Hub — Pre-built Images (Fastest) + +No need to clone or build. Pull the images directly from Docker Hub: + +```bash +# Create a project folder +mkdir openwa && cd openwa + +# Download the compose file +curl -o docker-compose.hub.yml https://raw.githubusercontent.com/3bsalam-1/OpenWA/main/docker-compose.hub.yml + +# Start +docker compose -f docker-compose.hub.yml up -d +``` + +Or run manually with `docker run`: + +```bash +# API +docker run -d \ + --name openwa-api \ + -p 127.0.0.1:2785:2785 \ + -e DATABASE_TYPE=sqlite \ + -e DATABASE_NAME=/app/data/openwa.sqlite \ + -e DATABASE_SYNCHRONIZE=true \ + -e ENGINE_TYPE=whatsapp-web.js \ + -e PUPPETEER_HEADLESS=true \ + -e "PUPPETEER_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu" \ + -v $(pwd)/data:/app/data \ + 3bsalam/openwa-api:latest + +# Dashboard +docker run -d \ + --name openwa-dashboard \ + -p 127.0.0.1:2886:80 \ + 3bsalam/openwa-dashboard:latest +``` + +| Image | Docker Hub | +| --- | --- | +| API | `3bsalam/openwa-api:latest` | +| Dashboard | `3bsalam/openwa-dashboard:latest` | + +--- + +### Option B: Build from Source ```bash # Clone and start -git clone https://github.com/rmyndharis/OpenWA.git +git clone https://github.com/3bsalam-1/OpenWA.git cd OpenWA docker compose -f docker-compose.dev.yml up -d @@ -119,11 +165,11 @@ docker compose -f docker-compose.dev.yml up -d > > Add the `export` line to your `~/.bashrc` to make it permanent. -### Option B: Local Development +### Option C: Local Development ```bash # Clone repository -git clone https://github.com/rmyndharis/OpenWA.git +git clone https://github.com/3bsalam-1/OpenWA.git cd OpenWA # Install dependencies (includes dashboard) diff --git a/docker-compose.hub.yml b/docker-compose.hub.yml new file mode 100644 index 0000000..6713b5e --- /dev/null +++ b/docker-compose.hub.yml @@ -0,0 +1,47 @@ +# OpenWA - Docker Compose using pre-built Docker Hub images +# Quick Start: docker compose -f docker-compose.hub.yml up -d + +services: + openwa: + image: 3bsalam/openwa-api:latest + container_name: openwa-api + ports: + - '127.0.0.1:2785:2785' + environment: + - NODE_ENV=production + - PORT=2785 + - DATABASE_TYPE=sqlite + - DATABASE_NAME=/app/data/openwa.sqlite + - DATABASE_SYNCHRONIZE=true + - ENGINE_TYPE=whatsapp-web.js + - SESSION_DATA_PATH=/app/data/sessions + - PUPPETEER_HEADLESS=true + - PUPPETEER_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu + - STORAGE_TYPE=local + - STORAGE_LOCAL_PATH=/app/data/media + - WEBHOOK_TIMEOUT=10000 + - WEBHOOK_MAX_RETRIES=3 + - QUEUE_ENABLED=false + volumes: + - ./data:/app/data + restart: unless-stopped + healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:2785/api/health'] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + dashboard: + image: 3bsalam/openwa-dashboard:latest + container_name: openwa-dashboard + ports: + - '127.0.0.1:2886:80' + depends_on: + openwa: + condition: service_healthy + restart: unless-stopped + +networks: + default: + name: openwa-network From 259daeab24659a6581f97878504d602271b9535d Mon Sep 17 00:00:00 2001 From: 3bsalam-1 <3bsalam0@gmail.com> Date: Mon, 18 May 2026 15:48:21 +0300 Subject: [PATCH 3/4] fix(hub): use .env vars in docker-compose.hub.yml instead of static values --- docker-compose.hub.yml | 56 +++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/docker-compose.hub.yml b/docker-compose.hub.yml index 6713b5e..1773432 100644 --- a/docker-compose.hub.yml +++ b/docker-compose.hub.yml @@ -1,27 +1,55 @@ # OpenWA - Docker Compose using pre-built Docker Hub images -# Quick Start: docker compose -f docker-compose.hub.yml up -d +# Quick Start: +# cp .env.example .env # then edit .env as needed +# docker compose -f docker-compose.hub.yml up -d services: openwa: image: 3bsalam/openwa-api:latest container_name: openwa-api ports: - - '127.0.0.1:2785:2785' + - '127.0.0.1:${API_PORT:-2785}:2785' environment: - - NODE_ENV=production + # Core + - NODE_ENV=${NODE_ENV:-production} - PORT=2785 - - DATABASE_TYPE=sqlite - - DATABASE_NAME=/app/data/openwa.sqlite - - DATABASE_SYNCHRONIZE=true - - ENGINE_TYPE=whatsapp-web.js + - LOG_LEVEL=${LOG_LEVEL:-info} + # Database + - DATABASE_TYPE=${DATABASE_TYPE:-sqlite} + - DATABASE_NAME=${DATABASE_NAME:-/app/data/openwa.sqlite} + - DATABASE_HOST=${DATABASE_HOST:-postgres} + - DATABASE_PORT=${DATABASE_PORT:-5432} + - DATABASE_USERNAME=${DATABASE_USERNAME:-openwa} + - DATABASE_PASSWORD=${DATABASE_PASSWORD:-openwa} + - DATABASE_SYNCHRONIZE=${DATABASE_SYNCHRONIZE:-false} + # Engine + - ENGINE_TYPE=${ENGINE_TYPE:-whatsapp-web.js} - SESSION_DATA_PATH=/app/data/sessions - - PUPPETEER_HEADLESS=true - - PUPPETEER_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu - - STORAGE_TYPE=local + - PUPPETEER_HEADLESS=${PUPPETEER_HEADLESS:-true} + - PUPPETEER_ARGS=${PUPPETEER_ARGS:---no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu} + # Storage + - STORAGE_TYPE=${STORAGE_TYPE:-local} - STORAGE_LOCAL_PATH=/app/data/media - - WEBHOOK_TIMEOUT=10000 - - WEBHOOK_MAX_RETRIES=3 - - QUEUE_ENABLED=false + - S3_ENDPOINT=${S3_ENDPOINT:-http://minio:9000} + - S3_ACCESS_KEY=${S3_ACCESS_KEY:-minioadmin} + - S3_SECRET_KEY=${S3_SECRET_KEY:-minioadmin} + - S3_BUCKET=${S3_BUCKET:-openwa} + # Redis + - REDIS_ENABLED=${REDIS_ENABLED:-false} + - REDIS_HOST=${REDIS_HOST:-redis} + - REDIS_PORT=${REDIS_PORT:-6379} + # Webhook + - WEBHOOK_TIMEOUT=${WEBHOOK_TIMEOUT:-10000} + - WEBHOOK_MAX_RETRIES=${WEBHOOK_MAX_RETRIES:-3} + - WEBHOOK_RETRY_DELAY=${WEBHOOK_RETRY_DELAY:-5000} + # Rate Limiting + - RATE_LIMIT_TTL=${RATE_LIMIT_TTL:-60} + - RATE_LIMIT_MAX=${RATE_LIMIT_MAX:-100} + # Plugins + - PLUGINS_ENABLED=${PLUGINS_ENABLED:-true} + - PLUGINS_DIR=/app/data/plugins + # Security + - API_MASTER_KEY=${API_MASTER_KEY:-} volumes: - ./data:/app/data restart: unless-stopped @@ -36,7 +64,7 @@ services: image: 3bsalam/openwa-dashboard:latest container_name: openwa-dashboard ports: - - '127.0.0.1:2886:80' + - '127.0.0.1:${DASHBOARD_PORT:-2886}:80' depends_on: openwa: condition: service_healthy From e67ed856d543dc34f79cf13738eb994a0963c8de Mon Sep 17 00:00:00 2001 From: 3bsalam-1 <3bsalam0@gmail.com> Date: Mon, 18 May 2026 15:50:38 +0300 Subject: [PATCH 4/4] docs: update Docker Hub install instructions to use .env config --- README.md | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 9c15e42..44f81b5 100644 --- a/README.md +++ b/README.md @@ -97,46 +97,43 @@ Built on a **pluggable architecture**, OpenWA lets you swap database engines (SQ ### Option A: Docker Hub — Pre-built Images (Fastest) -No need to clone or build. Pull the images directly from Docker Hub: +No need to clone or build. Three commands and you're running: ```bash -# Create a project folder +# 1. Create a project folder mkdir openwa && cd openwa -# Download the compose file +# 2. Download the compose file and default config curl -o docker-compose.hub.yml https://raw.githubusercontent.com/3bsalam-1/OpenWA/main/docker-compose.hub.yml +curl -o .env https://raw.githubusercontent.com/3bsalam-1/OpenWA/main/.env.example -# Start +# 3. (Optional) Edit .env to customise ports, database, storage, etc. +# nano .env + +# 4. Start docker compose -f docker-compose.hub.yml up -d ``` -Or run manually with `docker run`: +Once running: + +| URL | Description | +| --- | --- | +| `http://localhost:2886` | Dashboard | +| `http://localhost:2785/api` | REST API | +| `http://localhost:2785/api/docs` | Swagger docs | + +The API key is printed in the container logs on first boot: ```bash -# API -docker run -d \ - --name openwa-api \ - -p 127.0.0.1:2785:2785 \ - -e DATABASE_TYPE=sqlite \ - -e DATABASE_NAME=/app/data/openwa.sqlite \ - -e DATABASE_SYNCHRONIZE=true \ - -e ENGINE_TYPE=whatsapp-web.js \ - -e PUPPETEER_HEADLESS=true \ - -e "PUPPETEER_ARGS=--no-sandbox,--disable-setuid-sandbox,--disable-dev-shm-usage,--disable-gpu" \ - -v $(pwd)/data:/app/data \ - 3bsalam/openwa-api:latest - -# Dashboard -docker run -d \ - --name openwa-dashboard \ - -p 127.0.0.1:2886:80 \ - 3bsalam/openwa-dashboard:latest +docker logs openwa-api | grep "API Key" ``` -| Image | Docker Hub | +**Available images:** + +| Image | Tag | | --- | --- | -| API | `3bsalam/openwa-api:latest` | -| Dashboard | `3bsalam/openwa-dashboard:latest` | +| `3bsalam/openwa-api` | `latest`, `0.2.1` | +| `3bsalam/openwa-dashboard` | `latest`, `0.2.1` | ---