This upgrades Chatwoot to Rails 7.2.3.1 while retaining the current Rails 7.0 framework defaults, so the runtime upgrade can be deployed and observed independently from default-behavior changes. ## What changed - Upgrade Rails and the compatible dependency set to Rails 7.2.3.1. - Keep `config.load_defaults 7.0` for a staged, lower-risk rollout. - Replace the unmaintained Azure Active Storage fork with the maintained `azure-blob` adapter while preserving the `microsoft` service name. - Pin Sidekiq 7.3.10 with `connection_pool` 2.x after validating scheduled-job execution against Redis. - Update Rails 7.2 compatibility surfaces in Active Record, strong parameters, migrations, storage, and tests. - Add read-only production preflight checks, an opt-in Active Storage smoke script, a deployment runbook, and the full Rails 7.2/8.0/8.1 assessment. ## How to test 1. Sign in and verify the dashboard and conversation UI load normally. 2. Open the agent-management modal and confirm agent data is rendered. 3. Create an API inbox and wait for the asynchronous deletion flow to complete. 4. Open Super Admin pages, including instance status and account-user management. 5. Upload and download an attachment using the configured Active Storage service. 6. Confirm recurring Sidekiq Cron jobs register and execute after startup. ## Rollout Follow `docs/rails_upgrades/7_2.md` for pre-deploy checks, deployment order, smoke tests, monitoring, and rollback. Run `bundle exec rails runner script/rails_upgrade/preflight.rb` against a production-equivalent environment before rollout. ## Tracking - [CW-5863 — Upgrade Rails to 8+](https://linear.app/chatwoot/issue/CW-5863/upgrade-rails-to-8) - [Rails 7.2 to 8.1 upgrade and production rollout plan](https://linear.app/chatwoot/document/chatwoot-rails-72-to-81-upgrade-and-production-rollout-plan-44e9f4964cb2) --------- Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> Co-authored-by: Sony Mathew <2040199+sony-mathew@users.noreply.github.com> Co-authored-by: Sony Mathew <sony@chatwoot.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
5.9 KiB
Production migration guide: Rails 7.2.3.1
This checkpoint upgrades Chatwoot from Rails 7.1.5.2 to Rails 7.2.3.1. It deliberately keeps config.load_defaults 7.0, so it does not change the Rails 7.1 or 7.2 serialization, encryption, callback, job-enqueue, Active Storage WebP, or PostgreSQL date-decoding defaults.
There is no database schema migration in this checkpoint.
Application-level changes
- The
User#conversationsassociation alias uses a Ruby method alias because Rails 7.2 reservesalias_attributefor database attributes. - Migration status uses
ActiveRecord::MigrationContext, rather than the removed connection-level helper. - Strong parameters passed to Linear and LeadSquared are normalized to string-keyed hashes at their service boundaries.
- Integration hook type assignment runs only at creation, preserving Rails 7.2 readonly-attribute behavior.
- Existing encrypted MFA backup codes remain YAML-serialized. This release does not rewrite their persisted format.
devise-secure_passwordmoves from the Chatwoot fork to upstream 2.2.1, the latest release that supports both Devise 4 and Rails 8. Later upstream releases require Devise 5.- Jbuilder, Debug, TestProf, and the Administrate belongs-to search field move to Rails-7.2-compatible versions.
- Sidekiq moves to 7.3.10, which constrains
connection_poolbelow 3. Sidekiq 7.3.1 starts workers withconnection_pool3 but crashes both scheduler threads, so this pairing is a deployment requirement rather than an optional maintenance update. - Rack Mini Profiler moves to 4.0.1 so development and staging profiler assets work with Rack 3.2.
- Azure Active Storage moves from the abandoned
azure-storage-blobclient to theazure-blobadapter. The configured service name remainsmicrosoft, so existingactive_storage_blobs.service_namevalues and Azure object keys do not change.
Before deployment
-
Take the normal PostgreSQL and Redis backups and verify the database backup can be restored.
-
Use the same Ruby 3.4.4 and Node 24 versions as the release build.
-
Install dependencies and build assets.
-
Run the read-only preflight against a production replica or during the maintenance window:
EXPECTED_RAILS_VERSION=7.2.3.1 \ EXPECTED_CONFIG_DEFAULTS=7.0 \ EXPECTED_SIDEKIQ_VERSION=7.3.10 \ EXPECTED_AZURE_SERVICE=AzureBlob \ bundle exec rails runner script/rails_upgrade/preflight.rb -
If the installation has a large number of encrypted rows, a bounded rehearsal can use
PREFLIGHT_MAX_ENCRYPTED_ROWS=1000. The final production preflight should omit that limit so every encrypted value is read. -
If Azure is used, select a representative blob and verify that the new adapter can find it:
ACTIVE_STORAGE_CHECK_BLOB_ID=<blob-id> \ EXPECTED_RAILS_VERSION=7.2.3.1 \ EXPECTED_CONFIG_DEFAULTS=7.0 \ EXPECTED_AZURE_SERVICE=AzureBlob \ bundle exec rails runner script/rails_upgrade/preflight.rb -
Run the explicit write/read/delete smoke against every configured storage service. This creates one uniquely named text blob and purges it in an
ensureblock:RAILS_UPGRADE_ALLOW_STORAGE_WRITE=true \ RAILS_UPGRADE_STORAGE_SERVICE=microsoft \ bundle exec rails runner script/rails_upgrade/active_storage_smoke.rb
Azure configuration
Existing shared-key installations keep the same environment variables:
AZURE_STORAGE_ACCOUNT_NAMEAZURE_STORAGE_ACCESS_KEYAZURE_STORAGE_CONTAINER
The service key selected by ACTIVE_STORAGE_SERVICE remains microsoft. Only the adapter class in config/storage.yml changes from AzureStorage to AzureBlob; no blob copy or database update is required.
For an Azurite rehearsal, set AZURE_STORAGE_BLOB_HOST to the emulator endpoint and use its account name, access key, and pre-created container.
Deployment order
- Build the image and precompile assets before replacing any process.
- Run
bundle exec rails db:abort_if_pending_migrations. - Start one web canary and verify health, login, API authentication, Super Admin, message creation, attachments, and Action Cable.
- Replace the remaining web processes.
- Start one Sidekiq canary and verify immediate, scheduled, mail, webhook, and retry queues.
- Confirm startup logs show Sidekiq 7.3.10, every configured cron job is registered, and no scheduler thread reports a
ConnectionPool::TimedStack#popargument error. Wait for at least one minute-level cron job to enqueue and complete. - Replace the remaining workers and scheduler.
- Run the full preflight again against the primary database.
Web and worker processes from the old and new release may overlap because this checkpoint retains Rails 7.0 framework defaults and does not introduce a new persisted serialization format.
Post-deployment checks
- No increase in decrypt errors, login failures, HTTP 5xx responses, Sidekiq retries, or dead jobs.
- Both Sidekiq scheduler threads remain alive and cron/scheduled queues continue to receive work.
- New and existing attachments download successfully from every enabled storage backend.
- Email ingestion and delivery, webhooks, scheduled jobs, and cron jobs continue to run.
- Super Admin assets and custom Administrate fields render correctly.
Rails.versionreports7.2.3.1and the preflight reportsrails.framework_defaultsas7.0.
Rollback
Rollback is code-only because this checkpoint has no schema or data migration and keeps the old framework defaults.
- Restore the previous Rails 7.1 release for web and workers.
- Restore the previous
AzureStorageadapter configuration if Azure is enabled. - Re-run attachment reads, login, and a representative job.
- Keep the database and Redis data created during the canary; their formats remain compatible with the prior release.
Do not activate Rails 7.1/7.2 defaults in the same rollout. Encryption digest, cache/message serialization, callback ordering, job enqueue timing, WebP handling, and PostgreSQL date decoding require separately deployable compatibility work.