Docker सह VPS वर Chatwoot self-host कसे करावे
Docker Compose आणि Traefik वापरून VPS वर Chatwoot तैनात करा. Pinned tags, प्रत्यक्ष mail पाठवणारे SMTP, Postgres व uploads backups आणि सुरक्षित upgrades जाणून घ्या.
तुम्ही काय तयार करत आहात
VPS वर Chatwoot self-host करण्यासाठी तुम्ही चार containers चालवता: Rails web process, Sidekiq background worker, pgvector extension असलेले PostgreSQL आणि Redis. Chatwoot हे open source customer support desk आहे. त्यामुळे तुमच्या नियंत्रणाखालील server वर shared team inbox आणि website chat widget मिळतो. Installation सुमारे वीस मिनिटे घेते. त्यानंतरचे mail delivery, backups, upgrades आणि sizing हे सर्व system एक वर्षानंतरही चालू राहील की नाही हे ठरवतात.
प्रत्येक container चे एक काम आहे. Rails agent dashboard आणि widget API (application programming interface) उपलब्ध करून देतो. Sidekiq धीमी कामे चालवतो: email पाठवणे, जोडलेल्या channels चे polling करणे, automation rules चालवणे आणि reports तयार करणे. Postgres मध्ये conversations, contacts, agent accounts आणि dashboard मध्ये तुम्ही बदललेली प्रत्येक setting साठवली जाते. Redis मध्ये Sidekiq queues आणि ActionCable pub/sub channel साठवला जातो. हा channel page reload न करता उघडलेल्या dashboard मध्ये नवीन message पाठवतो. येथे Redis हा सहज टाकून देता येणारा cache नाही, कारण तो गमावल्यास queued jobs गमावतात.
Upstream compose file मधील Postgres image ही stock postgres image ऐवजी pgvector/pgvector:pg16 आहे, कारण Chatwoot च्या schema मध्ये त्याच्या AI features साठी vector extension सक्षम केलेली आहे. Stock Postgres वापरल्यास पहिल्या database run वेळी ERROR: extension "vector" is not available मुळे प्रक्रिया थांबते, कारण त्या image मध्ये extension ची control file नसते. Upstream कडून releases होणारी image वापरा.
या मार्गदर्शकात Docker आणि reverse proxy server वर आधीपासून कार्यरत आहेत असे गृहीत धरले आहे. ते कार्यरत नसल्यास VPS वर Docker Compose पासून सुरुवात करा आणि नंतर येथे परत या.
स्वतः होस्ट केलेल्या Chatwoot साठी किती VPS आवश्यक आहे?
August 2026 पर्यंत, upstream requirements पेजनुसार किमान 4 GB RAM आणि 4 CPU cores आवश्यक आहेत. या क्षमतेवर दररोज 10,000 पर्यंत conversations हाताळता येतात. 8 GB RAM आणि 8 cores असतील, तर दररोज 20,000 पर्यंत conversations हाताळता येतात. किमान 1 GB swap देखील आवश्यक आहे. त्याचे कारण स्पष्ट दिलेले आहे: upgrade दरम्यान मशीनची memory संपुष्टात येऊ नये. File uploads धरून न ठेवता Postgres साठी 5 GB ते 10 GB disk space गृहीत धरा.
आता स्पष्ट मुद्दा. 2 GB VPS वर Chatwoot सुरू होईल आणि दोन agents व कमी वापराच्या inbox सह ते व्यवस्थित दिसेल. परंतु दोन ठिकाणी समस्या येते. पहिली समस्या Sidekiq ची आहे. व्यस्त server वर त्याचा memory वापर 1 GB पेक्षा जास्त असल्याचे upstream मोजते. त्यामुळे email चा अचानक वाढलेला भार किंवा report job आल्यावर Rails, Postgres आणि Redis यांचा memory वापर होण्यापूर्वीच मशीनची memory संपते. दुसरी समस्या upgrade वेळी येते. कारण db:chatwoot_prepare migrations लागू करण्यासाठी नवीन Rails process सुरू करते. या image मध्ये Rails boot होण्यासाठी कोणतेही प्रत्यक्ष काम सुरू होण्यापूर्वीच शेकडो megabytes memory लागतात.
सुरुवातीला कोणतीही स्पष्ट warning मिळत नाही. Kernel चा out of memory killer सर्वात मोठ्या process ला SIGKILL पाठवतो. Docker container बंद झाल्याचे पाहतो आणि restart: always ते पुन्हा सुरू करते. docker compose ps नंतर असा container दाखवते, जो सतत Exited (137) येथे परत येतो. येथे 137 म्हणजे signal 9 मुळे process बंद केला गेला. Kernel ने कोणती process निवडली हे पाहण्यासाठी sudo dmesg -T | grep -i "killed process" वापरून त्याची पुष्टी करा.
4 GB चा खर्च परवडत नसेल, तर 2 GB मशीनवर 2 GB swap सह Chatwoot चालवा. भार वाढल्यावर response times खराब होतील, पण सेवा पूर्णपणे बंद पडणार नाही, हे स्वीकारावे लागेल. कोणत्याही परिस्थितीत प्रत्येक service साठी hard memory ceiling निश्चित करणे उपयुक्त आहे. त्यामुळे worker मुळे database बंद पडणार नाही. Docker Compose मधील memory limits पहा.
File uploads हा तुम्ही निश्चित केलेल्या मर्यादेशिवाय वाढणारा भाग आहे. ग्राहकाने जोडलेला प्रत्येक screenshot storage volume मध्ये साठतो आणि तिथेच राहतो. त्यामुळे disk database मुळे भरली असे गृहीत न धरता docker system df -v वर लक्ष ठेवा.
Compose फाइल मिळवा आणि version tag निश्चित करा
mkdir -p ~/chatwoot && cd ~/chatwoot
wget -O .env https://raw.githubusercontent.com/chatwoot/chatwoot/develop/.env.example
wget -O docker-compose.yaml https://raw.githubusercontent.com/chatwoot/chatwoot/develop/docker-compose.production.yaml
chmod 600 .envतुम्ही नुकतीच डाउनलोड केलेली फाइल image: chatwoot/chatwoot:latest दर्शवते. पुढील कोणतेही काम करण्यापूर्वी ते बदला.
services:
base: &base
image: chatwoot/chatwoot:v4.16.2
env_file: .env
volumes:
- storage_data:/app/storagelatest मुळे पुढील docker compose pull तुम्हाला त्या सकाळी publish केलेली कोणतीही आवृत्ती देते. त्यात तुम्ही कधीही वाचलेले नसलेले migrations असलेली major version असू शकते. Chatwoot migrations प्रत्यक्षात reversible नसतात. त्यामुळे चुकून झालेली version jump ही undo नसून backup मधून restore करण्याची प्रक्रिया असते. Tag निश्चित करा आणि तो जाणीवपूर्वक बदला. August 2026 पर्यंत v4.16.2 ही current release होती; आज कोणता tag निश्चित करायचा हे पाहण्यासाठी releases page तपासा.
base service हा YAML anchor आहे. rails आणि sidekiq दोन्ही तो merge करतात. त्यामुळे एका ठिकाणी tag बदलल्यास तो दोन्हींसाठी बदलतो. फाइलमध्ये असतानाच वरची version: '3' line हटवा. Modern Compose तिच्याकडे दुर्लक्ष करते आणि प्रत्येक command वर the attribute 'version' is obsolete, it will be ignored दाखवते.
.env फाइल भरा
प्रथम secret तयार करा. Upstream ला alphanumeric value अपेक्षित आहे, कारण ही value shell किंवा YAML parser मधून जाताना special characters चे स्वरूप बदलू शकतात.
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 63 ; echo ''त्यानंतर .env मध्ये या keys सेट करा.
SECRET_KEY_BASE=<the 63 characters you just generated>
FRONTEND_URL=https://support.example.com
FORCE_SSL=true
DEFAULT_LOCALE=en
ENABLE_ACCOUNT_SIGNUP=true
POSTGRES_HOST=postgres
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=<long random string>
POSTGRES_DATABASE=chatwoot
REDIS_URL=redis://redis:6379
REDIS_PASSWORD=<a different long random string>
RAILS_ENV=production
INSTALLATION_ENV=docker
ACTIVE_STORAGE_SERVICE=localPOSTGRES_HOST=postgres आणि redis://redis:6379 ही Compose service names आहेत. त्या project च्या default network वर resolve होतात. FRONTEND_URL केवळ सजावटीसाठी नाही. Chatwoot त्यावरून widget script URL आणि outgoing email मधील प्रत्येक link तयार करते. त्यामुळे चुकीची value दिल्यास password reset links प्रतिसाद न देणाऱ्या host कडे निर्देश करतात.
आता upstream फाइलमधील महत्त्वाचा अडथळा पाहू. postgres service .env वाचत नाही. तिच्यामध्ये स्वतःचा environment block आहे आणि POSTGRES_PASSWORD= रिक्त ठेवलेले आहे. त्यामुळे केवळ .env मध्ये password सेट केल्यास database कडे password नसतो, पण application कडे password असतो. Service ला त्याच variable कडे निर्देशित करा:
postgres:
image: pgvector/pgvector:pg16
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}Compose project directory मधून .env वाचते आणि ${...} substitution करते. त्यामुळे आता दोन्ही बाजूंना समान string मिळते. हे चुकीचे केल्यास Rails PG::ConnectionBad: FATAL: password authentication failed for user "postgres" सह थांबते.
एक वर्तन जवळपास सर्वांनाच आश्चर्यचकित करते: Postgres image POSTGRES_PASSWORD फक्त रिक्त data directory initialize करताना लागू करते. नंतर value बदलल्यास त्याचा परिणाम होत नाही, कारण initdb पुन्हा चालत नाही. Stack आधीच एकदा सुरू केला असल्यास database मध्येच ती value बदला.
docker compose exec postgres psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'the-new-password';"ENABLE_ACCOUNT_SIGNUP=true तात्पुरते आहे. पहिला account तयार करण्यासाठी ते public registration form उघडते. तुमचा account तयार होताच ते false वर सेट करा आणि docker compose up -d पुन्हा चालवा. अन्यथा URL सापडलेली कोणतीही व्यक्ती तुमच्या support desk वर register करू शकते. त्यानंतर agents invitation द्वारे जोडले जातात आणि त्यांचे passwords फक्त या एका app मध्ये ठेवले जातात. अनेक services चालवताना प्रत्येकामध्ये स्वतंत्र account list ठेवणे त्रासदायक होईपर्यंत ही रचना योग्य आहे. त्या वेळी Authentik सारखा self-hosted identity provider या स्वतंत्र account lists ची जागा घेतो.
.env मध्ये आता या stack मधील प्रत्येक secret plain text मध्ये आहे. त्यामुळे फाइलचा mode 600 ठेवा आणि ती git मध्ये commit करू नका. Compose env files कशा वाचते आणि secrets कुठे उघड होतात या विषयात env_file आणि environment मधील फरकासह महत्त्वाच्या धोक्यांचे स्पष्टीकरण दिले आहे.
तुमच्या विद्यमान Traefik च्या मागे Chatwoot ठेवा
एका अॅप्लिकेशनसाठी दुसरा reverse proxy तयार करू नका. या सर्व्हरवरील इतर कंटेनरसाठी Traefik आधीच TLS (transport layer security) termination करत असेल, तर Chatwoot label block द्वारे त्यात जोडता येतो. तुमच्याकडे ही रचना अद्याप नसेल, तर अनेक Docker Compose अॅप्सच्या पुढे Traefik एकदा सेट करा आणि नंतर येथे परत या.
Upstream चे docker-compose.yaml जवळपास मूळ स्वरूपात ठेवा, जेणेकरून नंतरच्या नवीन प्रतीशी त्याची diff तुलना करता येईल. तुमचे बदल override फाइलमध्ये ठेवा. Compose docker-compose.override.yaml आपोआप merge करते आणि Compose अनेक फाइल्समध्ये विभागणे merge नियम स्पष्ट करते.
services:
rails:
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.chatwoot.rule=Host(`support.example.com`)"
- "traefik.http.routers.chatwoot.entrypoints=websecure"
- "traefik.http.routers.chatwoot.tls.certresolver=letsencrypt"
- "traefik.http.services.chatwoot.loadbalancer.server.port=3000"
networks:
proxy:
external: trueतुमची entrypoint आणि certresolver नावे वापरा. कंटेनर Traefik च्या समान Docker network वर असणे आवश्यक आहे. proxy entry हेच सुनिश्चित करते. तसेच ते default वरही राहिले पाहिजे; अन्यथा Postgres आणि Redis शी त्याचा संपर्क तुटतो. ही दुसरी ओळ अनेकदा विसरली जाते.
ports: block मध्ये बदल करू नका. Upstream ते 127.0.0.1:3000 शी bind करते. हा फक्त loopback साठी उपलब्ध असल्यामुळे इंटरनेटवरून त्याच्यापर्यंत पोहोचता येत नाही. सर्व्हरच्या आतून curl -I http://127.0.0.1:3000 वापरून चाचणी करण्यासाठी ते उपयुक्त राहते.
Live message delivery साठी agent dashboard /cable शी websocket connection उघडे ठेवते. Traefik कोणत्याही अतिरिक्त configuration शिवाय HTTP upgrade forward करते, त्यामुळे काहीही जोडण्याची गरज नाही. नंतर Traefik च्या पुढे CDN किंवा दुसरा proxy ठेवला, तर तेथे websockets ला अनुमती द्या. अन्यथा dashboard सामान्यपणे load होईल, पण नवीन संदेश फक्त manually refresh केल्यानंतर दिसतील.
डेटाबेस सुरू करा आणि stack सुरू करा
प्रथम data services सुरू करा आणि Postgres चा पहिला run पूर्ण होऊ द्या.
docker compose up -d postgres redis
docker compose logs postgres | tail -n 5database system is ready to accept connections साठी प्रतीक्षा करा. त्यानंतर schema तयार करा.
docker compose run --rm rails bundle exec rails db:chatwoot_prepareयामुळे database उपलब्ध नसल्यास तो तयार होतो. त्यानंतर schema आणि default seed data लोड होतो. Migration ओळी मुद्रित होतात आणि command स्वच्छपणे बंद होते. जर postgres:5432 - no response मुद्रित होत राहिले, तर entrypoint अद्याप connections स्वीकारत नसलेल्या database ची प्रतीक्षा करत आहे. पहिल्या run मध्ये याचा अर्थ सहसा initdb चे काम सुरू आहे. प्रतीक्षा करा, Postgres logs वाचा आणि command पुन्हा चालवा. जर vector extension वर प्रक्रिया थांबली, तर तुम्ही pgvector image ऐवजी stock Postgres वापरले आहे.
docker compose up -d
docker compose ps
docker compose logs --tail 30 railsचारही containers ची स्थिती Up अशी असावी. rails log चा शेवट http://0.0.0.0:3000 वर listening करणाऱ्या Puma ओळीने झाला पाहिजे. त्यानंतर public path तपासा:
curl -sI https://support.example.com | head -n 1HTTP/2 200 याचा अर्थ संपूर्ण chain कार्यरत आहे. Traefik कडून 404 मिळाल्यास router rule जुळलेली नाही. याचे सामान्य कारण hostname मधील टंकलेखनाची चूक असते. 502 मिळाल्यास Traefik ने router जुळवला आहे, परंतु container पर्यंत पोहोचता आलेले नाही. याचे जवळजवळ नेहमीचे कारण म्हणजे proxy network नसणे किंवा loadbalancer.server.port चे मूल्य 3000 नसणे.
URL उघडा, /app/auth/signup येथे तुमचे account तयार करा, त्यानंतर ENABLE_ACCOUNT_SIGNUP=false सेट करा आणि form बंद करण्यासाठी docker compose up -d चालवा.
SMTP शिवाय password reset आणि email संभाषणे का अयशस्वी होतात
SMTP (simple mail transfer protocol) settings नसलेले Chatwoot हे mail पाठवू न शकणारे support desk असते. त्यामुळे notifications पेक्षा अधिक गोष्टी बंद पडतात. Password reset काम करणे थांबवतात. त्यामुळे lock out झालेला admin पुन्हा access मिळवू शकत नाही. Agent invitations काम करणे थांबवतात, कारण invitation हा email असतो. Email conversation मधील customer ला reply करणेही बंद पडते. त्यामुळे conversation फक्त एकाच दिशेने चालते. ही पायरी अनेकजण वगळतात आणि नंतर सर्वात अडचणीच्या काळात त्याचा परिणाम दिसतो.
यामागची प्रक्रिया सोपी आहे. SMTP settings नसल्यास ActionMailer त्याचे default setting ठेवतो आणि localhost वर port 25 वापरून mail पाठवण्याचा प्रयत्न करतो. Rails container मध्ये mail server नसल्यामुळे delivery job Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25 निर्माण करते. Mail background job मधून पाठवला जातो. त्यामुळे ही ओळ Rails log मध्ये नव्हे, तर Sidekiq log मध्ये दिसते. दरम्यान, "forgot password" वर click करणाऱ्या व्यक्तीला यशस्वी झाल्याचा संदेश दिसतो; पण तिला mail मिळत नाही.
MAILER_SENDER_EMAIL=Support <support@example.com>
SMTP_DOMAIN=example.com
SMTP_ADDRESS=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=support@example.com
SMTP_PASSWORD=<the relay password>
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=trueSTARTTLS सह port 587 वापरा. यामुळे connection plain text मध्ये सुरू होते आणि authentication पूर्वी ते encrypted होते. Spam मर्यादित करण्यासाठी बहुतांश VPS providers outbound port 25 block करतात. त्यामुळे 587 वरील relay शीच बहुतेक वेळा connection होऊ शकते. SMTP संभाषणादरम्यान तुमचा server जाहीर करतो ते domain म्हणजे SMTP_DOMAIN. हे domain जुळत नसल्यास काही relays request reject करतात.
Settings लागू करा आणि worker वर लक्ष ठेवा:
docker compose up -d rails sidekiq
docker compose logs -f sidekiqLogin page वरून password reset सुरू करा. Delivery यशस्वी असल्यास Sidekiq log मध्ये mailer job सामान्यपणे पूर्ण झालेली दिसते. Failure झाल्यास प्रथम exception class दिसते. त्यानंतर Sidekiq वाढत्या backoff सह पुन्हा प्रयत्न करतो. त्यामुळे relay चुकीचा असल्यास तोच error अनेक तास दर काही मिनिटांनी दिसतो.
दोन प्रकारचे rejection सामान्य आहेत आणि यापैकी कोणतेही Chatwoot bug नसते. 535 Authentication failed म्हणजे त्या relay साठी username किंवा password चुकीचा आहे. अनेक providers account password ऐवजी application password मागतात. 550 Sender address rejected म्हणजे MAILER_SENDER_EMAIL असा address आहे ज्यावरून relay mail पाठवू देत नाही. त्यामुळे तो mailbox किंवा तुम्ही त्या provider कडे verify केलेले domain असणे आवश्यक आहे.
Conversation मध्ये email प्राप्त करणे ही स्वतंत्र प्रक्रिया आहे. त्यासाठी MAILER_INBOUND_EMAIL_DOMAIN आणि RAILS_INBOUND_EMAIL_SERVICE आवश्यक आहेत. तसेच incoming messages Chatwoot कडे पाठवणारा mail server आवश्यक आहे. Relay भाड्याने घेणे हा जलद मार्ग आहे. संपूर्ण mail path स्वतः व्यवस्थापित करायचा असल्यास, Mailcow सह स्वतःचा mail server चालवणे या commitment मध्ये प्रत्यक्षात काय समाविष्ट आहे ते स्पष्ट करते.
कशाचा बॅकअप घ्यावा आणि restore कार्यरत असल्याचे कसे सिद्ध करावे
Chatwoot बॅकअपचे चार भाग असतात. यापैकी कोणताही भाग वगळल्यास restore करण्याऐवजी संपूर्ण सेवा पुन्हा उभारावी लागते.
- Postgres database, ज्यामध्ये conversations, contacts, agent accounts आणि प्रत्येक setting साठवलेली असते.
storage_datavolume, कारणACTIVE_STORAGE_SERVICE=localअपलोड केलेल्या files disk वर लिहिते आणि Postgres मध्ये फक्त reference row ठेवते..envfile, कारण त्यामध्येSECRET_KEY_BASEआणिACTIVE_RECORD_ENCRYPTION_*keys असतात.- compose files, कारण त्यामध्ये database schema शी जुळणारा अचूक image tag नोंदवलेला असतो.
फक्त database restore केल्यास सर्व conversations परत येतात; परंतु प्रत्येक attachment तुटलेला असतो, कारण त्या rows ज्या files कडे निर्देश करतात त्या disk वर उपलब्ध नसतात.
cd ~/chatwoot
docker compose exec -T postgres pg_dump -U postgres -Fc chatwoot > db-$(date +%F).dump-T महत्त्वाचे आहे. ते नसल्यास Compose pseudo terminal allocate करते. त्यामुळे stream मधील newline bytes बदलतात आणि pg_restore नाकारणारी dump file तयार होते. -Fc हा custom format आहे. तो compression करतो आणि pg_restore ला निवडकपणे काम करू देतो.
docker run --rm -v chatwoot_storage_data:/data:ro -v "$PWD":/backup alpine \
tar czf /backup/storage-$(date +%F).tgz -C /data .Volume चे नाव तुमच्या project directory च्या नावासोबत _storage_data जोडून तयार होते. त्या command वर विश्वास ठेवण्यापूर्वी docker volume ls | grep storage_data ने त्याची खात्री करा. अस्तित्वात नसलेले volume नाव दिल्यास Docker अपयशी ठरत नाही; त्याऐवजी ते रिकामे volume तयार करते. त्यामुळे वैध पण रिकामे archive तयार होईल आणि कोणतीही error दिसणार नाही. त्यानंतर ls -lh storage-*.tgz ने त्याचा size तपासा.
आता दोन्ही files त्यांच्याद्वारे संरक्षित केलेल्या गोष्टीच्या त्याच disk वर आहेत. त्यामुळे तुमचे संरक्षण होत नाही. त्या server बाहेर पाठवा आणि encrypt करा, कारण database dump मध्ये प्रत्येक customer message plain text मध्ये असतो. restic सह encrypted off-site backups या लेखात scheduling आणि retention पद्धत स्पष्ट केली आहे.
Restore drill: गरज पडण्यापूर्वी चालवून पाहा
Live server वर restore करू नका. दुसऱ्या VPS वर restore करा. .env, compose files आणि दोन्ही archives तेथे copy करा आणि नंतर हे चालवा:
docker compose up -d postgres
docker compose exec -T postgres pg_restore -U postgres -d chatwoot --clean --if-exists < db-2026-08-10.dump
docker run --rm -v chatwoot_storage_data:/data -v "$PWD":/backup alpine \
sh -c 'rm -rf /data/* && tar xzf /backup/storage-2026-08-10.tgz -C /data'
docker compose up -d--clean --if-exists loading करण्यापूर्वी विद्यमान objects काढून टाकते. त्यामुळे ती फक्त अशा database वर वापरा जी गमावण्यास तुम्ही तयार आहात. त्यानंतर sign in करा आणि attachment असलेले conversation उघडा. Message list load झाली आणि file download झाली, तर बॅकअप वास्तविक आहे.
वेगळ्या SECRET_KEY_BASE सह केलेल्या restore मुळे प्रत्येक session cookie अवैध होते आणि सर्वजण sign out होतात. वेगळ्या ACTIVE_RECORD_ENCRYPTION_* keys सह केलेला restore अधिक गंभीर आहे: Chatwoot channel credentials असलेले columns decrypt करू शकत नाही आणि ActiveRecord::Encryption::Errors::Decryption दाखवते. म्हणूनच .env बॅकअपच्या यादीत आहे.
नवीन tag वर Chatwoot कसे upgrade करावे
Commands पेक्षा त्यांचा क्रम अधिक महत्त्वाचा आहे.
- तुमच्या tag पासून target tag पर्यंतच्या release notes वाचा आणि आवश्यक manual steps शोधा.
- नवीन database dump आणि storage archive तयार करा. दोन्ही फाइल्सचे आकार योग्य आहेत का ते तपासा.
docker-compose.yamlमधीलbaseservice वर image tag बदला.- नवीन image pull करा, stack थांबवा, migrations चालवा आणि पुन्हा सुरू करा.
docker compose pull
docker compose down
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
docker compose up -d
docker compose imagesMigration चालवण्यापूर्वी image pull करा, कारण migration नवीन image मधूनच चालली पाहिजे. जुन्या image मध्ये नवीन migration files नसतात. Migration चालवण्यापूर्वी stack थांबवा, कारण जुना code आणि नवीन schema यांच्यात विसंगती असते. त्यामुळे सुरू असलेली जुनी Rails process errors निर्माण करू शकते किंवा नवीन schema स्वीकारणार नाही अशा rows लिहू शकते. Stack थांबवल्याने migration साठी आवश्यक memory मोकळी होते. Swap वापरण्याचा upstream चा आग्रह याच कारणामुळे आहे.
docker compose images प्रत्येक container प्रत्यक्षात कोणता tag चालवत आहे ते दाखवते. त्यामुळे tag बदलून pull करायचे विसरलात का हे समजते.
एकाच वेळी अनेक versions ओलांडू नका. जुन्या install साठी upstream चा सल्ला असा आहे की intermediate tags मधून क्रमाने पुढे जा. Migrations base schema मध्ये समाविष्ट झाल्यानंतर काढून टाकल्या जातात. त्यामुळे अतिशय जुन्या database ची अशी स्थिती होऊ शकते की पुढे जाण्यासाठी migration path उरत नाही. एका वेळी एक minor version upgrade करा आणि प्रत्येक upgrade नंतर prepare step चालवा.
Migration चालण्यापूर्वी Rails सुरू झाल्यास ती सेवा देण्यास नकार देते आणि ActiveRecord::PendingMigrationError: Migrations are pending log करते. restart: always set असल्यास container वारंवार restart होते. त्यामुळे docker compose ps दर काही सेकंदांनी reset होणारा uptime दाखवते. Prepare step चालवल्यावर ही समस्या दूर होते.
Rollback करण्यासाठी जुना tag पुन्हा set करा आणि dump restore करा. विश्वासार्ह reverse migration path उपलब्ध नाही. म्हणूनच step 2 आवश्यक आहे.
तुम्हाला दिसणाऱ्या त्रुटीस्थिती आणि संदेश
Traefik कडून 502 Bad Gateway. Router जुळला, पण backend ने उत्तर दिले नाही. docker compose ps मध्ये rails हे Up म्हणून दाखवले आहे का ते तपासा. त्यानंतर docker network inspect proxy चालवा आणि container यादीत rails container दिसत आहे का ते पडताळा. जोडलेला नसलेला container Traefik ला दिसत नाही. त्यामुळे विनंती router शी जुळते, पण पुढे कुठेही जात नाही.
Dashboard लोड होतो, पण नवीन संदेश पाहण्यासाठी refresh करावे लागते. /cable शी असलेले websocket connection पोहोचत नाही किंवा FRONTEND_URL हे browser bar मधील पत्त्याशी जुळत नाही. पत्ते जुळत नसल्यास पृष्ठ वेगळ्या origin कडे websocket उघडण्याचा प्रयत्न करते. Browser ते अवरोधित करतो.
FATAL: password authentication failed for user "postgres". .env मधील password आणि Postgres data volume मध्ये आधीपासून साठवलेला password वेगळा आहे. चालू container मध्ये ALTER USER वापरून ते दुरुस्त करा. .env पुन्हा संपादित केल्याने आधीच initialised database बदलत नाही.
NOAUTH Authentication required. Redis --requirepass सह चालू आहे, पण application password शिवाय जोडले गेले. त्यामुळे REDIS_PASSWORD हे .env मध्ये नाही किंवा ते लागू झालेले नाही. docker compose exec redis redis-cli -a "$REDIS_PASSWORD" ping वापरून थेट चाचणी करा. त्याने PONG असे उत्तर द्यायला हवे.
Code 137 सह बंद होणारे containers. हा SIGKILL आहे. लहान server वर याचा अर्थ kernel चा out of memory killer कार्यरत झाला आहे. Swap जोडा, प्रत्येक service साठी memory limits निश्चित करा किंवा मोठ्या plan वर स्थलांतर करा.
FAQ
स्वयं-host केलेल्या Chatwoot VPS साठी किती RAM आवश्यक आहे?
August 2026 नुसार, upstream किमान 4 GB RAM आणि 4 CPU cores मागतो. ही संरचना दररोज 10,000 conversations पर्यंतच्या वापरासाठी आहे. 20,000 पर्यंत conversations साठी 8 GB RAM आणि 8 cores आवश्यक आहेत. किमान 1 GB swap जोडा. Upgrade वेळी migrations लागू करण्यासाठी दुसरी Rails process सुरू होते. याच वेळी लहान VPS मध्ये memory कमी पडते. 2 GB VPS दोन-तीन agents साठी सुरू होऊन काम करते. परंतु load असताना फक्त Sidekiq 1 GB पेक्षा जास्त memory वापरू शकतो. त्यामुळे व्यस्त काळात आणि upgrades दरम्यान containers exit code 137 सह बंद होण्याची अपेक्षा ठेवा.
Chatwoot चे password reset emails कधीच का पोहोचत नाहीत?
कारण SMTP settings configured नसतात. त्यामुळे ActionMailer localhost कडे port 25 वर email पाठवण्याचा प्रयत्न करते. Container मध्ये mail server नसतो. Browser यशस्वी संदेश दाखवत असतानाही job Sidekiq मध्ये Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25 सह अपयशी ठरते. .env मध्ये SMTP_ADDRESS, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD आणि MAILER_SENDER_EMAIL सेट करा. त्यानंतर rails आणि sidekiq services restart करा. Reset सुरू करताना docker compose logs -f sidekiq चे monitoring करा.
Chatwoot restore करण्यासाठी कोणत्या गोष्टींचा backup घ्यावा?
Postgres database, storage_data Docker volume, .env file आणि compose files यांचा backup घ्या. फक्त database पुरेसा नाही. Uploaded files volume मध्ये असतात, तर Postgres मध्ये त्यांचे references असतात. त्यामुळे फक्त database restore केल्यास attachments तुटलेल्या conversations मिळतात. .env महत्त्वाचे आहे, कारण वेगळे SECRET_KEY_BASE वापरल्यास प्रत्येक user चे session logout होते. वेगळ्या ACTIVE_RECORD_ENCRYPTION_* keys मुळे encrypted columns वाचता येत नाहीत.
Database खराब न करता Chatwoot चे upgrade कसे करावे?
Backup घ्या आणि compose file मधील image tag बदला. त्यानंतर docker compose pull, docker compose down, docker compose run --rm rails bundle exec rails db:chatwoot_prepare आणि docker compose up -d चालवा. प्रथम image pull करा, कारण migrations नवीन image मधून चालवणे आवश्यक आहे. Stack आधी stop करा, कारण नवीन schema वर जुना code चालवल्यास errors येतात. जुन्या install मध्ये एका वेळी एक minor version upgrade करा. Migrations base schema मध्ये समाविष्ट झाल्यानंतर काढून टाकल्या जातात.
pgvector ऐवजी standard postgres image वापरता येतो का?
नाही. Chatwoot च्या schema मध्ये vector extension सक्षम केलेले आहे. त्यामुळे stock postgres image मध्ये db:chatwoot_prepare चालवताना ERROR: extension "vector" is not available सह failure येते. या image मध्ये extension ची control file उपलब्ध नसते. Upstream compose file मधील pgvector/pgvector:pg16 ठेवा. किंवा तुमच्या Postgres major version साठी pgvector समाविष्ट असलेली दुसरी image वापरा.