pedroslopez / whatsapp-web.js

A WhatsApp client library for NodeJS that connects through the WhatsApp Web browser app
https://wwebjs.dev
Apache License 2.0
15.1k stars 3.6k forks source link

Can't run Whatsapp-web.js on Docker Container #2542

Closed fpiantoni closed 9 months ago

fpiantoni commented 11 months ago

Is there an existing issue for this?

Describe the bug

I am trying to put my app inside a Docker Container. I am able to build it correctly after a lot of looking around but i am facing this issue.

Dockerfile

FROM node:18

RUN apt-get update \
    && apt-get install -y wget gnupg \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/googlechrome-linux-keyring.gpg \
    && sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrome-linux-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-khmeros fonts-kacst fonts-freefont-ttf libxss1 \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/* 
# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

Expected behavior

Normal initialization of the Whatsapp-web.js Client code.

Steps to Reproduce the Bug or Issue

Run the normal example on Docker.

This is my build command:

docker build --platform linux/amd64 --no-cache -t whatsappclient:development .

Run command:

docker run --platform linux/amd64 -p 3000:3000 whatsappclient:development

Error Code:


/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:241
            reject(new Error([
                   ^

Error: Failed to launch the browser process!
qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
[0928/234157.110661:ERROR:bus.cc(406)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[0928/234157.303689:ERROR:scoped_ptrace_attach.cc(27)] ptrace: Function not implemented (38)
Assertion failed: p_rcu_reader->depth != 0 (/qemu/include/qemu/rcu.h: rcu_read_unlock: 101)

TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md

    at onClose (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:241:20)
    at ChildProcess.<anonymous> (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:232:79)
    at ChildProcess.emit (node:events:529:35)
    at ChildProcess._handle.onexit (node:internal/child_process:292:12)

Node.js v18.18.0

Browser Type

Google Chrome

WhatsApp Account Type

Standard

Does your WhatsApp account have multidevice enabled?

Yes, I am using Multi Device

Environment

"whatsapp-web.js": "1.22.2-alpha.0" Node.js: 18

Additional context

No response

macleysousa commented 11 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]
diogenespetry commented 11 months ago

Do you use headless puppeteer come true or false?

fpiantoni commented 11 months ago

I have headless true!! @diogenespetry

fpiantoni commented 11 months ago

@macleysousa I will try your Dockerfile and keep you updated.

rodrigooliveira87 commented 11 months ago

I'll post my configs that's working:

Dockerfile:

FROM node:18 WORKDIR /usr/src/app RUN apt-get update RUN apt-get install -y gconf-service libgbm-dev libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget COPY package*.json ./ RUN npm install COPY . . EXPOSE 8080 CMD ["npm", "start"]

Client instance:

const client = new Client({ ... puppeteer: { headless: true, args: ['--no-sandbox'] } });

Hope it helps

fpiantoni commented 11 months ago

@rodrigooliveira87 i will try your Dockerfile and the other ones today!!

Thanks for the help :)

blastbeng commented 11 months ago

EXPOSE 8080 CMD ["npm", "start"]

Could you provide your package.json and index.js/server.js?

And also why are you exposing port 8080? I have nothing running on that port

rodrigooliveira87 commented 11 months ago

EXPOSE 8080 CMD ["npm", "start"]

Could you provide your package.json and index.js/server.js?

And also why are you exposing port 8080? I have nothing running on that port

for sure @blastbeng...

package.json:

{ "scripts": { "start": "node app > logs/log.txt 2>&1", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "express": "^4.18.2", "ftp": "^0.3.10", "helmet": "^6.0.1", "pg": "^8.10.0", "puppeteer": "^21.1.1", "qrcode-terminal": "^0.12.0", "uuid": "^9.0.0", "whatsapp-web.js": "git+https://github.com/rodrigooliveira87/whatsapp-web.js.git#30e34b5" } }

note that I'm using a specific branch of the library, because some changes of whatsapp web takes time to be released on main branch...

app.js: (index.js equivalent)

const express = require('express'); const register = require('./routes/wp/register'); const send = require('./routes/wp/send'); const message = require('./routes/wp/message'); const bodyParser = require("body-parser"); const config = require('./config/config'); const app = express();

process.setMaxListeners(100);

// Body Parser Middleware app.use(bodyParser.json({ limit: '20mb' }));

app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", "true"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("Access-Control-Allow-Credentials", true); next(); });

app.use(/wp/register, register); app.use(/wp/send, send); app.use(/wp/message, message);

const port = config.API_PORT;

const server = app.listen(port, () => { console.log(Running on port ${port}); });

server.timeout = 120000;

About 8080 port... my node server runs on 8080, so, the docker image needs to expose it. The definition of effective port to be used is set on docker run command, like:

sudo docker run -it --rm -p 8075:8080 --name ...

where 8075 is the "final" port..

blastbeng commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js

Why?

rodrigooliveira87 commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js

Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe?

Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

blastbeng commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe?

Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

which auth strategy should i usu to maintain session after bot restart?

rodrigooliveira87 commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe? Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

which auth strategy should i usu to maintain session after bot restart?

I'm using LocalAuth too, working on docker container... did you try start your application with no authStrategy just to test if that's the point?

blastbeng commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe? Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

which auth strategy should i usu to maintain session after bot restart?

I'm using LocalAuth too, working on docker container... did you try start your application with no authStrategy just to test if that's the point?

Yes, tested now, the bot is still stuck...


discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso...
rodrigooliveira87 commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe? Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

which auth strategy should i usu to maintain session after bot restart?

I'm using LocalAuth too, working on docker container... did you try start your application with no authStrategy just to test if that's the point?

Yes, tested now, the bot is still stuck...


discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso...

try with my fork and commit on package.json... I'm discovering how sensitive the variation between versions of this library is:

"whatsapp-web.js": "git+https://github.com/rodrigooliveira87/whatsapp-web.js.git#30e34b5"

blastbeng commented 11 months ago

I am using this bot.js and starting it as "node bot.js"

const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');

const client = new Client({
    puppeteer: {
        headless: true,
        args: ['--no-sandbox'],
        authStrategy: new LocalAuth()
    }
});

client.initialize();

client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
});

client.on('qr', qr => {
    console.log('QR RECEIVED', qr);
    qrcode.generate(qr, {small: true});
});

client.on('authenticated', () => {
    console.log('AUTHENTICATED');
});

client.on('auth_failure', msg => {
    // Fired if session restore was unsuccessful
    console.error('AUTHENTICATION FAILURE', msg);
});

client.on('disconnected', (reason) => {
    console.log('Client was logged out', reason);
})

client.on('ready', () => {
    console.log('READY');
});

client.on('message', msg => {
    if (msg.body == '!random') {

        msg.reply("pong");
    }
});

But nothing happens... the client is stuck, this is the log:

discord-tts-bot-whatsapp  | QR RECEIVED  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
discord-tts-bot-whatsapp Loggin qr code... 
discord-tts-bot-whatsapp  |
discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso..

and then nothing else and if I do "!random" in chat nothing happens. Tested in debug, the on message is never called. This happens both in docker mode and both running manually with node bot.js Why?

Hm... It's intentional to use " authStrategy: new LocalAuth()" on puppeteer? Some file write permission issue maybe? Your log suggests that's sessions has been connected and loaded... If nothing happens after that, you can check this...

which auth strategy should i usu to maintain session after bot restart?

I'm using LocalAuth too, working on docker container... did you try start your application with no authStrategy just to test if that's the point?

Yes, tested now, the bot is still stuck...


discord-tts-bot-whatsapp  | LOADING SCREEN 0 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Loading your chats
discord-tts-bot-whatsapp  | LOADING SCREEN 100 Caricamento delle chat in corso...

try with my fork and commit on package.json... I'm discovering how sensitive the variation between versions of this library is:

"whatsapp-web.js": "git+https://github.com/rodrigooliveira87/whatsapp-web.js.git#30e34b5"

how to add this in package.json?


{
  "dependencies": {
    "qrcode-terminal": "^0.12.0",
    "whatsapp-web.js": "git+https://github.com/rodrigooliveira87/whatsapp-web.js.git#30e34b5"
  }
}
8.443 npm notice Run `npm install -g npm@10.2.0` to update!
8.443 npm notice
8.460 npm ERR! code 1
8.471 npm ERR! The git reference could not be found
8.473 npm ERR! command git --no-replace-objects checkout 30e34b5
8.474 npm ERR! error: pathspec '30e34b5' did not match any file(s) known to git
blastbeng commented 11 months ago

I can confirm that using

"whatsapp-web.js": "git+https://github.com/rodrigooliveira87/whatsapp-web.js.git"

it works. it works also inside docker container.

fpiantoni commented 11 months ago

RUN apt-get update RUN apt-get install -y gconf-service libgbm-dev libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

When runnning your Dockerfile config i got the following error:

Server is running on http://0.0.0.0:8080
Client not initialized. Call createWhatsappClient first.
Creating client
/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:105
                throw new Error(missingText);
                      ^

Error: Could not find expected browser (chrome) locally. Run `npm install` to download the correct Chromium revision (982053).
    at ChromeLauncher.launch (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:105:23)
    at PuppeteerNode.launch (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Puppeteer.js:125:31)
    at Client.initialize (/app/node_modules/whatsapp-web.js/src/Client.js:106:39)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v18.18.0
fpiantoni commented 11 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

I got the following error while trying that Dockerfile


Server is running on http://0.0.0.0:8080
Client not initialized. Call createWhatsappClient first.
Creating client
/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:105
                throw new Error(missingText);
                      ^

Error: Could not find expected browser (chrome) locally. Run `npm install` to download the correct Chromium revision (982053).
    at ChromeLauncher.launch (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:105:23)
    at PuppeteerNode.launch (/app/node_modules/whatsapp-web.js/node_modules/puppeteer/lib/cjs/puppeteer/node/Puppeteer.js:125:31)
    at Client.initialize (/app/node_modules/whatsapp-web.js/src/Client.js:106:39)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v20.8.0
fpiantoni commented 11 months ago

Now i have this Dockerfile:

FROM node:18

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*
# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 8080

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

And i am recieving this error:


Server is running on http://0.0.0.0:8080
Client not initialized. Call createWhatsappClient first.
Creating client

  Puppeteer old Headless deprecation warning:
    In the near future `headless: true` will default to the new Headless mode
    for Chrome instead of the old Headless implementation. For more
    information, please see https://developer.chrome.com/articles/new-headless/.
    Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
    If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.

/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ProductLauncher.js:300
                    throw new Error(`Could not find Chrome (ver. ${this.puppeteer.browserRevision}). This can occur if either\n` +
                          ^

Error: Could not find Chrome (ver. 116.0.5845.96). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npm install`) or
 2. your cache path is incorrectly configured (which is: /root/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.
    at ChromeLauncher.resolveExecutablePath (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ProductLauncher.js:300:27)
    at ChromeLauncher.executablePath (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:182:25)
    at ChromeLauncher.computeLaunchArguments (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:98:37)
    at ChromeLauncher.launch (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ProductLauncher.js:79:39)
    at ChromeLauncher.launch (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:52:22)
    at PuppeteerNode.launch (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/node/PuppeteerNode.js:142:31)
    at Client.initialize (/app/node_modules/whatsapp-web.js/src/Client.js:106:39)

Have you seen anything like this?

james-innes commented 10 months ago

Using Zenika Docker Image

Dockerfile with comments

# Use the Zenika image with Puppeteer support
FROM zenika/alpine-chrome:with-puppeteer

# Set working directory inside the container
WORKDIR /usr/src/app

# Switch to 'chrome' user before copying and installing
USER chrome

# Copy the package.json and package-lock.json for npm install
COPY --chown=chrome:chrome package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your app files into the container
COPY --chown=chrome:chrome . .

# Expose the required ports
EXPOSE 3000

# Set the command to run your app. Adjust accordingly.
CMD ["node", "server.js"]

Dockerfile without comments

FROM zenika/alpine-chrome:with-puppeteer
WORKDIR /usr/src/app
USER chrome
COPY --chown=chrome:chrome package*.json ./
RUN npm install
COPY --chown=chrome:chrome . .
EXPOSE 3000
CMD ["node", "server.js"]

server.js

It's not the whole file but the important bits.

const { Client, LocalAuth } = require("whatsapp-web.js");

const whatsapp = new Client({
  puppeteer: {
    headless: true,
    args: ["--no-sandbox"],
  },
  authStrategy: new LocalAuth(),
});

Build image and run

docker build -t james-whatsapp-test  .
docker run -p 3000:3000 james-whatsapp-test

Project Structure

Screenshot 2023-10-31 at 12 04 16 am

Other comments

  1. You can mount persisted volumes for auth and cache dir so that when you deploy new code you don't have to login again.
  2. If you struggle to login you can send the QR code to yourself via for example Telegram or Email
picocode1 commented 10 months ago

I'll post my configs that's working:

Dockerfile:

FROM node:18 WORKDIR /usr/src/app RUN apt-get update RUN apt-get install -y gconf-service libgbm-dev libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget COPY package*.json ./ RUN npm install COPY . . EXPOSE 8080 CMD ["npm", "start"]

Client instance:

             const client = new Client({
                            ...
                            puppeteer: {
                                headless: true,
                                args: ['--no-sandbox']
                            }
                        });

Hope it helps

This worked perfectly, thank you!

deepesh-agarwal commented 9 months ago

It would be amazing if someone can publish a working docker public image to Docker hub, I tried https://hub.docker.com/r/deepesh83/wwjs but unable to get this working. There is no console access and no logs for me :(

haliltayfuroglu commented 9 months ago

Using Zenika Docker Image

Dockerfile with comments

# Use the Zenika image with Puppeteer support
FROM zenika/alpine-chrome:with-puppeteer

# Set working directory inside the container
WORKDIR /usr/src/app

# Switch to 'chrome' user before copying and installing
USER chrome

# Copy the package.json and package-lock.json for npm install
COPY --chown=chrome:chrome package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your app files into the container
COPY --chown=chrome:chrome . .

# Expose the required ports
EXPOSE 3000

# Set the command to run your app. Adjust accordingly.
CMD ["node", "server.js"]

Dockerfile without comments

FROM zenika/alpine-chrome:with-puppeteer
WORKDIR /usr/src/app
USER chrome
COPY --chown=chrome:chrome package*.json ./
RUN npm install
COPY --chown=chrome:chrome . .
EXPOSE 3000
CMD ["node", "server.js"]

server.js

It's not the whole file but the important bits.

const { Client, LocalAuth } = require("whatsapp-web.js");

const whatsapp = new Client({
  puppeteer: {
    headless: true,
    args: ["--no-sandbox"],
  },
  authStrategy: new LocalAuth(),
});

Build image and run

docker build -t james-whatsapp-test  .
docker run -p 3000:3000 james-whatsapp-test

Project Structure

Screenshot 2023-10-31 at 12 04 16 am

Other comments

  1. You can mount persisted volumes for auth and cache dir so that when you deploy new code you don't have to login again.
  2. If you struggle to login you can send the QR code to yourself via for example Telegram or Email

I got this error when I tried to mount persisted volume.

2023-12-05 18:53:59 node:fs:603 2023-12-05 18:53:59 handleErrorFromBinding(ctx); 2023-12-05 18:53:59 ^ 2023-12-05 18:53:59 2023-12-05 18:53:59 Error: EACCES: permission denied, open '/usr/src/app/appdata/wa_session/.web_cache/2.2353.0.html' 2023-12-05 18:53:59 at Object.openSync (node:fs:603:3) 2023-12-05 18:53:59 at Object.writeFileSync (node:fs:2324:35) 2023-12-05 18:53:59 at LocalWebCache.persist (/usr/src/app/node_modules/whatsapp-web.js/src/webCache/LocalWebCache.js:39:12) 2023-12-05 18:53:59 at /usr/src/app/node_modules/whatsapp-web.js/src/Client.js:744:36 2023-12-05 18:53:59 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { 2023-12-05 18:53:59 errno: -13, 2023-12-05 18:53:59 syscall: 'open', 2023-12-05 18:53:59 code: 'EACCES', 2023-12-05 18:53:59 path: '/usr/src/app/appdata/wa_session/.web_cache/2.2353.0.html'

VigilioYonatan commented 8 months ago

any update?

Elite commented 8 months ago

Here is a working Dockerfile example:

# Use Ubuntu 20.04 as the base image
FROM ubuntu:latest

# Set the working directory in the container
WORKDIR /usr/src/app

# Install necessary packages
RUN apt-get update && apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    git \
    chromium-browser

# Add NodeSource signing key & repository
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list

# Install Node.js
RUN apt-get update && apt-get install -y nodejs

# Clone the specific GitHub repository
RUN git clone https://github.com/XXXX/XXXX
# Change directory to the cloned repository and install npm dependencies
WORKDIR /usr/src/app/XXXX
RUN npm install

# Install additional dependencies required for the application
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \
    gconf-service \
    libgbm-dev \
    libasound2 \
    libatk1.0-0 \
    libc6 \
    libcairo2 \
    libcups2 \
    libdbus-1-3 \
    libexpat1 \
    libfontconfig1 \
    libgcc1 \
    libgconf-2-4 \
    libgdk-pixbuf2.0-0 \
    libglib2.0-0 \
    libgtk-3-0 \
    libnspr4 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libstdc++6 \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    ca-certificates \
    fonts-liberation \
    libappindicator1 \
    libnss3 \
    lsb-release \
    xdg-utils \
    wget

# Expose port 3000
EXPOSE 3000

# Install Google Chrome for Video & GIF support
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' 
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - 
RUN apt update
RUN apt install -y google-chrome-stable
VigilioYonatan commented 8 months ago

Here is a working Dockerfile example:

# Use Ubuntu 20.04 as the base image
FROM ubuntu:latest

# Set the working directory in the container
WORKDIR /usr/src/app

# Install necessary packages
RUN apt-get update && apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    git \
    chromium-browser

# Add NodeSource signing key & repository
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list

# Install Node.js
RUN apt-get update && apt-get install -y nodejs

# Clone the specific GitHub repository
RUN git clone https://github.com/XXXX/XXXX
# Change directory to the cloned repository and install npm dependencies
WORKDIR /usr/src/app/XXXX
RUN npm install

# Install additional dependencies required for the application
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \
    gconf-service \
    libgbm-dev \
    libasound2 \
    libatk1.0-0 \
    libc6 \
    libcairo2 \
    libcups2 \
    libdbus-1-3 \
    libexpat1 \
    libfontconfig1 \
    libgcc1 \
    libgconf-2-4 \
    libgdk-pixbuf2.0-0 \
    libglib2.0-0 \
    libgtk-3-0 \
    libnspr4 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libstdc++6 \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    ca-certificates \
    fonts-liberation \
    libappindicator1 \
    libnss3 \
    lsb-release \
    xdg-utils \
    wget

# Expose port 3000
EXPOSE 3000

# Install Google Chrome for Video & GIF support
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' 
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - 
RUN apt update
RUN apt install -y google-chrome-stable

its working

Aaketk17 commented 8 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

It worked for me.

fpiantoni commented 7 months ago

Using Zenika Docker Image

Dockerfile with comments

# Use the Zenika image with Puppeteer support
FROM zenika/alpine-chrome:with-puppeteer

# Set working directory inside the container
WORKDIR /usr/src/app

# Switch to 'chrome' user before copying and installing
USER chrome

# Copy the package.json and package-lock.json for npm install
COPY --chown=chrome:chrome package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your app files into the container
COPY --chown=chrome:chrome . .

# Expose the required ports
EXPOSE 3000

# Set the command to run your app. Adjust accordingly.
CMD ["node", "server.js"]

Dockerfile without comments

FROM zenika/alpine-chrome:with-puppeteer
WORKDIR /usr/src/app
USER chrome
COPY --chown=chrome:chrome package*.json ./
RUN npm install
COPY --chown=chrome:chrome . .
EXPOSE 3000
CMD ["node", "server.js"]

server.js

It's not the whole file but the important bits.

const { Client, LocalAuth } = require("whatsapp-web.js");

const whatsapp = new Client({
  puppeteer: {
    headless: true,
    args: ["--no-sandbox"],
  },
  authStrategy: new LocalAuth(),
});

Build image and run

docker build -t james-whatsapp-test  .
docker run -p 3000:3000 james-whatsapp-test

Project Structure

Screenshot 2023-10-31 at 12 04 16 am

Other comments

  1. You can mount persisted volumes for auth and cache dir so that when you deploy new code you don't have to login again.
  2. If you struggle to login you can send the QR code to yourself via for example Telegram or Email

I am getting the following error after trying these build

#9 [5/5] RUN npm install
#9 1.553 npm ERR! code ENOENT
#9 1.553 npm ERR! syscall mkdir
#9 1.554 npm ERR! path /home/chrome/.npm/_cacache/content-v2/sha512/21
#9 1.554 npm ERR! errno ENOENT
#9 1.556 npm ERR! enoent Invalid response body while trying to fetch https://registry.npmjs.org/node-fetch: ENOENT: no such file or directory, mkdir '/home/chrome/.npm/_cacache/content-v2/sha512/21'
#9 1.556 npm ERR! enoent This is related to npm not being able to find a file.
#9 1.556 npm ERR! enoent 
#9 1.558 
#9 1.558 npm ERR! A complete log of this run can be found in: /home/chrome/.npm/_logs/2024-01-30T20_36_19_681Z-debug-0.log
#9 ERROR: process "/bin/sh -c npm install" did not complete successfully: exit code: 1
------
 > [5/5] RUN npm install:
1.553 npm ERR! code ENOENT
1.553 npm ERR! syscall mkdir
1.554 npm ERR! path /home/chrome/.npm/_cacache/content-v2/sha512/21
1.554 npm ERR! errno ENOENT
1.556 npm ERR! enoent Invalid response body while trying to fetch https://registry.npmjs.org/node-fetch: ENOENT: no such file or directory, mkdir '/home/chrome/.npm/_cacache/content-v2/sha512/21'
1.556 npm ERR! enoent This is related to npm not being able to find a file.
1.556 npm ERR! enoent 
1.558 
1.558 npm ERR! A complete log of this run can be found in: /home/chrome/.npm/_logs/2024-01-30T20_36_19_681Z-debug-0.log
------
Dockerfile:17
--------------------
  15 |     
  16 |     # Install dependencies
  17 | >>> RUN npm install
  18 |     
  19 |     # Expose the required ports
--------------------
ERROR: failed to solve: process "/bin/sh -c npm install" did not complete successfully: exit code: 1
andrscyv commented 4 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

It worked for me.

this works with

` puppeter: { args: ['--no-sandbox'], }

`

on the clients opt object

leochen-g commented 3 months ago

RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - RUN apt update RUN apt install -y google-chrome-stable

The FROM ubuntu:latest here needs to be changed to FROM ubuntu:22.04 in order to use it, because some libraries are no longer supported in the latest Ubuntu version. It is recommended to specify the version number of Ubuntu.

ravikant-pal commented 3 months ago

Using Zenika Docker Image

Dockerfile with comments

# Use the Zenika image with Puppeteer support
FROM zenika/alpine-chrome:with-puppeteer

# Set working directory inside the container
WORKDIR /usr/src/app

# Switch to 'chrome' user before copying and installing
USER chrome

# Copy the package.json and package-lock.json for npm install
COPY --chown=chrome:chrome package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your app files into the container
COPY --chown=chrome:chrome . .

# Expose the required ports
EXPOSE 3000

# Set the command to run your app. Adjust accordingly.
CMD ["node", "server.js"]

Dockerfile without comments

FROM zenika/alpine-chrome:with-puppeteer
WORKDIR /usr/src/app
USER chrome
COPY --chown=chrome:chrome package*.json ./
RUN npm install
COPY --chown=chrome:chrome . .
EXPOSE 3000
CMD ["node", "server.js"]

server.js

It's not the whole file but the important bits.

const { Client, LocalAuth } = require("whatsapp-web.js");

const whatsapp = new Client({
  puppeteer: {
    headless: true,
    args: ["--no-sandbox"],
  },
  authStrategy: new LocalAuth(),
});

Build image and run

docker build -t james-whatsapp-test  .
docker run -p 3000:3000 james-whatsapp-test

Project Structure

Screenshot 2023-10-31 at 12 04 16 am

Other comments

  1. You can mount persisted volumes for auth and cache dir so that when you deploy new code you don't have to login again.
  2. If you struggle to login you can send the QR code to yourself via for example Telegram or Email

Hi I have tried this but getting below error

➜  whatsapp-api docker run -p 8002:8082 whatsapp-api
Server is running on http://localhost:8082
Error initializing client: ErrorEvent {
  [Symbol(kTarget)]: WebSocket {
    _events: [Object: null prototype] { open: [Function], error: [Function] },
    _eventsCount: 2,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 3,
    _receiver: null,
    _sender: null,
    _socket: null,
    _bufferedAmount: 0,
    _isServer: false,
    _redirects: 0,
    _url: 'ws://127.0.0.1:44515/devtools/browser/28a4e8d4-f53f-44a1-a289-918e2435e20b',
    _originalHost: '127.0.0.1:44515',
    _req: null,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
  },
  [Symbol(kType)]: 'error',
  [Symbol(kError)]: Error: read ECONNRESET
      at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
    errno: -104,
    code: 'ECONNRESET',
    syscall: 'read'
  },
  [Symbol(kMessage)]: 'read ECONNRESET'
}

Please help!

My DockerFfile

FROM zenika/alpine-chrome:with-puppeteer
WORKDIR /usr/src/app
USER chrome
COPY --chown=chrome:chrome package*.json ./
RUN npm install
COPY --chown=chrome:chrome . .
EXPOSE 8082
CMD ["node", "index.js"]

My Index.js

const qrcode = require('qrcode-terminal');
const express = require('express');
const app = express();
const port = process.env.PORT || 8082;

const { Client, LocalAuth } = require('whatsapp-web.js');

const client = new Client({
  puppeteer: {
    headless: true,
    args: ['--no-sandbox'],
  },
  authStrategy: new LocalAuth(),
});

client.on('qr', (qr) => {
  qrcode.generate(qr, { small: true });
});

client.on('ready', () => {
  console.log('Client is ready!');
});

client.on('authenticated', () => {
  console.log('Client is authenticated!');
});

client.on('auth_failure', (msg) => {
  console.error('Authentication failure:', msg);
});

client.on('disconnected', (reason) => {
  console.log('Client was logged out', reason);
});

client.on('message', async (msg) => {
  try {
    if (msg.body == '!ping') {
      await msg.reply('pong');
    }
  } catch (err) {
    console.error('Error handling message:', err);
  }
});

client.initialize().catch((err) => {
  console.error('Error initializing client:', err);
});

// Add a generic error handler for all client events
client.on('error', (err) => {
  console.error('Client error:', err);
});

app.get('/', (req, res) => {
  res.send('WhatsApp API is running');
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

// Global error handler for unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Application specific logging, throwing an error, or other logic here
});

// Global error handler for uncaught exceptions
process.on('uncaughtException', (err) => {
  console.error('Uncaught Exception:', err);
  // Optionally exit the process
  process.exit(1);
});

My directory structure

image

System info:

Mac OS Sonoma 14.5 (23F79) Apple M1 Pro and Using Colima for docker.

Thank you in advance 🙏🏻

hildanku commented 3 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

thanks this Dockerfile is work. Client.js: puppeteer: { // args: ['--proxy-server=proxy-server-that-requires-authentication.example.com'],

// Jika ingin di install di VPS Wajib install package chromium
// executablePath: '/usr/bin/google-chrome',
args: ['--no-sandbox'],
headless: true

}

ravikant-pal commented 3 months ago

Try this using the default browser

FROM node:latest

RUN apt-get update \
  && apt-get install -y \
  gconf-service \
  libgbm-dev \
  libasound2 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgcc1 \
  libgconf-2-4 \
  libgdk-pixbuf2.0-0 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libpango-1.0-0 \
  libpangocairo-1.0-0 \
  libstdc++6 \
  libx11-6 \
  libx11-xcb1 \
  libxcb1 \
  libxcomposite1 \
  libxcursor1 \
  libxdamage1 \
  libxext6 \
  libxfixes3 \
  libxi6 \
  libxrandr2 \
  libxrender1 \
  libxss1 \
  libxtst6 \
  ca-certificates \
  fonts-liberation \
  libappindicator1 \
  libnss3 \
  lsb-release \
  xdg-utils \
  && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Build your application
RUN npm run build

# Expose the port your application runs on
EXPOSE 3000

# Start your Node.js application
CMD ["node", "dist/server/server.js"]

thanks this Dockerfile is work. Client.js: puppeteer: { // args: ['--proxy-server=proxy-server-that-requires-authentication.example.com'],

// Jika ingin di install di VPS Wajib install package chromium
// executablePath: '/usr/bin/google-chrome',
args: ['--no-sandbox'],
headless: true

}

Hi @hildanku now I have made change

but now getting

➜  ~ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                                       NAMES
45bf422c2744   whatsapp-api   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:8002->8082/tcp, :::8002->8082/tcp   unruffled_knuth
➜  ~ docker logs --follow --tail 100 45bf422c2744
(node:1) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Server is running on http://localhost:8082
Error initializing client: ProtocolError: Protocol error (Target.setDiscoverTargets): Target closed.
    at /app/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:75:24
    at new Promise (<anonymous>)
    at Connection.send (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:71:16)
    at Browser.create (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/Browser.js:121:26)
    at ChromeLauncher.launch (/app/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:129:50)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Client.initialize (/app/node_modules/whatsapp-web.js/src/Client.js:107:23) {
  originalMessage: ''
}

My Dockerfile:

FROM node:latest

RUN apt-get update \
    && apt-get install -y \
    gconf-service \
    libgbm-dev \
    libasound2 \
    libatk1.0-0 \
    libc6 \
    libcairo2 \
    libcups2 \
    libdbus-1-3 \
    libexpat1 \
    libfontconfig1 \
    libgcc1 \
    libgconf-2-4 \
    libgdk-pixbuf2.0-0 \
    libglib2.0-0 \
    libgtk-3-0 \
    libnspr4 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libstdc++6 \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    ca-certificates \
    fonts-liberation \
    libappindicator1 \
    libnss3 \
    lsb-release \
    xdg-utils \
    && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Copy your application files into the container
COPY . .

# Install your Node.js application dependencies
RUN npm install

# Expose the port your application runs on
EXPOSE 8082

# Start your Node.js application
CMD ["node", "index.js"]

My Index.js


const qrcode = require('qrcode-terminal');
const express = require('express');
const app = express();
const port = process.env.PORT || 8082;

const { Client, LocalAuth } = require('whatsapp-web.js');

const client = new Client({
  puppeteer: {
    headless: true,
    args: ['--no-sandbox'],
  },
  authStrategy: new LocalAuth(),
});

client.on('qr', (qr) => {
  qrcode.generate(qr, { small: true });
});

client.on('ready', () => {
  console.log('Client is ready!');
});

client.on('authenticated', () => {
  console.log('Client is authenticated!');
});

client.on('auth_failure', (msg) => {
  console.error('Authentication failure:', msg);
});

client.on('disconnected', (reason) => {
  console.log('Client was logged out', reason);
});

client.on('message', async (msg) => {
  try {
    if (msg.body == '!ping') {
      await msg.reply('pong');
    }
  } catch (err) {
    console.error('Error handling message:', err);
  }
});

client.initialize().catch((err) => {
  console.error('Error initializing client:', err);
});

// Add a generic error handler for all client events
client.on('error', (err) => {
  console.error('Client error:', err);
});

app.get('/', (req, res) => {
  res.send('WhatsApp API is running');
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

// Global error handler for unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Application specific logging, throwing an error, or other logic here
});

// Global error handler for uncaught exceptions
process.on('uncaughtException', (err) => {
  console.error('Uncaught Exception:', err);
  // Optionally exit the process
  process.exit(1);
});

Please suggest if I'm missing something 🥲