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 @@
-
+
@@ -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 @@
-
+
-
+
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 @@
+
---
@@ -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` |
---