Jinsi ya kuweka Chatwoot kwenye VPS kwa Docker
Jifunze kusakinisha Chatwoot kwa Docker Compose na Traefik. Mwongozo huu unashughulikia usanidi sahihi wa SMTP, nakala za akiba za Postgres, na mbinu salama za kuboresha mfumo.
Unachojenga
Ili kujiendeshea Chatwoot kwenye VPS, utaendesha kontena nne: mchakato wa wavuti wa Rails, mfanyakazi wa usuli wa Sidekiq, PostgreSQL yenye kiendelezi cha pgvector, na Redis. Chatwoot ni mfumo huria wa huduma kwa wateja, hivyo unapata kikasha cha timu kilichoshirikiwa na wijeti ya gumzo ya tovuti kwenye seva unayoimiliki. Ufungaji huchukua takriban dakika ishirini. Kila kitu kinachofuata, kama vile utumaji barua pepe, nakala za akiba (backups), maboresho, na ukubwa wa mfumo, ndicho huamua kama mfumo utaendelea kufanya kazi baada ya mwaka mmoja.
Kila kontena lina kazi moja. Rails huhudumia dashibodi ya wakala na API (application programming interface) ya wijeti. Sidekiq hufanya kazi nzito: kutuma barua pepe, kufuatilia chaneli zilizounganishwa, kuendesha sheria za otomatiki, na kuandaa ripoti. Postgres huhifadhi mazungumzo, anwani, akaunti za mawakala, na kila mpangilio unaobadilisha kwenye dashibodi. Redis huhifadhi foleni za Sidekiq na chaneli ya ActionCable ya pub/sub inayotuma ujumbe mpya kwenye dashibodi iliyo wazi bila kuhitaji kurudisha ukurasa (page reload). Redis hapa si akiba ya muda mfupi (cache), kwa sababu kuipoteza kunamaanisha kupoteza kazi zilizopo kwenye foleni.
Picha (image) ya Postgres katika faili ya compose ya upstream ni pgvector/pgvector:pg16 badala ya picha ya kawaida ya postgres, kwa sababu schema ya Chatwoot huwezesha kiendelezi cha vector kwa ajili ya vipengele vyake vya AI. Ukibadilisha na Postgres ya kawaida, hifadhidata itashindwa kufanya kazi mara ya kwanza kwa sababu ya ERROR: extension "vector" is not available, kwani faili ya udhibiti wa kiendelezi hicho haipo kwenye picha hiyo. Tumia picha inayotolewa na upstream.
Mwongozo huu unachukulia kuwa Docker na reverse proxy tayari vinafanya kazi kwenye seva yako. Ikiwa sivyo, anza na Docker Compose kwenye VPS kisha urudi hapa.
Chatwoot inayojiendesha yenyewe inahitaji VPS ya ukubwa gani?
Kufikia Agosti 2026, ukurasa wa mahitaji ya msingi unapendekeza angalau 4 GB ya RAM na 4 CPU cores, na inakadiriwa kuhimili hadi mazungumzo 10,000 kwa siku. Inapendekeza 8 GB na 8 cores kwa hadi mazungumzo 20,000 kwa siku. Pia inahitaji angalau 1 GB ya swap, na sababu inatajwa wazi: ili mashine isikwame kwa kukosa kumbukumbu wakati wa upgrade. Panga nafasi ya 5 GB hadi 10 GB ya disk kwa ajili ya Postgres kabla ya kuhesabu faili zilizopakiwa.
Sasa, ukweli mchungu. VPS ya 2 GB itawasha Chatwoot, na inaonekana kufanya kazi vizuri ikiwa na mawakala wawili na inbox tulivu. Inafeli katika maeneo mawili. Eneo la kwanza ni Sidekiq, ambayo kulingana na watengenezaji hutumia zaidi ya 1 GB kwenye seva yenye shughuli nyingi, hivyo mlipuko wa barua pepe au kazi ya ripoti husukuma mashine kupita uwezo wake wa kumbukumbu kabla ya Rails, Postgres na Redis kuchukua sehemu yao. Eneo la pili ni wakati wa upgrade, kwa sababu db:chatwoot_prepare huwasha mchakato mpya wa Rails ili kutekeleza migrations, na kuwasha Rails kwenye image hii hutumia mamia ya megabytes kabla ya kufanya kazi yoyote ya maana.
Hupati onyo la upole kwanza. Mfumo wa kernel wa out of memory killer hutuma SIGKILL kwa mchakato mkubwa zaidi, Docker huona container inakufa, na restart: always huianzisha tena. docker compose ps kisha huonyesha container inayorudi mara kwa mara kwenye Exited (137), ambapo 137 inamaanisha iliuliwa na signal 9. Thibitisha hili kwa sudo dmesg -T | grep -i "killed process", ambayo hutaja mchakato uliochaguliwa na kernel.
Ikiwa 4 GB iko nje ya bajeti yako, tumia mashine ya 2 GB yenye 2 GB ya swap na ukubali kuwa muda wa majibu utapungua chini ya mzigo badala ya huduma kufa kabisa. Kuweka kikomo cha kumbukumbu kwa kila huduma ni jambo la busara kwa vyovyote vile, ili worker asishushe database pamoja naye. Tazama memory limits in Docker Compose.
Upakiaji wa faili ni sehemu inayokua bila kikomo ulichoweka. Kila screenshot inayotumwa na mteja hutua kwenye storage volume na kubaki hapo, kwa hivyo fuatilia docker system df -v badala ya kudhani kuwa database ndiyo iliyojaza disk.
Pata faili la compose na uweke tag ya toleo
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 .envFaili ulilopakua hivi punde lina image: chatwoot/chatwoot:latest. Badilisha hilo kabla ya kufanya jambo lingine lolote.
services:
base: &base
image: chatwoot/chatwoot:v4.16.2
env_file: .env
volumes:
- storage_data:/app/storagelatest inamaanisha kuwa docker compose pull inayofuata inakupa chochote kilichochapishwa asubuhi hiyo, ambacho kinaweza kuwa toleo kuu lenye mabadiliko (migrations) ambayo hujawahi kuyasoma. Mabadiliko ya Chatwoot hayawezi kutenduliwa kwa vitendo, kwa hivyo kuruka toleo kwa bahati mbaya kunamaanisha kurejesha data kutoka kwenye backup, siyo kutendua. Weka tag maalum na uibadilishe kwa makusudi. v4.16.2 ndilo lilikuwa toleo la sasa kufikia Agosti 2026; angalia ukurasa wa matoleo kwa ajili ya tag unayopaswa kuweka leo.
Huduma ya base ni YAML anchor ambayo rails na sidekiq zote zinaiunganisha, kwa hivyo kubadilisha tag katika sehemu moja kunabadilisha zote mbili. Ukiwa bado ndani ya faili hilo, futa mstari wa version: '3' ulio juu. Compose ya kisasa inaupuuza na kuchapisha the attribute 'version' is obsolete, it will be ignored kwenye kila amri.
Jaza faili la .env
Tengeneza siri (secret) kwanza. Upstream inahitaji thamani ya alphanumeric, kwa sababu herufi maalum huharibika thamani hiyo inapopita kwenye shell au YAML parser.
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 63 ; echo ''Kisha weka funguo hizi katika .env.
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 na redis://redis:6379 ni majina ya huduma za Compose, ambayo hutatuliwa kwenye mtandao chaguo-msingi wa mradi. FRONTEND_URL si mapambo. Chatwoot hujenga URL ya script ya widget na kila kiungo ndani ya barua pepe inayotoka humo, kwa hivyo thamani isiyo sahihi itakupa viungo vya kubadilisha nenosiri vinavyoelekeza kwenye host isiyojibu.
Sasa kuna mtego katika faili la upstream. Huduma ya postgres haisomi .env. Inabeba block yake ya environment ikiwa na POSTGRES_PASSWORD= tupu, kwa hivyo kuweka nenosiri katika .env pekee kutaiacha database bila nenosiri na programu ikiwa nalo. Elekeza huduma hiyo kwenye variable ileile:
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 inasoma .env kutoka kwenye saraka ya mradi kwa ajili ya uingizwaji wa ${...}, kwa hivyo pande zote mbili sasa zinapata string ileile. Ukikosea hapa, Rails itasimama na PG::ConnectionBad: FATAL: password authentication failed for user "postgres".
Tabia moja huwashangaza karibu kila mtu: image ya Postgres hutumia POSTGRES_PASSWORD tu wakati inapoanzisha saraka tupu ya data. Kubadilisha thamani hiyo baadaye hakuna athari, kwa sababu initdb haiwahi kuendeshwa mara ya pili. Ikiwa tayari umeanza stack mara moja, ibadilishe ndani ya database yenyewe.
docker compose exec postgres psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'the-new-password';"ENABLE_ACCOUNT_SIGNUP=true ni ya muda. Inafungua fomu ya usajili wa umma ili uweze kuunda akaunti ya kwanza. Iweke kuwa false na uendeshe docker compose up -d tena mara tu akaunti yako itakapokuwepo, au mtu yeyote anayepata URL hiyo anaweza kujiandikisha kwenye dawati lako la usaidizi. Kuanzia hapo, mawakala hufika kwa mwaliko na nywila zao hukaa katika programu hii moja tu, jambo ambalo ni sawa hadi utakapokuwa unaendesha huduma nusu dazeni na kuchoka na orodha tofauti ya akaunti katika kila moja, ambapo identity provider inayojiendesha kama Authentik ndiyo sehemu inayozichukua nafasi hizo.
.env sasa inashikilia kila siri ambayo stack hii inayo, katika maandishi wazi (plain text), kwa hivyo iweke katika mode 600 na uizuie isingie kwenye git. Jinsi Compose inavyosoma faili za env, na mahali ambapo siri huvuja inashughulikia hatari hizi, ikiwa ni pamoja na tofauti kati ya env_file na environment.
Weka Chatwoot nyuma ya Traefik yako iliyopo
Usijenge reverse proxy ya pili kwa ajili ya programu moja. Ikiwa Traefik tayari inashughulikia TLS (transport layer security) kwa container nyingine kwenye seva hii, Chatwoot inaunganishwa kwa kutumia block ya labels. Ikiwa huna usanidi huo bado, uweke mara moja kwa kufuata Traefik mbele ya programu kadhaa za Docker Compose, kisha rudi hapa.
Weka docker-compose.yaml ya upstream ikiwa karibu na hali yake ya asili ili uweze kuilinganisha na nakala mpya baadaye, na uweke mabadiliko yako kwenye faili ya override. Compose huunganisha docker-compose.override.yaml kiotomatiki, na kugawanya Compose katika faili nyingi kunaelezea kanuni za uunganishaji huo.
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: trueTumia majina yako ya entrypoint na certresolver. Container lazima iwe kwenye Docker network sawa na Traefik, jambo ambalo hufanywa na ingizo la proxy, na lazima ibaki kwenye default pia vinginevyo itapoteza muunganisho na Postgres na Redis. Hiyo ni mstari wa pili ambao watu husahau.
Acha block ya ports: kama ilivyo. Upstream huifunga kwenye 127.0.0.1:3000, ambayo ni loopback pekee, kwa hivyo haiwezi kufikiwa kutoka kwenye Internet na inabaki kuwa muhimu kwa majaribio kutoka ndani ya seva kwa kutumia curl -I http://127.0.0.1:3000.
Dashboard ya wakala huweka websocket wazi kwenye /cable kwa ajili ya utoaji wa ujumbe wa moja kwa moja. Traefik husambaza HTTP upgrade bila usanidi wa ziada, kwa hivyo hakuna cha kuongeza. Ikiwa baadaye utaweka CDN au proxy nyingine mbele ya Traefik, ruhusu websockets huko, kwa sababu dalili yake ni dashboard inayopakia kawaida wakati ujumbe mpya huonekana tu baada ya kuburudisha ukurasa (manual refresh).
Anzisha database na uwashe stack
Anza kwa kuwasha huduma za data na uiruhusu Postgres imalize mchakato wake wa kwanza.
docker compose up -d postgres redis
docker compose logs postgres | tail -n 5Subiri database system is ready to accept connections. Kisha tengeneza schema.
docker compose run --rm rails bundle exec rails db:chatwoot_prepareHii hutengeneza database ikiwa haipo, kisha hupakia schema na data za awali (seed data). Inachapisha mistari ya migration na kutoka kwa usalama. Ikiwa inakaa ikichapisha postgres:5432 - no response, entrypoint inasubiri database ambayo bado haikubali miunganisho, jambo ambalo kwenye mwanzo wa kwanza kwa kawaida humaanisha initdb bado inafanya kazi. Subiri, soma logi za Postgres, kisha iendeshe tena. Ikiwa inasimama kwenye extension ya vector, umeweka image ya kawaida ya Postgres badala ya pgvector.
docker compose up -d
docker compose ps
docker compose logs --tail 30 railsContainers zote nne zinapaswa kusoma Up, na logi ya rails inapaswa kuishia na mstari wa Puma unaosikiliza kwenye http://0.0.0.0:3000. Kisha kagua njia ya umma (public path):
curl -sI https://support.example.com | head -n 1HTTP/2 200 inamaanisha mnyororo mzima unafanya kazi. 404 kutoka kwa Traefik inamaanisha kuwa sheria ya router haikulingana, kwa kawaida ni kosa la kuandika hostname. 502 inamaanisha Traefik ililinganisha router lakini haikuweza kufikia container, jambo ambalo karibu kila mara ni kukosekana kwa mtandao wa proxy au loadbalancer.server.port ambayo si 3000.
Fungua URL, tengeneza akaunti yako kwenye /app/auth/signup, kisha weka ENABLE_ACCOUNT_SIGNUP=false na uendeshe docker compose up -d ili kufunga fomu hiyo.
Kwa nini urejeshaji wa nenosiri na mazungumzo ya barua pepe hushindwa bila SMTP
Chatwoot bila mipangilio ya SMTP (simple mail transfer protocol) ni dawati la usaidizi lisiloweza kutuma barua pepe, na hilo huvuruga mambo mengi zaidi ya arifa tu. Urejeshaji wa nenosiri huacha kufanya kazi, hivyo msimamizi anayefungiwa nje hubaki nje. Mialiko ya mawakala huacha kufanya kazi, kwa sababu mwaliko ni barua pepe. Kujibu mteja katika mazungumzo ya barua pepe huacha kufanya kazi, hivyo mazungumzo huenda upande mmoja tu. Hii ni hatua ambayo watu huruka na kuigundua wakati wa wiki yao mbaya zaidi.
Utaratibu huu ni rahisi. Bila mipangilio ya SMTP, ActionMailer hubaki na chaguo-msingi la kutuma kwenye localhost kupitia port 25. Hakuna seva ya barua pepe ndani ya container ya Rails, kwa hivyo kazi ya utumaji huleta Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25. Barua pepe hutoka kupitia background job, kwa hivyo mstari huo huonekana kwenye log ya Sidekiq na si kwenye log ya Rails. Wakati huo huo, mtu anayebofya "forgot password" huona uthibitisho wa kufurahisha na hapokei chochote.
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=trueTumia port 587 yenye STARTTLS, ambayo hufungua muunganisho kwa plain text na kuupandisha hadhi kuwa encrypted kabla ya authentication. Watoa huduma wengi wa VPS huzuia outbound port 25 ili kupunguza spam, kwa hivyo relay kwenye 587 kwa kawaida ndiyo kitu pekee kitakachounganishwa. SMTP_DOMAIN ni domain ambayo seva yako hutangaza wakati wa mazungumzo ya SMTP, na baadhi ya relay hukataa kama kuna kutolingana.
Tekeleza mipangilio na ufuatilie worker:
docker compose up -d rails sidekiq
docker compose logs -f sidekiqAnzisha urejeshaji wa nenosiri kutoka ukurasa wa kuingia. Utumaji unaofanya kazi huonyesha kazi ya mailer ikimalizika kawaida kwenye log ya Sidekiq. Kushindwa huonyesha exception class, kisha Sidekiq hujaribu tena kwa backoff inayoongezeka, ndiyo sababu relay iliyoharibika hutoa kosa lilelile kila baada ya dakika chache kwa saa kadhaa.
Kukataa mara mbili ni kawaida, na hakuna hata moja kati ya hizo ni hitilafu ya Chatwoot. 535 Authentication failed inamaanisha jina la mtumiaji au nenosiri si sahihi kwa relay hiyo, na watoa huduma wengi huhitaji application password badala ya nenosiri la akaunti. 550 Sender address rejected inamaanisha MAILER_SENDER_EMAIL ni anwani ambayo relay haitaituma kama mtumaji, kwa hivyo lazima iwe mailbox au domain uliyothibitisha nao.
Kupokea barua pepe kwenye mazungumzo ni kazi tofauti. Inahitaji MAILER_INBOUND_EMAIL_DOMAIN na RAILS_INBOUND_EMAIL_SERVICE, pamoja na seva ya barua pepe inayokabidhi ujumbe unaoingia kwa Chatwoot. Kukodisha relay ndiyo njia ya haraka. Ikiwa ungependa kumiliki njia nzima ya barua pepe, kuendesha seva yako ya barua pepe kwa kutumia Mailcow inaelezea kile ambacho ahadi hiyo inahusisha kihalisi.
Nini cha kuhifadhi (backup), na jinsi ya kuthibitisha kuwa urejeshaji (restore) unafanya kazi
Backup ya Chatwoot ina sehemu nne, na kuruka sehemu yoyote kati ya hizo kunafanya urejeshaji kuwa ujenzi upya.
- Database ya Postgres, ambayo huhifadhi mazungumzo, anwani, akaunti za mawakala na kila mpangilio.
- Volume ya
storage_data, kwa sababuACTIVE_STORAGE_SERVICE=localhuandika faili zilizopakiwa kwenye diski na kuhifadhi tu kumbukumbu ya marejeleo (reference row) ndani ya Postgres. - Faili ya
.env, kwa sababu inashikiliaSECRET_KEY_BASEna funguo zaACTIVE_RECORD_ENCRYPTION_*. - Faili za compose, kwa sababu zinarekodi tag kamili ya image inayolingana na schema ya database yako.
Ukirejesha database pekee, kila mazungumzo yatarejea yakiwa na viambatisho vilivyoharibika, kwa sababu safu (rows) hizo huelekeza kwenye faili ambazo hazipo tena kwenye diski.
cd ~/chatwoot
docker compose exec -T postgres pg_dump -U postgres -Fc chatwoot > db-$(date +%F).dump-T ni muhimu. Bila hiyo, Compose hutenga pseudo terminal, ambayo hubadilisha byte za mstari mpya (newline) kwenye mtiririko huo, hivyo unapata faili ya dump ambayo pg_restore huikataa. -Fc ni umbizo maalum, ambalo hubana data na kuruhusu pg_restore kufanya kazi kwa kuchagua.
docker run --rm -v chatwoot_storage_data:/data:ro -v "$PWD":/backup alpine \
tar czf /backup/storage-$(date +%F).tgz -C /data .Jina la volume ni jina la saraka ya mradi wako pamoja na _storage_data. Lithibitishe kwa docker volume ls | grep storage_data kabla ya kuamini amri hiyo, kwa sababu Docker hutengeneza volume tupu badala ya kutoa hitilafu unapotoa jina la volume isiyokuwepo. Utapata archive halali, tupu na bila hitilafu yoyote. Angalia ukubwa wake baadaye kwa ls -lh storage-*.tgz.
Faili zote mbili sasa ziko kwenye diski moja na kitu zinachokilinda, jambo ambalo halikupi ulinzi wowote. Zihamishe nje ya seva hiyo na uzifiche (encrypt), kwa sababu dump ya database ina kila ujumbe wa mteja katika maandishi ya kawaida (plain text). Backup zilizofichwa nje ya seva kwa kutumia restic inashughulikia upande wa upangaji ratiba na uhifadhi wa muda mrefu.
Zoezi la urejeshaji, lifanye kabla ya kulihitaji
Rejesha kwenye VPS ya pili, siyo ile inayotumika. Nakili .env, faili za compose na archives zote mbili, kisha endesha:
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 hufuta vitu vilivyopo kabla ya kupakia, kwa hivyo iweke tu kwenye database ambayo uko tayari kuipoteza. Kisha ingia na ufungue mazungumzo yenye kiambatisho. Ikiwa orodha ya ujumbe inapakia na faili inapakuliwa, basi backup hiyo ni halisi.
Urejeshaji wenye SECRET_KEY_BASE tofauti hubatilisha kila session cookie, kwa hivyo kila mtu atatolewa nje ya mfumo. Urejeshaji wenye funguo tofauti za ACTIVE_RECORD_ENCRYPTION_* ni mbaya zaidi: Chatwoot haiwezi kufungua (decrypt) safu zinazoshikilia vitambulisho vya channel na huibua ActiveRecord::Encryption::Errors::Decryption. Hiyo ndiyo sababu .env iko kwenye orodha ya backup.
Jinsi ya kupandisha toleo la Chatwoot kwenda tag mpya
Mpangilio wa hatua ni muhimu zaidi kuliko amri zenyewe.
- Soma maelezo ya toleo (release notes) kati ya tag yako ya sasa na ile unayolenga, ili kuona hatua zozote za mikono zinazohitajika.
- Chukua dump mpya ya database na nakala ya hifadhi (storage archive), kisha hakikisha ukubwa wa faili zote mbili unaonekana kuwa sahihi.
- Badilisha image tag kwenye huduma ya
basendani yadocker-compose.yaml. - Vuta (pull) image mpya, simamisha stack, endesha migrations, kisha uwashe tena.
docker compose pull
docker compose down
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
docker compose up -d
docker compose imagesVuta image kabla ya kufanya migration, kwa sababu migration lazima iendeshwe kutoka kwenye image mpya: image ya zamani haina faili mpya za migration. Simamisha stack kabla ya kufanya migration, kwa sababu code ya zamani na schema mpya haziendani, hivyo mchakato wa Rails wa zamani unaoendelea unaweza kutoa makosa au kuandika safu (rows) ambazo schema mpya haitakubali. Kusimamisha huduma pia kunafungua kumbukumbu (memory) inayohitajika na migration, jambo ambalo ndilo sababu kuu inayofanya upstream kuomba swap.
docker compose images huonyesha tag ambayo kila container inaendesha kwa sasa, jambo linalosaidia kubaini hali ambapo ulibadilisha tag lakini ukasahau kufanya pull.
Usiruke matoleo mengi kwa wakati mmoja. Ushauri wa upstream kwa usakinishaji wa zamani ni kupitia tag za katikati, kwa sababu migrations huondolewa pindi zinapojumuishwa kwenye base schema, hivyo database ya zamani sana inaweza kufikia hali isiyo na njia ya kusonga mbele. Sogeza toleo moja dogo (minor version) kwa wakati mmoja na uendeshe hatua ya maandalizi (prepare step) baada ya kila moja.
Ikiwa Rails itaanza kabla ya migration kuendeshwa, itakataa kuhudumia maombi na kuandika ActiveRecord::PendingMigrationError: Migrations are pending kwenye logi. Ikiwa restart: always imewekwa, container itajianzisha upya mara kwa mara, hivyo docker compose ps itaonyesha uptime inayojirudia kila baada ya sekunde chache. Endesha hatua ya maandalizi na hali hiyo itatoweka.
Kurejesha toleo la awali (rolling back) kunamaanisha kurudisha tag ya zamani na kurejesha dump uliyohifadhi. Hakuna njia ya kurejesha migration (reverse migration) unayoweza kuitegemea, ndiyo maana hatua ya 2 ni muhimu.
Njia za kufeli na ujumbe utakaouona
502 Bad Gateway kutoka kwa Traefik. Router imepata njia inayofaa lakini backend haijajibu. Angalia docker compose ps inaonyesha rails kama Up, kisha endesha docker network inspect proxy na uhakikishe container ya rails inaonekana kwenye orodha ya containers. Container ambayo haijaunganishwa haionekani kwa Traefik, kwa hivyo ombi linafanana na router lakini halina mahali pa kwenda.
Dashboard inapakia lakini ujumbe mpya unahitaji refresh. Websocket ya /cable haipiti, au FRONTEND_URL hailingani na anwani iliyo kwenye bar ya kivinjari. Kutolingana huku kunamaanisha ukurasa unajaribu kufungua websocket kwenye asili (origin) tofauti, jambo ambalo kivinjari huzuia.
FATAL: password authentication failed for user "postgres". Nenosiri lililo kwenye .env na lile lililowekwa ndani ya data volume ya Postgres ni tofauti. Rekebisha hili kwa ALTER USER ndani ya container inayofanya kazi, kwa sababu kuhariri .env tena hakutabadilisha database iliyokwishaanza kufanya kazi.
NOAUTH Authentication required. Redis inafanya kazi na --requirepass lakini programu imeunganishwa bila nenosiri, kwa hivyo REDIS_PASSWORD haipo kwenye .env au haikuchukuliwa. Ijaribu moja kwa moja na docker compose exec redis redis-cli -a "$REDIS_PASSWORD" ping, ambayo inapaswa kujibu PONG.
Containers zinazotoka na code 137. Hiyo ni SIGKILL, na kwenye seva ndogo, hii ni ishara ya kernel ya out of memory killer. Ongeza swap, weka mipaka ya kumbukumbu kwa kila huduma, au hamia kwenye mpango mkubwa zaidi.
FAQ
Je, Chatwoot inayojiendesha kwenye VPS inahitaji RAM kiasi gani?
Kufikia Agosti 2026, watengenezaji wanapendekeza angalau 4 GB ya RAM na 4 CPU cores kwa ajili ya mazungumzo 10,000 kwa siku, na 8 GB pamoja na 8 cores kwa ajili ya mazungumzo 20,000. Ongeza angalau 1 GB ya swap, kwa sababu mchakato wa upgrade huendesha Rails process ya pili ili kutekeleza migrations, na hapo ndipo seva ndogo hukosa kumbukumbu. VPS ya 2 GB inaweza kuwaka na kufanya kazi kwa mawakala wachache, lakini Sidekiq pekee inaweza kutumia zaidi ya 1 GB ikiwa na mzigo, hivyo tarajia containers kufungwa na exit code 137 wakati wa shughuli nyingi au wakati wa upgrades.
Kwa nini barua pepe za kubadilisha nenosiri la Chatwoot hazifiki?
Kwa sababu hakuna mipangilio ya SMTP iliyowekwa, hivyo ActionMailer hujaribu kutuma kupitia localhost kwenye port 25 na hakuna seva ya barua pepe ndani ya container. Kazi hiyo hushindwa katika Sidekiq na Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25 huku kivinjari kikionyesha ujumbe wa mafanikio. Weka SMTP_ADDRESS, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD na MAILER_SENDER_EMAIL katika .env, anzisha upya huduma za rails na sidekiq, kisha fuatilia docker compose logs -f sidekiq wakati unapoanzisha ombi la kubadilisha nenosiri.
Ninahitaji kuhifadhi nini ili kurejesha Chatwoot?
Database ya Postgres, Docker volume ya storage_data, faili la .env na faili za compose. Database pekee haitoshi, kwa sababu faili zilizopakiwa hukaa kwenye volume wakati Postgres inashikilia marejeleo yake tu, hivyo kurejesha database pekee kutakupa mazungumzo yenye viambatisho visivyofunguka. .env ni muhimu kwa sababu SECRET_KEY_BASE tofauti huwatoa watumiaji wote kwenye akaunti, na funguo tofauti za ACTIVE_RECORD_ENCRYPTION_* hufanya safu zilizosimbwa (encrypted columns) zisiweze kusomeka.
Ninawezaje kufanya upgrade ya Chatwoot bila kuharibu database?
Chukua backup, badilisha image tag katika faili lako la compose, kisha endesha docker compose pull, docker compose down, docker compose run --rm rails bundle exec rails db:chatwoot_prepare na docker compose up -d. Fanya pull kwanza kwa sababu migrations lazima ziendeshwe kutoka kwenye image mpya, na simamisha stack kwanza kwa sababu code ya zamani ikifanya kazi na schema mpya husababisha makosa. Kwenye usakinishaji wa zamani, hamia toleo moja dogo (minor version) kwa wakati mmoja, kwa sababu migrations huondolewa mara tu zinapojumuishwa kwenye base schema.
Je, ninaweza kutumia image ya kawaida ya postgres badala ya pgvector?
Hapana. Schema ya Chatwoot huwezesha extension ya vector, hivyo image ya kawaida ya postgres itashindwa wakati wa db:chatwoot_prepare na ERROR: extension "vector" is not available, kwa sababu faili la kudhibiti extension hiyo halipo kwenye image hiyo. Dumisha pgvector/pgvector:pg16 kutoka kwenye faili la compose la upstream, au tumia image nyingine inayokuja na pgvector kwa ajili ya toleo lako kuu la Postgres.