From f429db89b4646a649856b4f875bdbd7d0f2f043b Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Wed, 28 May 2025 23:42:34 +0530 Subject: [PATCH 01/11] add mintlify intro docs --- .../environment-setup/local-development.mdx | 588 ++++++++++ developer-docs/contributing/introduction.mdx | 322 ++++++ .../project-setup/common-errors.mdx | 1004 +++++++++++++++++ .../project-setup/environment-variables.mdx | 658 +++++++++++ .../project-setup/setup-guide.mdx | 589 ++++++++++ developer-docs/docs.json | 55 +- developer-docs/self-hosted/architecture.mdx | 342 ++++++ developer-docs/self-hosted/cloud/aws.mdx | 501 ++++++++ developer-docs/self-hosted/cloud/azure.mdx | 663 +++++++++++ .../self-hosted/cloud/digitalocean.mdx | 670 +++++++++++ developer-docs/self-hosted/cloud/gcp.mdx | 745 ++++++++++++ developer-docs/self-hosted/cloud/heroku.mdx | 505 +++++++++ .../configuration/environment-variables.mdx | 748 ++++++++++++ .../self-hosted/deployment/chatwoot-ctl.mdx | 416 +++++++ .../self-hosted/deployment/docker.mdx | 572 ++++++++++ .../self-hosted/deployment/kubernetes.mdx | 537 +++++++++ .../self-hosted/deployment/linux-vm.mdx | 675 +++++++++++ developer-docs/self-hosted/introduction.mdx | 127 +++ developer-docs/self-hosted/requirements.mdx | 339 ++++++ 19 files changed, 10055 insertions(+), 1 deletion(-) create mode 100644 developer-docs/contributing/environment-setup/local-development.mdx create mode 100644 developer-docs/contributing/introduction.mdx create mode 100644 developer-docs/contributing/project-setup/common-errors.mdx create mode 100644 developer-docs/contributing/project-setup/environment-variables.mdx create mode 100644 developer-docs/contributing/project-setup/setup-guide.mdx create mode 100644 developer-docs/self-hosted/architecture.mdx create mode 100644 developer-docs/self-hosted/cloud/aws.mdx create mode 100644 developer-docs/self-hosted/cloud/azure.mdx create mode 100644 developer-docs/self-hosted/cloud/digitalocean.mdx create mode 100644 developer-docs/self-hosted/cloud/gcp.mdx create mode 100644 developer-docs/self-hosted/cloud/heroku.mdx create mode 100644 developer-docs/self-hosted/configuration/environment-variables.mdx create mode 100644 developer-docs/self-hosted/deployment/chatwoot-ctl.mdx create mode 100644 developer-docs/self-hosted/deployment/docker.mdx create mode 100644 developer-docs/self-hosted/deployment/kubernetes.mdx create mode 100644 developer-docs/self-hosted/deployment/linux-vm.mdx create mode 100644 developer-docs/self-hosted/introduction.mdx create mode 100644 developer-docs/self-hosted/requirements.mdx diff --git a/developer-docs/contributing/environment-setup/local-development.mdx b/developer-docs/contributing/environment-setup/local-development.mdx new file mode 100644 index 000000000..ef85cd909 --- /dev/null +++ b/developer-docs/contributing/environment-setup/local-development.mdx @@ -0,0 +1,588 @@ +--- +title: Local Development Setup +description: Set up Chatwoot for local development on your machine +sidebarTitle: Local Development +--- + +# Local Development Setup + +This guide will help you set up Chatwoot for local development on your machine. Follow these steps to get a complete development environment running. + +## Prerequisites + +Before setting up Chatwoot locally, ensure you have the following installed: + +### Required Software + + + + Ruby 3.3.3 (managed with rbenv or RVM) + + + Node.js 20+ with pnpm package manager + + + PostgreSQL 13+ for the database + + + Redis 6+ for caching and background jobs + + + +### System Dependencies + + + + ```bash + # Install Homebrew if not already installed + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Install dependencies + brew install postgresql@15 redis imagemagick git + + # Install rbenv for Ruby version management + brew install rbenv ruby-build + + # Install Node.js and pnpm + brew install node + npm install -g pnpm + + # Start services + brew services start postgresql@15 + brew services start redis + ``` + + + + ```bash + # Update package list + sudo apt update + + # Install dependencies + sudo apt install -y curl git build-essential libssl-dev libreadline-dev \ + zlib1g-dev libpq-dev imagemagick libmagickwand-dev libffi-dev \ + postgresql postgresql-contrib redis-server + + # Install rbenv + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash + + # Install Node.js (using NodeSource) + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt install -y nodejs + + # Install pnpm + npm install -g pnpm + + # Start services + sudo systemctl start postgresql + sudo systemctl start redis-server + sudo systemctl enable postgresql + sudo systemctl enable redis-server + ``` + + + + ```bash + # Install EPEL repository + sudo yum install -y epel-release + + # Install dependencies + sudo yum groupinstall -y "Development Tools" + sudo yum install -y curl git openssl-devel readline-devel zlib-devel \ + postgresql-devel ImageMagick-devel libffi-devel postgresql-server \ + postgresql-contrib redis + + # Initialize PostgreSQL + sudo postgresql-setup initdb + + # Install rbenv + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash + + # Install Node.js + curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - + sudo yum install -y nodejs + + # Install pnpm + npm install -g pnpm + + # Start services + sudo systemctl start postgresql + sudo systemctl start redis + sudo systemctl enable postgresql + sudo systemctl enable redis + ``` + + + +## Ruby Setup + +### Install Ruby with rbenv + +```bash +# Add rbenv to your shell profile +echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(rbenv init -)"' >> ~/.bashrc +source ~/.bashrc + +# Install Ruby 3.3.3 +rbenv install 3.3.3 +rbenv global 3.3.3 + +# Verify installation +ruby --version +# Should output: ruby 3.3.3 + +# Install bundler +gem install bundler +``` + +### Alternative: Using RVM + +```bash +# Install RVM +curl -sSL https://get.rvm.io | bash -s stable +source ~/.rvm/scripts/rvm + +# Install Ruby 3.3.3 +rvm install 3.3.3 +rvm use 3.3.3 --default + +# Verify installation +ruby --version +gem install bundler +``` + +## Database Setup + +### PostgreSQL Configuration + +```bash +# Create PostgreSQL user (macOS with Homebrew) +createuser -s chatwoot + +# Create PostgreSQL user (Linux) +sudo -u postgres createuser -s chatwoot + +# Set password for the user +sudo -u postgres psql +postgres=# ALTER USER chatwoot PASSWORD 'password'; +postgres=# \q + +# Create databases +createdb chatwoot_development +createdb chatwoot_test +``` + +### PostgreSQL Authentication Setup + +Edit PostgreSQL configuration to allow local connections: + +```bash +# Find pg_hba.conf location +sudo -u postgres psql -c "SHOW hba_file;" + +# Edit the file (example path) +sudo nano /etc/postgresql/15/main/pg_hba.conf + +# Add or modify these lines: +local all chatwoot md5 +host all chatwoot 127.0.0.1/32 md5 +host all chatwoot ::1/128 md5 + +# Restart PostgreSQL +sudo systemctl restart postgresql +``` + +## Project Setup + +### Clone the Repository + +```bash +# Fork the repository on GitHub first, then clone your fork +git clone https://github.com/YOUR_USERNAME/chatwoot.git +cd chatwoot + +# Add upstream remote +git remote add upstream https://github.com/chatwoot/chatwoot.git + +# Verify remotes +git remote -v +``` + +### Install Dependencies + +```bash +# Install Ruby dependencies +bundle install + +# Install Node.js dependencies +pnpm install + +# Install Playwright for E2E tests (optional) +pnpm exec playwright install +``` + +### Environment Configuration + +```bash +# Copy environment file +cp .env.example .env + +# Edit the environment file +nano .env +``` + +Update the `.env` file with your local configuration: + +```bash +# Database configuration +DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development +REDIS_URL=redis://localhost:6379/0 + +# Application settings +FRONTEND_URL=http://localhost:3000 +FORCE_SSL=false +RAILS_ENV=development +NODE_ENV=development + +# Email configuration (for development) +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=localhost +SMTP_PORT=1025 + +# File storage (local) +ACTIVE_STORAGE_SERVICE=local + +# Development features +ENABLE_DEVELOPMENT_FEATURES=true +LOG_LEVEL=debug +``` + +### Database Initialization + +```bash +# Create and migrate the database +bundle exec rails db:create +bundle exec rails db:migrate + +# Seed the database with sample data +bundle exec rails db:seed + +# Prepare the test database +RAILS_ENV=test bundle exec rails db:create +RAILS_ENV=test bundle exec rails db:migrate +``` + +## Running the Application + +### Start Development Servers + +You'll need to run multiple processes for full development: + +#### Option 1: Using Foreman (Recommended) + +```bash +# Install foreman +gem install foreman + +# Start all services +foreman start -f Procfile.dev +``` + +#### Option 2: Manual Process Management + +Open multiple terminal windows/tabs: + +```bash +# Terminal 1: Rails server +bundle exec rails server -p 3000 + +# Terminal 2: Webpack dev server +pnpm run dev + +# Terminal 3: Sidekiq worker +bundle exec sidekiq + +# Terminal 4: MailHog (for email testing) +mailhog +``` + +### Access the Application + +Once all services are running: + +- **Web Application**: http://localhost:3000 +- **API Documentation**: http://localhost:3000/swagger +- **Sidekiq Web UI**: http://localhost:3000/sidekiq +- **MailHog (Email)**: http://localhost:8025 + +### Default Login Credentials + +After seeding the database, you can log in with: + +- **Email**: john@acme.inc +- **Password**: Password1! + +## Development Tools + +### Code Quality Tools + +```bash +# Install development gems +bundle install --with development test + +# Run RuboCop (Ruby linter) +bundle exec rubocop + +# Run RuboCop with auto-fix +bundle exec rubocop -a + +# Run ESLint (JavaScript linter) +pnpm run lint + +# Run ESLint with auto-fix +pnpm run lint:fix + +# Run Prettier (code formatter) +pnpm run format +``` + +### Testing + +```bash +# Run Ruby tests +bundle exec rspec + +# Run specific test file +bundle exec rspec spec/models/user_spec.rb + +# Run JavaScript tests +pnpm run test + +# Run E2E tests +pnpm run test:e2e + +# Run tests with coverage +COVERAGE=true bundle exec rspec +``` + +### Database Operations + +```bash +# Reset database +bundle exec rails db:drop db:create db:migrate db:seed + +# Generate migration +bundle exec rails generate migration AddColumnToTable column:type + +# Run migrations +bundle exec rails db:migrate + +# Rollback migration +bundle exec rails db:rollback + +# Check migration status +bundle exec rails db:migrate:status +``` + +## IDE and Editor Setup + +### VS Code Configuration + +Create `.vscode/settings.json`: + +```json +{ + "ruby.intellisense": "rubyLocate", + "ruby.codeCompletion": "rcodetools", + "ruby.format": "rubocop", + "editor.formatOnSave": true, + "editor.rulers": [120], + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + "eslint.autoFixOnSave": true, + "prettier.requireConfig": true +} +``` + +### Recommended VS Code Extensions + +```json +{ + "recommendations": [ + "rebornix.ruby", + "wingrunr21.vscode-ruby", + "bradlc.vscode-tailwindcss", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "ms-vscode.vscode-typescript-next", + "bradlc.vscode-tailwindcss" + ] +} +``` + +### RubyMine Configuration + +1. Open the project in RubyMine +2. Configure Ruby SDK: File → Project Structure → SDKs +3. Set up database connection in Database tool window +4. Configure code style: File → Settings → Editor → Code Style + +## Debugging + +### Rails Debugging + +```ruby +# Add to your code for debugging +binding.pry + +# Or use the built-in debugger +debugger +``` + +### JavaScript Debugging + +```javascript +// Add to your code +console.log('Debug info:', variable); +debugger; +``` + +### Database Debugging + +```bash +# Rails console +bundle exec rails console + +# Database console +bundle exec rails dbconsole + +# Check database queries in logs +tail -f log/development.log | grep SQL +``` + +## Common Issues and Solutions + +### Bundle Install Issues + + +```bash +# macOS +brew install postgresql +bundle config build.pg --with-pg-config=/usr/local/bin/pg_config + +# Ubuntu/Debian +sudo apt-get install libpq-dev +bundle install +``` + + + +```bash +# macOS +brew install imagemagick pkg-config + +# Ubuntu/Debian +sudo apt-get install libmagickwand-dev + +# Then reinstall the gem +bundle pristine rmagick +``` + + +### Node.js Issues + + +```bash +# Clear cache and reinstall +pnpm store prune +rm -rf node_modules +pnpm install +``` + + + +```bash +# Clear webpack cache +rm -rf tmp/cache/webpacker +pnpm run dev +``` + + +### Database Issues + + +```bash +# Check if PostgreSQL is running +sudo systemctl status postgresql + +# Start PostgreSQL if not running +sudo systemctl start postgresql + +# Check connection +psql -U chatwoot -d chatwoot_development -h localhost +``` + + + +```bash +# Reset PostgreSQL user password +sudo -u postgres psql +postgres=# ALTER USER chatwoot PASSWORD 'password'; +postgres=# \q +``` + + +## Performance Optimization + +### Development Performance Tips + +```bash +# Use spring for faster Rails commands +bundle exec spring binstub --all + +# Use bootsnap for faster boot times (already included) +# Ensure tmp/cache directory exists +mkdir -p tmp/cache + +# Use parallel testing +bundle exec rspec --parallel + +# Optimize database queries +# Add to config/environments/development.rb +config.active_record.verbose_query_logs = true +``` + +### Memory Usage Optimization + +```bash +# Monitor memory usage +ps aux | grep ruby +ps aux | grep node + +# Use jemalloc for better memory management +export MALLOC_ARENA_MAX=2 +bundle exec rails server +``` + +## Next Steps + +Once you have your development environment set up: + +1. **Read the Contributing Guidelines**: Check out the [contributing guide](../introduction) for code standards and workflow +2. **Explore the Codebase**: Familiarize yourself with the project structure +3. **Pick an Issue**: Look for "good first issue" labels on GitHub +4. **Join the Community**: Connect with other contributors on Discord or GitHub Discussions + +## Getting Help + +If you encounter issues during setup: + +- **GitHub Issues**: Search existing issues or create a new one +- **Discord Community**: Join the Chatwoot Discord server +- **Documentation**: Check the official documentation +- **Stack Overflow**: Search for Chatwoot-related questions + +--- + +You're now ready to start contributing to Chatwoot! The development environment should be fully functional and ready for coding. \ No newline at end of file diff --git a/developer-docs/contributing/introduction.mdx b/developer-docs/contributing/introduction.mdx new file mode 100644 index 000000000..cb29911a9 --- /dev/null +++ b/developer-docs/contributing/introduction.mdx @@ -0,0 +1,322 @@ +--- +title: Contributing to Chatwoot +description: Complete guide to contributing to Chatwoot - from setting up your development environment to submitting pull requests. +sidebarTitle: Introduction +--- + +Thank you for your interest in contributing to Chatwoot! This guide will help you get started with contributing to our open-source customer support platform. Whether you're fixing bugs, adding features, or improving documentation, your contributions are valuable to the community. + +## Why Contribute to Chatwoot? + +Contributing to Chatwoot offers many benefits: + +- **Learn and Grow**: Work with modern technologies like Ruby on Rails, Vue.js, and PostgreSQL +- **Make an Impact**: Help thousands of businesses improve their customer support +- **Build Your Portfolio**: Showcase your contributions to a popular open-source project +- **Join the Community**: Connect with developers and users from around the world +- **Give Back**: Support the open-source ecosystem + +## Ways to Contribute + +There are many ways to contribute to Chatwoot: + +### 🐛 Bug Reports and Fixes +- Report bugs you encounter +- Fix existing bugs in the codebase +- Improve error handling and edge cases + +### ✨ Feature Development +- Implement new features +- Enhance existing functionality +- Improve user experience + +### 📚 Documentation +- Improve existing documentation +- Write new guides and tutorials +- Translate documentation to other languages + +### 🧪 Testing +- Write unit and integration tests +- Perform manual testing +- Improve test coverage + +### 🎨 Design and UX +- Improve user interface design +- Enhance user experience +- Create mockups and prototypes + +### 🌍 Localization +- Translate Chatwoot to new languages +- Improve existing translations +- Help with internationalization + +## Getting Started + +### Prerequisites + +Before you start contributing, make sure you have: + +- **Git**: Version control system +- **GitHub Account**: For submitting pull requests +- **Development Environment**: See our environment setup guides +- **Basic Knowledge**: Familiarity with Ruby, JavaScript, or the technology you want to work with + +### Development Workflow + +Our development workflow follows these steps: + +1. **Find an Issue**: Look for issues tagged with "Good first issue" or create a new one +2. **Fork the Repository**: Create your own copy of the Chatwoot repository +3. **Create a Branch**: Make a feature branch for your changes +4. **Make Changes**: Implement your fix or feature +5. **Test Your Changes**: Ensure everything works correctly +6. **Submit a Pull Request**: Open a PR with a clear description +7. **Code Review**: Collaborate with maintainers to refine your changes +8. **Merge**: Your contribution becomes part of Chatwoot! + +## Before You Start + +### 1. Check Existing Issues + +Before starting work, check if someone else is already working on the same issue: + +- Browse [open issues](https://github.com/chatwoot/chatwoot/issues) +- Look for issues labeled "Good first issue" for beginners +- Check if there's an existing pull request for the same feature + +### 2. Create or Comment on an Issue + +- **For new features**: Create an issue to discuss the feature before implementing +- **For existing issues**: Comment that you'd like to work on it +- **Wait for assignment**: This helps avoid duplicate work + +### 3. Understand the Codebase + +Familiarize yourself with: +- **Architecture**: How Chatwoot is structured +- **Coding Standards**: Our style guides and conventions +- **Testing Practices**: How we write and run tests + +## Pull Request Guidelines + +### Branch Naming + +Use descriptive branch names that follow our conventions: + +```bash +# Feature branches +feature/issue-id-short-description +feature/235-contact-panel + +# Bug fix branches +fix/issue-id-short-description +fix/123-email-validation + +# Chore branches +chore/update-dependencies +chore/improve-documentation +``` + +### Commit Messages + +Write clear, descriptive commit messages: + +```bash +# Good commit messages +feat: Add contact search functionality (#235) +fix: Resolve email validation issue (#123) +docs: Update installation guide +test: Add unit tests for contact model + +# Avoid +Update stuff +Fix bug +WIP +``` + +### Pull Request Template + +When creating a pull request, include: + +**Description:** +- Clear description of what the PR does +- Link to related issues +- Screenshots for UI changes + +**Testing:** +- How you tested the changes +- Test cases covered +- Any manual testing performed + +**Checklist:** +- [ ] Code follows style guidelines +- [ ] Self-review completed +- [ ] Tests added/updated +- [ ] Documentation updated +- [ ] No breaking changes (or clearly documented) + +### Example Pull Request + +```markdown +## Description +Adds a new contact search feature that allows agents to quickly find contacts by name, email, or phone number. + +Fixes #235 + +## Changes Made +- Added search input to contact panel +- Implemented backend search API +- Added debounced search functionality +- Updated contact list component + +## Testing +- Added unit tests for search API +- Tested search with various input types +- Verified performance with large contact lists +- Manual testing on different browsers + +## Screenshots +[Include screenshots of the new feature] + +## Checklist +- [x] Code follows style guidelines +- [x] Self-review completed +- [x] Tests added +- [x] Documentation updated +- [x] No breaking changes +``` + +## Code Standards + +### Ruby/Rails Standards + +- Follow [Ruby Style Guide](https://rubystyle.guide/) +- Use [RuboCop](https://github.com/rubocop/rubocop) for linting +- Write descriptive method and variable names +- Add comments for complex logic +- Follow Rails conventions + +### JavaScript/Vue.js Standards + +- Follow [JavaScript Standard Style](https://standardjs.com/) +- Use [ESLint](https://eslint.org/) for linting +- Write modular, reusable components +- Use meaningful component and variable names +- Follow Vue.js best practices + +### Testing Standards + +- Write tests for new features +- Maintain or improve test coverage +- Use descriptive test names +- Test both happy path and edge cases +- Mock external dependencies + +## Development Environment + +Choose your preferred development environment: + + + + Set up development environment on macOS + + + Set up development environment on Ubuntu Linux + + + Set up development environment on Windows + + + Use Docker for consistent development environment + + + +## Issue Labels + +Understanding our issue labels helps you find the right issues to work on: + +| Label | Description | +|-------|-------------| +| `good first issue` | Perfect for new contributors | +| `help wanted` | Community help needed | +| `bug` | Something isn't working | +| `enhancement` | New feature or improvement | +| `documentation` | Documentation improvements | +| `question` | Further information requested | +| `wontfix` | This will not be worked on | +| `duplicate` | This issue already exists | + +## Community Guidelines + +### Be Respectful + +- Treat everyone with respect and kindness +- Be patient with new contributors +- Provide constructive feedback +- Help others learn and grow + +### Communication + +- Use clear, concise language +- Ask questions when unsure +- Share knowledge and resources +- Be responsive to feedback + +### Collaboration + +- Work together towards common goals +- Share credit for collaborative work +- Help review others' contributions +- Mentor new contributors + +## Getting Help + +If you need help while contributing: + +### Documentation +- Read our comprehensive guides +- Check the API documentation +- Review existing code examples + +### Community Support +- **Discord**: [Join our community chat](https://discord.gg/cJXdrwS) +- **GitHub Discussions**: [Ask questions and share ideas](https://github.com/chatwoot/chatwoot/discussions) +- **Issues**: Create an issue for bugs or feature requests + +### Maintainer Support +- Tag maintainers in issues or PRs when needed +- Be patient - maintainers are volunteers +- Provide detailed information when asking for help + +## Recognition + +We value all contributions and recognize contributors in several ways: + +- **Contributors Page**: Listed on our website and README +- **Release Notes**: Mentioned in release announcements +- **Social Media**: Highlighted on our social channels +- **Swag**: Occasional contributor swag for significant contributions + +## Code of Conduct + +All contributors must follow our [Code of Conduct](https://github.com/chatwoot/chatwoot/blob/develop/CODE_OF_CONDUCT.md). We are committed to providing a welcoming and inclusive environment for everyone. + +## Next Steps + +Ready to start contributing? Here's what to do next: + +1. **Set up your development environment** using one of our setup guides +2. **Find a good first issue** to work on +3. **Fork the repository** and create a feature branch +4. **Make your changes** following our guidelines +5. **Submit a pull request** with a clear description + +--- + + +Remember, contributing to open source is a learning process. Don't be afraid to ask questions, make mistakes, and learn from the community. Every contribution, no matter how small, makes a difference! + + + +Start small with documentation improvements or bug fixes to get familiar with the codebase and contribution process before tackling larger features. + \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/common-errors.mdx b/developer-docs/contributing/project-setup/common-errors.mdx new file mode 100644 index 000000000..5f1909188 --- /dev/null +++ b/developer-docs/contributing/project-setup/common-errors.mdx @@ -0,0 +1,1004 @@ +--- +title: Common Errors and Solutions +description: Troubleshooting guide for common errors during Chatwoot development setup +sidebarTitle: Common Errors +--- + +# Common Errors and Solutions + +This guide covers the most common errors encountered during Chatwoot development setup and their solutions. Use this as a quick reference when troubleshooting issues. + +## Installation and Setup Errors + +### Ruby and Bundler Issues + + +**Error Message**: +``` +An error occurred while installing pg (1.5.4), and Bundler cannot continue. +Make sure that `gem install pg -v '1.5.4'` succeeds before bundling. +``` + +**Cause**: Missing PostgreSQL development headers or incorrect pg_config path. + +**Solutions**: + + + +```bash +# Install PostgreSQL with Homebrew +brew install postgresql + +# Configure bundle to use correct pg_config +bundle config build.pg --with-pg-config=/opt/homebrew/bin/pg_config + +# For Intel Macs +bundle config build.pg --with-pg-config=/usr/local/bin/pg_config + +# Retry bundle install +bundle install +``` + + + +```bash +# Install PostgreSQL development headers +sudo apt-get update +sudo apt-get install libpq-dev postgresql-client + +# Install build essentials +sudo apt-get install build-essential + +# Retry bundle install +bundle install +``` + + + +```bash +# Install PostgreSQL development packages +sudo yum install postgresql-devel + +# Install development tools +sudo yum groupinstall "Development Tools" + +# Retry bundle install +bundle install +``` + + + + + +**Error Message**: +``` +Your Ruby version is 3.1.0, but your Gemfile specified 3.3.3 +``` + +**Cause**: Wrong Ruby version installed. + +**Solutions**: + + + +```bash +# Install correct Ruby version +rbenv install 3.3.3 + +# Set as global version +rbenv global 3.3.3 + +# Verify version +ruby --version + +# Rehash to update shims +rbenv rehash +``` + + + +```bash +# Install correct Ruby version +rvm install 3.3.3 + +# Use the version +rvm use 3.3.3 --default + +# Verify version +ruby --version +``` + + + +```bash +# Install correct Ruby version +asdf install ruby 3.3.3 + +# Set as global version +asdf global ruby 3.3.3 + +# Verify version +ruby --version +``` + + + + + +**Error Message**: +``` +Bundler could not find compatible versions for gem "bundler" +``` + +**Cause**: Incompatible Bundler version. + +**Solution**: +```bash +# Check current Bundler version +bundler --version + +# Install specific Bundler version (check Gemfile.lock) +gem install bundler:2.4.22 + +# Update Bundler +gem update bundler + +# Clean bundle cache +bundle clean --force + +# Retry installation +bundle install +``` + + +### Node.js and Package Manager Issues + + +**Error Message**: +``` +error @chatwoot/chatwoot@1.0.0: The engine "node" is incompatible with this module. +``` + +**Cause**: Wrong Node.js version. + +**Solutions**: + + + +```bash +# Install correct Node.js version +nvm install 20 + +# Use the version +nvm use 20 + +# Set as default +nvm alias default 20 + +# Verify version +node --version +``` + + + +```bash +# Install correct Node.js version +n 20 + +# Verify version +node --version +``` + + + +```bash +# Install correct Node.js version +asdf install nodejs 20.10.0 + +# Set as global version +asdf global nodejs 20.10.0 + +# Verify version +node --version +``` + + + + + +**Error Message**: +``` +pnpm: command not found +``` + +**Cause**: pnpm not installed. + +**Solutions**: +```bash +# Install pnpm globally +npm install -g pnpm + +# Or using corepack (Node.js 16.10+) +corepack enable +corepack prepare pnpm@latest --activate + +# Or using Homebrew (macOS) +brew install pnpm + +# Verify installation +pnpm --version +``` + + + +**Error Message**: +``` +ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies +``` + +**Cause**: Peer dependency conflicts or corrupted cache. + +**Solutions**: +```bash +# Clear pnpm cache +pnpm store prune + +# Remove node_modules and lock file +rm -rf node_modules pnpm-lock.yaml + +# Reinstall with legacy peer deps +pnpm install --legacy-peer-deps + +# Or force installation +pnpm install --force + +# Alternative: use npm +npm install +``` + + +## Database Errors + +### PostgreSQL Connection Issues + + +**Error Message**: +``` +PG::ConnectionBad: could not connect to server: Connection refused +``` + +**Cause**: PostgreSQL service not running or incorrect connection parameters. + +**Solutions**: + + + +```bash +# Check if PostgreSQL is running +brew services list | grep postgresql + +# Start PostgreSQL +brew services start postgresql + +# Check connection +psql postgres -c "SELECT 1;" + +# If user doesn't exist, create it +createuser -s chatwoot +``` + + + +```bash +# Check PostgreSQL status +sudo systemctl status postgresql + +# Start PostgreSQL +sudo systemctl start postgresql +sudo systemctl enable postgresql + +# Switch to postgres user and create chatwoot user +sudo -u postgres createuser -s chatwoot + +# Set password for chatwoot user +sudo -u postgres psql -c "ALTER USER chatwoot PASSWORD 'password';" +``` + + + +```bash +# Start PostgreSQL container +docker run --name postgres-chatwoot \ + -e POSTGRES_USER=chatwoot \ + -e POSTGRES_PASSWORD=password \ + -e POSTGRES_DB=chatwoot_development \ + -p 5432:5432 \ + -d postgres:15 + +# Check if container is running +docker ps | grep postgres +``` + + + + + +**Error Message**: +``` +ActiveRecord::NoDatabaseError: FATAL: database "chatwoot_development" does not exist +``` + +**Cause**: Database not created. + +**Solution**: +```bash +# Create databases +bundle exec rails db:create + +# If that fails, create manually +createdb chatwoot_development +createdb chatwoot_test + +# Or using psql +psql postgres -c "CREATE DATABASE chatwoot_development;" +psql postgres -c "CREATE DATABASE chatwoot_test;" +``` + + + +**Error Message**: +``` +ActiveRecord::PendingMigrationError: Migrations are pending +``` + +**Cause**: Database schema is not up to date. + +**Solutions**: +```bash +# Run pending migrations +bundle exec rails db:migrate + +# If migrations fail, check status +bundle exec rails db:migrate:status + +# Reset database (WARNING: destroys data) +bundle exec rails db:drop db:create db:migrate db:seed + +# For specific migration issues +bundle exec rails db:migrate:up VERSION=20231201000000 +``` + + +### Redis Connection Issues + + +**Error Message**: +``` +Redis::CannotConnectError: Error connecting to Redis on localhost:6379 +``` + +**Cause**: Redis service not running. + +**Solutions**: + + + +```bash +# Check if Redis is running +brew services list | grep redis + +# Start Redis +brew services start redis + +# Test connection +redis-cli ping +``` + + + +```bash +# Check Redis status +sudo systemctl status redis + +# Start Redis +sudo systemctl start redis +sudo systemctl enable redis + +# Test connection +redis-cli ping +``` + + + +```bash +# Start Redis container +docker run --name redis-chatwoot \ + -p 6379:6379 \ + -d redis:7-alpine + +# Test connection +docker exec redis-chatwoot redis-cli ping +``` + + + + +## Application Runtime Errors + +### Rails Server Issues + + +**Error Message**: +``` +Address already in use - bind(2) for "127.0.0.1" port 3000 +``` + +**Cause**: Another process is using port 3000. + +**Solutions**: +```bash +# Find process using port 3000 +lsof -ti:3000 + +# Kill the process +kill -9 $(lsof -ti:3000) + +# Or use a different port +bundle exec rails server -p 3001 + +# Check what's running on the port +netstat -tulpn | grep :3000 +``` + + + +**Error Message**: +``` +ArgumentError: Missing `secret_key_base` for 'development' environment +``` + +**Cause**: SECRET_KEY_BASE not set in environment. + +**Solution**: +```bash +# Generate a new secret key +bundle exec rails secret + +# Add to .env file +echo "SECRET_KEY_BASE=$(bundle exec rails secret)" >> .env + +# Or set temporarily +export SECRET_KEY_BASE=$(bundle exec rails secret) +bundle exec rails server +``` + + + +**Error Message**: +``` +Webpacker::Manifest::MissingEntryError: Webpacker can't find application.js +``` + +**Cause**: Webpack assets not compiled or compilation failed. + +**Solutions**: +```bash +# Check if webpack dev server is running +ps aux | grep webpack + +# Start webpack dev server +pnpm run dev + +# Or compile assets manually +bundle exec rails assets:precompile + +# Clear webpack cache +rm -rf tmp/cache/webpacker +rm -rf public/packs + +# Reinstall node modules +rm -rf node_modules +pnpm install +``` + + +### Sidekiq Worker Issues + + +**Error Message**: +``` +Jobs are queued but not being processed +``` + +**Cause**: Sidekiq worker not running. + +**Solutions**: +```bash +# Check if Sidekiq is running +ps aux | grep sidekiq + +# Start Sidekiq +bundle exec sidekiq + +# Check Sidekiq web interface +open http://localhost:3000/sidekiq + +# Clear failed jobs +bundle exec rails runner "Sidekiq::Queue.new.clear" +``` + + + +**Error Message**: +``` +Redis::CommandError: OOM command not allowed when used memory > 'maxmemory' +``` + +**Cause**: Redis running out of memory. + +**Solutions**: +```bash +# Check Redis memory usage +redis-cli info memory + +# Clear Redis cache +redis-cli flushall + +# Increase Redis memory limit (redis.conf) +# maxmemory 256mb + +# Or restart Redis +brew services restart redis # macOS +sudo systemctl restart redis # Linux +``` + + +## Testing Errors + +### RSpec Test Failures + + +**Error Message**: +``` +ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "users" does not exist +``` + +**Cause**: Test database not set up properly. + +**Solution**: +```bash +# Prepare test database +RAILS_ENV=test bundle exec rails db:create +RAILS_ENV=test bundle exec rails db:migrate + +# Or use the combined command +bundle exec rails db:test:prepare + +# Reset test database if needed +RAILS_ENV=test bundle exec rails db:drop db:create db:migrate +``` + + + +**Error Message**: +``` +FactoryBot::DuplicateDefinitionError: Factory already registered +``` + +**Cause**: Factory definitions loaded multiple times. + +**Solution**: +```bash +# Clear Spring cache +bundle exec spring stop + +# Restart test suite +bundle exec rspec + +# Check for duplicate factory definitions +grep -r "FactoryBot.define" spec/ +``` + + + +**Error Message**: +``` +Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver +``` + +**Cause**: ChromeDriver not installed or incompatible version. + +**Solutions**: +```bash +# Install ChromeDriver +# macOS +brew install chromedriver + +# Ubuntu/Debian +sudo apt-get install chromium-chromedriver + +# Or use webdrivers gem (should be automatic) +bundle exec rails runner "Webdrivers::Chromedriver.update" + +# Run tests in headless mode +HEADLESS=true bundle exec rspec spec/system/ +``` + + +## Development Environment Issues + +### IDE and Editor Problems + + +**Error**: Ruby IntelliSense not working, no syntax highlighting. + +**Solutions**: +```bash +# Install Ruby LSP +gem install ruby-lsp + +# Or add to Gemfile +echo 'gem "ruby-lsp", group: :development' >> Gemfile +bundle install + +# Restart VS Code +# Install recommended extensions: +# - Ruby LSP +# - Ruby Solargraph +# - Ruby Test Explorer +``` + + + +**Error**: Ruby documentation and autocomplete not working. + +**Solutions**: +```bash +# Install Solargraph +gem install solargraph + +# Generate documentation +bundle exec yard gems +bundle exec solargraph bundle + +# Create .solargraph.yml config +solargraph config + +# Restart your editor +``` + + +### Git and Version Control Issues + + +**Error**: Git commit rejected due to linting errors. + +**Solutions**: +```bash +# Fix RuboCop issues +bundle exec rubocop -a + +# Fix ESLint issues +pnpm run lint:fix + +# Format code +pnpm run format + +# Skip hooks temporarily (not recommended) +git commit --no-verify -m "Your commit message" + +# Update pre-commit hooks +pre-commit autoupdate +``` + + + +**Error**: Git LFS or large file warnings. + +**Solutions**: +```bash +# Install Git LFS +git lfs install + +# Track large files +git lfs track "*.png" +git lfs track "*.jpg" +git lfs track "*.pdf" + +# Add .gitattributes +git add .gitattributes + +# Check LFS status +git lfs status +``` + + +## Performance Issues + +### Slow Application Startup + + +**Cause**: Large codebase, slow database, or memory issues. + +**Solutions**: +```bash +# Use Spring for faster Rails commands +bundle exec spring binstub --all + +# Check Spring status +bundle exec spring status + +# Restart Spring if needed +bundle exec spring stop + +# Increase memory if needed +export RUBY_GC_HEAP_INIT_SLOTS=10000 +export RUBY_GC_HEAP_FREE_SLOTS=10000 + +# Profile startup time +time bundle exec rails runner "puts 'Rails loaded'" +``` + + + +**Cause**: Database setup, factory creation, or inefficient tests. + +**Solutions**: +```bash +# Use parallel testing +bundle exec rspec --parallel + +# Profile slow tests +bundle exec rspec --profile + +# Use database cleaner strategies +# Add to spec/rails_helper.rb: +# config.use_transactional_fixtures = true + +# Optimize factories +# Use build_stubbed instead of create when possible +``` + + +## Email and Communication Issues + +### Email Delivery Problems + + +**Cause**: SMTP configuration or email service issues. + +**Solutions**: + + + +```bash +# Install and start MailHog +brew install mailhog # macOS +mailhog + +# Configure .env +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=localhost +SMTP_PORT=1025 + +# Check web interface +open http://localhost:8025 +``` + + + +```bash +# Add to Gemfile +echo 'gem "letter_opener", group: :development' >> Gemfile +bundle install + +# Configure in development.rb +# config.action_mailer.delivery_method = :letter_opener + +# Emails will open in browser +``` + + + +```bash +# Use app password, not regular password +MAILER_SENDER_EMAIL=your-email@gmail.com +SMTP_ADDRESS=smtp.gmail.com +SMTP_PORT=587 +SMTP_USERNAME=your-email@gmail.com +SMTP_PASSWORD=your-app-password +SMTP_DOMAIN=gmail.com +SMTP_ENABLE_STARTTLS_AUTO=true +``` + + + + +### WebSocket Connection Issues + + +**Error**: Real-time features not working, WebSocket connection failed. + +**Solutions**: +```bash +# Check if ActionCable is mounted +grep -r "mount ActionCable" config/routes.rb + +# Check Redis connection +redis-cli ping + +# Configure ActionCable for development +# In config/environments/development.rb: +# config.action_cable.url = "ws://localhost:3000/cable" +# config.action_cable.allowed_request_origins = ["http://localhost:3000"] + +# Test WebSocket connection +# Open browser console and check for WebSocket errors +``` + + +## Debugging and Logging Issues + +### Log File Problems + + +**Cause**: Excessive logging in development. + +**Solutions**: +```bash +# Clear log files +> log/development.log +> log/test.log + +# Configure log rotation in development.rb +# config.logger = ActiveSupport::Logger.new("log/development.log", 5, 10.megabytes) + +# Reduce log level +# config.log_level = :info + +# Use logrotate (Linux) +sudo logrotate -f /etc/logrotate.conf +``` + + +### Debugging Tool Issues + + +**Cause**: Debugger not properly configured or running in wrong context. + +**Solutions**: +```bash +# Make sure gems are in Gemfile +echo 'gem "pry-rails", group: [:development, :test]' >> Gemfile +echo 'gem "pry-byebug", group: [:development, :test]' >> Gemfile +bundle install + +# Use correct debugger syntax +# binding.pry # for Pry +# debugger # for built-in debugger +# byebug # for byebug + +# Check if running in correct environment +puts Rails.env +``` + + +## Quick Diagnostic Commands + +### System Health Check + +```bash +#!/bin/bash +# health_check.sh - Quick system diagnostic + +echo "=== Chatwoot Development Health Check ===" + +# Check Ruby version +echo "Ruby version: $(ruby --version)" + +# Check Node.js version +echo "Node.js version: $(node --version)" + +# Check database connection +if bundle exec rails runner "ActiveRecord::Base.connection.execute('SELECT 1')" > /dev/null 2>&1; then + echo "✅ Database connection: OK" +else + echo "❌ Database connection: FAILED" +fi + +# Check Redis connection +if redis-cli ping > /dev/null 2>&1; then + echo "✅ Redis connection: OK" +else + echo "❌ Redis connection: FAILED" +fi + +# Check if services are running +echo "Running processes:" +ps aux | grep -E "(rails|sidekiq|webpack|mailhog)" | grep -v grep + +# Check ports +echo "Port usage:" +lsof -i :3000,3035,6379,5432,8025 2>/dev/null || echo "No processes found on common ports" + +echo "=== Health Check Complete ===" +``` + +### Environment Validation + +```bash +#!/bin/bash +# validate_env.sh - Validate development environment + +required_vars=( + "RAILS_ENV" + "DATABASE_URL" + "REDIS_URL" + "SECRET_KEY_BASE" + "FRONTEND_URL" +) + +echo "=== Environment Variable Check ===" +for var in "${required_vars[@]}"; do + if [ -z "${!var}" ]; then + echo "❌ Missing: $var" + else + echo "✅ Set: $var" + fi +done + +echo "=== Dependency Check ===" +commands=("ruby" "node" "psql" "redis-cli" "git") +for cmd in "${commands[@]}"; do + if command -v $cmd > /dev/null 2>&1; then + echo "✅ $cmd: $(command -v $cmd)" + else + echo "❌ $cmd: Not found" + fi +done +``` + +## Getting Additional Help + +If you're still experiencing issues after trying these solutions: + +1. **Search GitHub Issues**: Check if others have reported similar problems +2. **Check Logs**: Look at `log/development.log` for detailed error messages +3. **Discord Community**: Join the Chatwoot Discord for real-time help +4. **Documentation**: Review the official documentation +5. **Create an Issue**: If it's a bug, create a detailed GitHub issue + +### Creating a Good Bug Report + +When reporting issues, include: + +```markdown +## Environment +- OS: [e.g., macOS 13.0, Ubuntu 22.04] +- Ruby version: [e.g., 3.3.3] +- Node.js version: [e.g., 20.10.0] +- Database: [e.g., PostgreSQL 15.0] + +## Steps to Reproduce +1. Step one +2. Step two +3. Step three + +## Expected Behavior +What you expected to happen + +## Actual Behavior +What actually happened + +## Error Messages +``` +Full error message and stack trace +``` + +## Additional Context +Any other relevant information +``` + +--- + +This guide covers the most common development issues. For production deployment issues, see the [Self-hosted documentation](../../self-hosted/). \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/environment-variables.mdx b/developer-docs/contributing/project-setup/environment-variables.mdx new file mode 100644 index 000000000..570dcf482 --- /dev/null +++ b/developer-docs/contributing/project-setup/environment-variables.mdx @@ -0,0 +1,658 @@ +--- +title: Environment Variables for Development +description: Complete guide to environment variables for Chatwoot development and testing +sidebarTitle: Environment Variables +--- + +# Environment Variables for Development + +This guide covers environment variables specifically for development and testing environments. For production environment variables, see the [Self-hosted Environment Variables](../../self-hosted/configuration/environment-variables) guide. + +## Development Environment Setup + +### Basic Development Configuration + +Create your `.env` file from the example: + +```bash +cp .env.example .env +``` + +### Essential Development Variables + +```bash +# Rails Environment +RAILS_ENV=development +NODE_ENV=development + +# Application Configuration +FRONTEND_URL=http://localhost:3000 +FORCE_SSL=false +SECRET_KEY_BASE=your-secret-key-here + +# Database Configuration +DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development +REDIS_URL=redis://localhost:6379/0 + +# Development Features +ENABLE_DEVELOPMENT_FEATURES=true +RAILS_LOG_LEVEL=debug +LOG_LEVEL=debug +``` + +## Database Configuration + +### PostgreSQL Settings + +```bash +# Primary database connection +DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_development + +# Alternative format (individual variables) +DB_HOST=localhost +DB_PORT=5432 +DB_USERNAME=chatwoot +DB_PASSWORD=password +DB_NAME=chatwoot_development + +# Test database +TEST_DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_test +``` + +### Redis Configuration + +```bash +# Redis connection for development +REDIS_URL=redis://localhost:6379/0 + +# Redis with authentication +REDIS_URL=redis://:password@localhost:6379/0 + +# Redis Sentinel (for advanced setups) +REDIS_SENTINELS=localhost:26379 +REDIS_SENTINEL_MASTER_NAME=mymaster + +# Sidekiq Redis (can be separate) +SIDEKIQ_REDIS_URL=redis://localhost:6379/1 +``` + +## Email Configuration for Development + +### Local Email Testing + +```bash +# MailHog configuration (recommended for development) +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=localhost +SMTP_PORT=1025 +SMTP_DOMAIN=chatwoot.local +SMTP_ENABLE_STARTTLS_AUTO=false +SMTP_TLS=false + +# Alternative: Letter Opener (emails open in browser) +LETTER_OPENER=true +``` + +### Gmail SMTP (for testing real emails) + +```bash +MAILER_SENDER_EMAIL=your-email@gmail.com +SMTP_ADDRESS=smtp.gmail.com +SMTP_PORT=587 +SMTP_USERNAME=your-email@gmail.com +SMTP_PASSWORD=your-app-password +SMTP_DOMAIN=gmail.com +SMTP_ENABLE_STARTTLS_AUTO=true +SMTP_TLS=true +``` + +### Mailtrap (for testing) + +```bash +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=smtp.mailtrap.io +SMTP_PORT=2525 +SMTP_USERNAME=your-mailtrap-username +SMTP_PASSWORD=your-mailtrap-password +SMTP_DOMAIN=chatwoot.local +``` + +## File Storage Configuration + +### Local Storage (Default for Development) + +```bash +ACTIVE_STORAGE_SERVICE=local +``` + +### AWS S3 for Development + +```bash +ACTIVE_STORAGE_SERVICE=amazon +AWS_ACCESS_KEY_ID=your-access-key +AWS_SECRET_ACCESS_KEY=your-secret-key +AWS_REGION=us-east-1 +AWS_BUCKET_NAME=chatwoot-dev-bucket +``` + +### Google Cloud Storage + +```bash +ACTIVE_STORAGE_SERVICE=google +GCS_PROJECT_ID=your-project-id +GCS_CREDENTIALS=path/to/credentials.json +GCS_BUCKET=chatwoot-dev-bucket +``` + +## Development Features + +### Debug and Logging + +```bash +# Enable development features +ENABLE_DEVELOPMENT_FEATURES=true + +# Logging levels +RAILS_LOG_LEVEL=debug +LOG_LEVEL=debug +SIDEKIQ_LOG_LEVEL=debug + +# SQL query logging +ACTIVE_RECORD_VERBOSE_QUERY_LOGS=true + +# Bullet gem for N+1 query detection +BULLET_ENABLED=true +``` + +### Performance Monitoring + +```bash +# Enable query analysis +QUERY_ANALYSIS=true + +# Memory profiling +MEMORY_PROFILER=true + +# Rack Mini Profiler +RACK_MINI_PROFILER=true + +# Benchmark mode +BENCHMARK_MODE=true +``` + +### Code Quality Tools + +```bash +# RuboCop configuration +RUBOCOP_PARALLEL=true + +# Coverage reporting +COVERAGE=true +SIMPLECOV_FORMATTER=html + +# Test environment +RSPEC_RETRY_COUNT=3 +PARALLEL_TEST_PROCESSORS=4 +``` + +## Testing Environment Variables + +### Test Database Configuration + +```bash +# Test environment +RAILS_ENV=test + +# Test database +TEST_DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_test + +# Test Redis +TEST_REDIS_URL=redis://localhost:6379/15 + +# Disable external services in tests +DISABLE_EXTERNAL_HTTP=true +MOCK_EXTERNAL_SERVICES=true +``` + +### Test-Specific Settings + +```bash +# Faster tests +RAILS_ENV=test +DISABLE_SPRING=true +PARALLEL_WORKERS=4 + +# Test coverage +COVERAGE=true +COVERAGE_REPORTS=true + +# Selenium/Capybara configuration +SELENIUM_REMOTE_URL=http://localhost:4444/wd/hub +CAPYBARA_SERVER_PORT=3001 +HEADLESS_CHROME=true + +# Factory Bot settings +FACTORY_BOT_ALLOW_CLASS_LOOKUP=false +``` + +## Integration Testing + +### External Service Mocking + +```bash +# Mock external APIs +MOCK_FACEBOOK_API=true +MOCK_TWITTER_API=true +MOCK_WHATSAPP_API=true +MOCK_TELEGRAM_API=true + +# Webhook testing +WEBHOOK_TEST_URL=http://localhost:3000/webhooks/test +NGROK_TUNNEL_URL=https://your-tunnel.ngrok.io +``` + +### API Testing + +```bash +# API testing configuration +API_TEST_TOKEN=test-token-123 +API_TEST_ACCOUNT_ID=1 +API_TEST_USER_ID=1 + +# Rate limiting (disabled for tests) +RATE_LIMITING_ENABLED=false +``` + +## Development Tools + +### Code Analysis + +```bash +# Brakeman security scanner +BRAKEMAN_ENABLED=true + +# Bundle audit +BUNDLE_AUDIT_ENABLED=true + +# Reek code smell detector +REEK_ENABLED=true + +# Rails Best Practices +RAILS_BEST_PRACTICES_ENABLED=true +``` + +### Development Servers + +```bash +# Webpack dev server +WEBPACK_DEV_SERVER_HOST=localhost +WEBPACK_DEV_SERVER_PORT=3035 + +# Hot module replacement +HMR_ENABLED=true + +# Live reload +LIVE_RELOAD=true +``` + +## Third-Party Integrations (Development) + +### Social Media (Test Credentials) + +```bash +# Facebook (use test app credentials) +FB_APP_ID=your-test-app-id +FB_APP_SECRET=your-test-app-secret +FB_VERIFY_TOKEN=test-verify-token + +# Twitter (use test credentials) +TWITTER_APP_ID=your-test-app-id +TWITTER_CONSUMER_KEY=your-test-consumer-key +TWITTER_CONSUMER_SECRET=your-test-consumer-secret + +# WhatsApp (use test credentials) +WHATSAPP_VERIFY_TOKEN=test-verify-token +``` + +### Push Notifications (Development) + +```bash +# FCM (use development project) +FCM_SERVER_KEY=your-dev-server-key +FCM_PROJECT_ID=your-dev-project-id + +# Vapid keys for web push +VAPID_PUBLIC_KEY=your-dev-public-key +VAPID_PRIVATE_KEY=your-dev-private-key +``` + +## Security Settings for Development + +### Authentication + +```bash +# JWT settings +JWT_SECRET_KEY=your-dev-jwt-secret +JWT_EXPIRY=24h + +# Session configuration +SESSION_TIMEOUT=1440 +SECURE_COOKIES=false + +# CORS settings (permissive for development) +CORS_ORIGINS=http://localhost:3000,http://localhost:3001 +``` + +### Development Security + +```bash +# Disable security features for development +FORCE_SSL=false +SECURE_HEADERS=false +CSP_ENABLED=false + +# Allow insecure connections +ALLOW_HTTP=true +SKIP_SSL_VERIFICATION=true +``` + +## Environment-Specific Configurations + +### Development Environment + +```bash +# .env.development +RAILS_ENV=development +NODE_ENV=development +CACHE_CLASSES=false +EAGER_LOAD=false +CONSIDER_ALL_REQUESTS_LOCAL=true +ACTION_CONTROLLER_PERFORM_CACHING=false +``` + +### Test Environment + +```bash +# .env.test +RAILS_ENV=test +NODE_ENV=test +CACHE_CLASSES=true +EAGER_LOAD=false +PUBLIC_FILE_SERVER_ENABLED=true +SHOW_EXCEPTIONS=false +``` + +### Staging Environment + +```bash +# .env.staging +RAILS_ENV=staging +NODE_ENV=production +FORCE_SSL=true +LOG_LEVEL=info +RAILS_SERVE_STATIC_FILES=true +``` + +## Docker Development + +### Docker Compose Variables + +```bash +# Docker-specific configuration +POSTGRES_HOST=postgres +POSTGRES_PORT=5432 +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_DB=chatwoot + +REDIS_HOST=redis +REDIS_PORT=6379 + +# Rails configuration for Docker +RAILS_ENV=development +RAILS_MAX_THREADS=5 +WEB_CONCURRENCY=2 +``` + +### Development with Docker + +```bash +# Use Docker services +DATABASE_URL=postgresql://postgres:postgres@postgres:5432/chatwoot_development +REDIS_URL=redis://redis:6379/0 + +# File permissions (for volume mounts) +DOCKER_USER_ID=1000 +DOCKER_GROUP_ID=1000 +``` + +## IDE and Editor Configuration + +### VS Code Settings + +```bash +# Ruby LSP configuration +RUBY_LSP_ENABLED=true +RUBY_LSP_EXPERIMENTAL_FEATURES=true + +# Solargraph configuration +SOLARGRAPH_ENABLED=true +``` + +### RubyMine Settings + +```bash +# RubyMine-specific settings +RUBYMINE_PROJECT_ROOT=/path/to/chatwoot +RUBYMINE_RUBY_VERSION=3.3.3 +``` + +## Performance and Monitoring + +### Development Monitoring + +```bash +# New Relic (development license) +NEW_RELIC_LICENSE_KEY=your-dev-license-key +NEW_RELIC_APP_NAME=Chatwoot Development + +# Sentry (development DSN) +SENTRY_DSN=your-dev-sentry-dsn +SENTRY_ENVIRONMENT=development + +# DataDog (development) +DD_API_KEY=your-dev-datadog-key +DD_ENV=development +``` + +### Memory and Performance + +```bash +# Memory settings +RUBY_GC_HEAP_INIT_SLOTS=10000 +RUBY_GC_HEAP_FREE_SLOTS=10000 +RUBY_GC_HEAP_GROWTH_FACTOR=1.1 + +# Puma configuration +PUMA_WORKERS=1 +PUMA_THREADS=5 +PUMA_PRELOAD_APP=false +``` + +## Common Development Scenarios + +### API Development + +```bash +# API-specific settings +API_RATE_LIMIT=1000 +API_RATE_LIMIT_WINDOW=3600 +API_PAGINATION_LIMIT=100 + +# CORS for API development +API_CORS_ORIGINS=http://localhost:3001,http://localhost:8080 +``` + +### Widget Development + +```bash +# Widget development +WIDGET_BASE_URL=http://localhost:3000 +WIDGET_API_URL=http://localhost:3000/api/v1 +WIDGET_WS_URL=ws://localhost:3000/cable +``` + +### Mobile App Development + +```bash +# Mobile API endpoints +MOBILE_API_URL=http://localhost:3000/api/v1 +MOBILE_WS_URL=ws://localhost:3000/cable + +# Push notification testing +MOBILE_PUSH_ENABLED=true +``` + +## Troubleshooting Environment Issues + +### Common Environment Problems + + +**Problem**: `ActiveRecord::ConnectionNotEstablished` + +**Check these variables**: +```bash +DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_development +DB_HOST=localhost +DB_PORT=5432 +``` + +**Verify connection**: +```bash +psql $DATABASE_URL -c "SELECT 1;" +``` + + + +**Problem**: `Redis::CannotConnectError` + +**Check these variables**: +```bash +REDIS_URL=redis://localhost:6379/0 +``` + +**Verify connection**: +```bash +redis-cli -u $REDIS_URL ping +``` + + + +**Problem**: Emails not being sent in development + +**Check these variables**: +```bash +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=localhost +SMTP_PORT=1025 +``` + +**For MailHog**: +```bash +# Start MailHog +mailhog + +# Check web interface at http://localhost:8025 +``` + + + +**Problem**: `Webpacker::Manifest::MissingEntryError` + +**Check these variables**: +```bash +NODE_ENV=development +RAILS_ENV=development +``` + +**Recompile assets**: +```bash +pnpm run dev +# or +bundle exec rails assets:precompile +``` + + +### Environment Validation + +Create a script to validate your environment: + +```bash +#!/bin/bash +# validate_env.sh + +echo "Validating development environment..." + +# Check required variables +required_vars=( + "RAILS_ENV" + "DATABASE_URL" + "REDIS_URL" + "SECRET_KEY_BASE" + "FRONTEND_URL" +) + +for var in "${required_vars[@]}"; do + if [ -z "${!var}" ]; then + echo "❌ Missing required variable: $var" + else + echo "✅ $var is set" + fi +done + +# Test database connection +if bundle exec rails runner "ActiveRecord::Base.connection.execute('SELECT 1')" > /dev/null 2>&1; then + echo "✅ Database connection successful" +else + echo "❌ Database connection failed" +fi + +# Test Redis connection +if bundle exec rails runner "Redis.new.ping" > /dev/null 2>&1; then + echo "✅ Redis connection successful" +else + echo "❌ Redis connection failed" +fi + +echo "Environment validation complete!" +``` + +## Best Practices + +### Environment File Management + +1. **Never commit `.env` files** to version control +2. **Use `.env.example`** as a template for required variables +3. **Document all variables** with comments +4. **Use different `.env` files** for different environments +5. **Validate environment** before starting development + +### Security Considerations + +1. **Use weak credentials** only in development +2. **Never use production credentials** in development +3. **Rotate test API keys** regularly +4. **Use local services** when possible +5. **Mock external services** in tests + +### Performance Tips + +1. **Use local Redis** for faster development +2. **Enable query caching** in development +3. **Use parallel testing** for faster test runs +4. **Profile memory usage** regularly +5. **Monitor database queries** for N+1 issues + +--- + +This guide covers the essential environment variables for Chatwoot development. For production deployment, refer to the [Self-hosted Environment Variables](../../self-hosted/configuration/environment-variables) guide. \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/setup-guide.mdx b/developer-docs/contributing/project-setup/setup-guide.mdx new file mode 100644 index 000000000..2e06ffffc --- /dev/null +++ b/developer-docs/contributing/project-setup/setup-guide.mdx @@ -0,0 +1,589 @@ +--- +title: Project Setup Guide +description: Complete guide to setting up Chatwoot for development and contribution +sidebarTitle: Setup Guide +--- + +# Project Setup Guide + +This comprehensive guide will walk you through setting up Chatwoot for development, from initial repository setup to running your first successful build. + +## Prerequisites Check + +Before starting, ensure you have completed the [Local Development Setup](../environment-setup/local-development) guide and have all required dependencies installed. + +### Quick Prerequisites Verification + +```bash +# Check Ruby version (should be 3.3.3) +ruby --version + +# Check Node.js version (should be 20+) +node --version + +# Check PostgreSQL +psql --version + +# Check Redis +redis-cli --version + +# Check Git +git --version +``` + +## Repository Setup + +### 1. Fork and Clone + +```bash +# Fork the repository on GitHub first +# Then clone your fork +git clone https://github.com/YOUR_USERNAME/chatwoot.git +cd chatwoot + +# Add upstream remote for syncing +git remote add upstream https://github.com/chatwoot/chatwoot.git + +# Verify remotes +git remote -v +# Should show: +# origin https://github.com/YOUR_USERNAME/chatwoot.git (fetch) +# origin https://github.com/YOUR_USERNAME/chatwoot.git (push) +# upstream https://github.com/chatwoot/chatwoot.git (fetch) +# upstream https://github.com/chatwoot/chatwoot.git (push) +``` + +### 2. Branch Strategy + +```bash +# Create a development branch +git checkout -b develop + +# For feature work, create feature branches +git checkout -b feature/your-feature-name + +# Keep your fork synced +git fetch upstream +git checkout develop +git merge upstream/develop +git push origin develop +``` + +## Environment Configuration + +### 1. Environment File Setup + +```bash +# Copy the example environment file +cp .env.example .env + +# Open the file for editing +nano .env +``` + +### 2. Basic Configuration + +Update your `.env` file with the following essential settings: + +```bash +# Rails Environment +RAILS_ENV=development +NODE_ENV=development + +# Application URLs +FRONTEND_URL=http://localhost:3000 +FORCE_SSL=false + +# Database Configuration +DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development +REDIS_URL=redis://localhost:6379/0 + +# Email Configuration (for development) +MAILER_SENDER_EMAIL=dev@chatwoot.local +SMTP_ADDRESS=localhost +SMTP_PORT=1025 + +# File Storage +ACTIVE_STORAGE_SERVICE=local + +# Development Features +ENABLE_DEVELOPMENT_FEATURES=true +LOG_LEVEL=debug +RAILS_LOG_LEVEL=debug + +# Disable SSL in development +SMTP_ENABLE_STARTTLS_AUTO=false +SMTP_TLS=false +``` + +### 3. Generate Secret Keys + +```bash +# Generate secret key base +bundle exec rails secret + +# Add to your .env file +echo "SECRET_KEY_BASE=your-generated-secret" >> .env +``` + +## Database Setup + +### 1. Database Creation + +```bash +# Create development and test databases +bundle exec rails db:create + +# Expected output: +# Created database 'chatwoot_development' +# Created database 'chatwoot_test' +``` + +### 2. Database Migration + +```bash +# Run database migrations +bundle exec rails db:migrate + +# Check migration status +bundle exec rails db:migrate:status +``` + +### 3. Database Seeding + +```bash +# Seed the database with sample data +bundle exec rails db:seed + +# This creates: +# - Sample account +# - Admin user +# - Sample conversations +# - Test data for development +``` + +### 4. Test Database Setup + +```bash +# Prepare test database +RAILS_ENV=test bundle exec rails db:create +RAILS_ENV=test bundle exec rails db:migrate +``` + +## Dependency Installation + +### 1. Ruby Dependencies + +```bash +# Install Ruby gems +bundle install + +# If you encounter issues, try: +bundle install --retry=3 + +# For development and test gems +bundle install --with development test +``` + +### 2. Node.js Dependencies + +```bash +# Install Node.js packages +pnpm install + +# If pnpm is not available, install it first: +npm install -g pnpm + +# Clear cache if needed +pnpm store prune +``` + +### 3. Additional Tools + +```bash +# Install Foreman for process management +gem install foreman + +# Install MailHog for email testing (optional) +# macOS +brew install mailhog + +# Ubuntu/Debian +sudo apt-get install mailhog + +# Or download binary from GitHub releases +``` + +## Application Startup + +### 1. Using Foreman (Recommended) + +```bash +# Start all services with Foreman +foreman start -f Procfile.dev + +# This starts: +# - Rails server (port 3000) +# - Webpack dev server +# - Sidekiq worker +``` + +### 2. Manual Startup + +If you prefer to run services separately: + +```bash +# Terminal 1: Rails server +bundle exec rails server -p 3000 + +# Terminal 2: Webpack dev server +pnpm run dev + +# Terminal 3: Sidekiq worker +bundle exec sidekiq + +# Terminal 4: MailHog (optional) +mailhog +``` + +### 3. Verify Installation + +Once all services are running, verify your setup: + +- **Web Application**: http://localhost:3000 +- **API Health Check**: http://localhost:3000/api +- **Sidekiq Web UI**: http://localhost:3000/sidekiq +- **MailHog**: http://localhost:8025 (if running) + +## Initial Login + +### Default Credentials + +After seeding the database, you can log in with: + +``` +Email: john@acme.inc +Password: Password1! +``` + +### Creating Additional Users + +```bash +# Access Rails console +bundle exec rails console + +# Create a new user +user = User.create!( + name: "Your Name", + email: "your.email@example.com", + password: "Password123!", + password_confirmation: "Password123!" +) + +# Make user an administrator +user.account_users.first.update!(role: 'administrator') +``` + +## Development Workflow + +### 1. Code Quality Setup + +```bash +# Install pre-commit hooks (optional but recommended) +# Create .git/hooks/pre-commit +cat > .git/hooks/pre-commit << 'EOF' +#!/bin/sh +# Run RuboCop +bundle exec rubocop --parallel + +# Run ESLint +pnpm run lint + +# Run tests +bundle exec rspec --fail-fast +EOF + +chmod +x .git/hooks/pre-commit +``` + +### 2. Running Tests + +```bash +# Run Ruby tests +bundle exec rspec + +# Run specific test file +bundle exec rspec spec/models/user_spec.rb + +# Run JavaScript tests +pnpm run test + +# Run E2E tests (requires Playwright) +pnpm exec playwright install +pnpm run test:e2e + +# Run tests with coverage +COVERAGE=true bundle exec rspec +``` + +### 3. Code Linting and Formatting + +```bash +# Ruby linting with RuboCop +bundle exec rubocop + +# Auto-fix Ruby issues +bundle exec rubocop -a + +# JavaScript linting +pnpm run lint + +# Auto-fix JavaScript issues +pnpm run lint:fix + +# Format code with Prettier +pnpm run format +``` + +## IDE Configuration + +### VS Code Setup + +Create `.vscode/settings.json`: + +```json +{ + "ruby.intellisense": "rubyLocate", + "ruby.codeCompletion": "rcodetools", + "ruby.format": "rubocop", + "editor.formatOnSave": true, + "editor.rulers": [120], + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + "eslint.autoFixOnSave": true, + "prettier.requireConfig": true, + "ruby.rubocop.executePath": "./bin/", + "ruby.rubocop.onSave": true +} +``` + +Create `.vscode/extensions.json`: + +```json +{ + "recommendations": [ + "rebornix.ruby", + "wingrunr21.vscode-ruby", + "bradlc.vscode-tailwindcss", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "ms-vscode.vscode-typescript-next", + "shopify.ruby-lsp" + ] +} +``` + +### RubyMine Setup + +1. **Open Project**: File → Open → Select chatwoot directory +2. **Configure Ruby SDK**: File → Project Structure → SDKs → Add Ruby SDK +3. **Database Connection**: Database tool window → Add PostgreSQL connection +4. **Code Style**: File → Settings → Editor → Code Style → Import scheme + +## Debugging Setup + +### Rails Debugging + +Add to your code for debugging: + +```ruby +# Using Pry (recommended) +binding.pry + +# Using built-in debugger +debugger + +# Using byebug +byebug +``` + +### JavaScript Debugging + +```javascript +// Browser debugging +console.log('Debug info:', variable); +debugger; + +// Node.js debugging +console.log('Debug info:', variable); +``` + +### Database Debugging + +```bash +# Rails console +bundle exec rails console + +# Database console +bundle exec rails dbconsole + +# Check queries in development log +tail -f log/development.log | grep -E "(SELECT|INSERT|UPDATE|DELETE)" +``` + +## Performance Optimization + +### Development Performance + +```bash +# Use Spring for faster Rails commands +bundle exec spring binstub --all + +# Precompile assets for faster loading +bundle exec rails assets:precompile + +# Use parallel testing +bundle exec rspec --parallel + +# Monitor memory usage +ps aux | grep -E "(ruby|node)" | head -10 +``` + +### Database Performance + +```ruby +# Add to config/environments/development.rb for query analysis +config.active_record.verbose_query_logs = true + +# Enable query plan logging +config.active_record.dump_schema_after_migration = false +``` + +## Troubleshooting Setup Issues + +### Common Setup Problems + + +**Error**: `An error occurred while installing pg` + +**Solution**: +```bash +# macOS +brew install postgresql +bundle config build.pg --with-pg-config=/usr/local/bin/pg_config + +# Ubuntu/Debian +sudo apt-get install libpq-dev +bundle install +``` + + + +**Error**: `could not connect to server: Connection refused` + +**Solution**: +```bash +# Check if PostgreSQL is running +sudo systemctl status postgresql + +# Start PostgreSQL +sudo systemctl start postgresql + +# macOS with Homebrew +brew services start postgresql +``` + + + +**Error**: `Redis::CannotConnectError` + +**Solution**: +```bash +# Check if Redis is running +redis-cli ping + +# Start Redis +sudo systemctl start redis + +# macOS with Homebrew +brew services start redis +``` + + + +**Error**: `Module not found` or compilation errors + +**Solution**: +```bash +# Clear webpack cache +rm -rf tmp/cache/webpacker + +# Reinstall node modules +rm -rf node_modules +pnpm install + +# Restart webpack dev server +pnpm run dev +``` + + +### Verification Commands + +```bash +# Check all services are running +ps aux | grep -E "(rails|sidekiq|webpack|mailhog)" + +# Test database connection +bundle exec rails runner "puts ActiveRecord::Base.connection.execute('SELECT 1').first" + +# Test Redis connection +bundle exec rails runner "puts Redis.new.ping" + +# Check application health +curl http://localhost:3000/api +``` + +## Next Steps + +After successful setup: + +1. **Explore the Codebase**: Familiarize yourself with the project structure +2. **Read Contributing Guidelines**: Review code standards and workflow +3. **Pick Your First Issue**: Look for "good first issue" labels +4. **Join the Community**: Connect with other contributors + +### Useful Development Commands + +```bash +# Generate new migration +bundle exec rails generate migration AddColumnToTable column:type + +# Generate new model +bundle exec rails generate model ModelName attribute:type + +# Generate new controller +bundle exec rails generate controller ControllerName + +# Run specific migration +bundle exec rails db:migrate:up VERSION=20231201000000 + +# Rollback migration +bundle exec rails db:rollback STEP=1 + +# Reset database (careful!) +bundle exec rails db:drop db:create db:migrate db:seed +``` + +## Getting Help + +If you encounter issues during setup: + +- **Check Common Errors**: See [Common Errors](./common-errors) guide +- **Environment Variables**: Review [Environment Variables](./environment-variables) guide +- **GitHub Issues**: Search existing issues or create a new one +- **Discord Community**: Join the Chatwoot Discord server +- **Documentation**: Check the official documentation + +--- + +You're now ready to start developing with Chatwoot! Your development environment should be fully functional and ready for contribution. \ No newline at end of file diff --git a/developer-docs/docs.json b/developer-docs/docs.json index a2ff9d1f6..e7e6c55af 100644 --- a/developer-docs/docs.json +++ b/developer-docs/docs.json @@ -30,11 +30,64 @@ "navigation": { "groups": [ { - "group": "API Reference", + "group": "Getting Started", "pages": [ "introduction" ] }, + { + "group": "Self-Hosted Installation", + "pages": [ + "self-hosted/introduction", + "self-hosted/architecture", + { + "group": "Deployment", + "pages": [ + "self-hosted/deployment/linux-vm", + "self-hosted/deployment/docker", + "self-hosted/deployment/kubernetes", + "self-hosted/deployment/chatwoot-ctl" + ] + }, + { + "group": "Cloud Providers", + "pages": [ + "self-hosted/cloud/aws", + "self-hosted/cloud/azure", + "self-hosted/cloud/digitalocean", + "self-hosted/cloud/gcp", + "self-hosted/cloud/heroku" + ] + }, + { + "group": "Configuration", + "pages": [ + "self-hosted/configuration/environment-variables" + ] + } + ] + }, + { + "group": "Contributing Guide", + "pages": [ + "contributing/introduction", + { + "group": "Project Setup", + "pages": [ + "contributing/project-setup/setup-guide", + "contributing/project-setup/environment-variables", + "contributing/project-setup/common-errors" + ] + }, + "contributing/testing", + "contributing/guidelines", + "contributing/code-of-conduct" + ] + }, + { + "group": "API Reference", + "pages": [] + }, { "group": "Application API", "description": "APIs for managing application aspects of Chatwoot", diff --git a/developer-docs/self-hosted/architecture.mdx b/developer-docs/self-hosted/architecture.mdx new file mode 100644 index 000000000..98c3b0f8c --- /dev/null +++ b/developer-docs/self-hosted/architecture.mdx @@ -0,0 +1,342 @@ +--- +title: Chatwoot Architecture +description: Understanding Chatwoot's system architecture, components, and how they work together. +sidebarTitle: Architecture +--- + +Understanding Chatwoot's architecture is crucial for successful deployment, scaling, and maintenance. This guide explains the core components and how they interact. + +## High-Level Architecture + +Chatwoot follows a modern, scalable web application architecture with clear separation of concerns: + +```mermaid +graph TB + subgraph "Client Layer" + A[Web Dashboard] + B[Mobile Apps] + C[Website Widget] + D[API Clients] + end + + subgraph "Load Balancer" + E[Nginx/ALB] + end + + subgraph "Application Layer" + F[Rails Web Server] + G[Sidekiq Workers] + H[WebSocket Server] + end + + subgraph "Data Layer" + I[PostgreSQL] + J[Redis] + K[File Storage] + end + + subgraph "External Services" + L[SMTP Server] + M[Third-party APIs] + N[CDN] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + E --> H + F --> G + F --> I + F --> J + G --> I + G --> J + F --> K + F --> L + F --> M + K --> N +``` + +## Core Components + +### 1. Web Application (Rails) + +The main application server built with Ruby on Rails handles: + +- **HTTP API endpoints** for all client interactions +- **Authentication and authorization** for users and agents +- **Business logic** for conversations, contacts, and workflows +- **Real-time features** via ActionCable WebSockets +- **File uploads and processing** + +**Key characteristics:** +- Stateless design for horizontal scaling +- RESTful API architecture +- WebSocket support for real-time updates +- Multi-tenant architecture support + +### 2. Background Workers (Sidekiq) + +Sidekiq handles asynchronous processing: + +- **Email notifications** and delivery +- **Webhook processing** for integrations +- **File processing** and optimization +- **Report generation** and analytics +- **Third-party API calls** (Facebook, WhatsApp, etc.) + +**Key characteristics:** +- Redis-backed job queue +- Retry mechanisms for failed jobs +- Horizontal scaling support +- Job prioritization and scheduling + +### 3. Database (PostgreSQL) + +PostgreSQL stores all application data: + +- **User accounts and authentication** +- **Conversations and messages** +- **Contact information and profiles** +- **Configuration and settings** +- **Analytics and reporting data** + +**Key characteristics:** +- ACID compliance for data integrity +- JSON support for flexible schemas +- Full-text search capabilities +- Horizontal scaling with read replicas + +### 4. Cache and Session Store (Redis) + +Redis provides high-performance caching and session management: + +- **Session storage** for user authentication +- **Cache layer** for frequently accessed data +- **Job queue** for background processing +- **Real-time data** for WebSocket connections +- **Rate limiting** and throttling + +**Key characteristics:** +- In-memory performance +- Persistence options available +- Pub/Sub for real-time features +- Clustering support for high availability + +### 5. File Storage + +Chatwoot supports multiple storage backends: + +- **Local filesystem** (development/small deployments) +- **AWS S3** (recommended for production) +- **Google Cloud Storage** +- **Azure Blob Storage** +- **MinIO** (self-hosted S3-compatible) + +**Stored content:** +- User avatars and profile images +- Message attachments and files +- Email templates and assets +- Exported reports and backups + +### 6. Reverse Proxy (Nginx) + +Nginx serves as the front-end proxy: + +- **SSL termination** and certificate management +- **Static file serving** for assets +- **Load balancing** across application instances +- **Request routing** and filtering +- **Compression** and caching headers + +## Data Flow + +### 1. Incoming Messages + +```mermaid +sequenceDiagram + participant C as Customer + participant W as Widget/Channel + participant N as Nginx + participant R as Rails App + participant D as Database + participant Q as Redis Queue + participant S as Sidekiq + participant A as Agent Dashboard + + C->>W: Sends message + W->>N: HTTP/WebSocket request + N->>R: Forward request + R->>D: Store message + R->>Q: Queue notification job + R->>A: Real-time update (WebSocket) + Q->>S: Process notification + S->>D: Update delivery status +``` + +### 2. Agent Responses + +```mermaid +sequenceDiagram + participant A as Agent + participant D as Dashboard + participant R as Rails App + participant DB as Database + participant Q as Redis Queue + participant S as Sidekiq + participant C as Customer + + A->>D: Types response + D->>R: Send message API + R->>DB: Store message + R->>Q: Queue delivery job + R->>D: Real-time update + Q->>S: Process delivery + S->>C: Deliver via channel + S->>DB: Update status +``` + +## Scaling Considerations + +### Horizontal Scaling + +Chatwoot is designed for horizontal scaling: + +**Web Servers:** +- Stateless design allows multiple instances +- Load balancer distributes traffic +- Session data stored in Redis + +**Background Workers:** +- Multiple Sidekiq processes can run +- Jobs distributed across workers +- Queue-based processing prevents overload + +**Database:** +- Read replicas for query scaling +- Connection pooling for efficiency +- Partitioning for large datasets + +### Vertical Scaling + +For smaller deployments, vertical scaling is often sufficient: + +**CPU:** Background processing and real-time features +**Memory:** Caching and session storage +**Storage:** Database and file storage growth +**Network:** WebSocket connections and API traffic + +## Security Architecture + +### Authentication Flow + +```mermaid +graph LR + A[User Login] --> B[Rails Auth] + B --> C[JWT Token] + C --> D[API Requests] + D --> E[Token Validation] + E --> F[Authorized Access] +``` + +### Data Protection + +- **Encryption at rest** for sensitive data +- **TLS encryption** for data in transit +- **Input validation** and sanitization +- **SQL injection** protection via ORM +- **XSS protection** with content security policies + +### Access Control + +- **Role-based permissions** (Admin, Agent, etc.) +- **Account-level isolation** in multi-tenant setup +- **API rate limiting** to prevent abuse +- **Audit logging** for compliance + +## Monitoring and Observability + +### Application Metrics + +- **Response times** and throughput +- **Error rates** and exceptions +- **Background job** processing times +- **WebSocket connection** counts + +### Infrastructure Metrics + +- **CPU and memory** utilization +- **Database performance** and connections +- **Redis memory** usage and hit rates +- **Storage usage** and I/O patterns + +### Logging Strategy + +- **Structured logging** with JSON format +- **Centralized collection** (ELK, Fluentd) +- **Log levels** for different environments +- **Sensitive data** filtering + +## Deployment Patterns + +### Single Server + +Suitable for small teams and development: +- All components on one server +- SQLite or PostgreSQL database +- Local file storage +- Simple backup strategy + +### Multi-Server + +For production environments: +- Separate database server +- Dedicated Redis instance +- Load-balanced web servers +- Shared file storage (S3/NFS) + +### Containerized + +Using Docker and orchestration: +- Container images for each component +- Kubernetes or Docker Swarm +- Service discovery and networking +- Rolling updates and health checks + +### Cloud-Native + +Leveraging cloud services: +- Managed databases (RDS, Cloud SQL) +- Managed Redis (ElastiCache, MemoryStore) +- Object storage (S3, GCS) +- Load balancers and CDN + +## Performance Optimization + +### Database Optimization + +- **Indexing strategy** for common queries +- **Connection pooling** to reduce overhead +- **Query optimization** and monitoring +- **Read replicas** for scaling reads + +### Caching Strategy + +- **Application-level caching** for expensive operations +- **HTTP caching** for static assets +- **Database query caching** with Redis +- **CDN caching** for global distribution + +### Background Processing + +- **Job prioritization** for critical tasks +- **Batch processing** for bulk operations +- **Queue monitoring** and alerting +- **Resource allocation** per job type + +--- + + +Understanding this architecture helps you make informed decisions about deployment, scaling, and maintenance of your Chatwoot instance. + \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/aws.mdx b/developer-docs/self-hosted/cloud/aws.mdx new file mode 100644 index 000000000..eb3cf9298 --- /dev/null +++ b/developer-docs/self-hosted/cloud/aws.mdx @@ -0,0 +1,501 @@ +--- +title: AWS Deployment +description: Deploy Chatwoot on Amazon Web Services with manual installation or marketplace AMI +sidebarTitle: AWS +--- + +# AWS Deployment Guide + +Deploy Chatwoot on Amazon Web Services (AWS) using either manual installation or the AWS Marketplace AMI for a scalable, production-ready setup. + +## Deployment Options + + + + Full control over the deployment with custom architecture + + + Quick deployment using pre-configured AMI + + + +## Manual Installation + +### Architecture Overview + +This guide follows a standard 3-tier architecture on AWS for high availability: + +``` +Internet Gateway + | +Application Load Balancer (Public Subnets) + | +Chatwoot Instances (Private Subnets) + | +RDS PostgreSQL + ElastiCache Redis (Private Subnets) +``` + +### Prerequisites + +- AWS account with appropriate permissions +- Domain name for your Chatwoot installation +- Basic knowledge of AWS services (VPC, EC2, RDS, etc.) + +### Step 1: Network Setup + +#### Create VPC + +1. Navigate to the VPC console in your chosen AWS region +2. Create a new VPC: + - **Name**: `chatwoot-vpc` + - **CIDR block**: `10.0.0.0/16` + - Leave other options as default + +#### Create Subnets + +Create subnets across two availability zones: + +| Name | Type | AZ | CIDR Block | +|------|------|----|-----------| +| chatwoot-public-1 | Public | us-east-1a | 10.0.0.0/24 | +| chatwoot-public-2 | Public | us-east-1b | 10.0.1.0/24 | +| chatwoot-private-1 | Private | us-east-1a | 10.0.2.0/24 | +| chatwoot-private-2 | Private | us-east-1b | 10.0.3.0/24 | + + +Enable "Auto-assign public IPv4 address" for public subnets under Actions > Subnet Settings. + + +#### Internet Gateway + +1. Create Internet Gateway named `chatwoot-igw` +2. Attach it to `chatwoot-vpc` + +#### NAT Gateways + +Create NAT gateways in each public subnet: + +1. **chatwoot-nat-1** in `chatwoot-public-1` +2. **chatwoot-nat-2** in `chatwoot-public-2` + +Allocate Elastic IPs for each NAT gateway. + +#### Route Tables + +**Public Route Table** (`chatwoot-public-rt`): +- Route: `0.0.0.0/0` → `chatwoot-igw` +- Associate with public subnets + +**Private Route Tables**: +- `chatwoot-private-a`: Route `0.0.0.0/0` → `chatwoot-nat-1` +- `chatwoot-private-b`: Route `0.0.0.0/0` → `chatwoot-nat-2` + +### Step 2: Application Load Balancer + +1. Navigate to EC2 > Load Balancers +2. Create Application Load Balancer: + - **Name**: `chatwoot-loadbalancer` + - **Scheme**: Internet-facing + - **IP address type**: IPv4 + - **VPC**: `chatwoot-vpc` + - **Subnets**: Select both public subnets + +#### Security Group for ALB + +Create `chatwoot-loadbalancer-sg` with rules: +- HTTP (80) from `0.0.0.0/0` +- HTTPS (443) from `0.0.0.0/0` +- TCP (3000) from `0.0.0.0/0` (for health checks) + +#### Target Group + +Create `chatwoot-tg` target group: +- **Target type**: Instances +- **Protocol**: HTTP +- **Port**: 3000 +- **Health check path**: `/api` + +### Step 3: Database Setup (RDS) + +#### RDS Security Group + +Create `chatwoot-rds-sg`: +- PostgreSQL (5432) from `chatwoot-loadbalancer-sg` + +#### RDS Subnet Group + +Create `chatwoot-rds-group`: +- **VPC**: `chatwoot-vpc` +- **Subnets**: Both private subnets + +#### Create RDS Instance + +1. Navigate to RDS > Databases +2. Create database: + - **Engine**: PostgreSQL + - **Template**: Production + - **DB instance identifier**: `chatwoot-db` + - **Master username**: `chatwoot` + - **Master password**: Generate secure password + - **DB instance class**: `db.t3.medium` (minimum) + - **Storage**: 100 GB GP2 (minimum) + - **Multi-AZ**: Yes + - **VPC**: `chatwoot-vpc` + - **Subnet group**: `chatwoot-rds-group` + - **Security group**: `chatwoot-rds-sg` + + +Note down the RDS endpoint, username, and password for later configuration. + + +### Step 4: Redis Setup (ElastiCache) + +#### ElastiCache Security Group + +Create `chatwoot-redis-sg`: +- Redis (6379) from `chatwoot-loadbalancer-sg` + +#### ElastiCache Subnet Group + +Create `chatwoot-redis-group`: +- **VPC**: `chatwoot-vpc` +- **Subnets**: Both private subnets + +#### Create Redis Cluster + +1. Navigate to ElastiCache > Redis clusters +2. Create cluster: + - **Name**: `chatwoot-redis` + - **Engine version**: 7.0+ + - **Node type**: `cache.t3.micro` (minimum) + - **Multi-AZ**: Yes + - **Subnet group**: `chatwoot-redis-group` + - **Security group**: `chatwoot-redis-sg` + +### Step 5: Bastion Host + +Create bastion servers for secure access to private instances: + +1. Launch EC2 instance: + - **AMI**: Ubuntu 20.04 LTS + - **Instance type**: `t3.micro` + - **VPC**: `chatwoot-vpc` + - **Subnet**: `chatwoot-public-1` + - **Auto-assign public IP**: Yes + - **Security group**: Create `chatwoot-bastion-sg` (SSH from your IP) + +### Step 6: Chatwoot Application Servers + +#### Launch Chatwoot Instance + +1. Launch EC2 instance: + - **AMI**: Ubuntu 20.04 LTS + - **Instance type**: `c5.xlarge` (minimum for production) + - **VPC**: `chatwoot-vpc` + - **Subnet**: `chatwoot-private-1` + - **Auto-assign public IP**: No + - **Storage**: 60 GB GP2 + - **Security group**: `chatwoot-loadbalancer-sg` + +#### Install Chatwoot + +1. SSH to bastion host, then to Chatwoot instance +2. Switch to root user and download installation script: + +```bash +sudo su - +wget https://get.chatwoot.app/linux/install.sh +chmod +x install.sh +./install.sh --install +``` + +#### Configure Chatwoot + +1. Switch to chatwoot user and edit environment: + +```bash +sudo -i -u chatwoot +cd chatwoot +nano .env +``` + +2. Update database and Redis configuration: + +```bash +# Database +DATABASE_URL="postgresql://chatwoot:password@your-rds-endpoint:5432/chatwoot_production" + +# Redis +REDIS_URL="redis://your-elasticache-endpoint:6379/0" + +# Frontend URL +FRONTEND_URL="https://chatwoot.yourdomain.com" + +# Force SSL +FORCE_SSL=true + +# Email configuration (example with SES) +MAILER_SENDER_EMAIL="noreply@yourdomain.com" +SMTP_ADDRESS="email-smtp.us-east-1.amazonaws.com" +SMTP_PORT=587 +SMTP_USERNAME="your-ses-username" +SMTP_PASSWORD="your-ses-password" +SMTP_AUTHENTICATION="plain" +SMTP_ENABLE_STARTTLS_AUTO=true + +# Storage (S3) +ACTIVE_STORAGE_SERVICE="amazon" +S3_BUCKET_NAME="your-chatwoot-bucket" +AWS_ACCESS_KEY_ID="your-access-key" +AWS_SECRET_ACCESS_KEY="your-secret-key" +AWS_REGION="us-east-1" +``` + +3. Run database preparation: + +```bash +RAILS_ENV=production bundle exec rake db:chatwoot_prepare +``` + +4. Restart services: + +```bash +sudo cwctl --restart +``` + +### Step 7: SSL Certificate (ACM) + +1. Navigate to Certificate Manager +2. Request public certificate for your domain +3. Validate domain ownership +4. Attach certificate to ALB HTTPS listener + +### Step 8: Auto Scaling + +#### Create AMI + +1. Stop the Chatwoot instance +2. Create AMI named `chatwoot-base-ami` +3. Terminate the original instance + +#### Launch Template + +Create launch template with: +- **AMI**: `chatwoot-base-ami` +- **Instance type**: `c5.xlarge` +- **Security group**: `chatwoot-loadbalancer-sg` +- **User data** (optional): + +```bash +#!/bin/bash +sudo cwctl --restart +``` + +#### Auto Scaling Group + +Create ASG with: +- **Launch template**: Use created template +- **VPC**: `chatwoot-vpc` +- **Subnets**: Both private subnets +- **Target group**: `chatwoot-tg` +- **Desired capacity**: 2 +- **Minimum**: 2 +- **Maximum**: 4 + +#### Scaling Policies + +Create scaling policies based on: +- CPU utilization (scale out at 70%, scale in at 30%) +- Memory utilization +- Request count per target + +## AWS Marketplace AMI + +### Quick Deployment + +1. Navigate to AWS Marketplace +2. Search for "Chatwoot" +3. Subscribe to Chatwoot AMI +4. Launch instance with recommended settings: + - **Instance type**: `t3.medium` or larger + - **Storage**: 20 GB minimum + - **Security group**: Allow HTTP, HTTPS, and SSH + +### Post-Launch Configuration + +1. SSH to the instance +2. Complete initial setup: + +```bash +sudo /opt/chatwoot/setup.sh +``` + +3. Configure domain and SSL: + +```bash +sudo /opt/chatwoot/configure-domain.sh yourdomain.com +``` + +## Production Optimizations + +### Performance Tuning + +```bash +# Optimize Rails configuration +export RAILS_MAX_THREADS=20 +export WEB_CONCURRENCY=4 +export SIDEKIQ_CONCURRENCY=25 + +# Database connection pooling +export DATABASE_POOL_SIZE=25 +``` + +### Monitoring Setup + +#### CloudWatch Metrics + +Enable detailed monitoring for: +- EC2 instances +- RDS database +- ElastiCache cluster +- Application Load Balancer + +#### Custom Metrics + +```bash +# Install CloudWatch agent +wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm +sudo rpm -U ./amazon-cloudwatch-agent.rpm + +# Configure custom metrics +sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard +``` + +### Backup Strategy + +#### RDS Automated Backups + +- Enable automated backups with 7-day retention +- Configure backup window during low-traffic hours +- Enable point-in-time recovery + +#### Application Data Backup + +```bash +#!/bin/bash +# Backup script for application data +DATE=$(date +%Y%m%d_%H%M%S) + +# Database backup +pg_dump $DATABASE_URL | gzip > "s3://your-backup-bucket/db/chatwoot_$DATE.sql.gz" + +# File uploads backup (if using local storage) +aws s3 sync /home/chatwoot/chatwoot/storage s3://your-backup-bucket/storage/ +``` + +### Security Hardening + +#### IAM Roles + +Create IAM roles with minimal permissions: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "s3:PutObject", + "s3:DeleteObject" + ], + "Resource": "arn:aws:s3:::your-chatwoot-bucket/*" + }, + { + "Effect": "Allow", + "Action": [ + "ses:SendEmail", + "ses:SendRawEmail" + ], + "Resource": "*" + } + ] +} +``` + +#### Security Groups + +Implement least-privilege access: +- ALB: Only HTTP/HTTPS from internet +- App servers: Only from ALB and bastion +- Database: Only from app servers +- Redis: Only from app servers + +## Cost Optimization + +### Reserved Instances + +Purchase Reserved Instances for: +- RDS database instances +- ElastiCache clusters +- Predictable EC2 workloads + +### Spot Instances + +Use Spot Instances for: +- Development environments +- Non-critical worker processes +- Batch processing tasks + +### Storage Optimization + +- Use GP3 volumes for better price/performance +- Implement S3 lifecycle policies for old backups +- Use S3 Intelligent Tiering for file storage + +## Troubleshooting + +### Common Issues + + +Check: +- Security group rules +- Target group health +- Route table configuration +- DNS resolution + + + +Verify: +- RDS security group allows connections +- Database credentials in .env file +- Network connectivity from app servers + + + +Solutions: +- Increase instance size +- Optimize Sidekiq concurrency +- Enable swap memory +- Monitor for memory leaks + + +### Monitoring Commands + +```bash +# Check application health +curl -I http://localhost:3000/api + +# Monitor system resources +htop +iostat -x 1 +free -h + +# Check service status +sudo systemctl status chatwoot.target +``` + +--- + +This AWS deployment guide provides a comprehensive approach to hosting Chatwoot on AWS infrastructure. Choose the deployment method that best fits your requirements and scale as needed. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/azure.mdx b/developer-docs/self-hosted/cloud/azure.mdx new file mode 100644 index 000000000..c467e28f3 --- /dev/null +++ b/developer-docs/self-hosted/cloud/azure.mdx @@ -0,0 +1,663 @@ +--- +title: Azure Deployment +description: Deploy Chatwoot on Microsoft Azure with various deployment options +sidebarTitle: Azure +--- + +# Azure Deployment Guide + +Deploy Chatwoot on Microsoft Azure using various deployment options including Virtual Machines, Container Instances, or App Service for a scalable, production-ready setup. + +## Deployment Options + + + + Full control with custom VM deployment + + + Serverless container deployment + + + Platform-as-a-Service deployment + + + +## Virtual Machines Deployment + +### Architecture Overview + +``` +Azure Load Balancer + | +Virtual Machines (Availability Set) + | +Azure Database for PostgreSQL + Azure Cache for Redis +``` + +### Prerequisites + +- Azure subscription with appropriate permissions +- Azure CLI installed and configured +- Domain name for your Chatwoot installation + +### Step 1: Resource Group and Network + +#### Create Resource Group + +```bash +# Create resource group +az group create \ + --name chatwoot-rg \ + --location eastus +``` + +#### Create Virtual Network + +```bash +# Create virtual network +az network vnet create \ + --resource-group chatwoot-rg \ + --name chatwoot-vnet \ + --address-prefix 10.0.0.0/16 \ + --subnet-name chatwoot-subnet \ + --subnet-prefix 10.0.1.0/24 +``` + +#### Create Network Security Group + +```bash +# Create NSG +az network nsg create \ + --resource-group chatwoot-rg \ + --name chatwoot-nsg + +# Add rules +az network nsg rule create \ + --resource-group chatwoot-rg \ + --nsg-name chatwoot-nsg \ + --name AllowHTTP \ + --protocol tcp \ + --priority 1000 \ + --destination-port-range 80 + +az network nsg rule create \ + --resource-group chatwoot-rg \ + --nsg-name chatwoot-nsg \ + --name AllowHTTPS \ + --protocol tcp \ + --priority 1001 \ + --destination-port-range 443 + +az network nsg rule create \ + --resource-group chatwoot-rg \ + --nsg-name chatwoot-nsg \ + --name AllowSSH \ + --protocol tcp \ + --priority 1002 \ + --destination-port-range 22 \ + --source-address-prefix "YOUR_IP_ADDRESS" +``` + +### Step 2: Database Setup + +#### Create PostgreSQL Server + +```bash +# Create PostgreSQL server +az postgres server create \ + --resource-group chatwoot-rg \ + --name chatwoot-postgres \ + --location eastus \ + --admin-user chatwoot \ + --admin-password "YourSecurePassword123!" \ + --sku-name GP_Gen5_2 \ + --version 13 + +# Create database +az postgres db create \ + --resource-group chatwoot-rg \ + --server-name chatwoot-postgres \ + --name chatwoot_production + +# Configure firewall +az postgres server firewall-rule create \ + --resource-group chatwoot-rg \ + --server chatwoot-postgres \ + --name AllowAzureServices \ + --start-ip-address 0.0.0.0 \ + --end-ip-address 0.0.0.0 +``` + +#### Create Redis Cache + +```bash +# Create Redis cache +az redis create \ + --resource-group chatwoot-rg \ + --name chatwoot-redis \ + --location eastus \ + --sku Basic \ + --vm-size c0 +``` + +### Step 3: Storage Account + +```bash +# Create storage account +az storage account create \ + --resource-group chatwoot-rg \ + --name chatwootstorage \ + --location eastus \ + --sku Standard_LRS + +# Create container for file uploads +az storage container create \ + --account-name chatwootstorage \ + --name uploads \ + --public-access blob +``` + +### Step 4: Virtual Machine + +#### Create Availability Set + +```bash +# Create availability set +az vm availability-set create \ + --resource-group chatwoot-rg \ + --name chatwoot-avset \ + --platform-fault-domain-count 2 \ + --platform-update-domain-count 2 +``` + +#### Create Virtual Machine + +```bash +# Create VM +az vm create \ + --resource-group chatwoot-rg \ + --name chatwoot-vm \ + --image UbuntuLTS \ + --size Standard_D2s_v3 \ + --availability-set chatwoot-avset \ + --vnet-name chatwoot-vnet \ + --subnet chatwoot-subnet \ + --nsg chatwoot-nsg \ + --admin-username azureuser \ + --generate-ssh-keys \ + --custom-data cloud-init.txt +``` + +#### Cloud-Init Configuration + +Create `cloud-init.txt`: + +```yaml +#cloud-config +package_upgrade: true +packages: + - curl + - wget + - git + +runcmd: + - wget https://get.chatwoot.app/linux/install.sh + - chmod +x install.sh + - ./install.sh --install +``` + +### Step 5: Load Balancer + +```bash +# Create public IP +az network public-ip create \ + --resource-group chatwoot-rg \ + --name chatwoot-lb-ip \ + --sku Standard + +# Create load balancer +az network lb create \ + --resource-group chatwoot-rg \ + --name chatwoot-lb \ + --public-ip-address chatwoot-lb-ip \ + --frontend-ip-name chatwoot-frontend \ + --backend-pool-name chatwoot-backend + +# Create health probe +az network lb probe create \ + --resource-group chatwoot-rg \ + --lb-name chatwoot-lb \ + --name chatwoot-health \ + --protocol http \ + --port 3000 \ + --path /api + +# Create load balancing rule +az network lb rule create \ + --resource-group chatwoot-rg \ + --lb-name chatwoot-lb \ + --name chatwoot-rule \ + --protocol tcp \ + --frontend-port 80 \ + --backend-port 3000 \ + --frontend-ip-name chatwoot-frontend \ + --backend-pool-name chatwoot-backend \ + --probe-name chatwoot-health +``` + +### Step 6: Configuration + +SSH to the VM and configure Chatwoot: + +```bash +# SSH to VM +ssh azureuser@ + +# Switch to chatwoot user +sudo -i -u chatwoot +cd chatwoot + +# Edit environment variables +nano .env +``` + +Update `.env` with Azure services: + +```bash +# Database +DATABASE_URL="postgresql://chatwoot:YourSecurePassword123!@chatwoot-postgres.postgres.database.azure.com:5432/chatwoot_production" + +# Redis +REDIS_URL="redis://:PRIMARY_ACCESS_KEY@chatwoot-redis.redis.cache.windows.net:6380/0?ssl=true" + +# Storage (Azure Blob) +ACTIVE_STORAGE_SERVICE="azure" +AZURE_STORAGE_ACCOUNT_NAME="chatwootstorage" +AZURE_STORAGE_ACCESS_KEY="your-access-key" +AZURE_STORAGE_CONTAINER="uploads" + +# Frontend URL +FRONTEND_URL="https://chatwoot.yourdomain.com" +FORCE_SSL=true +``` + +## Container Instances Deployment + +### Docker Compose for Azure + +Create `docker-compose.azure.yml`: + +```yaml +version: '3.8' + +services: + chatwoot-web: + image: chatwoot/chatwoot:latest + environment: + - RAILS_ENV=production + - DATABASE_URL=postgresql://chatwoot:password@postgres:5432/chatwoot_production + - REDIS_URL=redis://redis:6379/0 + - FRONTEND_URL=https://chatwoot.yourdomain.com + - FORCE_SSL=true + ports: + - "3000:3000" + depends_on: + - postgres + - redis + + chatwoot-worker: + image: chatwoot/chatwoot:latest + environment: + - RAILS_ENV=production + - DATABASE_URL=postgresql://chatwoot:password@postgres:5432/chatwoot_production + - REDIS_URL=redis://redis:6379/0 + command: bundle exec sidekiq -C config/sidekiq.yml + depends_on: + - postgres + - redis + + postgres: + image: postgres:13 + environment: + - POSTGRES_DB=chatwoot_production + - POSTGRES_USER=chatwoot + - POSTGRES_PASSWORD=password + volumes: + - postgres_data:/var/lib/postgresql/data + + redis: + image: redis:7-alpine + volumes: + - redis_data:/data + +volumes: + postgres_data: + redis_data: +``` + +### Deploy with Azure Container Instances + +```bash +# Create container group +az container create \ + --resource-group chatwoot-rg \ + --file docker-compose.azure.yml \ + --dns-name-label chatwoot-app \ + --ports 3000 +``` + +## App Service Deployment + +### Create App Service Plan + +```bash +# Create App Service plan +az appservice plan create \ + --resource-group chatwoot-rg \ + --name chatwoot-plan \ + --sku P1V2 \ + --is-linux + +# Create web app +az webapp create \ + --resource-group chatwoot-rg \ + --plan chatwoot-plan \ + --name chatwoot-app \ + --deployment-container-image-name chatwoot/chatwoot:latest +``` + +### Configure App Settings + +```bash +# Set environment variables +az webapp config appsettings set \ + --resource-group chatwoot-rg \ + --name chatwoot-app \ + --settings \ + RAILS_ENV=production \ + DATABASE_URL="postgresql://chatwoot:password@chatwoot-postgres.postgres.database.azure.com:5432/chatwoot_production" \ + REDIS_URL="redis://:key@chatwoot-redis.redis.cache.windows.net:6380/0?ssl=true" \ + FRONTEND_URL="https://chatwoot-app.azurewebsites.net" \ + FORCE_SSL=true +``` + +## Monitoring and Logging + +### Application Insights + +```bash +# Create Application Insights +az monitor app-insights component create \ + --resource-group chatwoot-rg \ + --app chatwoot-insights \ + --location eastus \ + --kind web + +# Get instrumentation key +az monitor app-insights component show \ + --resource-group chatwoot-rg \ + --app chatwoot-insights \ + --query instrumentationKey +``` + +### Log Analytics Workspace + +```bash +# Create Log Analytics workspace +az monitor log-analytics workspace create \ + --resource-group chatwoot-rg \ + --workspace-name chatwoot-logs \ + --location eastus +``` + +## Security Configuration + +### Key Vault for Secrets + +```bash +# Create Key Vault +az keyvault create \ + --resource-group chatwoot-rg \ + --name chatwoot-vault \ + --location eastus + +# Store secrets +az keyvault secret set \ + --vault-name chatwoot-vault \ + --name database-password \ + --value "YourSecurePassword123!" + +az keyvault secret set \ + --vault-name chatwoot-vault \ + --name redis-key \ + --value "your-redis-access-key" +``` + +### Managed Identity + +```bash +# Enable managed identity for VM +az vm identity assign \ + --resource-group chatwoot-rg \ + --name chatwoot-vm + +# Grant access to Key Vault +az keyvault set-policy \ + --name chatwoot-vault \ + --object-id \ + --secret-permissions get list +``` + +## Backup and Disaster Recovery + +### Database Backup + +```bash +# Enable automated backup for PostgreSQL +az postgres server configuration set \ + --resource-group chatwoot-rg \ + --server-name chatwoot-postgres \ + --name backup_retention_days \ + --value 7 + +# Create manual backup +az postgres server backup create \ + --resource-group chatwoot-rg \ + --server-name chatwoot-postgres \ + --backup-name manual-backup-$(date +%Y%m%d) +``` + +### VM Backup + +```bash +# Create Recovery Services vault +az backup vault create \ + --resource-group chatwoot-rg \ + --name chatwoot-vault \ + --location eastus + +# Enable backup for VM +az backup protection enable-for-vm \ + --resource-group chatwoot-rg \ + --vault-name chatwoot-vault \ + --vm chatwoot-vm \ + --policy-name DefaultPolicy +``` + +## Scaling and Performance + +### VM Scale Sets + +```bash +# Create VM scale set +az vmss create \ + --resource-group chatwoot-rg \ + --name chatwoot-vmss \ + --image UbuntuLTS \ + --vm-sku Standard_D2s_v3 \ + --instance-count 2 \ + --vnet-name chatwoot-vnet \ + --subnet chatwoot-subnet \ + --lb chatwoot-lb \ + --backend-pool-name chatwoot-backend \ + --custom-data cloud-init.txt + +# Configure autoscaling +az monitor autoscale create \ + --resource-group chatwoot-rg \ + --resource chatwoot-vmss \ + --resource-type Microsoft.Compute/virtualMachineScaleSets \ + --name chatwoot-autoscale \ + --min-count 2 \ + --max-count 5 \ + --count 2 + +# Add scale-out rule +az monitor autoscale rule create \ + --resource-group chatwoot-rg \ + --autoscale-name chatwoot-autoscale \ + --condition "Percentage CPU > 70 avg 5m" \ + --scale out 1 + +# Add scale-in rule +az monitor autoscale rule create \ + --resource-group chatwoot-rg \ + --autoscale-name chatwoot-autoscale \ + --condition "Percentage CPU < 30 avg 5m" \ + --scale in 1 +``` + +## SSL Certificate + +### App Service Certificate + +```bash +# Create App Service certificate +az webapp config ssl upload \ + --resource-group chatwoot-rg \ + --name chatwoot-app \ + --certificate-file certificate.pfx \ + --certificate-password "certificate-password" + +# Bind certificate to domain +az webapp config ssl bind \ + --resource-group chatwoot-rg \ + --name chatwoot-app \ + --certificate-thumbprint \ + --ssl-type SNI +``` + +### Let's Encrypt with VM + +```bash +# Install Certbot on VM +sudo apt update +sudo apt install certbot python3-certbot-nginx + +# Obtain certificate +sudo certbot --nginx -d chatwoot.yourdomain.com + +# Auto-renewal +sudo crontab -e +# Add: 0 12 * * * /usr/bin/certbot renew --quiet +``` + +## Cost Optimization + +### Reserved Instances + +```bash +# Purchase reserved capacity for VMs +az reservations reservation-order purchase \ + --reservation-order-id \ + --sku Standard_D2s_v3 \ + --location eastus \ + --quantity 2 \ + --term P1Y +``` + +### Azure Advisor + +```bash +# Get cost recommendations +az advisor recommendation list \ + --category Cost \ + --resource-group chatwoot-rg +``` + +## Troubleshooting + +### Common Issues + + +Check: +- PostgreSQL firewall rules +- Network security group rules +- Connection string format +- SSL requirements for Azure Database + + + +Verify: +- Redis access keys +- SSL configuration (required for Azure Cache) +- Network connectivity +- Port 6380 (SSL) vs 6379 (non-SSL) + + + +Solutions: +- Verify storage account access keys +- Check container permissions +- Ensure CORS settings if needed +- Validate Azure Storage configuration + + +### Diagnostic Commands + +```bash +# Check VM status +az vm get-instance-view \ + --resource-group chatwoot-rg \ + --name chatwoot-vm + +# View application logs +az webapp log tail \ + --resource-group chatwoot-rg \ + --name chatwoot-app + +# Check database connectivity +az postgres server show \ + --resource-group chatwoot-rg \ + --name chatwoot-postgres +``` + +## Best Practices + +### Security +- Use Azure Key Vault for secrets management +- Enable managed identities for Azure resources +- Implement network security groups with least privilege +- Enable Azure Security Center recommendations + +### Performance +- Use Azure CDN for static assets +- Implement Redis caching strategies +- Monitor with Application Insights +- Use proximity placement groups for low latency + +### Cost Management +- Use Azure Cost Management for monitoring +- Implement auto-shutdown for development VMs +- Consider spot instances for non-critical workloads +- Use reserved instances for predictable workloads + +### Backup and Recovery +- Enable automated backups for all data services +- Test backup restoration procedures regularly +- Implement geo-redundant storage for critical data +- Document disaster recovery procedures + +--- + +This Azure deployment guide provides multiple options for hosting Chatwoot on Microsoft Azure. Choose the deployment method that best fits your requirements, budget, and operational preferences. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/digitalocean.mdx b/developer-docs/self-hosted/cloud/digitalocean.mdx new file mode 100644 index 000000000..279edca3c --- /dev/null +++ b/developer-docs/self-hosted/cloud/digitalocean.mdx @@ -0,0 +1,670 @@ +--- +title: DigitalOcean Deployment +description: Deploy Chatwoot on DigitalOcean with Droplets, App Platform, or Kubernetes +sidebarTitle: DigitalOcean +--- + +# DigitalOcean Deployment Guide + +Deploy Chatwoot on DigitalOcean using Droplets, App Platform, or DigitalOcean Kubernetes for a scalable, cost-effective solution. + +## Deployment Options + + + + Traditional VPS deployment with full control + + + Platform-as-a-Service deployment + + + Container orchestration with DOKS + + + +## Droplets Deployment + +### Quick Start with One-Click Install + +DigitalOcean offers a one-click Chatwoot installation from the Marketplace: + +1. **Navigate to DigitalOcean Marketplace** +2. **Search for "Chatwoot"** +3. **Click "Create Chatwoot Droplet"** +4. **Configure your Droplet:** + - **Plan**: Basic ($12/month minimum recommended) + - **CPU options**: Regular Intel + - **Region**: Choose closest to your users + - **Authentication**: SSH keys (recommended) + - **Hostname**: chatwoot-production + +5. **Access your installation:** + ```bash + ssh root@your-droplet-ip + ``` + +### Manual Installation + +#### Create Droplet + +```bash +# Using doctl CLI +doctl compute droplet create chatwoot-prod \ + --image ubuntu-20-04-x64 \ + --size s-2vcpu-4gb \ + --region nyc3 \ + --ssh-keys your-ssh-key-id \ + --enable-monitoring \ + --enable-ipv6 +``` + +#### Install Chatwoot + +```bash +# SSH to droplet +ssh root@your-droplet-ip + +# Download and run installation script +wget https://get.chatwoot.app/linux/install.sh +chmod +x install.sh +./install.sh --install +``` + +### Database Setup + +#### Managed PostgreSQL + +```bash +# Create managed database cluster +doctl databases create chatwoot-db \ + --engine postgres \ + --version 13 \ + --size db-s-1vcpu-1gb \ + --region nyc3 \ + --num-nodes 1 + +# Create database +doctl databases db create chatwoot-db-id chatwoot_production + +# Create user +doctl databases user create chatwoot-db-id chatwoot +``` + +#### Managed Redis + +```bash +# Create managed Redis cluster +doctl databases create chatwoot-redis \ + --engine redis \ + --version 6 \ + --size db-s-1vcpu-1gb \ + --region nyc3 \ + --num-nodes 1 +``` + +### Configuration + +Update Chatwoot configuration to use managed services: + +```bash +# Switch to chatwoot user +sudo -i -u chatwoot +cd chatwoot + +# Edit environment file +nano .env +``` + +Add managed database configuration: + +```bash +# Database (from DigitalOcean dashboard) +DATABASE_URL="postgresql://chatwoot:password@chatwoot-db-do-user-123456-0.b.db.ondigitalocean.com:25060/chatwoot_production?sslmode=require" + +# Redis (from DigitalOcean dashboard) +REDIS_URL="rediss://default:password@chatwoot-redis-do-user-123456-0.b.db.ondigitalocean.com:25061" + +# Frontend URL +FRONTEND_URL="https://chatwoot.yourdomain.com" +FORCE_SSL=true + +# Storage (DigitalOcean Spaces) +ACTIVE_STORAGE_SERVICE="amazon" +S3_BUCKET_NAME="your-chatwoot-space" +AWS_ACCESS_KEY_ID="your-spaces-key" +AWS_SECRET_ACCESS_KEY="your-spaces-secret" +AWS_REGION="nyc3" +S3_ENDPOINT="https://nyc3.digitaloceanspaces.com" +``` + +### Load Balancer Setup + +```bash +# Create load balancer +doctl compute load-balancer create \ + --name chatwoot-lb \ + --forwarding-rules entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:your-cert-id \ + --forwarding-rules entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000 \ + --health-check protocol:http,port:3000,path:/api,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:3,unhealthy_threshold:3 \ + --region nyc3 \ + --droplet-ids droplet-id-1,droplet-id-2 +``` + +## App Platform Deployment + +### App Spec Configuration + +Create `app.yaml`: + +```yaml +name: chatwoot-app +services: +- name: web + source_dir: / + github: + repo: your-username/chatwoot-fork + branch: main + run_command: bundle exec rails server -b 0.0.0.0 -p $PORT + environment_slug: ruby + instance_count: 1 + instance_size_slug: basic-xxs + envs: + - key: RAILS_ENV + value: production + - key: DATABASE_URL + value: ${chatwoot-db.DATABASE_URL} + - key: REDIS_URL + value: ${chatwoot-redis.REDIS_URL} + - key: FRONTEND_URL + value: ${APP_URL} + - key: FORCE_SSL + value: "true" + http_port: 8080 + +- name: worker + source_dir: / + github: + repo: your-username/chatwoot-fork + branch: main + run_command: bundle exec sidekiq -C config/sidekiq.yml + environment_slug: ruby + instance_count: 1 + instance_size_slug: basic-xxs + envs: + - key: RAILS_ENV + value: production + - key: DATABASE_URL + value: ${chatwoot-db.DATABASE_URL} + - key: REDIS_URL + value: ${chatwoot-redis.REDIS_URL} + +databases: +- name: chatwoot-db + engine: PG + version: "13" + size: db-s-dev-database + +- name: chatwoot-redis + engine: REDIS + version: "6" + size: db-s-dev-database + +static_sites: +- name: assets + source_dir: /public + github: + repo: your-username/chatwoot-fork + branch: main + build_command: bundle exec rails assets:precompile +``` + +### Deploy with App Platform + +```bash +# Deploy using doctl +doctl apps create --spec app.yaml + +# Or deploy via DigitalOcean Control Panel +# 1. Go to App Platform +# 2. Create App +# 3. Connect your GitHub repository +# 4. Configure build and run commands +# 5. Add environment variables +# 6. Deploy +``` + +## Kubernetes Deployment + +### Create DOKS Cluster + +```bash +# Create Kubernetes cluster +doctl kubernetes cluster create chatwoot-k8s \ + --region nyc3 \ + --version 1.24.4-do.0 \ + --count 3 \ + --size s-2vcpu-4gb \ + --auto-upgrade=true \ + --maintenance-window="saturday=06:00" + +# Get kubeconfig +doctl kubernetes cluster kubeconfig save chatwoot-k8s +``` + +### Helm Deployment + +```bash +# Add Chatwoot Helm repository +helm repo add chatwoot https://chatwoot.github.io/charts +helm repo update + +# Create namespace +kubectl create namespace chatwoot + +# Install with DigitalOcean-specific values +helm install chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --set ingress.enabled=true \ + --set ingress.className=nginx \ + --set ingress.hosts[0].host=chatwoot.yourdomain.com \ + --set postgresql.enabled=false \ + --set redis.enabled=false \ + --set env.DATABASE_URL="postgresql://..." \ + --set env.REDIS_URL="redis://..." +``` + +### DigitalOcean-Specific Values + +Create `do-values.yaml`: + +```yaml +# DigitalOcean Kubernetes values +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + kubernetes.digitalocean.com/load-balancer-id: "your-lb-id" + hosts: + - host: chatwoot.yourdomain.com + paths: + - path: / + pathType: Prefix + +# Use DigitalOcean managed databases +postgresql: + enabled: false + +redis: + enabled: false + +# DigitalOcean Spaces for storage +env: + ACTIVE_STORAGE_SERVICE: "amazon" + S3_BUCKET_NAME: "your-chatwoot-space" + AWS_ACCESS_KEY_ID: "your-spaces-key" + AWS_SECRET_ACCESS_KEY: "your-spaces-secret" + AWS_REGION: "nyc3" + S3_ENDPOINT: "https://nyc3.digitaloceanspaces.com" + +# Resource limits for DigitalOcean +resources: + limits: + cpu: 1000m + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + +# Storage class for DigitalOcean Block Storage +persistence: + enabled: true + storageClass: "do-block-storage" + size: 20Gi +``` + +## Storage Configuration + +### DigitalOcean Spaces + +```bash +# Create Spaces bucket +doctl compute cdn create \ + --origin nyc3.digitaloceanspaces.com/your-chatwoot-space \ + --ttl 3600 + +# Configure CORS for Spaces +# Create cors.json: +{ + "CORSRules": [ + { + "AllowedOrigins": ["https://chatwoot.yourdomain.com"], + "AllowedMethods": ["GET", "PUT", "POST", "DELETE"], + "AllowedHeaders": ["*"], + "MaxAgeSeconds": 3000 + } + ] +} + +# Apply CORS configuration +s3cmd setcors cors.json s3://your-chatwoot-space +``` + +### Block Storage for Droplets + +```bash +# Create and attach block storage +doctl compute volume create chatwoot-storage \ + --size 100GiB \ + --region nyc3 + +doctl compute volume-action attach chatwoot-storage \ + --droplet-id your-droplet-id + +# Mount the volume +sudo mkdir /mnt/chatwoot-storage +sudo mount -o discard,defaults /dev/disk/by-id/scsi-0DO_Volume_chatwoot-storage /mnt/chatwoot-storage +echo '/dev/disk/by-id/scsi-0DO_Volume_chatwoot-storage /mnt/chatwoot-storage ext4 defaults,nofail,discard 0 0' | sudo tee -a /etc/fstab +``` + +## SSL Certificate + +### Let's Encrypt with Certbot + +```bash +# Install Certbot +sudo apt update +sudo apt install certbot python3-certbot-nginx + +# Obtain certificate +sudo certbot --nginx -d chatwoot.yourdomain.com + +# Auto-renewal +sudo crontab -e +# Add: 0 12 * * * /usr/bin/certbot renew --quiet +``` + +### DigitalOcean Load Balancer SSL + +```bash +# Upload certificate to DigitalOcean +doctl compute certificate create \ + --name chatwoot-cert \ + --private-key-path private.key \ + --leaf-certificate-path certificate.crt \ + --certificate-chain-path ca_bundle.crt + +# Update load balancer with certificate +doctl compute load-balancer update your-lb-id \ + --forwarding-rules entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:your-cert-id +``` + +## Monitoring and Alerting + +### DigitalOcean Monitoring + +```bash +# Enable monitoring for droplets +doctl compute droplet create chatwoot-prod \ + --enable-monitoring \ + --enable-ipv6 + +# Create alert policies +doctl monitoring alert-policy create \ + --type v1/insights/droplet/cpu \ + --description "High CPU usage" \ + --compare GreaterThan \ + --value 80 \ + --window 5m \ + --entities droplet:your-droplet-id +``` + +### Custom Metrics with Prometheus + +```yaml +# prometheus-config.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + namespace: monitoring +data: + prometheus.yml: | + global: + scrape_interval: 15s + scrape_configs: + - job_name: 'chatwoot' + static_configs: + - targets: ['chatwoot-service:3000'] + metrics_path: /metrics +``` + +## Backup Strategy + +### Database Backups + +```bash +# Automated backups for managed databases are enabled by default +# Manual backup +doctl databases backups list chatwoot-db-id + +# Restore from backup +doctl databases backups restore chatwoot-db-id backup-id +``` + +### Droplet Snapshots + +```bash +# Create snapshot +doctl compute droplet-action snapshot your-droplet-id \ + --snapshot-name "chatwoot-backup-$(date +%Y%m%d)" + +# Schedule automated snapshots +doctl compute droplet-action enable-backups your-droplet-id +``` + +### Application Data Backup + +```bash +#!/bin/bash +# backup-script.sh +DATE=$(date +%Y%m%d_%H%M%S) + +# Database backup (if using managed database) +pg_dump $DATABASE_URL | gzip > "/tmp/chatwoot_db_$DATE.sql.gz" + +# Upload to Spaces +s3cmd put "/tmp/chatwoot_db_$DATE.sql.gz" s3://your-backup-space/db/ + +# File uploads backup +s3cmd sync s3://your-chatwoot-space/ s3://your-backup-space/files/ + +# Cleanup local backup +rm "/tmp/chatwoot_db_$DATE.sql.gz" +``` + +## Scaling and Performance + +### Horizontal Scaling with Load Balancer + +```bash +# Create additional droplets +for i in {2..3}; do + doctl compute droplet create chatwoot-prod-$i \ + --image ubuntu-20-04-x64 \ + --size s-2vcpu-4gb \ + --region nyc3 \ + --ssh-keys your-ssh-key-id \ + --user-data-file cloud-init.yaml +done + +# Add droplets to load balancer +doctl compute load-balancer add-droplets your-lb-id \ + --droplet-ids droplet-id-2,droplet-id-3 +``` + +### Vertical Scaling + +```bash +# Resize droplet +doctl compute droplet-action resize your-droplet-id \ + --size s-4vcpu-8gb \ + --resize-disk +``` + +### Auto-scaling with Kubernetes + +```yaml +# hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: chatwoot-hpa + namespace: chatwoot +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: chatwoot + minReplicas: 2 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +``` + +## Cost Optimization + +### Reserved Instances + +```bash +# DigitalOcean doesn't offer reserved instances +# But you can optimize costs by: + +# 1. Right-sizing droplets +doctl compute size list + +# 2. Using appropriate database sizes +doctl databases options sizes + +# 3. Implementing auto-scaling to scale down during low usage +``` + +### Cost Monitoring + +```bash +# Check current usage and costs +doctl account get + +# Monitor resource usage +doctl monitoring metrics bandwidth droplet:your-droplet-id +doctl monitoring metrics cpu droplet:your-droplet-id +doctl monitoring metrics memory droplet:your-droplet-id +``` + +## Troubleshooting + +### Common Issues + + +Check: +- Firewall rules (ufw status) +- DigitalOcean Cloud Firewalls +- SSH key configuration +- Network connectivity + + + +Verify: +- Database cluster status +- Connection string format +- SSL requirements for managed databases +- Firewall rules for database access + + + +Solutions: +- Verify health check path (/api) +- Check application startup time +- Ensure proper port configuration +- Review application logs + + +### Diagnostic Commands + +```bash +# Check droplet status +doctl compute droplet get your-droplet-id + +# View load balancer status +doctl compute load-balancer get your-lb-id + +# Check database status +doctl databases get chatwoot-db-id + +# Monitor application logs +sudo journalctl -u chatwoot-web.1.service -f +sudo journalctl -u chatwoot-worker.1.service -f +``` + +### Performance Monitoring + +```bash +# System resources +htop +iostat -x 1 +free -h +df -h + +# Network monitoring +iftop +netstat -tulpn + +# Application metrics +curl http://localhost:3000/api +curl http://localhost:3000/metrics +``` + +## Best Practices + +### Security +- Enable DigitalOcean Cloud Firewalls +- Use SSH keys instead of passwords +- Enable automatic security updates +- Implement fail2ban for SSH protection +- Use managed databases for better security + +### Performance +- Use DigitalOcean Spaces CDN for static assets +- Implement Redis caching +- Monitor with DigitalOcean Monitoring +- Use SSD-backed droplets +- Place resources in the same region + +### Reliability +- Use multiple availability zones +- Implement automated backups +- Set up monitoring and alerting +- Use load balancers for high availability +- Test disaster recovery procedures + +### Cost Management +- Right-size your resources +- Use managed services to reduce operational overhead +- Implement monitoring to track usage +- Clean up unused resources regularly +- Consider using Kubernetes for better resource utilization + +--- + +This DigitalOcean deployment guide provides multiple options for hosting Chatwoot on DigitalOcean's infrastructure. Choose the deployment method that best fits your technical requirements and budget constraints. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/gcp.mdx b/developer-docs/self-hosted/cloud/gcp.mdx new file mode 100644 index 000000000..a4770107e --- /dev/null +++ b/developer-docs/self-hosted/cloud/gcp.mdx @@ -0,0 +1,745 @@ +--- +title: Google Cloud Platform (GCP) Deployment +description: Deploy Chatwoot on Google Cloud Platform with Compute Engine, Cloud Run, or GKE +sidebarTitle: GCP +--- + +# Google Cloud Platform Deployment Guide + +Deploy Chatwoot on Google Cloud Platform using Compute Engine, Cloud Run, or Google Kubernetes Engine for a scalable, enterprise-ready solution. + +## Deployment Options + + + + Traditional VM deployment with full control + + + Serverless container deployment + + + Managed Kubernetes deployment + + + +## Compute Engine Deployment + +### Prerequisites + +```bash +# Install and configure gcloud CLI +curl https://sdk.cloud.google.com | bash +exec -l $SHELL +gcloud init + +# Set project and region +gcloud config set project your-project-id +gcloud config set compute/region us-central1 +gcloud config set compute/zone us-central1-a +``` + +### Network Setup + +```bash +# Create VPC network +gcloud compute networks create chatwoot-vpc --subnet-mode=custom + +# Create subnet +gcloud compute networks subnets create chatwoot-subnet \ + --network=chatwoot-vpc \ + --range=10.0.1.0/24 \ + --region=us-central1 + +# Create firewall rules +gcloud compute firewall-rules create chatwoot-allow-http \ + --network=chatwoot-vpc \ + --allow=tcp:80,tcp:443,tcp:3000 \ + --source-ranges=0.0.0.0/0 \ + --target-tags=chatwoot-server + +gcloud compute firewall-rules create chatwoot-allow-ssh \ + --network=chatwoot-vpc \ + --allow=tcp:22 \ + --source-ranges=0.0.0.0/0 \ + --target-tags=chatwoot-server +``` + +### Database Setup + +#### Cloud SQL PostgreSQL + +```bash +# Create Cloud SQL instance +gcloud sql instances create chatwoot-db \ + --database-version=POSTGRES_13 \ + --tier=db-g1-small \ + --region=us-central1 \ + --storage-type=SSD \ + --storage-size=100GB \ + --storage-auto-increase \ + --backup-start-time=03:00 \ + --enable-bin-log \ + --maintenance-window-day=SUN \ + --maintenance-window-hour=04 + +# Create database +gcloud sql databases create chatwoot_production --instance=chatwoot-db + +# Create user +gcloud sql users create chatwoot \ + --instance=chatwoot-db \ + --password=your-secure-password + +# Get connection name +gcloud sql instances describe chatwoot-db --format="value(connectionName)" +``` + +#### Memorystore Redis + +```bash +# Create Redis instance +gcloud redis instances create chatwoot-redis \ + --size=1 \ + --region=us-central1 \ + --redis-version=redis_6_x \ + --network=chatwoot-vpc +``` + +### Storage Setup + +```bash +# Create Cloud Storage bucket +gsutil mb -p your-project-id -c STANDARD -l us-central1 gs://your-chatwoot-bucket + +# Set bucket permissions +gsutil iam ch allUsers:objectViewer gs://your-chatwoot-bucket + +# Enable CORS +cat > cors.json << EOF +[ + { + "origin": ["https://chatwoot.yourdomain.com"], + "method": ["GET", "PUT", "POST", "DELETE"], + "responseHeader": ["Content-Type"], + "maxAgeSeconds": 3600 + } +] +EOF + +gsutil cors set cors.json gs://your-chatwoot-bucket +``` + +### Compute Instance + +#### Create Instance Template + +```bash +# Create startup script +cat > startup-script.sh << 'EOF' +#!/bin/bash +apt-get update +apt-get install -y wget curl + +# Download and install Chatwoot +wget https://get.chatwoot.app/linux/install.sh +chmod +x install.sh +./install.sh --install + +# Configure environment +sudo -u chatwoot bash << 'INNER_EOF' +cd /home/chatwoot/chatwoot +cat > .env << 'ENV_EOF' +RAILS_ENV=production +NODE_ENV=production +FRONTEND_URL=https://chatwoot.yourdomain.com +FORCE_SSL=true + +# Database +DATABASE_URL=postgresql://chatwoot:password@/chatwoot_production?host=/cloudsql/your-project:us-central1:chatwoot-db + +# Redis +REDIS_URL=redis://10.0.0.3:6379/0 + +# Storage +ACTIVE_STORAGE_SERVICE=google +GCS_PROJECT=your-project-id +GCS_BUCKET=your-chatwoot-bucket + +# Email (using SendGrid) +MAILER_SENDER_EMAIL=noreply@yourdomain.com +SMTP_ADDRESS=smtp.sendgrid.net +SMTP_PORT=587 +SMTP_USERNAME=apikey +SMTP_PASSWORD=your-sendgrid-api-key +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true +ENV_EOF + +# Prepare database +RAILS_ENV=production bundle exec rake db:chatwoot_prepare +INNER_EOF + +# Restart services +systemctl restart chatwoot.target +EOF + +# Create instance template +gcloud compute instance-templates create chatwoot-template \ + --machine-type=e2-standard-2 \ + --network-interface=network=chatwoot-vpc,subnet=chatwoot-subnet \ + --boot-disk-size=50GB \ + --boot-disk-type=pd-ssd \ + --image-family=ubuntu-2004-lts \ + --image-project=ubuntu-os-cloud \ + --tags=chatwoot-server \ + --metadata-from-file startup-script=startup-script.sh \ + --service-account=chatwoot-sa@your-project-id.iam.gserviceaccount.com \ + --scopes=https://www.googleapis.com/auth/cloud-platform +``` + +#### Create Managed Instance Group + +```bash +# Create instance group +gcloud compute instance-groups managed create chatwoot-ig \ + --template=chatwoot-template \ + --size=2 \ + --zone=us-central1-a + +# Configure autoscaling +gcloud compute instance-groups managed set-autoscaling chatwoot-ig \ + --max-num-replicas=5 \ + --min-num-replicas=2 \ + --target-cpu-utilization=0.7 \ + --zone=us-central1-a +``` + +### Load Balancer + +```bash +# Create health check +gcloud compute health-checks create http chatwoot-health-check \ + --port=3000 \ + --request-path=/api + +# Create backend service +gcloud compute backend-services create chatwoot-backend \ + --protocol=HTTP \ + --health-checks=chatwoot-health-check \ + --global + +# Add instance group to backend service +gcloud compute backend-services add-backend chatwoot-backend \ + --instance-group=chatwoot-ig \ + --instance-group-zone=us-central1-a \ + --global + +# Create URL map +gcloud compute url-maps create chatwoot-map \ + --default-service=chatwoot-backend + +# Create SSL certificate +gcloud compute ssl-certificates create chatwoot-ssl \ + --domains=chatwoot.yourdomain.com + +# Create HTTPS proxy +gcloud compute target-https-proxies create chatwoot-https-proxy \ + --url-map=chatwoot-map \ + --ssl-certificates=chatwoot-ssl + +# Create global forwarding rule +gcloud compute forwarding-rules create chatwoot-https-rule \ + --global \ + --target-https-proxy=chatwoot-https-proxy \ + --ports=443 + +# Create HTTP to HTTPS redirect +gcloud compute url-maps create chatwoot-redirect \ + --default-url-redirect-response-code=301 \ + --default-url-redirect-https-redirect + +gcloud compute target-http-proxies create chatwoot-http-proxy \ + --url-map=chatwoot-redirect + +gcloud compute forwarding-rules create chatwoot-http-rule \ + --global \ + --target-http-proxy=chatwoot-http-proxy \ + --ports=80 +``` + +## Cloud Run Deployment + +### Containerize Chatwoot + +Create `Dockerfile`: + +```dockerfile +FROM chatwoot/chatwoot:latest + +# Set environment variables +ENV RAILS_ENV=production +ENV NODE_ENV=production +ENV PORT=8080 + +# Expose port +EXPOSE 8080 + +# Start command +CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "8080"] +``` + +### Build and Deploy + +```bash +# Build container image +gcloud builds submit --tag gcr.io/your-project-id/chatwoot + +# Deploy to Cloud Run +gcloud run deploy chatwoot \ + --image gcr.io/your-project-id/chatwoot \ + --platform managed \ + --region us-central1 \ + --allow-unauthenticated \ + --memory 2Gi \ + --cpu 2 \ + --max-instances 10 \ + --set-env-vars RAILS_ENV=production \ + --set-env-vars DATABASE_URL="postgresql://..." \ + --set-env-vars REDIS_URL="redis://..." \ + --set-env-vars FRONTEND_URL="https://chatwoot.yourdomain.com" + +# Deploy worker service +gcloud run deploy chatwoot-worker \ + --image gcr.io/your-project-id/chatwoot \ + --platform managed \ + --region us-central1 \ + --no-allow-unauthenticated \ + --memory 1Gi \ + --cpu 1 \ + --max-instances 5 \ + --command "bundle,exec,sidekiq,-C,config/sidekiq.yml" \ + --set-env-vars RAILS_ENV=production \ + --set-env-vars DATABASE_URL="postgresql://..." \ + --set-env-vars REDIS_URL="redis://..." +``` + +### Custom Domain + +```bash +# Map custom domain +gcloud run domain-mappings create \ + --service chatwoot \ + --domain chatwoot.yourdomain.com \ + --region us-central1 +``` + +## Google Kubernetes Engine (GKE) + +### Create GKE Cluster + +```bash +# Create GKE cluster +gcloud container clusters create chatwoot-cluster \ + --zone us-central1-a \ + --num-nodes 3 \ + --machine-type e2-standard-2 \ + --disk-size 50GB \ + --disk-type pd-ssd \ + --enable-autoscaling \ + --min-nodes 1 \ + --max-nodes 5 \ + --enable-autorepair \ + --enable-autoupgrade \ + --network chatwoot-vpc \ + --subnetwork chatwoot-subnet + +# Get credentials +gcloud container clusters get-credentials chatwoot-cluster --zone us-central1-a +``` + +### Helm Deployment + +```bash +# Add Chatwoot Helm repository +helm repo add chatwoot https://chatwoot.github.io/charts +helm repo update + +# Create namespace +kubectl create namespace chatwoot + +# Create values file for GCP +cat > gcp-values.yaml << EOF +# GCP-specific values +ingress: + enabled: true + className: gce + annotations: + kubernetes.io/ingress.global-static-ip-name: "chatwoot-ip" + networking.gke.io/managed-certificates: "chatwoot-ssl" + kubernetes.io/ingress.allow-http: "false" + hosts: + - host: chatwoot.yourdomain.com + paths: + - path: / + pathType: Prefix + +# Use Cloud SQL and Memorystore +postgresql: + enabled: false + +redis: + enabled: false + +env: + DATABASE_URL: "postgresql://chatwoot:password@/chatwoot_production?host=/cloudsql/your-project:us-central1:chatwoot-db" + REDIS_URL: "redis://10.0.0.3:6379/0" + ACTIVE_STORAGE_SERVICE: "google" + GCS_PROJECT: "your-project-id" + GCS_BUCKET: "your-chatwoot-bucket" + +# Resource limits +resources: + limits: + cpu: 1000m + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + +# Workload Identity +serviceAccount: + create: true + annotations: + iam.gke.io/gcp-service-account: chatwoot-sa@your-project-id.iam.gserviceaccount.com +EOF + +# Install Chatwoot +helm install chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --values gcp-values.yaml +``` + +### SSL Certificate + +```yaml +# managed-cert.yaml +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: chatwoot-ssl + namespace: chatwoot +spec: + domains: + - chatwoot.yourdomain.com +``` + +```bash +kubectl apply -f managed-cert.yaml +``` + +## Service Account and IAM + +### Create Service Account + +```bash +# Create service account +gcloud iam service-accounts create chatwoot-sa \ + --display-name="Chatwoot Service Account" + +# Grant necessary permissions +gcloud projects add-iam-policy-binding your-project-id \ + --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ + --role="roles/cloudsql.client" + +gcloud projects add-iam-policy-binding your-project-id \ + --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ + --role="roles/storage.objectAdmin" + +gcloud projects add-iam-policy-binding your-project-id \ + --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ + --role="roles/redis.editor" + +# Create and download key +gcloud iam service-accounts keys create chatwoot-key.json \ + --iam-account=chatwoot-sa@your-project-id.iam.gserviceaccount.com +``` + +## Monitoring and Logging + +### Cloud Monitoring + +```bash +# Enable APIs +gcloud services enable monitoring.googleapis.com +gcloud services enable logging.googleapis.com + +# Create notification channel +gcloud alpha monitoring channels create \ + --display-name="Email Alerts" \ + --type=email \ + --channel-labels=email_address=admin@yourdomain.com +``` + +### Custom Metrics + +```yaml +# monitoring.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + namespace: chatwoot +data: + prometheus.yml: | + global: + scrape_interval: 15s + scrape_configs: + - job_name: 'chatwoot' + static_configs: + - targets: ['chatwoot-service:3000'] + metrics_path: /metrics +``` + +### Alerting Policies + +```bash +# Create alerting policy for high CPU +gcloud alpha monitoring policies create \ + --policy-from-file=cpu-alert-policy.yaml + +# cpu-alert-policy.yaml +cat > cpu-alert-policy.yaml << EOF +displayName: "High CPU Usage" +conditions: + - displayName: "CPU usage above 80%" + conditionThreshold: + filter: 'resource.type="gce_instance"' + comparison: COMPARISON_GREATER_THAN + thresholdValue: 0.8 + duration: 300s +combiner: OR +enabled: true +notificationChannels: + - projects/your-project-id/notificationChannels/CHANNEL_ID +EOF +``` + +## Backup and Disaster Recovery + +### Database Backups + +```bash +# Cloud SQL automatic backups are enabled by default +# Create on-demand backup +gcloud sql backups create --instance=chatwoot-db + +# List backups +gcloud sql backups list --instance=chatwoot-db + +# Restore from backup +gcloud sql backups restore BACKUP_ID --restore-instance=chatwoot-db-restore +``` + +### Application Backups + +```bash +#!/bin/bash +# backup-script.sh +DATE=$(date +%Y%m%d_%H%M%S) + +# Database backup +gcloud sql export sql chatwoot-db gs://your-backup-bucket/db/chatwoot_$DATE.sql + +# File storage backup +gsutil -m rsync -r -d gs://your-chatwoot-bucket gs://your-backup-bucket/files/ + +# Kubernetes configuration backup +kubectl get all -n chatwoot -o yaml > k8s-backup-$DATE.yaml +gsutil cp k8s-backup-$DATE.yaml gs://your-backup-bucket/k8s/ +``` + +## Security Best Practices + +### Network Security + +```bash +# Create private cluster +gcloud container clusters create chatwoot-private \ + --enable-private-nodes \ + --master-ipv4-cidr-block 172.16.0.0/28 \ + --enable-ip-alias \ + --enable-network-policy + +# Create firewall rules for private access +gcloud compute firewall-rules create allow-chatwoot-private \ + --network chatwoot-vpc \ + --allow tcp:443,tcp:80 \ + --source-ranges 10.0.0.0/8 +``` + +### Secret Management + +```bash +# Create secrets in Secret Manager +gcloud secrets create database-password --data-file=db-password.txt +gcloud secrets create redis-password --data-file=redis-password.txt + +# Grant access to service account +gcloud secrets add-iam-policy-binding database-password \ + --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ + --role="roles/secretmanager.secretAccessor" +``` + +### Binary Authorization + +```bash +# Enable Binary Authorization +gcloud container binauthz policy import policy.yaml + +# policy.yaml +cat > policy.yaml << EOF +defaultAdmissionRule: + requireAttestationsBy: + - projects/your-project-id/attestors/prod-attestor + enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG +globalPolicyEvaluationMode: ENABLE +EOF +``` + +## Cost Optimization + +### Preemptible Instances + +```bash +# Create preemptible node pool +gcloud container node-pools create preemptible-pool \ + --cluster=chatwoot-cluster \ + --zone=us-central1-a \ + --machine-type=e2-standard-2 \ + --preemptible \ + --num-nodes=2 \ + --enable-autoscaling \ + --min-nodes=0 \ + --max-nodes=5 +``` + +### Committed Use Discounts + +```bash +# Purchase committed use discount +gcloud compute commitments create chatwoot-commitment \ + --plan=12-month \ + --region=us-central1 \ + --resources=type=VCPU,amount=4 \ + --resources=type=MEMORY,amount=16 +``` + +### Resource Optimization + +```yaml +# resource-quota.yaml +apiVersion: v1 +kind: ResourceQuota +metadata: + name: chatwoot-quota + namespace: chatwoot +spec: + hard: + requests.cpu: "4" + requests.memory: 8Gi + limits.cpu: "8" + limits.memory: 16Gi + persistentvolumeclaims: "4" +``` + +## Troubleshooting + +### Common Issues + + +Check: +- Cloud SQL Proxy configuration +- Service account permissions +- Network connectivity +- SSL requirements + + + +Verify: +- Resource quotas and limits +- Image pull permissions +- Service account configuration +- Network policies + + + +Solutions: +- Verify health check path (/api) +- Check firewall rules +- Ensure proper backend configuration +- Review application startup time + + +### Diagnostic Commands + +```bash +# Check Compute Engine instances +gcloud compute instances list + +# View Cloud Run services +gcloud run services list + +# Check GKE cluster status +gcloud container clusters describe chatwoot-cluster --zone us-central1-a + +# View logs +gcloud logging read "resource.type=gce_instance" --limit 50 +gcloud logging read "resource.type=cloud_run_revision" --limit 50 + +# Check Cloud SQL status +gcloud sql instances describe chatwoot-db +``` + +### Performance Monitoring + +```bash +# View metrics +gcloud monitoring metrics list --filter="metric.type:compute" + +# Create dashboard +gcloud monitoring dashboards create --config-from-file=dashboard.json +``` + +## Best Practices + +### Security +- Use private GKE clusters +- Enable Workload Identity +- Implement Binary Authorization +- Use Secret Manager for sensitive data +- Enable audit logging + +### Performance +- Use Cloud CDN for static assets +- Implement Cloud Memorystore for caching +- Use SSD persistent disks +- Enable HTTP/2 and gRPC +- Optimize container images + +### Reliability +- Deploy across multiple zones +- Use managed services (Cloud SQL, Memorystore) +- Implement proper health checks +- Set up monitoring and alerting +- Test disaster recovery procedures + +### Cost Management +- Use preemptible instances for non-critical workloads +- Implement resource quotas +- Purchase committed use discounts +- Monitor usage with Cloud Billing +- Use Cloud Functions for event-driven tasks + +--- + +This GCP deployment guide provides comprehensive options for hosting Chatwoot on Google Cloud Platform. Choose the deployment method that best aligns with your scalability, security, and operational requirements. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/heroku.mdx b/developer-docs/self-hosted/cloud/heroku.mdx new file mode 100644 index 000000000..2d78df5ad --- /dev/null +++ b/developer-docs/self-hosted/cloud/heroku.mdx @@ -0,0 +1,505 @@ +--- +title: Heroku Deployment +description: Deploy Chatwoot on Heroku with one-click deployment and managed services +sidebarTitle: Heroku +--- + +# Heroku Deployment Guide + +Deploy Chatwoot on Heroku using the one-click deployment option for a quick and managed hosting solution. This guide covers deployment, configuration, and maintenance on Heroku's platform. + + +Heroku has discontinued free dynos, postgres and redis. [Chatwoot will use basic/mini plans](https://blog.heroku.com/new-low-cost-plans) for all new Heroku deployments going forward. + + +## Quick Deployment + +### One-Click Deploy + +The fastest way to get Chatwoot running on Heroku is using the one-click deploy button: + + + Click here to deploy Chatwoot to Heroku with one click + + +### Deployment Steps + +1. **Click the Deploy Button**: Use the one-click deploy button above +2. **Configure App Settings**: + - Choose an app name (or let Heroku generate one) + - Select your region (US or Europe) + - Review the default configuration + +3. **Deploy the Application**: Click "Deploy app" and wait for the build to complete + +4. **Enable Worker Dynos**: + - Go to the **Resources** tab in your Heroku app dashboard + - Ensure the **worker** dynos are turned on + - This is crucial for background job processing + +5. **Configure Environment Variables**: + - Go to **Settings** tab in Heroku app dashboard + - Click **Reveal Config Vars** + - Configure additional variables as needed + +6. **Access Your Installation**: Navigate to `yourapp.herokuapp.com` + +## Configuration + +### Required Environment Variables + +Heroku automatically sets up basic configuration, but you'll need to configure additional variables: + +#### Email Configuration + +```bash +# SMTP Settings (required for notifications) +MAILER_SENDER_EMAIL=noreply@yourdomain.com +SMTP_ADDRESS=smtp.sendgrid.net +SMTP_PORT=587 +SMTP_USERNAME=apikey +SMTP_PASSWORD=your-sendgrid-api-key +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true +``` + +#### File Storage Configuration + + +Heroku has an "ephemeral" hard disk. Files uploaded to Chatwoot will not persist after application restarts. You must configure cloud storage. + + +**Amazon S3 Configuration:** + +```bash +ACTIVE_STORAGE_SERVICE=amazon +S3_BUCKET_NAME=your-chatwoot-bucket +AWS_ACCESS_KEY_ID=your-access-key +AWS_SECRET_ACCESS_KEY=your-secret-key +AWS_REGION=us-east-1 +``` + +**Google Cloud Storage Configuration:** + +```bash +ACTIVE_STORAGE_SERVICE=google +GCS_PROJECT=your-project-id +GCS_BUCKET=your-chatwoot-bucket +GOOGLE_APPLICATION_CREDENTIALS={"type":"service_account",...} +``` + +#### Frontend URL + +```bash +FRONTEND_URL=https://yourapp.herokuapp.com +FORCE_SSL=true +``` + +### Setting Environment Variables + +#### Via Heroku Dashboard + +1. Go to your app's **Settings** tab +2. Click **Reveal Config Vars** +3. Add each variable name and value +4. Click **Add** for each variable + +#### Via Heroku CLI + +```bash +# Install Heroku CLI +npm install -g heroku + +# Login to Heroku +heroku login + +# Set environment variables +heroku config:set MAILER_SENDER_EMAIL=noreply@yourdomain.com -a your-app-name +heroku config:set SMTP_ADDRESS=smtp.sendgrid.net -a your-app-name +heroku config:set SMTP_PORT=587 -a your-app-name + +# Set storage configuration +heroku config:set ACTIVE_STORAGE_SERVICE=amazon -a your-app-name +heroku config:set S3_BUCKET_NAME=your-bucket -a your-app-name +heroku config:set AWS_ACCESS_KEY_ID=your-key -a your-app-name +heroku config:set AWS_SECRET_ACCESS_KEY=your-secret -a your-app-name +``` + +## Add-ons and Services + +### Database (PostgreSQL) + +Heroku automatically provisions a PostgreSQL database: + +```bash +# Check database info +heroku pg:info -a your-app-name + +# Access database console +heroku pg:psql -a your-app-name + +# Create database backup +heroku pg:backups:capture -a your-app-name + +# Download backup +heroku pg:backups:download -a your-app-name +``` + +### Redis + +Heroku automatically provisions Redis for caching and background jobs: + +```bash +# Check Redis info +heroku redis:info -a your-app-name + +# Access Redis CLI +heroku redis:cli -a your-app-name + +# Monitor Redis +heroku redis:monitor -a your-app-name +``` + +### Email Service (SendGrid) + +Add SendGrid for email delivery: + +```bash +# Add SendGrid add-on +heroku addons:create sendgrid:starter -a your-app-name + +# Get SendGrid credentials +heroku config:get SENDGRID_USERNAME -a your-app-name +heroku config:get SENDGRID_PASSWORD -a your-app-name +``` + +## Updating Your Deployment + +### Method 1: GitHub Integration (Recommended) + +1. **Connect GitHub Repository**: + - Go to the **Deploy** tab in your Heroku app dashboard + - Choose **GitHub** as the deployment method + - Connect the `chatwoot/chatwoot` repository + +2. **Enable Automatic Deploys** (Optional): + - Enable automatic deploys from the `master` branch + - This will automatically deploy when new releases are available + +3. **Manual Deploy**: + - Go to **Manual deploy** section + - Choose `master` branch + - Click **Deploy Branch** + +### Method 2: Heroku CLI + +```bash +# Clone the Chatwoot repository +git clone https://github.com/chatwoot/chatwoot.git +cd chatwoot + +# Add Heroku remote +heroku git:remote -a your-app-name + +# Deploy latest version +git push heroku master +``` + +### Method 3: Docker Deployment + +```bash +# Login to Heroku Container Registry +heroku container:login + +# Build and push Docker image +heroku container:push web -a your-app-name + +# Release the image +heroku container:release web -a your-app-name +``` + +## Scaling and Performance + +### Dyno Management + +```bash +# Scale web dynos +heroku ps:scale web=2 -a your-app-name + +# Scale worker dynos +heroku ps:scale worker=1 -a your-app-name + +# Check dyno status +heroku ps -a your-app-name +``` + +### Performance Monitoring + +```bash +# View application metrics +heroku logs --tail -a your-app-name + +# Monitor dyno performance +heroku ps:exec -a your-app-name + +# Check memory usage +heroku logs --source app --tail -a your-app-name | grep "Memory usage" +``` + +## Monitoring and Logging + +### Application Logs + +```bash +# View recent logs +heroku logs -a your-app-name + +# Tail logs in real-time +heroku logs --tail -a your-app-name + +# Filter logs by source +heroku logs --source app -a your-app-name +heroku logs --source heroku -a your-app-name +``` + +### Add Monitoring Services + +#### Papertrail (Log Management) + +```bash +# Add Papertrail +heroku addons:create papertrail:choklad -a your-app-name + +# View logs in Papertrail +heroku addons:open papertrail -a your-app-name +``` + +#### New Relic (Application Monitoring) + +```bash +# Add New Relic +heroku addons:create newrelic:wayne -a your-app-name + +# Configure New Relic +heroku config:set NEW_RELIC_APP_NAME="Chatwoot Production" -a your-app-name + +# Open New Relic dashboard +heroku addons:open newrelic -a your-app-name +``` + +## Security Configuration + +### SSL/TLS + +Heroku automatically provides SSL certificates for custom domains: + +```bash +# Add custom domain +heroku domains:add chatwoot.yourdomain.com -a your-app-name + +# Check SSL certificate status +heroku certs -a your-app-name + +# Enable Automated Certificate Management +heroku certs:auto:enable -a your-app-name +``` + +### Environment Security + +```bash +# Rotate database credentials +heroku pg:credentials:rotate -a your-app-name + +# Rotate Redis credentials +heroku redis:credentials:rotate -a your-app-name + +# Review security settings +heroku config -a your-app-name +``` + +## Backup and Recovery + +### Database Backups + +```bash +# Schedule automatic backups +heroku pg:backups:schedule DATABASE_URL --at '02:00 America/Los_Angeles' -a your-app-name + +# Create manual backup +heroku pg:backups:capture -a your-app-name + +# List all backups +heroku pg:backups -a your-app-name + +# Restore from backup +heroku pg:backups:restore b001 DATABASE_URL -a your-app-name +``` + +### File Storage Backups + +Since Heroku has ephemeral storage, ensure your cloud storage has backup policies: + +**For S3:** +```bash +# Enable versioning on S3 bucket +aws s3api put-bucket-versioning \ + --bucket your-chatwoot-bucket \ + --versioning-configuration Status=Enabled + +# Set up lifecycle policy for old versions +aws s3api put-bucket-lifecycle-configuration \ + --bucket your-chatwoot-bucket \ + --lifecycle-configuration file://lifecycle.json +``` + +## Troubleshooting + +### Common Issues + + +**Symptoms**: App crashes on startup, H10 errors + +**Solutions**: +- Check that worker dynos are enabled in Resources tab +- Verify all required environment variables are set +- Check application logs: `heroku logs --tail -a your-app-name` +- Ensure database migrations have run: `heroku run rails db:migrate -a your-app-name` + + + +**Symptoms**: Files upload but disappear after app restart + +**Solutions**: +- Configure cloud storage (S3, GCS, etc.) +- Verify storage credentials are correct +- Check CORS settings on your storage bucket +- Test storage configuration: `heroku run rails console -a your-app-name` + + + +**Symptoms**: Users not receiving email notifications + +**Solutions**: +- Verify SMTP configuration in config vars +- Check SendGrid add-on status +- Test email configuration: `heroku run rails console -a your-app-name` +- Review email logs in SendGrid dashboard + + + +**Symptoms**: Settings page shows "unknown" build version + +**Solution**: +Enable runtime dyno metadata: +```bash +heroku labs:enable runtime-dyno-metadata -a your-app-name +``` + + +### Performance Issues + + +**Solutions**: +- Scale up web dynos: `heroku ps:scale web=2 -a your-app-name` +- Upgrade to higher performance dynos +- Monitor database performance with `heroku pg:diagnose -a your-app-name` +- Check Redis performance with `heroku redis:info -a your-app-name` + + + +**Solutions**: +- Ensure worker dynos are running: `heroku ps -a your-app-name` +- Scale worker dynos if needed: `heroku ps:scale worker=1 -a your-app-name` +- Check Sidekiq logs: `heroku logs --source app --tail -a your-app-name | grep sidekiq` + + +### Diagnostic Commands + +```bash +# Check app status +heroku ps -a your-app-name + +# View configuration +heroku config -a your-app-name + +# Check add-ons +heroku addons -a your-app-name + +# Run Rails console +heroku run rails console -a your-app-name + +# Run database migrations +heroku run rails db:migrate -a your-app-name + +# Check database status +heroku pg:info -a your-app-name + +# Check Redis status +heroku redis:info -a your-app-name +``` + +## Known Limitations + +### Platform Limitations + +1. **Ephemeral File System**: Files uploaded to local storage will be lost on dyno restart +2. **Dyno Sleep**: Free tier dynos sleep after 30 minutes of inactivity (upgrade to paid tier to avoid) +3. **Request Timeout**: Heroku has a 30-second request timeout limit +4. **Memory Limits**: Dynos have memory limits based on the plan selected + +### Workarounds + +1. **File Storage**: Use cloud storage (S3, GCS) instead of local storage +2. **Dyno Sleep**: Upgrade to paid dynos or use external monitoring to keep app awake +3. **Long Requests**: Implement background job processing for long-running tasks +4. **Memory Usage**: Monitor and optimize application memory usage + +## Cost Optimization + +### Dyno Sizing + +```bash +# Check current dyno usage +heroku ps -a your-app-name + +# Optimize dyno allocation +heroku ps:scale web=1:standard-1x worker=1:standard-1x -a your-app-name +``` + +### Add-on Optimization + +- Use appropriate add-on tiers based on usage +- Monitor add-on usage and costs in Heroku dashboard +- Consider consolidating services where possible + +## Best Practices + +### Security +- Use environment variables for all sensitive configuration +- Enable Automated Certificate Management for SSL +- Regularly rotate database and Redis credentials +- Monitor access logs and set up alerts + +### Performance +- Use appropriate dyno types for your workload +- Monitor application performance with New Relic or similar +- Implement caching strategies +- Optimize database queries + +### Reliability +- Set up automatic database backups +- Monitor application health with external services +- Implement proper error handling and logging +- Use multiple dynos for high availability + +### Cost Management +- Monitor dyno usage and scale appropriately +- Use scheduler add-on for periodic tasks instead of always-on workers +- Review and optimize add-on usage regularly +- Consider reserved capacity for predictable workloads + +--- + +This Heroku deployment guide provides a complete solution for hosting Chatwoot on Heroku's platform. The managed infrastructure and add-on ecosystem make it an excellent choice for teams who want to focus on using Chatwoot rather than managing infrastructure. + +For more information, visit the [official Chatwoot Heroku documentation](https://www.chatwoot.com/docs/self-hosted/deployment/heroku). \ No newline at end of file diff --git a/developer-docs/self-hosted/configuration/environment-variables.mdx b/developer-docs/self-hosted/configuration/environment-variables.mdx new file mode 100644 index 000000000..4515edd87 --- /dev/null +++ b/developer-docs/self-hosted/configuration/environment-variables.mdx @@ -0,0 +1,748 @@ +--- +title: Environment Variables +description: Complete reference for Chatwoot environment variables and configuration options +sidebarTitle: Environment Variables +--- + +# Environment Variables Reference + +Chatwoot uses environment variables for configuration. This guide provides a comprehensive reference for all available environment variables and their usage. + +## Core Application Settings + +### Basic Configuration + +```bash +# Rails Environment +RAILS_ENV=production + +# Node Environment +NODE_ENV=production + +# Frontend URL (required) +FRONTEND_URL=https://chatwoot.yourdomain.com + +# Force SSL (recommended for production) +FORCE_SSL=true + +# Secret Key Base (auto-generated during installation) +SECRET_KEY_BASE=your-secret-key-base + +# Rails Log Level +RAILS_LOG_LEVEL=info + +# Rails Max Threads +RAILS_MAX_THREADS=5 + +# Web Concurrency (Puma workers) +WEB_CONCURRENCY=2 +``` + +### Application Behavior + +```bash +# Enable/disable account signup +ENABLE_ACCOUNT_SIGNUP=false + +# Auto-assign conversations to online agents +AUTO_ASSIGN_CONVERSATIONS=true + +# Enable conversation continuity (link conversations across sessions) +CONVERSATION_CONTINUITY=true + +# Maximum file upload size (in MB) +MAXIMUM_FILE_UPLOAD_SIZE=40 + +# Enable IP-based rate limiting +ENABLE_IP_RATE_LIMIT=true + +# Rate limit per IP (requests per minute) +IP_RATE_LIMIT=100 +``` + +## Database Configuration + +### PostgreSQL + +```bash +# Database URL (primary configuration method) +DATABASE_URL=postgresql://username:password@hostname:port/database_name + +# Alternative: Individual components +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_USERNAME=chatwoot +POSTGRES_PASSWORD=your-password +POSTGRES_DATABASE=chatwoot_production + +# Database pool size +DATABASE_POOL_SIZE=5 + +# Database timeout (seconds) +DATABASE_TIMEOUT=5000 + +# Enable prepared statements +DATABASE_PREPARED_STATEMENTS=true +``` + +### Database SSL Configuration + +```bash +# SSL Mode (disable, allow, prefer, require, verify-ca, verify-full) +DATABASE_SSL_MODE=require + +# SSL Certificate paths (for verify-ca and verify-full modes) +DATABASE_SSL_CERT=/path/to/client-cert.pem +DATABASE_SSL_KEY=/path/to/client-key.pem +DATABASE_SSL_ROOT_CERT=/path/to/ca-cert.pem +``` + +## Redis Configuration + +### Basic Redis Settings + +```bash +# Redis URL (primary configuration method) +REDIS_URL=redis://localhost:6379/0 + +# Alternative: Individual components +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_DB=0 +REDIS_PASSWORD=your-redis-password + +# Redis connection pool size +REDIS_POOL_SIZE=5 + +# Redis timeout (seconds) +REDIS_TIMEOUT=1 +``` + +### Redis SSL Configuration + +```bash +# Enable SSL for Redis +REDIS_SSL=true + +# Redis SSL certificate verification +REDIS_SSL_VERIFY=true + +# Redis SSL certificate paths +REDIS_SSL_CERT=/path/to/redis-client.crt +REDIS_SSL_KEY=/path/to/redis-client.key +REDIS_SSL_CA=/path/to/redis-ca.crt +``` + +### Sidekiq Configuration + +```bash +# Sidekiq concurrency (number of worker threads) +SIDEKIQ_CONCURRENCY=10 + +# Sidekiq Redis namespace +SIDEKIQ_REDIS_NAMESPACE=chatwoot_sidekiq + +# Sidekiq log level +SIDEKIQ_LOG_LEVEL=info + +# Enable Sidekiq web UI +SIDEKIQ_WEB_UI=true + +# Sidekiq web UI username/password +SIDEKIQ_WEB_USERNAME=admin +SIDEKIQ_WEB_PASSWORD=your-password +``` + +## Email Configuration + +### SMTP Settings + +```bash +# Sender email address +MAILER_SENDER_EMAIL=noreply@yourdomain.com + +# SMTP server configuration +SMTP_ADDRESS=smtp.gmail.com +SMTP_PORT=587 +SMTP_USERNAME=your-email@gmail.com +SMTP_PASSWORD=your-app-password +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true +SMTP_OPENSSL_VERIFY_MODE=peer + +# SMTP domain (for HELO command) +SMTP_DOMAIN=yourdomain.com + +# Force TLS +SMTP_TLS=true +``` + +### Email Provider Examples + + + + ```bash + SMTP_ADDRESS=smtp.gmail.com + SMTP_PORT=587 + SMTP_USERNAME=your-email@gmail.com + SMTP_PASSWORD=your-app-password + SMTP_AUTHENTICATION=plain + SMTP_ENABLE_STARTTLS_AUTO=true + ``` + + + + ```bash + SMTP_ADDRESS=smtp.sendgrid.net + SMTP_PORT=587 + SMTP_USERNAME=apikey + SMTP_PASSWORD=your-sendgrid-api-key + SMTP_AUTHENTICATION=plain + SMTP_ENABLE_STARTTLS_AUTO=true + ``` + + + + ```bash + SMTP_ADDRESS=smtp.mailgun.org + SMTP_PORT=587 + SMTP_USERNAME=postmaster@mg.yourdomain.com + SMTP_PASSWORD=your-mailgun-password + SMTP_AUTHENTICATION=plain + SMTP_ENABLE_STARTTLS_AUTO=true + ``` + + + + ```bash + SMTP_ADDRESS=email-smtp.us-east-1.amazonaws.com + SMTP_PORT=587 + SMTP_USERNAME=your-ses-username + SMTP_PASSWORD=your-ses-password + SMTP_AUTHENTICATION=plain + SMTP_ENABLE_STARTTLS_AUTO=true + ``` + + + +### Email Templates + +```bash +# Custom email template path +CUSTOM_EMAIL_TEMPLATE_PATH=/path/to/custom/templates + +# Email template language +EMAIL_TEMPLATE_LANGUAGE=en + +# Enable email tracking +EMAIL_TRACKING_ENABLED=true + +# Email delivery method (smtp, sendmail, test) +EMAIL_DELIVERY_METHOD=smtp +``` + +## File Storage Configuration + +### Local Storage + +```bash +# Active storage service +ACTIVE_STORAGE_SERVICE=local + +# Local storage path +LOCAL_STORAGE_PATH=/home/chatwoot/chatwoot/storage +``` + +### Amazon S3 + +```bash +# Active storage service +ACTIVE_STORAGE_SERVICE=amazon + +# S3 configuration +S3_BUCKET_NAME=your-chatwoot-bucket +AWS_ACCESS_KEY_ID=your-access-key +AWS_SECRET_ACCESS_KEY=your-secret-key +AWS_REGION=us-east-1 + +# S3 endpoint (for S3-compatible services) +S3_ENDPOINT=https://s3.amazonaws.com + +# S3 force path style (for MinIO and other S3-compatible services) +S3_FORCE_PATH_STYLE=false + +# S3 public URL (for CDN) +S3_PUBLIC_URL=https://cdn.yourdomain.com +``` + +### Google Cloud Storage + +```bash +# Active storage service +ACTIVE_STORAGE_SERVICE=google + +# GCS configuration +GCS_PROJECT=your-project-id +GCS_BUCKET=your-chatwoot-bucket + +# GCS credentials (JSON key file path) +GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json + +# GCS public URL (for CDN) +GCS_PUBLIC_URL=https://cdn.yourdomain.com +``` + +### Azure Blob Storage + +```bash +# Active storage service +ACTIVE_STORAGE_SERVICE=azure + +# Azure configuration +AZURE_STORAGE_ACCOUNT_NAME=your-storage-account +AZURE_STORAGE_ACCESS_KEY=your-access-key +AZURE_STORAGE_CONTAINER=your-container-name + +# Azure public URL (for CDN) +AZURE_PUBLIC_URL=https://cdn.yourdomain.com +``` + +## Third-Party Integrations + +### Facebook + +```bash +# Facebook App ID and Secret +FB_APP_ID=your-facebook-app-id +FB_APP_SECRET=your-facebook-app-secret + +# Facebook Verify Token +FB_VERIFY_TOKEN=your-verify-token + +# Facebook API Version +FB_API_VERSION=v13.0 +``` + +### Twitter + +```bash +# Twitter API credentials +TWITTER_APP_ID=your-twitter-app-id +TWITTER_CONSUMER_KEY=your-consumer-key +TWITTER_CONSUMER_SECRET=your-consumer-secret +TWITTER_ENVIRONMENT=your-twitter-environment +``` + +### Slack + +```bash +# Slack App credentials +SLACK_CLIENT_ID=your-slack-client-id +SLACK_CLIENT_SECRET=your-slack-client-secret +``` + +### Google OAuth + +```bash +# Google OAuth credentials +GOOGLE_OAUTH_CLIENT_ID=your-google-client-id +GOOGLE_OAUTH_CLIENT_SECRET=your-google-client-secret +``` + +### Microsoft OAuth + +```bash +# Microsoft OAuth credentials +MICROSOFT_APP_ID=your-microsoft-app-id +MICROSOFT_APP_SECRET=your-microsoft-app-secret +``` + +## Push Notifications + +### FCM (Firebase Cloud Messaging) + +```bash +# FCM Server Key +FCM_SERVER_KEY=your-fcm-server-key + +# FCM Project ID +FCM_PROJECT_ID=your-firebase-project-id + +# FCM credentials file +GOOGLE_APPLICATION_CREDENTIALS=/path/to/firebase-service-account.json +``` + +### Vapid Keys (Web Push) + +```bash +# Vapid public and private keys +VAPID_PUBLIC_KEY=your-vapid-public-key +VAPID_PRIVATE_KEY=your-vapid-private-key + +# Vapid subject (email or URL) +VAPID_SUBJECT=mailto:admin@yourdomain.com +``` + +## Analytics and Monitoring + +### Application Monitoring + +```bash +# Enable application metrics +ENABLE_METRICS=true + +# Metrics endpoint path +METRICS_PATH=/metrics + +# Prometheus exporter +PROMETHEUS_EXPORTER=true +PROMETHEUS_EXPORTER_PORT=9394 + +# New Relic +NEW_RELIC_LICENSE_KEY=your-newrelic-license-key +NEW_RELIC_APP_NAME=Chatwoot + +# Sentry error tracking +SENTRY_DSN=your-sentry-dsn +``` + +### Google Analytics + +```bash +# Google Analytics tracking ID +GOOGLE_ANALYTICS_ID=UA-XXXXXXXXX-X + +# Google Tag Manager ID +GOOGLE_TAG_MANAGER_ID=GTM-XXXXXXX +``` + +### Hotjar + +```bash +# Hotjar site ID +HOTJAR_SITE_ID=your-hotjar-site-id +``` + +## Security Configuration + +### Authentication + +```bash +# JWT secret key +JWT_SECRET_KEY=your-jwt-secret-key + +# Session timeout (in seconds) +SESSION_TIMEOUT=86400 + +# Password minimum length +PASSWORD_MIN_LENGTH=8 + +# Enable two-factor authentication +ENABLE_2FA=true + +# TOTP issuer name +TOTP_ISSUER_NAME=Chatwoot +``` + +### CORS Configuration + +```bash +# Allowed origins for CORS +CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com + +# Enable CORS credentials +CORS_CREDENTIALS=true +``` + +### Content Security Policy + +```bash +# Enable CSP +ENABLE_CSP=true + +# CSP report URI +CSP_REPORT_URI=/csp-report + +# CSP directives +CSP_DEFAULT_SRC='self' +CSP_SCRIPT_SRC='self' 'unsafe-inline' 'unsafe-eval' +CSP_STYLE_SRC='self' 'unsafe-inline' +``` + +## Performance Configuration + +### Caching + +```bash +# Enable caching +ENABLE_CACHING=true + +# Cache store (memory_store, redis_cache_store) +CACHE_STORE=redis_cache_store + +# Cache namespace +CACHE_NAMESPACE=chatwoot_cache + +# Cache TTL (seconds) +CACHE_TTL=3600 +``` + +### Rate Limiting + +```bash +# Enable rate limiting +ENABLE_RATE_LIMITING=true + +# Rate limit store (memory_store, redis_store) +RATE_LIMIT_STORE=redis_store + +# API rate limit (requests per minute) +API_RATE_LIMIT=100 + +# Login rate limit (attempts per minute) +LOGIN_RATE_LIMIT=5 +``` + +### Asset Configuration + +```bash +# Asset host (for CDN) +ASSET_HOST=https://cdn.yourdomain.com + +# Enable asset compression +ENABLE_ASSET_COMPRESSION=true + +# Asset cache TTL (seconds) +ASSET_CACHE_TTL=31536000 +``` + +## Development and Testing + +### Development Settings + +```bash +# Enable development features +ENABLE_DEVELOPMENT_FEATURES=false + +# Development email delivery +DEVELOPMENT_EMAIL_DELIVERY=true + +# Development file storage +DEVELOPMENT_FILE_STORAGE=local + +# Enable SQL logging +ENABLE_SQL_LOGGING=false +``` + +### Testing Configuration + +```bash +# Test database URL +TEST_DATABASE_URL=postgresql://username:password@localhost/chatwoot_test + +# Test Redis URL +TEST_REDIS_URL=redis://localhost:6379/1 + +# Enable test coverage +ENABLE_TEST_COVERAGE=true + +# Test email delivery +TEST_EMAIL_DELIVERY=test +``` + +## Logging Configuration + +### Log Settings + +```bash +# Log level (debug, info, warn, error, fatal) +LOG_LEVEL=info + +# Log format (text, json) +LOG_FORMAT=text + +# Log to stdout +LOG_TO_STDOUT=true + +# Log file path +LOG_FILE_PATH=/var/log/chatwoot/chatwoot.log + +# Log rotation +LOG_ROTATION=daily +LOG_RETENTION=30 +``` + +### Structured Logging + +```bash +# Enable structured logging +ENABLE_STRUCTURED_LOGGING=true + +# Log correlation ID +LOG_CORRELATION_ID=true + +# Log request ID +LOG_REQUEST_ID=true + +# Log user context +LOG_USER_CONTEXT=true +``` + +## Feature Flags + +### Experimental Features + +```bash +# Enable experimental features +ENABLE_EXPERIMENTAL_FEATURES=false + +# Feature flags +FEATURE_FLAG_CONVERSATION_CONTINUITY=true +FEATURE_FLAG_AUTO_RESOLVE=false +FEATURE_FLAG_CUSTOM_ATTRIBUTES=true +FEATURE_FLAG_TEAM_MANAGEMENT=true +``` + +## Webhook Configuration + +```bash +# Webhook URL for external integrations +WEBHOOK_URL=https://your-webhook-endpoint.com/chatwoot + +# Webhook secret for verification +WEBHOOK_SECRET=your-webhook-secret + +# Webhook timeout (seconds) +WEBHOOK_TIMEOUT=30 + +# Webhook retry attempts +WEBHOOK_RETRY_ATTEMPTS=3 +``` + +## Custom Branding + +```bash +# Custom brand name +BRAND_NAME=Your Company + +# Custom logo URL +BRAND_LOGO_URL=https://yourdomain.com/logo.png + +# Custom favicon URL +BRAND_FAVICON_URL=https://yourdomain.com/favicon.ico + +# Custom primary color +BRAND_PRIMARY_COLOR=#1f93ff + +# Custom secondary color +BRAND_SECONDARY_COLOR=#f0f0f0 +``` + +## Environment-Specific Examples + +### Production Environment + +```bash +# Production .env example +RAILS_ENV=production +NODE_ENV=production +FRONTEND_URL=https://chat.yourcompany.com +FORCE_SSL=true +SECRET_KEY_BASE=your-production-secret-key + +# Database +DATABASE_URL=postgresql://chatwoot:secure-password@db.yourcompany.com:5432/chatwoot_production + +# Redis +REDIS_URL=redis://redis.yourcompany.com:6379/0 + +# Email +MAILER_SENDER_EMAIL=noreply@yourcompany.com +SMTP_ADDRESS=smtp.yourcompany.com +SMTP_PORT=587 +SMTP_USERNAME=noreply@yourcompany.com +SMTP_PASSWORD=your-smtp-password + +# Storage +ACTIVE_STORAGE_SERVICE=amazon +S3_BUCKET_NAME=yourcompany-chatwoot +AWS_ACCESS_KEY_ID=your-aws-key +AWS_SECRET_ACCESS_KEY=your-aws-secret +AWS_REGION=us-east-1 + +# Security +ENABLE_2FA=true +ENABLE_RATE_LIMITING=true +CORS_ORIGINS=https://yourcompany.com + +# Monitoring +SENTRY_DSN=your-sentry-dsn +NEW_RELIC_LICENSE_KEY=your-newrelic-key +``` + +### Development Environment + +```bash +# Development .env example +RAILS_ENV=development +NODE_ENV=development +FRONTEND_URL=http://localhost:3000 +FORCE_SSL=false + +# Database +DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development + +# Redis +REDIS_URL=redis://localhost:6379/0 + +# Email (development) +MAILER_SENDER_EMAIL=dev@localhost +EMAIL_DELIVERY_METHOD=test + +# Storage (local) +ACTIVE_STORAGE_SERVICE=local + +# Development features +ENABLE_DEVELOPMENT_FEATURES=true +ENABLE_SQL_LOGGING=true +LOG_LEVEL=debug +``` + +## Validation and Best Practices + +### Required Variables + + +These environment variables are required for Chatwoot to function properly: +- `FRONTEND_URL` +- `SECRET_KEY_BASE` +- `DATABASE_URL` or individual database components +- `REDIS_URL` or individual Redis components + + +### Security Best Practices + + +**Security Recommendations:** +- Use strong, unique passwords for all services +- Enable SSL/TLS for all external connections +- Use environment-specific secret keys +- Enable rate limiting and CORS protection +- Regularly rotate API keys and passwords +- Use managed services for databases when possible + + +### Performance Optimization + + +**Performance Tips:** +- Adjust `SIDEKIQ_CONCURRENCY` based on your server resources +- Use Redis for caching and session storage +- Configure CDN for static assets +- Enable compression and caching +- Monitor and adjust database pool sizes + + +--- + +This comprehensive environment variables reference covers all aspects of Chatwoot configuration. Customize these settings based on your specific deployment requirements and infrastructure setup. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx b/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx new file mode 100644 index 000000000..91b6f31ee --- /dev/null +++ b/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx @@ -0,0 +1,416 @@ +--- +title: Chatwoot CTL (cwctl) +description: Command-line tool for managing Chatwoot installations with ease +sidebarTitle: Chatwoot CTL +--- + +# Chatwoot CTL (cwctl) + +Chatwoot CTL (`cwctl`) is a command-line tool that simplifies the management of your Chatwoot installation. It provides convenient commands for common administrative tasks like upgrades, restarts, console access, and log viewing. + +## Installation + +### Automatic Installation + +`cwctl` is automatically installed when you use the Linux installation script (v2.7.0+): + +```bash +wget https://get.chatwoot.app/linux/install.sh +chmod +x install.sh +./install.sh --install +``` + +### Manual Installation + +If you have an older installation or need to install `cwctl` separately: + +```bash +# Download and install cwctl +wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl +chmod +x /usr/local/bin/cwctl + +# Verify installation +cwctl --help +``` + + +The manual installation requires root access to install `cwctl` to `/usr/local/bin`. + + +## Available Commands + +### Help and Version + +```bash +# Display help information +cwctl --help +cwctl -h + +# Show version information +cwctl --version +cwctl -v +``` + +### Installation Management + +```bash +# Install Chatwoot (same as running install.sh --install) +cwctl --install + +# Upgrade to the latest version +cwctl --upgrade + +# Restart Chatwoot services +cwctl --restart +cwctl -r +``` + +### Console and Debugging + +```bash +# Access Rails console +cwctl --console +cwctl -c + +# View web server logs +cwctl --logs web +cwctl -l web + +# View worker logs +cwctl --logs worker +cwctl -l worker + +# View all logs +cwctl --logs +cwctl -l +``` + +### Service Management + +```bash +# Check service status +cwctl --status +cwctl -s + +# Stop Chatwoot services +cwctl --stop + +# Start Chatwoot services +cwctl --start +``` + +## Detailed Command Usage + +### Upgrading Chatwoot + +The upgrade command handles the complete upgrade process: + +```bash +cwctl --upgrade +``` + +This command performs the following steps: +1. Switches to the chatwoot user +2. Navigates to the Chatwoot directory +3. Pulls the latest code from the master branch +4. Updates Ruby version if needed +5. Installs/updates dependencies (bundle, pnpm) +6. Precompiles assets +7. Runs database migrations +8. Updates systemd service files +9. Restarts services + + +Always backup your database before upgrading: +```bash +# Create a backup before upgrading +sudo -u postgres pg_dump chatwoot_production > chatwoot_backup_$(date +%Y%m%d).sql +``` + + +### Console Access + +Access the Rails console for debugging and administration: + +```bash +cwctl --console +``` + +This opens an interactive Ruby console where you can: + +```ruby +# Check application version +Rails.application.config.version + +# List all accounts +Account.all + +# Find a specific user +User.find_by(email: 'admin@example.com') + +# Check system statistics +Account.count +User.count +Conversation.count + +# Clear cache +Rails.cache.clear +``` + +### Log Management + +View real-time logs for troubleshooting: + +```bash +# Web server logs (Rails application) +cwctl -l web + +# Worker logs (Sidekiq background jobs) +cwctl -l worker + +# All logs (both web and worker) +cwctl -l +``` + +### Service Management + +Control Chatwoot services: + +```bash +# Check if services are running +cwctl --status + +# Restart all services (web + worker) +cwctl --restart + +# Stop all services +cwctl --stop + +# Start all services +cwctl --start +``` + +## Configuration + +### Environment Variables + +`cwctl` respects the same environment variables as your Chatwoot installation. Key variables include: + +```bash +# Chatwoot installation directory +CHATWOOT_DIR="/home/chatwoot/chatwoot" + +# Rails environment +RAILS_ENV="production" + +# Database configuration +DATABASE_URL="postgresql://..." + +# Redis configuration +REDIS_URL="redis://..." +``` + +### Custom Installation Paths + +If Chatwoot is installed in a non-standard location, you can specify the path: + +```bash +# Set custom Chatwoot directory +export CHATWOOT_DIR="/opt/chatwoot" +cwctl --restart +``` + +## Troubleshooting + +### Common Issues + + +If `cwctl` is not found, ensure it's installed and in your PATH: + +```bash +# Check if cwctl exists +which cwctl + +# If not found, install it +wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl +chmod +x /usr/local/bin/cwctl + +# Add to PATH if needed +echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + + + +Ensure you have the necessary permissions: + +```bash +# Run with sudo if needed +sudo cwctl --restart + +# Or ensure your user is in the chatwoot group +sudo usermod -a -G chatwoot $USER +``` + + + +If services fail to restart, check the logs: + +```bash +# Check systemd status +sudo systemctl status chatwoot.target +sudo systemctl status chatwoot-web.1.service +sudo systemctl status chatwoot-worker.1.service + +# View detailed logs +sudo journalctl -u chatwoot-web.1.service -f +sudo journalctl -u chatwoot-worker.1.service -f +``` + + +### Debug Mode + +For verbose output during operations: + +```bash +# Enable debug mode +export CWCTL_DEBUG=1 +cwctl --upgrade +``` + +### Manual Operations + +If `cwctl` fails, you can perform operations manually: + +```bash +# Manual upgrade process +sudo -i -u chatwoot +cd chatwoot +git checkout master && git pull +rvm use 3.3.3 --default +bundle install +pnpm install +RAILS_ENV=production bundle exec rake assets:precompile +RAILS_ENV=production bundle exec rake db:migrate +exit + +# Restart services manually +sudo systemctl restart chatwoot.target +``` + +## Best Practices + +### Regular Maintenance + +```bash +# Weekly upgrade check +cwctl --upgrade + +# Daily log monitoring +cwctl -l | grep ERROR + +# Monthly service restart +cwctl --restart +``` + +### Backup Before Operations + +```bash +# Create backup script +#!/bin/bash +DATE=$(date +%Y%m%d_%H%M%S) +sudo -u postgres pg_dump chatwoot_production > "/backup/chatwoot_$DATE.sql" +cwctl --upgrade +``` + +### Monitoring + +```bash +# Check service health +cwctl --status + +# Monitor logs for errors +cwctl -l | grep -E "(ERROR|FATAL|Exception)" + +# Check disk space before upgrades +df -h /home/chatwoot +``` + +## Integration with System Tools + +### Systemd Integration + +`cwctl` works seamlessly with systemd: + +```bash +# These commands are equivalent +cwctl --restart +sudo systemctl restart chatwoot.target + +cwctl --status +sudo systemctl status chatwoot.target +``` + +### Cron Jobs + +Automate maintenance tasks: + +```bash +# Add to crontab +# Weekly upgrade (Sundays at 2 AM) +0 2 * * 0 /usr/local/bin/cwctl --upgrade + +# Daily restart (to clear memory leaks) +0 3 * * * /usr/local/bin/cwctl --restart +``` + +### Monitoring Scripts + +```bash +#!/bin/bash +# Health check script +if ! cwctl --status > /dev/null 2>&1; then + echo "Chatwoot services are down, attempting restart..." + cwctl --restart + # Send alert notification +fi +``` + +## Advanced Usage + +### Custom Commands + +You can extend `cwctl` functionality by creating wrapper scripts: + +```bash +#!/bin/bash +# custom-cwctl.sh - Extended cwctl with additional features + +case "$1" in + --backup) + echo "Creating backup..." + sudo -u postgres pg_dump chatwoot_production > "backup_$(date +%Y%m%d).sql" + ;; + --health-check) + echo "Performing health check..." + curl -f http://localhost:3000/api || echo "Health check failed" + ;; + *) + cwctl "$@" + ;; +esac +``` + +### Environment-Specific Operations + +```bash +# Development environment +RAILS_ENV=development cwctl --console + +# Staging environment +RAILS_ENV=staging cwctl --restart +``` + +--- + +`cwctl` simplifies Chatwoot administration by providing a unified interface for common tasks. Use it regularly to maintain your installation and troubleshoot issues efficiently. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/docker.mdx b/developer-docs/self-hosted/deployment/docker.mdx new file mode 100644 index 000000000..a083eddf5 --- /dev/null +++ b/developer-docs/self-hosted/deployment/docker.mdx @@ -0,0 +1,572 @@ +--- +title: Docker Deployment Guide +description: Complete guide to deploy Chatwoot using Docker containers for production environments. +sidebarTitle: Docker +--- + +Docker provides a consistent, portable way to deploy Chatwoot across different environments. This guide covers production deployment using Docker Compose with best practices for security, performance, and maintenance. + +## Prerequisites + +Before starting, ensure you have: + +- Docker 20.10+ installed +- Docker Compose 2.0+ installed +- At least 4GB RAM and 2 CPU cores +- Domain name with DNS configured (recommended) +- Basic understanding of Docker concepts + +### Version Check + +Verify your Docker installation: + +```bash +$ docker --version +Docker version 25.0.4, build 1a576c5 + +$ docker compose version +Docker Compose version v2.24.7 +``` + + +Container names use dashes instead of underscores by default with newer Docker Compose versions. If using an older version, replace `-` with `_` and use `docker-compose` instead of `docker compose`. + + +## Quick Start + +### 1. Install Docker + +**Ubuntu/Debian:** +```bash +# Update package index +apt-get update && apt-get upgrade -y + +# Install Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +# Install Docker Compose plugin +apt install docker-compose-plugin + +# Add user to docker group (optional) +sudo usermod -aG docker $USER +``` + +**CentOS/RHEL:** +```bash +# Install Docker +sudo yum install -y yum-utils +sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo +sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin + +# Start Docker service +sudo systemctl start docker +sudo systemctl enable docker +``` + +### 2. Download Configuration Files + +```bash +# Create project directory +mkdir chatwoot && cd chatwoot + +# Download environment template +wget -O .env https://raw.githubusercontent.com/chatwoot/chatwoot/develop/.env.example + +# Download Docker Compose configuration +wget -O docker-compose.yaml https://raw.githubusercontent.com/chatwoot/chatwoot/develop/docker-compose.production.yaml +``` + +### 3. Configure Environment + +Edit the `.env` file with your settings: + +```bash +nano .env +``` + +**Essential configurations:** + +```env +# Database Configuration +POSTGRES_PASSWORD=your_secure_postgres_password +REDIS_PASSWORD=your_secure_redis_password + +# Application Configuration +SECRET_KEY_BASE=your_secret_key_base_64_chars_long +FRONTEND_URL=https://your-domain.com + +# Email Configuration (required for notifications) +MAILER_SENDER_EMAIL=noreply@your-domain.com +SMTP_ADDRESS=smtp.your-provider.com +SMTP_PORT=587 +SMTP_USERNAME=your-smtp-username +SMTP_PASSWORD=your-smtp-password +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true + +# File Storage (optional - defaults to local) +ACTIVE_STORAGE_SERVICE=local +# For S3: ACTIVE_STORAGE_SERVICE=amazon +# AWS_ACCESS_KEY_ID=your_access_key +# AWS_SECRET_ACCESS_KEY=your_secret_key +# AWS_REGION=us-east-1 +# AWS_BUCKET=your-bucket-name +``` + +### 4. Update Docker Compose + +Edit `docker-compose.yaml` to match your `.env` passwords: + +```yaml +services: + postgres: + environment: + - POSTGRES_PASSWORD=your_secure_postgres_password # Match .env + + redis: + command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"] +``` + +### 5. Initialize Database + +```bash +# Prepare the database +docker compose run --rm rails bundle exec rails db:chatwoot_prepare +``` + +### 6. Start Services + +```bash +# Start all services in background +docker compose up -d + +# Check service status +docker compose ps +``` + +### 7. Verify Installation + +```bash +# Check if Chatwoot is responding +curl -I localhost:3000/api + +# Should return: HTTP/1.1 200 OK +``` + +## Production Configuration + +### Docker Compose Setup + +Here's a complete production-ready `docker-compose.yaml`: + +```yaml +version: '3.8' + +services: + base: &base + image: chatwoot/chatwoot:latest + env_file: .env + volumes: + - ./data/storage:/app/storage + depends_on: + - postgres + - redis + + rails: + <<: *base + container_name: chatwoot-rails + command: ["sh", "-c", "bundle exec rails s -b 0.0.0.0 -p 3000"] + ports: + - "127.0.0.1:3000:3000" + environment: + - NODE_ENV=production + - RAILS_ENV=production + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/api"] + interval: 30s + timeout: 10s + retries: 3 + + sidekiq: + <<: *base + container_name: chatwoot-sidekiq + command: ["sh", "-c", "bundle exec sidekiq -C config/sidekiq.yml"] + restart: unless-stopped + healthcheck: + test: ["CMD", "pgrep", "-f", "sidekiq"] + interval: 30s + timeout: 10s + retries: 3 + + postgres: + image: postgres:14-alpine + container_name: chatwoot-postgres + restart: unless-stopped + ports: + - "127.0.0.1:5432:5432" + volumes: + - ./data/postgres:/var/lib/postgresql/data + environment: + - POSTGRES_DB=chatwoot + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=your_secure_postgres_password + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 10s + retries: 3 + + redis: + image: redis:7-alpine + container_name: chatwoot-redis + restart: unless-stopped + command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"] + ports: + - "127.0.0.1:6379:6379" + volumes: + - ./data/redis:/data + healthcheck: + test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + interval: 30s + timeout: 10s + retries: 3 + +volumes: + postgres_data: + redis_data: + storage_data: +``` + +### Nginx Reverse Proxy + +Create `/etc/nginx/sites-available/chatwoot.conf`: + +```nginx +server { + server_name your-domain.com; + + # Point upstream to Chatwoot App Server + set $upstream 127.0.0.1:3000; + + # Nginx strips out underscore in headers by default + # Chatwoot relies on underscore in headers for API + underscores_in_headers on; + + # Increase client max body size for file uploads + client_max_body_size 50M; + + location /.well-known { + alias /var/www/ssl-proof/chatwoot/.well-known; + } + + location / { + proxy_pass_header Authorization; + proxy_pass http://$upstream; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Ssl on; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_buffering off; + proxy_read_timeout 36000s; + proxy_redirect off; + } + + listen 80; +} +``` + +Enable the site and configure SSL: + +```bash +# Enable site +sudo ln -s /etc/nginx/sites-available/chatwoot.conf /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl reload nginx + +# Install Certbot and get SSL certificate +sudo apt install certbot python3-certbot-nginx +sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known +sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx +``` + +## Advanced Configuration + +### Environment Variables + +Key environment variables for production: + +```env +# Application +RAILS_ENV=production +NODE_ENV=production +SECRET_KEY_BASE=generate_64_character_secret +FRONTEND_URL=https://your-domain.com + +# Database +DATABASE_URL=postgresql://postgres:password@postgres:5432/chatwoot +REDIS_URL=redis://redis:6379/0 +REDIS_PASSWORD=your_redis_password + +# Email +MAILER_SENDER_EMAIL=noreply@your-domain.com +SMTP_ADDRESS=smtp.your-provider.com +SMTP_PORT=587 +SMTP_USERNAME=your_username +SMTP_PASSWORD=your_password +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true + +# File Storage +ACTIVE_STORAGE_SERVICE=amazon +AWS_ACCESS_KEY_ID=your_access_key +AWS_SECRET_ACCESS_KEY=your_secret_key +AWS_REGION=us-east-1 +AWS_BUCKET=your-bucket-name + +# Security +FORCE_SSL=true +RAILS_LOG_TO_STDOUT=true + +# Performance +RAILS_MAX_THREADS=5 +WEB_CONCURRENCY=2 +``` + +### Resource Limits + +Add resource limits to your `docker-compose.yaml`: + +```yaml +services: + rails: + deploy: + resources: + limits: + cpus: '2.0' + memory: 2G + reservations: + cpus: '1.0' + memory: 1G + + sidekiq: + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.5' + memory: 512M + + postgres: + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.5' + memory: 512M + + redis: + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + reservations: + cpus: '0.25' + memory: 256M +``` + +### Logging Configuration + +Configure centralized logging: + +```yaml +services: + rails: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + sidekiq: + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +## Maintenance Operations + +### Upgrading Chatwoot + +```bash +# Pull latest images +docker compose pull + +# Stop services +docker compose down + +# Start with new images +docker compose up -d + +# Run database migrations +docker compose run --rm rails bundle exec rails db:chatwoot_prepare +``` + +### Backup and Restore + +**Database Backup:** +```bash +# Create backup +docker compose exec postgres pg_dump -U postgres chatwoot > backup_$(date +%Y%m%d_%H%M%S).sql + +# Restore backup +docker compose exec -T postgres psql -U postgres chatwoot < backup_file.sql +``` + +**File Storage Backup:** +```bash +# Backup storage directory +tar -czf storage_backup_$(date +%Y%m%d_%H%M%S).tar.gz ./data/storage/ +``` + +### Monitoring and Logs + +**View logs:** +```bash +# All services +docker compose logs -f + +# Specific service +docker compose logs -f rails +docker compose logs -f sidekiq + +# Last 100 lines +docker compose logs --tail=100 rails +``` + +**Monitor resources:** +```bash +# Container stats +docker stats + +# Service health +docker compose ps +``` + +### Rails Console Access + +```bash +# Access Rails console +docker compose exec rails bundle exec rails console + +# Run one-off commands +docker compose run --rm rails bundle exec rails runner "puts User.count" +``` + +## Troubleshooting + +### Common Issues + +**1. Permission Issues:** +```bash +# Fix file permissions +sudo chown -R 1000:1000 ./data/ +``` + +**2. Database Connection Issues:** +```bash +# Check database connectivity +docker compose exec rails bundle exec rails db:version +``` + +**3. Memory Issues:** +```bash +# Check memory usage +docker stats --no-stream +``` + +**4. SSL Certificate Issues:** +```bash +# Renew certificates +sudo certbot renew --dry-run +``` + +### Performance Optimization + +**1. Database Optimization:** +```sql +-- Connect to database +docker compose exec postgres psql -U postgres chatwoot + +-- Check slow queries +SELECT query, mean_time, calls +FROM pg_stat_statements +ORDER BY mean_time DESC +LIMIT 10; +``` + +**2. Redis Optimization:** +```bash +# Check Redis memory usage +docker compose exec redis redis-cli info memory +``` + +### Security Hardening + +**1. Network Security:** +```yaml +# Add to docker-compose.yaml +networks: + chatwoot: + driver: bridge + internal: true + +services: + rails: + networks: + - chatwoot + - default # Only rails needs external access +``` + +**2. Secrets Management:** +```bash +# Use Docker secrets for sensitive data +echo "your_secret_password" | docker secret create postgres_password - +``` + +## Community Edition vs Enterprise + +This guide covers Chatwoot Community Edition (CE). For Enterprise features: + +**CE Docker Tags:** +- `chatwoot/chatwoot:latest-ce` (latest CE) +- `chatwoot/chatwoot:v2.3.2-ce` (specific version CE) + +**Enterprise Features:** +- Advanced reporting and analytics +- SAML SSO integration +- Advanced automation rules +- Priority support + +--- + + +Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and file storage. + + + +For high-availability deployments, consider using Docker Swarm or Kubernetes instead of Docker Compose. + \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/kubernetes.mdx b/developer-docs/self-hosted/deployment/kubernetes.mdx new file mode 100644 index 000000000..30c45b96b --- /dev/null +++ b/developer-docs/self-hosted/deployment/kubernetes.mdx @@ -0,0 +1,537 @@ +--- +title: Kubernetes Deployment +description: Deploy Chatwoot on Kubernetes using Helm charts for scalable, production-ready installations +sidebarTitle: Kubernetes +--- + +# Kubernetes Deployment Guide + +Deploy Chatwoot on Kubernetes using our official Helm charts for a scalable, production-ready installation. + +## Prerequisites + +Before deploying Chatwoot on Kubernetes, ensure you have: + +- **Kubernetes cluster** (v1.19+) with sufficient resources +- **Helm 3.x** installed and configured +- **kubectl** configured to access your cluster +- **Ingress controller** (nginx, traefik, etc.) for external access +- **Cert-manager** (optional, for automatic SSL certificates) + +### Minimum Resource Requirements + +- **CPU**: 2 cores minimum (4+ cores recommended) +- **Memory**: 4GB RAM minimum (8GB+ recommended) +- **Storage**: 20GB persistent storage for PostgreSQL +- **Nodes**: 3+ nodes for high availability + +## Quick Start + +### 1. Add Chatwoot Helm Repository + +```bash +helm repo add chatwoot https://chatwoot.github.io/charts +helm repo update +``` + +### 2. Create Namespace + +```bash +kubectl create namespace chatwoot +``` + +### 3. Install with Default Values + +```bash +helm install chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --set ingress.enabled=true \ + --set ingress.hosts[0].host=chatwoot.yourdomain.com \ + --set ingress.hosts[0].paths[0].path=/ \ + --set ingress.hosts[0].paths[0].pathType=Prefix +``` + +## Production Configuration + +### Custom Values File + +Create a `values.yaml` file for production deployment: + +```yaml +# values.yaml +replicaCount: 3 + +image: + repository: chatwoot/chatwoot + tag: "latest" + pullPolicy: IfNotPresent + +env: + RAILS_ENV: production + NODE_ENV: production + FRONTEND_URL: "https://chatwoot.yourdomain.com" + FORCE_SSL: "true" + +# Database Configuration +postgresql: + enabled: true + auth: + postgresPassword: "your-secure-password" + database: "chatwoot_production" + primary: + persistence: + enabled: true + size: 50Gi + storageClass: "fast-ssd" + metrics: + enabled: true + +# Redis Configuration +redis: + enabled: true + auth: + enabled: true + password: "your-redis-password" + master: + persistence: + enabled: true + size: 10Gi + metrics: + enabled: true + +# Ingress Configuration +ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/proxy-body-size: "50m" + nginx.ingress.kubernetes.io/proxy-read-timeout: "300" + nginx.ingress.kubernetes.io/proxy-send-timeout: "300" + hosts: + - host: chatwoot.yourdomain.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: chatwoot-tls + hosts: + - chatwoot.yourdomain.com + +# Resource Limits +resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 1000m + memory: 2Gi + +# Horizontal Pod Autoscaler +autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 80 + +# Storage Configuration +persistence: + enabled: true + storageClass: "fast-ssd" + size: 20Gi + +# Service Configuration +service: + type: ClusterIP + port: 3000 + +# Worker Configuration +worker: + enabled: true + replicaCount: 2 + resources: + limits: + cpu: 1000m + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + +# Monitoring +serviceMonitor: + enabled: true + namespace: monitoring +``` + +### Deploy with Custom Configuration + +```bash +helm install chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --values values.yaml +``` + +## External Dependencies + +### Using External PostgreSQL + +```yaml +postgresql: + enabled: false + +env: + DATABASE_URL: "postgresql://username:password@postgres-host:5432/chatwoot_production" +``` + +### Using External Redis + +```yaml +redis: + enabled: false + +env: + REDIS_URL: "redis://redis-host:6379/0" +``` + +### Using Cloud Storage + +```yaml +env: + # AWS S3 + ACTIVE_STORAGE_SERVICE: "amazon" + S3_BUCKET_NAME: "your-chatwoot-bucket" + AWS_ACCESS_KEY_ID: "your-access-key" + AWS_SECRET_ACCESS_KEY: "your-secret-key" + AWS_REGION: "us-east-1" + + # Google Cloud Storage + # ACTIVE_STORAGE_SERVICE: "google" + # GCS_PROJECT: "your-project" + # GCS_BUCKET: "your-bucket" +``` + +## High Availability Setup + +### Multi-Zone Deployment + +```yaml +# Spread pods across availability zones +affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - chatwoot + topologyKey: topology.kubernetes.io/zone + +# Node selection +nodeSelector: + node-type: "application" + +# Tolerations for dedicated nodes +tolerations: +- key: "dedicated" + operator: "Equal" + value: "chatwoot" + effect: "NoSchedule" +``` + +### Database High Availability + +```yaml +postgresql: + enabled: true + architecture: replication + auth: + replicationPassword: "replication-password" + primary: + persistence: + enabled: true + size: 100Gi + readReplicas: + replicaCount: 2 + persistence: + enabled: true + size: 100Gi +``` + +## Security Configuration + +### Network Policies + +```yaml +# network-policy.yaml +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: chatwoot-network-policy + namespace: chatwoot +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: chatwoot + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + name: ingress-nginx + ports: + - protocol: TCP + port: 3000 + egress: + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + ports: + - protocol: TCP + port: 5432 + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: redis + ports: + - protocol: TCP + port: 6379 +``` + +### Pod Security Standards + +```yaml +securityContext: + runAsNonRoot: true + runAsUser: 1001 + fsGroup: 1001 + seccompProfile: + type: RuntimeDefault + +containerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1001 + capabilities: + drop: + - ALL +``` + +## Monitoring and Observability + +### Prometheus Monitoring + +```yaml +serviceMonitor: + enabled: true + labels: + app: chatwoot + interval: 30s + scrapeTimeout: 10s + path: /metrics + +# Custom metrics +env: + PROMETHEUS_EXPORTER: "true" + PROMETHEUS_EXPORTER_PORT: "9394" +``` + +### Logging Configuration + +```yaml +# Structured logging +env: + LOG_LEVEL: "info" + LOG_FORMAT: "json" + +# Log aggregation with Fluentd/Fluent Bit +annotations: + fluentbit.io/parser: "json" + fluentbit.io/exclude: "false" +``` + +### Health Checks + +```yaml +livenessProbe: + httpGet: + path: /api + port: 3000 + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 3 + +readinessProbe: + httpGet: + path: /api + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 +``` + +## Backup and Disaster Recovery + +### Database Backup + +```yaml +# CronJob for database backup +apiVersion: batch/v1 +kind: CronJob +metadata: + name: chatwoot-db-backup + namespace: chatwoot +spec: + schedule: "0 2 * * *" # Daily at 2 AM + jobTemplate: + spec: + template: + spec: + containers: + - name: postgres-backup + image: postgres:15 + command: + - /bin/bash + - -c + - | + pg_dump $DATABASE_URL | gzip > /backup/chatwoot-$(date +%Y%m%d-%H%M%S).sql.gz + # Upload to S3 or other storage + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: chatwoot-secrets + key: database-url + volumeMounts: + - name: backup-storage + mountPath: /backup + volumes: + - name: backup-storage + persistentVolumeClaim: + claimName: backup-pvc + restartPolicy: OnFailure +``` + +## Upgrading Chatwoot + +### Rolling Update + +```bash +# Update to latest version +helm upgrade chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --values values.yaml + +# Update to specific version +helm upgrade chatwoot chatwoot/chatwoot \ + --namespace chatwoot \ + --values values.yaml \ + --set image.tag="v2.15.0" +``` + +### Database Migration + +```bash +# Run migrations after upgrade +kubectl exec -it deployment/chatwoot -n chatwoot -- \ + bundle exec rails db:migrate RAILS_ENV=production +``` + +## Troubleshooting + +### Common Issues + + +**Pod Startup Issues**: Check resource limits and node capacity +```bash +kubectl describe pod -n chatwoot +kubectl top nodes +``` + + + +**Database Connection Issues**: Verify database credentials and network policies +```bash +kubectl logs deployment/chatwoot -n chatwoot +kubectl exec -it deployment/chatwoot -n chatwoot -- nc -zv postgres-host 5432 +``` + + +### Debug Commands + +```bash +# Check pod status +kubectl get pods -n chatwoot + +# View logs +kubectl logs -f deployment/chatwoot -n chatwoot + +# Access pod shell +kubectl exec -it deployment/chatwoot -n chatwoot -- /bin/bash + +# Check service endpoints +kubectl get endpoints -n chatwoot + +# Describe ingress +kubectl describe ingress chatwoot -n chatwoot +``` + +### Performance Tuning + +```yaml +# Optimize for high traffic +env: + RAILS_MAX_THREADS: "20" + WEB_CONCURRENCY: "4" + SIDEKIQ_CONCURRENCY: "25" + +resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 2000m + memory: 4Gi + +# Database connection pooling +env: + DATABASE_POOL_SIZE: "25" +``` + +## Best Practices + +### Resource Management +- Set appropriate resource requests and limits +- Use horizontal pod autoscaling for dynamic scaling +- Monitor resource usage and adjust as needed + +### Security +- Use network policies to restrict traffic +- Enable pod security standards +- Regularly update container images +- Use secrets for sensitive configuration + +### Monitoring +- Enable Prometheus metrics collection +- Set up alerting for critical metrics +- Monitor application and infrastructure health +- Use distributed tracing for complex issues + +### Backup +- Implement automated database backups +- Test backup restoration procedures +- Store backups in multiple locations +- Document recovery procedures + +--- + +This Kubernetes deployment guide provides a solid foundation for running Chatwoot in production. Customize the configuration based on your specific requirements and infrastructure setup. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/linux-vm.mdx b/developer-docs/self-hosted/deployment/linux-vm.mdx new file mode 100644 index 000000000..d3f30b297 --- /dev/null +++ b/developer-docs/self-hosted/deployment/linux-vm.mdx @@ -0,0 +1,675 @@ +--- +title: Linux VM Deployment Guide +description: Complete guide to deploy Chatwoot on Linux virtual machines using the automated installation script. +sidebarTitle: Linux VM +--- + +This guide covers deploying Chatwoot on Linux virtual machines using our automated installation script. This method is ideal for traditional server environments and provides full control over the installation process. + +## Prerequisites + +Before starting, ensure you have: + +- Ubuntu 20.04 LTS or later (recommended) +- At least 4GB RAM and 2 CPU cores +- 50GB+ available disk space +- Root or sudo access +- Domain name with DNS configured (optional but recommended) +- SMTP server for email notifications + +### Supported Operating Systems + +| OS | Version | Status | +|---|---|---| +| **Ubuntu** | 20.04 LTS, 22.04 LTS, 24.04 LTS | ✅ Recommended | +| **Debian** | 10, 11, 12 | ✅ Supported | +| **CentOS** | 8, 9 | ✅ Supported | +| **RHEL** | 8, 9 | ✅ Supported | +| **Amazon Linux** | 2 | ✅ Supported | + +## Quick Installation + +### 1. Download Installation Script + +```bash +# Download the installation script +wget https://get.chatwoot.app/linux/install.sh + +# Make it executable +chmod +x install.sh +``` + +### 2. Run Installation + +```bash +# Run the installation script +./install.sh --install +``` + +The script will: +- Install all required dependencies +- Set up PostgreSQL and Redis +- Install Ruby, Node.js, and other runtime dependencies +- Clone and configure Chatwoot +- Set up systemd services +- Configure Nginx (if domain is provided) +- Set up SSL with Let's Encrypt (if domain is provided) + +### 3. Domain Configuration (Optional) + +If you have a domain name: + +1. **Create DNS A Record**: Point your domain to your server's IP address +2. **During installation**: Enter `yes` when prompted about domain setup +3. **Enter your domain**: The script will configure Nginx and SSL automatically + +### 4. Access Your Installation + +- **With domain**: `https://your-domain.com` +- **Without domain**: `http://your-server-ip:3000` + +**Default login credentials:** +``` +URL: https://your-domain.com +Email: john@acme.inc +Password: Password1! +``` + +## Manual Installation + +For more control over the installation process, you can install manually: + +### 1. System Preparation + +```bash +# Update system packages +sudo apt update && sudo apt upgrade -y + +# Install essential packages +sudo apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates lsb-release +``` + +### 2. Install Dependencies + +**PostgreSQL:** +```bash +# Install PostgreSQL +sudo apt install -y postgresql postgresql-contrib + +# Start and enable PostgreSQL +sudo systemctl start postgresql +sudo systemctl enable postgresql + +# Create database and user +sudo -u postgres psql << EOF +CREATE DATABASE chatwoot; +CREATE USER chatwoot WITH ENCRYPTED PASSWORD 'your_secure_password'; +GRANT ALL PRIVILEGES ON DATABASE chatwoot TO chatwoot; +ALTER USER chatwoot CREATEDB; +\q +EOF +``` + +**Redis:** +```bash +# Install Redis +sudo apt install -y redis-server + +# Configure Redis +sudo sed -i 's/^# requirepass foobared/requirepass your_redis_password/' /etc/redis/redis.conf + +# Start and enable Redis +sudo systemctl start redis-server +sudo systemctl enable redis-server +``` + +**Ruby (using RVM):** +```bash +# Install RVM +curl -sSL https://get.rvm.io | bash -s stable +source ~/.rvm/scripts/rvm + +# Install Ruby +rvm install 3.3.3 +rvm use 3.3.3 --default +``` + +**Node.js:** +```bash +# Install Node.js 20.x +curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - +sudo apt install -y nodejs + +# Install pnpm +npm install -g pnpm +``` + +**Additional Dependencies:** +```bash +# Install build tools and libraries +sudo apt install -y git build-essential libssl-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libyaml-dev libsqlite3-dev libgdbm-compat-dev libncurses5-dev libreadline6-dev + +# Install ImageMagick for image processing +sudo apt install -y imagemagick libmagickwand-dev + +# Install FFmpeg for media processing +sudo apt install -y ffmpeg +``` + +### 3. Install Chatwoot + +```bash +# Create chatwoot user +sudo adduser --disabled-login --gecos "" chatwoot + +# Switch to chatwoot user +sudo -i -u chatwoot + +# Clone Chatwoot repository +git clone https://github.com/chatwoot/chatwoot.git +cd chatwoot + +# Checkout latest stable version +git checkout master + +# Install Ruby dependencies +bundle install + +# Install Node.js dependencies +pnpm install + +# Copy environment file +cp .env.example .env +``` + +### 4. Configure Environment + +Edit the `.env` file: + +```bash +nano .env +``` + +**Essential configurations:** + +```env +# Database Configuration +DATABASE_URL=postgresql://chatwoot:your_secure_password@localhost:5432/chatwoot + +# Redis Configuration +REDIS_URL=redis://localhost:6379/0 +REDIS_PASSWORD=your_redis_password + +# Application Configuration +SECRET_KEY_BASE=generate_a_64_character_secret_key +FRONTEND_URL=https://your-domain.com + +# Email Configuration +MAILER_SENDER_EMAIL=noreply@your-domain.com +SMTP_ADDRESS=smtp.your-provider.com +SMTP_PORT=587 +SMTP_USERNAME=your-smtp-username +SMTP_PASSWORD=your-smtp-password +SMTP_AUTHENTICATION=plain +SMTP_ENABLE_STARTTLS_AUTO=true + +# File Storage (optional) +ACTIVE_STORAGE_SERVICE=local +# For S3: ACTIVE_STORAGE_SERVICE=amazon +# AWS_ACCESS_KEY_ID=your_access_key +# AWS_SECRET_ACCESS_KEY=your_secret_key +# AWS_REGION=us-east-1 +# AWS_BUCKET=your-bucket-name + +# Security +FORCE_SSL=true +RAILS_ENV=production +NODE_ENV=production +``` + +### 5. Setup Database + +```bash +# Prepare the database +RAILS_ENV=production bundle exec rails db:chatwoot_prepare + +# Precompile assets +RAILS_ENV=production bundle exec rails assets:precompile +``` + +### 6. Configure Systemd Services + +Create systemd service files: + +**Web Service (`/etc/systemd/system/chatwoot-web.1.service`):** +```ini +[Unit] +Description=Chatwoot web server +After=network.target + +[Service] +Type=simple +User=chatwoot +WorkingDirectory=/home/chatwoot/chatwoot +Environment=RAILS_ENV=production +Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile +ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec rails server -b 0.0.0.0 -p 3000 -e production +Restart=always +RestartSec=1 + +[Install] +WantedBy=multi-user.target +``` + +**Worker Service (`/etc/systemd/system/chatwoot-worker.1.service`):** +```ini +[Unit] +Description=Chatwoot sidekiq worker +After=network.target + +[Service] +Type=simple +User=chatwoot +WorkingDirectory=/home/chatwoot/chatwoot +Environment=RAILS_ENV=production +Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile +ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec sidekiq -C config/sidekiq.yml +Restart=always +RestartSec=1 + +[Install] +WantedBy=multi-user.target +``` + +**Target Service (`/etc/systemd/system/chatwoot.target`):** +```ini +[Unit] +Description=Chatwoot services +Wants=chatwoot-web.1.service chatwoot-worker.1.service + +[Install] +WantedBy=multi-user.target +``` + +Enable and start services: +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable and start Chatwoot services +sudo systemctl enable chatwoot.target +sudo systemctl start chatwoot.target + +# Check status +sudo systemctl status chatwoot.target +``` + +### 7. Configure Nginx + +Install and configure Nginx: + +```bash +# Install Nginx +sudo apt install -y nginx + +# Create Nginx configuration +sudo nano /etc/nginx/sites-available/chatwoot +``` + +**Nginx configuration:** +```nginx +server { + server_name your-domain.com; + + # Point upstream to Chatwoot App Server + set $upstream 127.0.0.1:3000; + + # Nginx strips out underscore in headers by default + # Chatwoot relies on underscore in headers for API + underscores_in_headers on; + + # Increase client max body size for file uploads + client_max_body_size 50M; + + location /.well-known { + alias /var/www/ssl-proof/chatwoot/.well-known; + } + + location / { + proxy_pass_header Authorization; + proxy_pass http://$upstream; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Ssl on; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_buffering off; + proxy_read_timeout 36000s; + proxy_redirect off; + } + + listen 80; +} +``` + +Enable the site: +```bash +# Enable site +sudo ln -s /etc/nginx/sites-available/chatwoot /etc/nginx/sites-enabled/ + +# Test configuration +sudo nginx -t + +# Restart Nginx +sudo systemctl restart nginx +``` + +### 8. Setup SSL with Let's Encrypt + +```bash +# Install Certbot +sudo apt install -y certbot python3-certbot-nginx + +# Create directory for SSL verification +sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known + +# Get SSL certificate +sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx + +# Test automatic renewal +sudo certbot renew --dry-run +``` + +## Chatwoot CLI (cwctl) + +Starting with Chatwoot v2.7.0, the installation includes the Chatwoot CLI for easier management: + +### Installation + +If you don't have `cwctl` installed: + +```bash +# Download and install cwctl +sudo wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl +sudo chmod +x /usr/local/bin/cwctl + +# Verify installation +cwctl --help +``` + +### Usage + +```bash +# Restart Chatwoot services +cwctl -r + +# Upgrade Chatwoot +cwctl --upgrade + +# Access Rails console +cwctl -c + +# View logs +cwctl -l web # Web server logs +cwctl -l worker # Worker logs + +# Get help +cwctl --help +``` + +## Maintenance Operations + +### Upgrading Chatwoot + +**Using cwctl (recommended):** +```bash +cwctl --upgrade +``` + +**Manual upgrade:** +```bash +# Switch to chatwoot user +sudo -i -u chatwoot +cd chatwoot + +# Pull latest changes +git checkout master && git pull + +# Update Ruby version if needed +rvm install "ruby-3.3.3" +rvm use 3.3.3 --default + +# Update dependencies +bundle install +pnpm install + +# Precompile assets +RAILS_ENV=production bundle exec rails assets:precompile + +# Run database migrations +RAILS_ENV=production bundle exec rails db:migrate + +# Exit to root user +exit + +# Update systemd service files +sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/ +sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/ +sudo cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/ + +# Reload and restart services +sudo systemctl daemon-reload +sudo systemctl restart chatwoot.target +``` + +### Backup and Restore + +**Database Backup:** +```bash +# Create backup +sudo -u postgres pg_dump chatwoot > chatwoot_backup_$(date +%Y%m%d_%H%M%S).sql + +# Restore backup +sudo -u postgres psql chatwoot < chatwoot_backup_file.sql +``` + +**File Storage Backup:** +```bash +# Backup storage directory +sudo tar -czf chatwoot_storage_$(date +%Y%m%d_%H%M%S).tar.gz /home/chatwoot/chatwoot/storage/ +``` + +**Complete System Backup:** +```bash +# Create backup script +cat > /home/chatwoot/backup.sh << 'EOF' +#!/bin/bash +BACKUP_DIR="/backup/chatwoot/$(date +%Y%m%d_%H%M%S)" +mkdir -p $BACKUP_DIR + +# Database backup +sudo -u postgres pg_dump chatwoot > $BACKUP_DIR/database.sql + +# Application files +tar -czf $BACKUP_DIR/application.tar.gz /home/chatwoot/chatwoot/ + +# Storage files +tar -czf $BACKUP_DIR/storage.tar.gz /home/chatwoot/chatwoot/storage/ + +# Environment file +cp /home/chatwoot/chatwoot/.env $BACKUP_DIR/ + +echo "Backup completed: $BACKUP_DIR" +EOF + +chmod +x /home/chatwoot/backup.sh +``` + +### Monitoring and Logs + +**View logs:** +```bash +# Web server logs +sudo journalctl -u chatwoot-web.1.service -f + +# Worker logs +sudo journalctl -u chatwoot-worker.1.service -f + +# Nginx logs +sudo tail -f /var/log/nginx/access.log +sudo tail -f /var/log/nginx/error.log + +# PostgreSQL logs +sudo tail -f /var/log/postgresql/postgresql-*.log +``` + +**System monitoring:** +```bash +# Check service status +sudo systemctl status chatwoot.target + +# Check resource usage +htop +df -h +free -h + +# Check database connections +sudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity;" +``` + +### Rails Console Access + +```bash +# Using cwctl +cwctl -c + +# Manual access +sudo -i -u chatwoot +cd chatwoot +RAILS_ENV=production bundle exec rails console +``` + +## Troubleshooting + +### Common Issues + +**1. Asset Precompilation Fails:** +```bash +# Clear and rebuild assets +sudo -i -u chatwoot +cd chatwoot +RAILS_ENV=production bundle exec rails assets:clean assets:clobber assets:precompile +``` + +**2. Database Connection Issues:** +```bash +# Check PostgreSQL status +sudo systemctl status postgresql + +# Test database connection +sudo -u postgres psql -c "SELECT version();" + +# Check database configuration +sudo -i -u chatwoot +cd chatwoot +RAILS_ENV=production bundle exec rails db:version +``` + +**3. Permission Issues:** +```bash +# Fix file permissions +sudo chown -R chatwoot:chatwoot /home/chatwoot/chatwoot/ +``` + +**4. Service Won't Start:** +```bash +# Check service logs +sudo journalctl -u chatwoot-web.1.service --no-pager +sudo journalctl -u chatwoot-worker.1.service --no-pager + +# Check configuration +sudo systemctl status chatwoot.target +``` + +### Performance Optimization + +**1. Database Optimization:** +```sql +-- Connect to database +sudo -u postgres psql chatwoot + +-- Check database size +SELECT pg_size_pretty(pg_database_size('chatwoot')); + +-- Check slow queries (if pg_stat_statements is enabled) +SELECT query, mean_time, calls +FROM pg_stat_statements +ORDER BY mean_time DESC +LIMIT 10; +``` + +**2. System Optimization:** +```bash +# Increase file limits for chatwoot user +echo "chatwoot soft nofile 65536" | sudo tee -a /etc/security/limits.conf +echo "chatwoot hard nofile 65536" | sudo tee -a /etc/security/limits.conf + +# Optimize PostgreSQL configuration +sudo nano /etc/postgresql/*/main/postgresql.conf +# Adjust shared_buffers, effective_cache_size, work_mem based on available RAM +``` + +### Security Hardening + +**1. Firewall Configuration:** +```bash +# Install and configure UFW +sudo ufw enable +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow ssh +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +``` + +**2. Fail2ban Setup:** +```bash +# Install Fail2ban +sudo apt install -y fail2ban + +# Configure Fail2ban for SSH +sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local +sudo systemctl enable fail2ban +sudo systemctl start fail2ban +``` + +**3. Regular Updates:** +```bash +# Create update script +cat > /home/chatwoot/update_system.sh << 'EOF' +#!/bin/bash +sudo apt update +sudo apt upgrade -y +sudo apt autoremove -y +sudo apt autoclean +EOF + +chmod +x /home/chatwoot/update_system.sh + +# Add to crontab for weekly updates +echo "0 2 * * 0 /home/chatwoot/update_system.sh" | sudo crontab - +``` + +--- + + +Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and application files. + + + +For high-availability deployments, consider setting up multiple servers with load balancing and database replication. + \ No newline at end of file diff --git a/developer-docs/self-hosted/introduction.mdx b/developer-docs/self-hosted/introduction.mdx new file mode 100644 index 000000000..32078651d --- /dev/null +++ b/developer-docs/self-hosted/introduction.mdx @@ -0,0 +1,127 @@ +--- +title: Self-Hosted Installation Guide +description: Complete guide to install and setup a production-ready Chatwoot instance on your own infrastructure. +sidebarTitle: Introduction +--- + +Welcome to the Chatwoot self-hosted installation guide. This comprehensive documentation will help you deploy, configure, and maintain your own Chatwoot instance with full control over your data and infrastructure. + +## Why Self-Host Chatwoot? + +Self-hosting Chatwoot gives you complete control over your customer support platform: + +- **Data Privacy**: Keep all customer data on your own servers +- **Customization**: Modify the platform to fit your specific needs +- **Cost Control**: No per-agent pricing - scale as much as you need +- **Compliance**: Meet specific regulatory requirements +- **Integration**: Deep integration with your existing infrastructure + +## Deployment Options + +Chatwoot supports multiple deployment methods to fit different infrastructure needs: + +### 🐧 Linux VM Deployment +Deploy directly on Ubuntu/Linux virtual machines with our automated installation script. +- **Best for**: Traditional server environments +- **Complexity**: Low to Medium +- **Maintenance**: Manual updates required + +### 🐳 Docker Deployment +Use Docker containers for consistent, portable deployments. +- **Best for**: Containerized environments +- **Complexity**: Medium +- **Maintenance**: Easy updates with container pulls + +### ☸️ Kubernetes Deployment +Deploy on Kubernetes clusters for enterprise-scale operations. +- **Best for**: Large-scale, high-availability deployments +- **Complexity**: High +- **Maintenance**: Automated with proper CI/CD + +### ☁️ Cloud Provider Deployments +One-click deployments on major cloud platforms: +- **AWS**: EC2, ECS, and Marketplace options +- **Azure**: Container Instances and VM deployments +- **DigitalOcean**: Droplets and App Platform +- **Google Cloud**: Compute Engine and Cloud Run +- **Heroku**: Simple one-click deployment + +## System Requirements + +### Minimum Requirements +- **CPU**: 2 cores +- **RAM**: 4GB +- **Storage**: 20GB SSD +- **OS**: Ubuntu 20.04+ or compatible Linux distribution + +### Recommended for Production +- **CPU**: 4+ cores +- **RAM**: 8GB+ +- **Storage**: 50GB+ SSD +- **Database**: PostgreSQL 12+ +- **Cache**: Redis 6+ +- **Reverse Proxy**: Nginx or similar + +## What You'll Need + +Before starting your Chatwoot installation, ensure you have: + +### Technical Requirements +- [ ] Server or cloud instance meeting minimum requirements +- [ ] Domain name (recommended for production) +- [ ] SSL certificate (Let's Encrypt recommended) +- [ ] SMTP server for email notifications + +### Access Requirements +- [ ] SSH access to your server +- [ ] Root or sudo privileges +- [ ] Firewall configuration access + +### Optional but Recommended +- [ ] Object storage (AWS S3, Google Cloud Storage, etc.) +- [ ] CDN for static assets +- [ ] Monitoring tools (APM, logging) +- [ ] Backup solution + +## Security Considerations + +When self-hosting Chatwoot, consider these security aspects: + +- **Regular Updates**: Keep Chatwoot and system packages updated +- **Firewall Configuration**: Only expose necessary ports +- **SSL/TLS**: Always use HTTPS in production +- **Database Security**: Secure PostgreSQL with strong passwords +- **Backup Encryption**: Encrypt sensitive backup data +- **Access Control**: Implement proper user access controls + +## Getting Started + +Ready to deploy Chatwoot? Choose your preferred deployment method: + + + + Get up and running quickly with Docker containers + + + Traditional server deployment with our automated script + + + Enterprise-scale deployment on Kubernetes + + + One-click deployments on major cloud platforms + + + +## Community and Support + +- **Documentation**: Comprehensive guides and API references +- **GitHub**: [Source code and issue tracking](https://github.com/chatwoot/chatwoot) +- **Discord**: [Community chat and support](https://discord.gg/cJXdrwS) +- **Forum**: [Community discussions and Q&A](https://github.com/chatwoot/chatwoot/discussions) + +--- + + +This documentation covers Chatwoot Community Edition (CE). For Enterprise features and support, visit [Chatwoot Enterprise](https://www.chatwoot.com/pricing). + \ No newline at end of file diff --git a/developer-docs/self-hosted/requirements.mdx b/developer-docs/self-hosted/requirements.mdx new file mode 100644 index 000000000..da816e55f --- /dev/null +++ b/developer-docs/self-hosted/requirements.mdx @@ -0,0 +1,339 @@ +--- +title: System Requirements +description: Hardware, software, and infrastructure requirements for deploying Chatwoot in different environments. +sidebarTitle: Requirements +--- + +Before deploying Chatwoot, ensure your infrastructure meets the minimum requirements for your expected usage. This guide covers requirements for different deployment scenarios and scales. + +## Minimum System Requirements + +### Development Environment + +For local development and testing: + +| Component | Requirement | +|-----------|-------------| +| **CPU** | 2 cores (2.0 GHz+) | +| **RAM** | 4GB | +| **Storage** | 20GB available space | +| **OS** | Ubuntu 20.04+, macOS 10.15+, Windows 10+ | +| **Network** | Broadband internet connection | + +### Small Production (1-10 agents) + +For small teams and low-volume usage: + +| Component | Requirement | +|-----------|-------------| +| **CPU** | 2 cores (2.4 GHz+) | +| **RAM** | 4GB | +| **Storage** | 50GB SSD | +| **Network** | 100 Mbps bandwidth | +| **Concurrent Users** | Up to 100 | + +### Medium Production (10-50 agents) + +For growing teams with moderate usage: + +| Component | Requirement | +|-----------|-------------| +| **CPU** | 4 cores (2.4 GHz+) | +| **RAM** | 8GB | +| **Storage** | 100GB SSD | +| **Network** | 500 Mbps bandwidth | +| **Concurrent Users** | Up to 500 | + +### Large Production (50+ agents) + +For enterprise deployments with high volume: + +| Component | Requirement | +|-----------|-------------| +| **CPU** | 8+ cores (2.4 GHz+) | +| **RAM** | 16GB+ | +| **Storage** | 200GB+ SSD | +| **Network** | 1 Gbps+ bandwidth | +| **Concurrent Users** | 1000+ | + +## Software Requirements + +### Operating System + +**Supported Linux Distributions:** +- Ubuntu 20.04 LTS or later (recommended) +- Ubuntu 22.04 LTS +- Debian 10 or later +- CentOS 8 or later +- RHEL 8 or later +- Amazon Linux 2 + +**Container Platforms:** +- Docker 20.10+ with Docker Compose 2.0+ +- Kubernetes 1.20+ +- OpenShift 4.6+ + +### Runtime Dependencies + +| Component | Version | Purpose | +|-----------|---------|---------| +| **Ruby** | 3.3.3+ | Application runtime | +| **Node.js** | 20.x LTS | Frontend build tools | +| **PostgreSQL** | 12+ | Primary database | +| **Redis** | 6.0+ | Cache and job queue | +| **Nginx** | 1.18+ | Reverse proxy | + +### Development Dependencies + +For building from source: + +| Component | Version | Purpose | +|-----------|---------|---------| +| **Git** | 2.25+ | Source code management | +| **Build tools** | Latest | Compiling native extensions | +| **ImageMagick** | 7.0+ | Image processing | +| **FFmpeg** | 4.0+ | Video/audio processing | + +## Database Requirements + +### PostgreSQL Configuration + +**Minimum Version:** PostgreSQL 12+ +**Recommended Version:** PostgreSQL 14+ + +**Required Extensions:** +- `pg_stat_statements` (performance monitoring) +- `uuid-ossp` (UUID generation) +- `pg_trgm` (full-text search) + +**Configuration Recommendations:** + +```sql +-- Memory settings (adjust based on available RAM) +shared_buffers = 256MB # 25% of RAM for small instances +effective_cache_size = 1GB # 75% of RAM +work_mem = 4MB # Per connection +maintenance_work_mem = 64MB # For maintenance operations + +-- Connection settings +max_connections = 100 # Adjust based on expected load +max_prepared_transactions = 100 # For prepared statements + +-- Write-ahead logging +wal_buffers = 16MB # WAL buffer size +checkpoint_completion_target = 0.9 # Checkpoint target +``` + +### Redis Configuration + +**Minimum Version:** Redis 6.0+ +**Recommended Version:** Redis 7.0+ + +**Memory Requirements:** +- **Small deployment:** 512MB +- **Medium deployment:** 2GB +- **Large deployment:** 4GB+ + +**Configuration Recommendations:** + +```redis +# Memory management +maxmemory 2gb +maxmemory-policy allkeys-lru + +# Persistence (choose one) +save 900 1 # RDB snapshots +# appendonly yes # AOF logging + +# Security +requirepass your_secure_password +``` + +## Network Requirements + +### Ports + +| Port | Protocol | Purpose | External Access | +|------|----------|---------|-----------------| +| **80** | HTTP | Web traffic (redirect to HTTPS) | Yes | +| **443** | HTTPS | Secure web traffic | Yes | +| **3000** | HTTP | Application server (behind proxy) | No | +| **5432** | TCP | PostgreSQL database | No | +| **6379** | TCP | Redis cache | No | +| **22** | SSH | Server administration | Admin only | + +### Firewall Configuration + +**Inbound Rules:** +```bash +# Allow HTTP and HTTPS +ufw allow 80/tcp +ufw allow 443/tcp + +# Allow SSH (restrict to admin IPs) +ufw allow from YOUR_ADMIN_IP to any port 22 + +# Deny all other inbound traffic +ufw default deny incoming +``` + +**Outbound Rules:** +```bash +# Allow all outbound (for updates, integrations) +ufw default allow outgoing + +# Or restrict to specific services +ufw allow out 53/udp # DNS +ufw allow out 80/tcp # HTTP +ufw allow out 443/tcp # HTTPS +ufw allow out 587/tcp # SMTP +``` + +### Bandwidth Estimation + +**Per Agent (monthly):** +- **Light usage:** 1-2 GB +- **Medium usage:** 3-5 GB +- **Heavy usage:** 8-10 GB + +**Per Customer Conversation:** +- **Text only:** 10-50 KB +- **With images:** 500 KB - 2 MB +- **With files:** 1-10 MB + +## Storage Requirements + +### Disk Space Planning + +**Base Installation:** 5-10 GB +**Database Growth:** 100 MB - 1 GB per 1000 conversations +**File Attachments:** Varies by usage (plan for 10-50 GB) +**Logs:** 1-5 GB per month +**Backups:** 2x database size + file storage + +### Storage Performance + +| Deployment Size | IOPS | Throughput | +|-----------------|------|------------| +| **Small** | 1,000 IOPS | 50 MB/s | +| **Medium** | 3,000 IOPS | 150 MB/s | +| **Large** | 10,000+ IOPS | 500+ MB/s | + +### File Storage Options + +**Local Storage:** +- Suitable for small deployments +- Requires backup strategy +- Limited scalability + +**Object Storage (Recommended):** +- AWS S3, Google Cloud Storage, Azure Blob +- Unlimited scalability +- Built-in redundancy +- CDN integration + +## Security Requirements + +### SSL/TLS Certificates + +**Required for Production:** +- Valid SSL certificate for your domain +- TLS 1.2 or higher +- Strong cipher suites + +**Certificate Options:** +- Let's Encrypt (free, automated) +- Commercial certificates +- Wildcard certificates for subdomains + +### Access Control + +**Server Access:** +- SSH key-based authentication +- Disable password authentication +- Regular security updates +- Fail2ban or similar intrusion prevention + +**Application Security:** +- Strong database passwords +- Redis authentication +- Regular security updates +- Web Application Firewall (optional) + +## Cloud Provider Specifications + +### AWS EC2 Instance Types + +| Use Case | Instance Type | vCPU | RAM | Storage | +|----------|---------------|------|-----|---------| +| **Development** | t3.medium | 2 | 4 GB | 20 GB gp3 | +| **Small Production** | t3.large | 2 | 8 GB | 50 GB gp3 | +| **Medium Production** | m5.xlarge | 4 | 16 GB | 100 GB gp3 | +| **Large Production** | m5.2xlarge | 8 | 32 GB | 200 GB gp3 | + +### DigitalOcean Droplets + +| Use Case | Droplet Size | vCPU | RAM | Storage | +|----------|--------------|------|-----|---------| +| **Development** | 2 GB | 1 | 2 GB | 50 GB SSD | +| **Small Production** | 4 GB | 2 | 4 GB | 80 GB SSD | +| **Medium Production** | 8 GB | 4 | 8 GB | 160 GB SSD | +| **Large Production** | 16 GB | 6 | 16 GB | 320 GB SSD | + +### Google Cloud Compute Engine + +| Use Case | Machine Type | vCPU | RAM | Storage | +|----------|--------------|------|-----|---------| +| **Development** | e2-medium | 2 | 4 GB | 50 GB SSD | +| **Small Production** | e2-standard-2 | 2 | 8 GB | 100 GB SSD | +| **Medium Production** | e2-standard-4 | 4 | 16 GB | 200 GB SSD | +| **Large Production** | e2-standard-8 | 8 | 32 GB | 500 GB SSD | + +## Performance Benchmarks + +### Expected Performance + +| Metric | Small | Medium | Large | +|--------|-------|--------|-------| +| **Concurrent Users** | 100 | 500 | 1000+ | +| **Messages/minute** | 1,000 | 5,000 | 20,000+ | +| **Response Time** | <200ms | <300ms | <500ms | +| **Uptime** | 99.5% | 99.9% | 99.95% | + +### Load Testing + +Before production deployment, consider load testing: + +```bash +# Example using Apache Bench +ab -n 1000 -c 10 https://your-chatwoot-domain.com/api/v1/accounts + +# Example using wrk +wrk -t12 -c400 -d30s https://your-chatwoot-domain.com/ +``` + +## Monitoring Requirements + +### Essential Metrics + +- **System:** CPU, memory, disk, network +- **Application:** Response times, error rates +- **Database:** Connection count, query performance +- **Redis:** Memory usage, hit rates + +### Recommended Tools + +- **System Monitoring:** Prometheus + Grafana, DataDog, New Relic +- **Log Management:** ELK Stack, Fluentd, Splunk +- **Uptime Monitoring:** Pingdom, UptimeRobot +- **APM:** New Relic, DataDog APM, Scout + +--- + + +These requirements are guidelines. Your actual needs may vary based on usage patterns, integrations, and performance expectations. Monitor your deployment and adjust resources accordingly. + + + +For high-availability deployments, consider redundancy in all components and implement proper backup and disaster recovery procedures. + \ No newline at end of file From c3619f51a1348a2fe6322082e742d15b0bc9be1d Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Fri, 13 Jun 2025 00:15:46 +0530 Subject: [PATCH 02/11] feat: add multimodal message content support --- .../accounts/captain/assistants_controller.rb | 2 +- enterprise/app/helpers/captain/chat_helper.rb | 78 +++++++++++++++++++ .../conversation/response_builder_job.rb | 45 ++++------- .../conversation/response_builder_job_spec.rb | 22 ++++++ 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb b/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb index e5a055836..17ce78fba 100644 --- a/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb +++ b/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb @@ -25,7 +25,7 @@ class Api::V1::Accounts::Captain::AssistantsController < Api::V1::Accounts::Base def playground response = Captain::Llm::AssistantChatService.new(assistant: @assistant).generate_response( - params[:message_content], + message_content_multimodal(params[:message_content]), message_history ) diff --git a/enterprise/app/helpers/captain/chat_helper.rb b/enterprise/app/helpers/captain/chat_helper.rb index f90b8d07e..fecb7d6e7 100644 --- a/enterprise/app/helpers/captain/chat_helper.rb +++ b/enterprise/app/helpers/captain/chat_helper.rb @@ -18,6 +18,84 @@ module Captain::ChatHelper raise e end + def message_content_multimodal(message) + # If message has text content, start with that + content_parts = [] + + if message.content.present? + content_parts << { + type: 'text', + text: message.content + } + end + + # Add image content if available + if message.attachments.any? + image_attachments = message.attachments.where(file_type: :image) + + image_attachments.each do |attachment| + image_url = get_attachment_url(attachment) + next unless image_url.present? + + content_parts << { + type: 'image_url', + image_url: { + url: image_url + } + } + end + + # Handle audio transcriptions + audio_transcriptions = extract_audio_transcriptions(message.attachments) + if audio_transcriptions.present? + content_parts << { + type: 'text', + text: audio_transcriptions + } + end + + # Handle other attachment types + other_attachments = message.attachments.where.not(file_type: [:image, :audio]) + if other_attachments.any? + content_parts << { + type: 'text', + text: 'User has shared an attachment' + } + end + end + + # Return just text if no special content, otherwise return array for multimodal + if content_parts.length == 1 && content_parts.first[:type] == 'text' + content_parts.first[:text] + elsif content_parts.any? + content_parts + else + 'Message without content' + end + end + + def get_attachment_url(attachment) + if attachment.external_url.present? + attachment.external_url + elsif attachment.file.attached? + # For uploaded files, we need to generate a public URL + # This will work if the file is stored in a public cloud storage + attachment.file.url if attachment.file.respond_to?(:url) + end + end + + def extract_audio_transcriptions(attachments) + audio_attachments = attachments.where(file_type: :audio) + return '' if audio_attachments.blank? + + transcriptions = '' + audio_attachments.each do |attachment| + result = Messages::AudioTranscriptionService.new(attachment).perform + transcriptions += result[:transcriptions] if result[:success] + end + transcriptions + end + private def handle_response(response) diff --git a/enterprise/app/jobs/captain/conversation/response_builder_job.rb b/enterprise/app/jobs/captain/conversation/response_builder_job.rb index eb62a9a38..308e5fd68 100644 --- a/enterprise/app/jobs/captain/conversation/response_builder_job.rb +++ b/enterprise/app/jobs/captain/conversation/response_builder_job.rb @@ -1,4 +1,6 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob + include Captain::ChatHelper + MAX_MESSAGE_LENGTH = 10_000 retry_on ActiveStorage::FileNotFoundError, attempts: 3 @@ -25,8 +27,9 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob delegate :account, :inbox, to: :@conversation def generate_and_process_response + latest_message = @conversation.messages.incoming.last @response = Captain::Llm::AssistantChatService.new(assistant: @assistant).generate_response( - @conversation.messages.incoming.last.content, + message_content_multimodal(latest_message), collect_previous_messages ) @@ -37,39 +40,19 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob account.increment_response_usage end - def collect_previous_messages - @conversation - .messages - .where(message_type: [:incoming, :outgoing]) - .where(private: false) - .map do |message| - { - content: message_content(message), - role: determine_role(message) - } - end - end + def collect_previous_messages(include_all: false) + messages_query = @conversation + .messages + .where(message_type: [:incoming, :outgoing]) - def message_content(message) - return message.content if message.content.present? - return 'User has shared a message without content' unless message.attachments.any? + messages_query = messages_query.where(private: false) unless include_all - audio_transcriptions = extract_audio_transcriptions(message.attachments) - return audio_transcriptions if audio_transcriptions.present? - - 'User has shared an attachment' - end - - def extract_audio_transcriptions(attachments) - audio_attachments = attachments.where(file_type: :audio) - return '' if audio_attachments.blank? - - transcriptions = '' - audio_attachments.each do |attachment| - result = Messages::AudioTranscriptionService.new(attachment).perform - transcriptions += result[:transcriptions] if result[:success] + messages_query.map do |message| + { + content: message_content_multimodal(message), + role: determine_role(message) + } end - transcriptions end def determine_role(message) diff --git a/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb b/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb index 1e4a6e824..e2765fbdc 100644 --- a/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb +++ b/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb @@ -30,5 +30,27 @@ RSpec.describe Captain::Conversation::ResponseBuilderJob, type: :job do account.reload expect(account.usage_limits[:captain][:responses][:consumed]).to eq(1) end + + context 'when message contains an image' do + let(:message_with_image) { create(:message, conversation: conversation, message_type: :incoming, content: 'Can you help with this error?') } + let(:image_attachment) { message_with_image.attachments.create!(account: account, file_type: :image, external_url: 'https://example.com/error.jpg') } + + before do + image_attachment + end + + it 'includes image URL directly in the message content for OpenAI vision analysis' do + # Expect the generate_response to receive multimodal content with image URL + expect(mock_llm_chat_service).to receive(:generate_response) do |content, _history| + # Content should be an array for multimodal + expect(content).to be_an(Array) + expect(content.any? { |part| part[:type] == 'text' && part[:text] == 'Can you help with this error?' }).to be true + expect(content.any? { |part| part[:type] == 'image_url' && part[:image_url][:url] == 'https://example.com/error.jpg' }).to be true + { 'response' => 'I can see the error in your image. It appears to be a database connection issue.' } + end + + described_class.perform_now(conversation, assistant) + end + end end end From 36d09597a23c8912be0d10e794554bdbe548749f Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Fri, 13 Jun 2025 21:10:16 +0530 Subject: [PATCH 03/11] refactor: improve message handling in chat services --- .../accounts/captain/assistants_controller.rb | 4 +- enterprise/app/helpers/captain/chat_helper.rb | 66 ------------------- .../conversation/response_builder_job.rb | 65 ++++++++++++++++-- .../captain/llm/assistant_chat_service.rb | 13 +++- enterprise/lib/chat_gpt.rb | 6 +- .../captain/assistants_controller_spec.rb | 8 +-- .../conversation/response_builder_job_spec.rb | 13 ++-- 7 files changed, 88 insertions(+), 87 deletions(-) diff --git a/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb b/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb index 17ce78fba..ec8e8e653 100644 --- a/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb +++ b/enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb @@ -25,8 +25,8 @@ class Api::V1::Accounts::Captain::AssistantsController < Api::V1::Accounts::Base def playground response = Captain::Llm::AssistantChatService.new(assistant: @assistant).generate_response( - message_content_multimodal(params[:message_content]), - message_history + additional_message: params[:message_content], + message_history: message_history ) render json: response diff --git a/enterprise/app/helpers/captain/chat_helper.rb b/enterprise/app/helpers/captain/chat_helper.rb index fecb7d6e7..baff0a209 100644 --- a/enterprise/app/helpers/captain/chat_helper.rb +++ b/enterprise/app/helpers/captain/chat_helper.rb @@ -18,72 +18,6 @@ module Captain::ChatHelper raise e end - def message_content_multimodal(message) - # If message has text content, start with that - content_parts = [] - - if message.content.present? - content_parts << { - type: 'text', - text: message.content - } - end - - # Add image content if available - if message.attachments.any? - image_attachments = message.attachments.where(file_type: :image) - - image_attachments.each do |attachment| - image_url = get_attachment_url(attachment) - next unless image_url.present? - - content_parts << { - type: 'image_url', - image_url: { - url: image_url - } - } - end - - # Handle audio transcriptions - audio_transcriptions = extract_audio_transcriptions(message.attachments) - if audio_transcriptions.present? - content_parts << { - type: 'text', - text: audio_transcriptions - } - end - - # Handle other attachment types - other_attachments = message.attachments.where.not(file_type: [:image, :audio]) - if other_attachments.any? - content_parts << { - type: 'text', - text: 'User has shared an attachment' - } - end - end - - # Return just text if no special content, otherwise return array for multimodal - if content_parts.length == 1 && content_parts.first[:type] == 'text' - content_parts.first[:text] - elsif content_parts.any? - content_parts - else - 'Message without content' - end - end - - def get_attachment_url(attachment) - if attachment.external_url.present? - attachment.external_url - elsif attachment.file.attached? - # For uploaded files, we need to generate a public URL - # This will work if the file is stored in a public cloud storage - attachment.file.url if attachment.file.respond_to?(:url) - end - end - def extract_audio_transcriptions(attachments) audio_attachments = attachments.where(file_type: :audio) return '' if audio_attachments.blank? diff --git a/enterprise/app/jobs/captain/conversation/response_builder_job.rb b/enterprise/app/jobs/captain/conversation/response_builder_job.rb index 308e5fd68..eea8b934e 100644 --- a/enterprise/app/jobs/captain/conversation/response_builder_job.rb +++ b/enterprise/app/jobs/captain/conversation/response_builder_job.rb @@ -15,7 +15,7 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob generate_and_process_response end rescue StandardError => e - raise e if e.is_a?(ActiveJob::FileNotFoundError) + raise e if e.is_a?(ActiveStorage::FileNotFoundError) handle_error(e) ensure @@ -27,10 +27,8 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob delegate :account, :inbox, to: :@conversation def generate_and_process_response - latest_message = @conversation.messages.incoming.last @response = Captain::Llm::AssistantChatService.new(assistant: @assistant).generate_response( - message_content_multimodal(latest_message), - collect_previous_messages + message_history: collect_previous_messages ) return process_action('handoff') if handoff_requested? @@ -61,6 +59,65 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob message.message_type == 'incoming' ? 'user' : 'system' end + def message_content_multimodal(message) + parts = [] + + parts << text_part(message.content) if message.content.present? + parts.concat(attachment_parts(message.attachments)) if message.attachments.any? + + finalize_content_parts(parts) + end + + def text_part(text) + { type: 'text', text: text } + end + + def attachment_parts(attachments) + [].tap do |parts| + parts.concat(image_parts(attachments.where(file_type: :image))) + + transcription = extract_audio_transcriptions(attachments) + parts << text_part(transcription) if transcription.present? + + parts << text_part('User has shared an attachment') if attachments.where.not(file_type: %i[image audio]).exists? + end + end + + def image_parts(image_attachments) + image_attachments.each_with_object([]) do |attachment, parts| + url = get_attachment_url(attachment) + next if url.blank? + + parts << { + type: 'image_url', + image_url: { url: url } + } + end + end + + def finalize_content_parts(parts) + return 'Message without content' if parts.blank? + return parts.first[:text] if single_text_part?(parts) + + parts + end + + def single_text_part?(parts) + parts.one? && parts.first[:type] == 'text' + end + + def get_attachment_url(attachment) + return attachment.external_url if attachment.external_url.present? + + return unless attachment.file.attached? + + begin + attachment.file_url + rescue ActiveStorage::FileNotFoundError + nil + end + end + def handoff_requested? @response['response'] == 'conversation_handoff' end diff --git a/enterprise/app/services/captain/llm/assistant_chat_service.rb b/enterprise/app/services/captain/llm/assistant_chat_service.rb index 569931d44..ca8fafaa0 100644 --- a/enterprise/app/services/captain/llm/assistant_chat_service.rb +++ b/enterprise/app/services/captain/llm/assistant_chat_service.rb @@ -12,9 +12,16 @@ class Captain::Llm::AssistantChatService < Llm::BaseOpenAiService register_tools end - def generate_response(input, previous_messages = [], role = 'user') - @messages += previous_messages - @messages << { role: role, content: input } if input.present? + # additional_message: A single message (String) from the user that should be appended to the chat. + # It can be an empty String or nil when you only want to supply historical messages. + # message_history: An Array of already formatted messages that provide the previous context. + # role: The role for the additional_message (defaults to `user`). + # + # NOTE: Parameters are provided as keyword arguments to improve clarity and avoid relying on + # positional ordering. + def generate_response(additional_message: nil, message_history: [], role: 'user') + @messages += message_history + @messages << { role: role, content: additional_message } if additional_message.present? request_chat_completion end diff --git a/enterprise/lib/chat_gpt.rb b/enterprise/lib/chat_gpt.rb index 44afbd641..ad77159cf 100644 --- a/enterprise/lib/chat_gpt.rb +++ b/enterprise/lib/chat_gpt.rb @@ -8,9 +8,9 @@ class ChatGpt @messages = [system_message(context_sections)] end - def generate_response(input, previous_messages = [], role = 'user') - @messages += previous_messages - @messages << { 'role': role, 'content': input } if input.present? + def generate_response(additional_message: nil, message_history: [], role: 'user') + @messages += message_history + @messages << { 'role': role, 'content': additional_message } if additional_message.present? response = request_gpt JSON.parse(response['choices'][0]['message']['content'].strip) diff --git a/spec/enterprise/controllers/api/v1/accounts/captain/assistants_controller_spec.rb b/spec/enterprise/controllers/api/v1/accounts/captain/assistants_controller_spec.rb index 1f6d83d80..80be6f30f 100644 --- a/spec/enterprise/controllers/api/v1/accounts/captain/assistants_controller_spec.rb +++ b/spec/enterprise/controllers/api/v1/accounts/captain/assistants_controller_spec.rb @@ -211,8 +211,8 @@ RSpec.describe 'Api::V1::Accounts::Captain::Assistants', type: :request do expect(response).to have_http_status(:success) expect(chat_service).to have_received(:generate_response).with( - valid_params[:message_content], - valid_params[:message_history] + additional_message: valid_params[:message_content], + message_history: valid_params[:message_history] ) expect(json_response[:content]).to eq('Assistant response') end @@ -232,8 +232,8 @@ RSpec.describe 'Api::V1::Accounts::Captain::Assistants', type: :request do expect(response).to have_http_status(:success) expect(chat_service).to have_received(:generate_response).with( - params_without_history[:message_content], - [] + additional_message: params_without_history[:message_content], + message_history: [] ) end end diff --git a/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb b/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb index e2765fbdc..ca8d4a6c0 100644 --- a/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb +++ b/spec/enterprise/jobs/captain/conversation/response_builder_job_spec.rb @@ -41,11 +41,14 @@ RSpec.describe Captain::Conversation::ResponseBuilderJob, type: :job do it 'includes image URL directly in the message content for OpenAI vision analysis' do # Expect the generate_response to receive multimodal content with image URL - expect(mock_llm_chat_service).to receive(:generate_response) do |content, _history| - # Content should be an array for multimodal - expect(content).to be_an(Array) - expect(content.any? { |part| part[:type] == 'text' && part[:text] == 'Can you help with this error?' }).to be true - expect(content.any? { |part| part[:type] == 'image_url' && part[:image_url][:url] == 'https://example.com/error.jpg' }).to be true + expect(mock_llm_chat_service).to receive(:generate_response) do |**kwargs| + history = kwargs[:message_history] + last_entry = history.last + expect(last_entry[:content]).to be_an(Array) + expect(last_entry[:content].any? { |part| part[:type] == 'text' && part[:text] == 'Can you help with this error?' }).to be true + expect(last_entry[:content].any? do |part| + part[:type] == 'image_url' && part[:image_url][:url] == 'https://example.com/error.jpg' + end).to be true { 'response' => 'I can see the error in your image. It appears to be a database connection issue.' } end From f07e171c0be848994dad03c2d4f9cf1777970f2f Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Fri, 13 Jun 2025 21:51:46 +0530 Subject: [PATCH 04/11] remove developer docs --- .../environment-setup/local-development.mdx | 588 ---------- developer-docs/contributing/introduction.mdx | 322 ------ .../project-setup/common-errors.mdx | 1004 ----------------- .../project-setup/environment-variables.mdx | 658 ----------- .../project-setup/setup-guide.mdx | 589 ---------- developer-docs/self-hosted/architecture.mdx | 342 ------ developer-docs/self-hosted/cloud/aws.mdx | 501 -------- developer-docs/self-hosted/cloud/azure.mdx | 663 ----------- .../self-hosted/cloud/digitalocean.mdx | 670 ----------- developer-docs/self-hosted/cloud/gcp.mdx | 745 ------------ developer-docs/self-hosted/cloud/heroku.mdx | 505 --------- .../configuration/environment-variables.mdx | 748 ------------ .../self-hosted/deployment/chatwoot-ctl.mdx | 416 ------- .../self-hosted/deployment/docker.mdx | 572 ---------- .../self-hosted/deployment/kubernetes.mdx | 537 --------- .../self-hosted/deployment/linux-vm.mdx | 675 ----------- developer-docs/self-hosted/introduction.mdx | 127 --- developer-docs/self-hosted/requirements.mdx | 339 ------ 18 files changed, 10001 deletions(-) delete mode 100644 developer-docs/contributing/environment-setup/local-development.mdx delete mode 100644 developer-docs/contributing/introduction.mdx delete mode 100644 developer-docs/contributing/project-setup/common-errors.mdx delete mode 100644 developer-docs/contributing/project-setup/environment-variables.mdx delete mode 100644 developer-docs/contributing/project-setup/setup-guide.mdx delete mode 100644 developer-docs/self-hosted/architecture.mdx delete mode 100644 developer-docs/self-hosted/cloud/aws.mdx delete mode 100644 developer-docs/self-hosted/cloud/azure.mdx delete mode 100644 developer-docs/self-hosted/cloud/digitalocean.mdx delete mode 100644 developer-docs/self-hosted/cloud/gcp.mdx delete mode 100644 developer-docs/self-hosted/cloud/heroku.mdx delete mode 100644 developer-docs/self-hosted/configuration/environment-variables.mdx delete mode 100644 developer-docs/self-hosted/deployment/chatwoot-ctl.mdx delete mode 100644 developer-docs/self-hosted/deployment/docker.mdx delete mode 100644 developer-docs/self-hosted/deployment/kubernetes.mdx delete mode 100644 developer-docs/self-hosted/deployment/linux-vm.mdx delete mode 100644 developer-docs/self-hosted/introduction.mdx delete mode 100644 developer-docs/self-hosted/requirements.mdx diff --git a/developer-docs/contributing/environment-setup/local-development.mdx b/developer-docs/contributing/environment-setup/local-development.mdx deleted file mode 100644 index ef85cd909..000000000 --- a/developer-docs/contributing/environment-setup/local-development.mdx +++ /dev/null @@ -1,588 +0,0 @@ ---- -title: Local Development Setup -description: Set up Chatwoot for local development on your machine -sidebarTitle: Local Development ---- - -# Local Development Setup - -This guide will help you set up Chatwoot for local development on your machine. Follow these steps to get a complete development environment running. - -## Prerequisites - -Before setting up Chatwoot locally, ensure you have the following installed: - -### Required Software - - - - Ruby 3.3.3 (managed with rbenv or RVM) - - - Node.js 20+ with pnpm package manager - - - PostgreSQL 13+ for the database - - - Redis 6+ for caching and background jobs - - - -### System Dependencies - - - - ```bash - # Install Homebrew if not already installed - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - - # Install dependencies - brew install postgresql@15 redis imagemagick git - - # Install rbenv for Ruby version management - brew install rbenv ruby-build - - # Install Node.js and pnpm - brew install node - npm install -g pnpm - - # Start services - brew services start postgresql@15 - brew services start redis - ``` - - - - ```bash - # Update package list - sudo apt update - - # Install dependencies - sudo apt install -y curl git build-essential libssl-dev libreadline-dev \ - zlib1g-dev libpq-dev imagemagick libmagickwand-dev libffi-dev \ - postgresql postgresql-contrib redis-server - - # Install rbenv - curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash - - # Install Node.js (using NodeSource) - curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - - sudo apt install -y nodejs - - # Install pnpm - npm install -g pnpm - - # Start services - sudo systemctl start postgresql - sudo systemctl start redis-server - sudo systemctl enable postgresql - sudo systemctl enable redis-server - ``` - - - - ```bash - # Install EPEL repository - sudo yum install -y epel-release - - # Install dependencies - sudo yum groupinstall -y "Development Tools" - sudo yum install -y curl git openssl-devel readline-devel zlib-devel \ - postgresql-devel ImageMagick-devel libffi-devel postgresql-server \ - postgresql-contrib redis - - # Initialize PostgreSQL - sudo postgresql-setup initdb - - # Install rbenv - curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash - - # Install Node.js - curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - - sudo yum install -y nodejs - - # Install pnpm - npm install -g pnpm - - # Start services - sudo systemctl start postgresql - sudo systemctl start redis - sudo systemctl enable postgresql - sudo systemctl enable redis - ``` - - - -## Ruby Setup - -### Install Ruby with rbenv - -```bash -# Add rbenv to your shell profile -echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc -echo 'eval "$(rbenv init -)"' >> ~/.bashrc -source ~/.bashrc - -# Install Ruby 3.3.3 -rbenv install 3.3.3 -rbenv global 3.3.3 - -# Verify installation -ruby --version -# Should output: ruby 3.3.3 - -# Install bundler -gem install bundler -``` - -### Alternative: Using RVM - -```bash -# Install RVM -curl -sSL https://get.rvm.io | bash -s stable -source ~/.rvm/scripts/rvm - -# Install Ruby 3.3.3 -rvm install 3.3.3 -rvm use 3.3.3 --default - -# Verify installation -ruby --version -gem install bundler -``` - -## Database Setup - -### PostgreSQL Configuration - -```bash -# Create PostgreSQL user (macOS with Homebrew) -createuser -s chatwoot - -# Create PostgreSQL user (Linux) -sudo -u postgres createuser -s chatwoot - -# Set password for the user -sudo -u postgres psql -postgres=# ALTER USER chatwoot PASSWORD 'password'; -postgres=# \q - -# Create databases -createdb chatwoot_development -createdb chatwoot_test -``` - -### PostgreSQL Authentication Setup - -Edit PostgreSQL configuration to allow local connections: - -```bash -# Find pg_hba.conf location -sudo -u postgres psql -c "SHOW hba_file;" - -# Edit the file (example path) -sudo nano /etc/postgresql/15/main/pg_hba.conf - -# Add or modify these lines: -local all chatwoot md5 -host all chatwoot 127.0.0.1/32 md5 -host all chatwoot ::1/128 md5 - -# Restart PostgreSQL -sudo systemctl restart postgresql -``` - -## Project Setup - -### Clone the Repository - -```bash -# Fork the repository on GitHub first, then clone your fork -git clone https://github.com/YOUR_USERNAME/chatwoot.git -cd chatwoot - -# Add upstream remote -git remote add upstream https://github.com/chatwoot/chatwoot.git - -# Verify remotes -git remote -v -``` - -### Install Dependencies - -```bash -# Install Ruby dependencies -bundle install - -# Install Node.js dependencies -pnpm install - -# Install Playwright for E2E tests (optional) -pnpm exec playwright install -``` - -### Environment Configuration - -```bash -# Copy environment file -cp .env.example .env - -# Edit the environment file -nano .env -``` - -Update the `.env` file with your local configuration: - -```bash -# Database configuration -DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development -REDIS_URL=redis://localhost:6379/0 - -# Application settings -FRONTEND_URL=http://localhost:3000 -FORCE_SSL=false -RAILS_ENV=development -NODE_ENV=development - -# Email configuration (for development) -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=localhost -SMTP_PORT=1025 - -# File storage (local) -ACTIVE_STORAGE_SERVICE=local - -# Development features -ENABLE_DEVELOPMENT_FEATURES=true -LOG_LEVEL=debug -``` - -### Database Initialization - -```bash -# Create and migrate the database -bundle exec rails db:create -bundle exec rails db:migrate - -# Seed the database with sample data -bundle exec rails db:seed - -# Prepare the test database -RAILS_ENV=test bundle exec rails db:create -RAILS_ENV=test bundle exec rails db:migrate -``` - -## Running the Application - -### Start Development Servers - -You'll need to run multiple processes for full development: - -#### Option 1: Using Foreman (Recommended) - -```bash -# Install foreman -gem install foreman - -# Start all services -foreman start -f Procfile.dev -``` - -#### Option 2: Manual Process Management - -Open multiple terminal windows/tabs: - -```bash -# Terminal 1: Rails server -bundle exec rails server -p 3000 - -# Terminal 2: Webpack dev server -pnpm run dev - -# Terminal 3: Sidekiq worker -bundle exec sidekiq - -# Terminal 4: MailHog (for email testing) -mailhog -``` - -### Access the Application - -Once all services are running: - -- **Web Application**: http://localhost:3000 -- **API Documentation**: http://localhost:3000/swagger -- **Sidekiq Web UI**: http://localhost:3000/sidekiq -- **MailHog (Email)**: http://localhost:8025 - -### Default Login Credentials - -After seeding the database, you can log in with: - -- **Email**: john@acme.inc -- **Password**: Password1! - -## Development Tools - -### Code Quality Tools - -```bash -# Install development gems -bundle install --with development test - -# Run RuboCop (Ruby linter) -bundle exec rubocop - -# Run RuboCop with auto-fix -bundle exec rubocop -a - -# Run ESLint (JavaScript linter) -pnpm run lint - -# Run ESLint with auto-fix -pnpm run lint:fix - -# Run Prettier (code formatter) -pnpm run format -``` - -### Testing - -```bash -# Run Ruby tests -bundle exec rspec - -# Run specific test file -bundle exec rspec spec/models/user_spec.rb - -# Run JavaScript tests -pnpm run test - -# Run E2E tests -pnpm run test:e2e - -# Run tests with coverage -COVERAGE=true bundle exec rspec -``` - -### Database Operations - -```bash -# Reset database -bundle exec rails db:drop db:create db:migrate db:seed - -# Generate migration -bundle exec rails generate migration AddColumnToTable column:type - -# Run migrations -bundle exec rails db:migrate - -# Rollback migration -bundle exec rails db:rollback - -# Check migration status -bundle exec rails db:migrate:status -``` - -## IDE and Editor Setup - -### VS Code Configuration - -Create `.vscode/settings.json`: - -```json -{ - "ruby.intellisense": "rubyLocate", - "ruby.codeCompletion": "rcodetools", - "ruby.format": "rubocop", - "editor.formatOnSave": true, - "editor.rulers": [120], - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "eslint.autoFixOnSave": true, - "prettier.requireConfig": true -} -``` - -### Recommended VS Code Extensions - -```json -{ - "recommendations": [ - "rebornix.ruby", - "wingrunr21.vscode-ruby", - "bradlc.vscode-tailwindcss", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "ms-vscode.vscode-typescript-next", - "bradlc.vscode-tailwindcss" - ] -} -``` - -### RubyMine Configuration - -1. Open the project in RubyMine -2. Configure Ruby SDK: File → Project Structure → SDKs -3. Set up database connection in Database tool window -4. Configure code style: File → Settings → Editor → Code Style - -## Debugging - -### Rails Debugging - -```ruby -# Add to your code for debugging -binding.pry - -# Or use the built-in debugger -debugger -``` - -### JavaScript Debugging - -```javascript -// Add to your code -console.log('Debug info:', variable); -debugger; -``` - -### Database Debugging - -```bash -# Rails console -bundle exec rails console - -# Database console -bundle exec rails dbconsole - -# Check database queries in logs -tail -f log/development.log | grep SQL -``` - -## Common Issues and Solutions - -### Bundle Install Issues - - -```bash -# macOS -brew install postgresql -bundle config build.pg --with-pg-config=/usr/local/bin/pg_config - -# Ubuntu/Debian -sudo apt-get install libpq-dev -bundle install -``` - - - -```bash -# macOS -brew install imagemagick pkg-config - -# Ubuntu/Debian -sudo apt-get install libmagickwand-dev - -# Then reinstall the gem -bundle pristine rmagick -``` - - -### Node.js Issues - - -```bash -# Clear cache and reinstall -pnpm store prune -rm -rf node_modules -pnpm install -``` - - - -```bash -# Clear webpack cache -rm -rf tmp/cache/webpacker -pnpm run dev -``` - - -### Database Issues - - -```bash -# Check if PostgreSQL is running -sudo systemctl status postgresql - -# Start PostgreSQL if not running -sudo systemctl start postgresql - -# Check connection -psql -U chatwoot -d chatwoot_development -h localhost -``` - - - -```bash -# Reset PostgreSQL user password -sudo -u postgres psql -postgres=# ALTER USER chatwoot PASSWORD 'password'; -postgres=# \q -``` - - -## Performance Optimization - -### Development Performance Tips - -```bash -# Use spring for faster Rails commands -bundle exec spring binstub --all - -# Use bootsnap for faster boot times (already included) -# Ensure tmp/cache directory exists -mkdir -p tmp/cache - -# Use parallel testing -bundle exec rspec --parallel - -# Optimize database queries -# Add to config/environments/development.rb -config.active_record.verbose_query_logs = true -``` - -### Memory Usage Optimization - -```bash -# Monitor memory usage -ps aux | grep ruby -ps aux | grep node - -# Use jemalloc for better memory management -export MALLOC_ARENA_MAX=2 -bundle exec rails server -``` - -## Next Steps - -Once you have your development environment set up: - -1. **Read the Contributing Guidelines**: Check out the [contributing guide](../introduction) for code standards and workflow -2. **Explore the Codebase**: Familiarize yourself with the project structure -3. **Pick an Issue**: Look for "good first issue" labels on GitHub -4. **Join the Community**: Connect with other contributors on Discord or GitHub Discussions - -## Getting Help - -If you encounter issues during setup: - -- **GitHub Issues**: Search existing issues or create a new one -- **Discord Community**: Join the Chatwoot Discord server -- **Documentation**: Check the official documentation -- **Stack Overflow**: Search for Chatwoot-related questions - ---- - -You're now ready to start contributing to Chatwoot! The development environment should be fully functional and ready for coding. \ No newline at end of file diff --git a/developer-docs/contributing/introduction.mdx b/developer-docs/contributing/introduction.mdx deleted file mode 100644 index cb29911a9..000000000 --- a/developer-docs/contributing/introduction.mdx +++ /dev/null @@ -1,322 +0,0 @@ ---- -title: Contributing to Chatwoot -description: Complete guide to contributing to Chatwoot - from setting up your development environment to submitting pull requests. -sidebarTitle: Introduction ---- - -Thank you for your interest in contributing to Chatwoot! This guide will help you get started with contributing to our open-source customer support platform. Whether you're fixing bugs, adding features, or improving documentation, your contributions are valuable to the community. - -## Why Contribute to Chatwoot? - -Contributing to Chatwoot offers many benefits: - -- **Learn and Grow**: Work with modern technologies like Ruby on Rails, Vue.js, and PostgreSQL -- **Make an Impact**: Help thousands of businesses improve their customer support -- **Build Your Portfolio**: Showcase your contributions to a popular open-source project -- **Join the Community**: Connect with developers and users from around the world -- **Give Back**: Support the open-source ecosystem - -## Ways to Contribute - -There are many ways to contribute to Chatwoot: - -### 🐛 Bug Reports and Fixes -- Report bugs you encounter -- Fix existing bugs in the codebase -- Improve error handling and edge cases - -### ✨ Feature Development -- Implement new features -- Enhance existing functionality -- Improve user experience - -### 📚 Documentation -- Improve existing documentation -- Write new guides and tutorials -- Translate documentation to other languages - -### 🧪 Testing -- Write unit and integration tests -- Perform manual testing -- Improve test coverage - -### 🎨 Design and UX -- Improve user interface design -- Enhance user experience -- Create mockups and prototypes - -### 🌍 Localization -- Translate Chatwoot to new languages -- Improve existing translations -- Help with internationalization - -## Getting Started - -### Prerequisites - -Before you start contributing, make sure you have: - -- **Git**: Version control system -- **GitHub Account**: For submitting pull requests -- **Development Environment**: See our environment setup guides -- **Basic Knowledge**: Familiarity with Ruby, JavaScript, or the technology you want to work with - -### Development Workflow - -Our development workflow follows these steps: - -1. **Find an Issue**: Look for issues tagged with "Good first issue" or create a new one -2. **Fork the Repository**: Create your own copy of the Chatwoot repository -3. **Create a Branch**: Make a feature branch for your changes -4. **Make Changes**: Implement your fix or feature -5. **Test Your Changes**: Ensure everything works correctly -6. **Submit a Pull Request**: Open a PR with a clear description -7. **Code Review**: Collaborate with maintainers to refine your changes -8. **Merge**: Your contribution becomes part of Chatwoot! - -## Before You Start - -### 1. Check Existing Issues - -Before starting work, check if someone else is already working on the same issue: - -- Browse [open issues](https://github.com/chatwoot/chatwoot/issues) -- Look for issues labeled "Good first issue" for beginners -- Check if there's an existing pull request for the same feature - -### 2. Create or Comment on an Issue - -- **For new features**: Create an issue to discuss the feature before implementing -- **For existing issues**: Comment that you'd like to work on it -- **Wait for assignment**: This helps avoid duplicate work - -### 3. Understand the Codebase - -Familiarize yourself with: -- **Architecture**: How Chatwoot is structured -- **Coding Standards**: Our style guides and conventions -- **Testing Practices**: How we write and run tests - -## Pull Request Guidelines - -### Branch Naming - -Use descriptive branch names that follow our conventions: - -```bash -# Feature branches -feature/issue-id-short-description -feature/235-contact-panel - -# Bug fix branches -fix/issue-id-short-description -fix/123-email-validation - -# Chore branches -chore/update-dependencies -chore/improve-documentation -``` - -### Commit Messages - -Write clear, descriptive commit messages: - -```bash -# Good commit messages -feat: Add contact search functionality (#235) -fix: Resolve email validation issue (#123) -docs: Update installation guide -test: Add unit tests for contact model - -# Avoid -Update stuff -Fix bug -WIP -``` - -### Pull Request Template - -When creating a pull request, include: - -**Description:** -- Clear description of what the PR does -- Link to related issues -- Screenshots for UI changes - -**Testing:** -- How you tested the changes -- Test cases covered -- Any manual testing performed - -**Checklist:** -- [ ] Code follows style guidelines -- [ ] Self-review completed -- [ ] Tests added/updated -- [ ] Documentation updated -- [ ] No breaking changes (or clearly documented) - -### Example Pull Request - -```markdown -## Description -Adds a new contact search feature that allows agents to quickly find contacts by name, email, or phone number. - -Fixes #235 - -## Changes Made -- Added search input to contact panel -- Implemented backend search API -- Added debounced search functionality -- Updated contact list component - -## Testing -- Added unit tests for search API -- Tested search with various input types -- Verified performance with large contact lists -- Manual testing on different browsers - -## Screenshots -[Include screenshots of the new feature] - -## Checklist -- [x] Code follows style guidelines -- [x] Self-review completed -- [x] Tests added -- [x] Documentation updated -- [x] No breaking changes -``` - -## Code Standards - -### Ruby/Rails Standards - -- Follow [Ruby Style Guide](https://rubystyle.guide/) -- Use [RuboCop](https://github.com/rubocop/rubocop) for linting -- Write descriptive method and variable names -- Add comments for complex logic -- Follow Rails conventions - -### JavaScript/Vue.js Standards - -- Follow [JavaScript Standard Style](https://standardjs.com/) -- Use [ESLint](https://eslint.org/) for linting -- Write modular, reusable components -- Use meaningful component and variable names -- Follow Vue.js best practices - -### Testing Standards - -- Write tests for new features -- Maintain or improve test coverage -- Use descriptive test names -- Test both happy path and edge cases -- Mock external dependencies - -## Development Environment - -Choose your preferred development environment: - - - - Set up development environment on macOS - - - Set up development environment on Ubuntu Linux - - - Set up development environment on Windows - - - Use Docker for consistent development environment - - - -## Issue Labels - -Understanding our issue labels helps you find the right issues to work on: - -| Label | Description | -|-------|-------------| -| `good first issue` | Perfect for new contributors | -| `help wanted` | Community help needed | -| `bug` | Something isn't working | -| `enhancement` | New feature or improvement | -| `documentation` | Documentation improvements | -| `question` | Further information requested | -| `wontfix` | This will not be worked on | -| `duplicate` | This issue already exists | - -## Community Guidelines - -### Be Respectful - -- Treat everyone with respect and kindness -- Be patient with new contributors -- Provide constructive feedback -- Help others learn and grow - -### Communication - -- Use clear, concise language -- Ask questions when unsure -- Share knowledge and resources -- Be responsive to feedback - -### Collaboration - -- Work together towards common goals -- Share credit for collaborative work -- Help review others' contributions -- Mentor new contributors - -## Getting Help - -If you need help while contributing: - -### Documentation -- Read our comprehensive guides -- Check the API documentation -- Review existing code examples - -### Community Support -- **Discord**: [Join our community chat](https://discord.gg/cJXdrwS) -- **GitHub Discussions**: [Ask questions and share ideas](https://github.com/chatwoot/chatwoot/discussions) -- **Issues**: Create an issue for bugs or feature requests - -### Maintainer Support -- Tag maintainers in issues or PRs when needed -- Be patient - maintainers are volunteers -- Provide detailed information when asking for help - -## Recognition - -We value all contributions and recognize contributors in several ways: - -- **Contributors Page**: Listed on our website and README -- **Release Notes**: Mentioned in release announcements -- **Social Media**: Highlighted on our social channels -- **Swag**: Occasional contributor swag for significant contributions - -## Code of Conduct - -All contributors must follow our [Code of Conduct](https://github.com/chatwoot/chatwoot/blob/develop/CODE_OF_CONDUCT.md). We are committed to providing a welcoming and inclusive environment for everyone. - -## Next Steps - -Ready to start contributing? Here's what to do next: - -1. **Set up your development environment** using one of our setup guides -2. **Find a good first issue** to work on -3. **Fork the repository** and create a feature branch -4. **Make your changes** following our guidelines -5. **Submit a pull request** with a clear description - ---- - - -Remember, contributing to open source is a learning process. Don't be afraid to ask questions, make mistakes, and learn from the community. Every contribution, no matter how small, makes a difference! - - - -Start small with documentation improvements or bug fixes to get familiar with the codebase and contribution process before tackling larger features. - \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/common-errors.mdx b/developer-docs/contributing/project-setup/common-errors.mdx deleted file mode 100644 index 5f1909188..000000000 --- a/developer-docs/contributing/project-setup/common-errors.mdx +++ /dev/null @@ -1,1004 +0,0 @@ ---- -title: Common Errors and Solutions -description: Troubleshooting guide for common errors during Chatwoot development setup -sidebarTitle: Common Errors ---- - -# Common Errors and Solutions - -This guide covers the most common errors encountered during Chatwoot development setup and their solutions. Use this as a quick reference when troubleshooting issues. - -## Installation and Setup Errors - -### Ruby and Bundler Issues - - -**Error Message**: -``` -An error occurred while installing pg (1.5.4), and Bundler cannot continue. -Make sure that `gem install pg -v '1.5.4'` succeeds before bundling. -``` - -**Cause**: Missing PostgreSQL development headers or incorrect pg_config path. - -**Solutions**: - - - -```bash -# Install PostgreSQL with Homebrew -brew install postgresql - -# Configure bundle to use correct pg_config -bundle config build.pg --with-pg-config=/opt/homebrew/bin/pg_config - -# For Intel Macs -bundle config build.pg --with-pg-config=/usr/local/bin/pg_config - -# Retry bundle install -bundle install -``` - - - -```bash -# Install PostgreSQL development headers -sudo apt-get update -sudo apt-get install libpq-dev postgresql-client - -# Install build essentials -sudo apt-get install build-essential - -# Retry bundle install -bundle install -``` - - - -```bash -# Install PostgreSQL development packages -sudo yum install postgresql-devel - -# Install development tools -sudo yum groupinstall "Development Tools" - -# Retry bundle install -bundle install -``` - - - - - -**Error Message**: -``` -Your Ruby version is 3.1.0, but your Gemfile specified 3.3.3 -``` - -**Cause**: Wrong Ruby version installed. - -**Solutions**: - - - -```bash -# Install correct Ruby version -rbenv install 3.3.3 - -# Set as global version -rbenv global 3.3.3 - -# Verify version -ruby --version - -# Rehash to update shims -rbenv rehash -``` - - - -```bash -# Install correct Ruby version -rvm install 3.3.3 - -# Use the version -rvm use 3.3.3 --default - -# Verify version -ruby --version -``` - - - -```bash -# Install correct Ruby version -asdf install ruby 3.3.3 - -# Set as global version -asdf global ruby 3.3.3 - -# Verify version -ruby --version -``` - - - - - -**Error Message**: -``` -Bundler could not find compatible versions for gem "bundler" -``` - -**Cause**: Incompatible Bundler version. - -**Solution**: -```bash -# Check current Bundler version -bundler --version - -# Install specific Bundler version (check Gemfile.lock) -gem install bundler:2.4.22 - -# Update Bundler -gem update bundler - -# Clean bundle cache -bundle clean --force - -# Retry installation -bundle install -``` - - -### Node.js and Package Manager Issues - - -**Error Message**: -``` -error @chatwoot/chatwoot@1.0.0: The engine "node" is incompatible with this module. -``` - -**Cause**: Wrong Node.js version. - -**Solutions**: - - - -```bash -# Install correct Node.js version -nvm install 20 - -# Use the version -nvm use 20 - -# Set as default -nvm alias default 20 - -# Verify version -node --version -``` - - - -```bash -# Install correct Node.js version -n 20 - -# Verify version -node --version -``` - - - -```bash -# Install correct Node.js version -asdf install nodejs 20.10.0 - -# Set as global version -asdf global nodejs 20.10.0 - -# Verify version -node --version -``` - - - - - -**Error Message**: -``` -pnpm: command not found -``` - -**Cause**: pnpm not installed. - -**Solutions**: -```bash -# Install pnpm globally -npm install -g pnpm - -# Or using corepack (Node.js 16.10+) -corepack enable -corepack prepare pnpm@latest --activate - -# Or using Homebrew (macOS) -brew install pnpm - -# Verify installation -pnpm --version -``` - - - -**Error Message**: -``` -ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies -``` - -**Cause**: Peer dependency conflicts or corrupted cache. - -**Solutions**: -```bash -# Clear pnpm cache -pnpm store prune - -# Remove node_modules and lock file -rm -rf node_modules pnpm-lock.yaml - -# Reinstall with legacy peer deps -pnpm install --legacy-peer-deps - -# Or force installation -pnpm install --force - -# Alternative: use npm -npm install -``` - - -## Database Errors - -### PostgreSQL Connection Issues - - -**Error Message**: -``` -PG::ConnectionBad: could not connect to server: Connection refused -``` - -**Cause**: PostgreSQL service not running or incorrect connection parameters. - -**Solutions**: - - - -```bash -# Check if PostgreSQL is running -brew services list | grep postgresql - -# Start PostgreSQL -brew services start postgresql - -# Check connection -psql postgres -c "SELECT 1;" - -# If user doesn't exist, create it -createuser -s chatwoot -``` - - - -```bash -# Check PostgreSQL status -sudo systemctl status postgresql - -# Start PostgreSQL -sudo systemctl start postgresql -sudo systemctl enable postgresql - -# Switch to postgres user and create chatwoot user -sudo -u postgres createuser -s chatwoot - -# Set password for chatwoot user -sudo -u postgres psql -c "ALTER USER chatwoot PASSWORD 'password';" -``` - - - -```bash -# Start PostgreSQL container -docker run --name postgres-chatwoot \ - -e POSTGRES_USER=chatwoot \ - -e POSTGRES_PASSWORD=password \ - -e POSTGRES_DB=chatwoot_development \ - -p 5432:5432 \ - -d postgres:15 - -# Check if container is running -docker ps | grep postgres -``` - - - - - -**Error Message**: -``` -ActiveRecord::NoDatabaseError: FATAL: database "chatwoot_development" does not exist -``` - -**Cause**: Database not created. - -**Solution**: -```bash -# Create databases -bundle exec rails db:create - -# If that fails, create manually -createdb chatwoot_development -createdb chatwoot_test - -# Or using psql -psql postgres -c "CREATE DATABASE chatwoot_development;" -psql postgres -c "CREATE DATABASE chatwoot_test;" -``` - - - -**Error Message**: -``` -ActiveRecord::PendingMigrationError: Migrations are pending -``` - -**Cause**: Database schema is not up to date. - -**Solutions**: -```bash -# Run pending migrations -bundle exec rails db:migrate - -# If migrations fail, check status -bundle exec rails db:migrate:status - -# Reset database (WARNING: destroys data) -bundle exec rails db:drop db:create db:migrate db:seed - -# For specific migration issues -bundle exec rails db:migrate:up VERSION=20231201000000 -``` - - -### Redis Connection Issues - - -**Error Message**: -``` -Redis::CannotConnectError: Error connecting to Redis on localhost:6379 -``` - -**Cause**: Redis service not running. - -**Solutions**: - - - -```bash -# Check if Redis is running -brew services list | grep redis - -# Start Redis -brew services start redis - -# Test connection -redis-cli ping -``` - - - -```bash -# Check Redis status -sudo systemctl status redis - -# Start Redis -sudo systemctl start redis -sudo systemctl enable redis - -# Test connection -redis-cli ping -``` - - - -```bash -# Start Redis container -docker run --name redis-chatwoot \ - -p 6379:6379 \ - -d redis:7-alpine - -# Test connection -docker exec redis-chatwoot redis-cli ping -``` - - - - -## Application Runtime Errors - -### Rails Server Issues - - -**Error Message**: -``` -Address already in use - bind(2) for "127.0.0.1" port 3000 -``` - -**Cause**: Another process is using port 3000. - -**Solutions**: -```bash -# Find process using port 3000 -lsof -ti:3000 - -# Kill the process -kill -9 $(lsof -ti:3000) - -# Or use a different port -bundle exec rails server -p 3001 - -# Check what's running on the port -netstat -tulpn | grep :3000 -``` - - - -**Error Message**: -``` -ArgumentError: Missing `secret_key_base` for 'development' environment -``` - -**Cause**: SECRET_KEY_BASE not set in environment. - -**Solution**: -```bash -# Generate a new secret key -bundle exec rails secret - -# Add to .env file -echo "SECRET_KEY_BASE=$(bundle exec rails secret)" >> .env - -# Or set temporarily -export SECRET_KEY_BASE=$(bundle exec rails secret) -bundle exec rails server -``` - - - -**Error Message**: -``` -Webpacker::Manifest::MissingEntryError: Webpacker can't find application.js -``` - -**Cause**: Webpack assets not compiled or compilation failed. - -**Solutions**: -```bash -# Check if webpack dev server is running -ps aux | grep webpack - -# Start webpack dev server -pnpm run dev - -# Or compile assets manually -bundle exec rails assets:precompile - -# Clear webpack cache -rm -rf tmp/cache/webpacker -rm -rf public/packs - -# Reinstall node modules -rm -rf node_modules -pnpm install -``` - - -### Sidekiq Worker Issues - - -**Error Message**: -``` -Jobs are queued but not being processed -``` - -**Cause**: Sidekiq worker not running. - -**Solutions**: -```bash -# Check if Sidekiq is running -ps aux | grep sidekiq - -# Start Sidekiq -bundle exec sidekiq - -# Check Sidekiq web interface -open http://localhost:3000/sidekiq - -# Clear failed jobs -bundle exec rails runner "Sidekiq::Queue.new.clear" -``` - - - -**Error Message**: -``` -Redis::CommandError: OOM command not allowed when used memory > 'maxmemory' -``` - -**Cause**: Redis running out of memory. - -**Solutions**: -```bash -# Check Redis memory usage -redis-cli info memory - -# Clear Redis cache -redis-cli flushall - -# Increase Redis memory limit (redis.conf) -# maxmemory 256mb - -# Or restart Redis -brew services restart redis # macOS -sudo systemctl restart redis # Linux -``` - - -## Testing Errors - -### RSpec Test Failures - - -**Error Message**: -``` -ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "users" does not exist -``` - -**Cause**: Test database not set up properly. - -**Solution**: -```bash -# Prepare test database -RAILS_ENV=test bundle exec rails db:create -RAILS_ENV=test bundle exec rails db:migrate - -# Or use the combined command -bundle exec rails db:test:prepare - -# Reset test database if needed -RAILS_ENV=test bundle exec rails db:drop db:create db:migrate -``` - - - -**Error Message**: -``` -FactoryBot::DuplicateDefinitionError: Factory already registered -``` - -**Cause**: Factory definitions loaded multiple times. - -**Solution**: -```bash -# Clear Spring cache -bundle exec spring stop - -# Restart test suite -bundle exec rspec - -# Check for duplicate factory definitions -grep -r "FactoryBot.define" spec/ -``` - - - -**Error Message**: -``` -Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver -``` - -**Cause**: ChromeDriver not installed or incompatible version. - -**Solutions**: -```bash -# Install ChromeDriver -# macOS -brew install chromedriver - -# Ubuntu/Debian -sudo apt-get install chromium-chromedriver - -# Or use webdrivers gem (should be automatic) -bundle exec rails runner "Webdrivers::Chromedriver.update" - -# Run tests in headless mode -HEADLESS=true bundle exec rspec spec/system/ -``` - - -## Development Environment Issues - -### IDE and Editor Problems - - -**Error**: Ruby IntelliSense not working, no syntax highlighting. - -**Solutions**: -```bash -# Install Ruby LSP -gem install ruby-lsp - -# Or add to Gemfile -echo 'gem "ruby-lsp", group: :development' >> Gemfile -bundle install - -# Restart VS Code -# Install recommended extensions: -# - Ruby LSP -# - Ruby Solargraph -# - Ruby Test Explorer -``` - - - -**Error**: Ruby documentation and autocomplete not working. - -**Solutions**: -```bash -# Install Solargraph -gem install solargraph - -# Generate documentation -bundle exec yard gems -bundle exec solargraph bundle - -# Create .solargraph.yml config -solargraph config - -# Restart your editor -``` - - -### Git and Version Control Issues - - -**Error**: Git commit rejected due to linting errors. - -**Solutions**: -```bash -# Fix RuboCop issues -bundle exec rubocop -a - -# Fix ESLint issues -pnpm run lint:fix - -# Format code -pnpm run format - -# Skip hooks temporarily (not recommended) -git commit --no-verify -m "Your commit message" - -# Update pre-commit hooks -pre-commit autoupdate -``` - - - -**Error**: Git LFS or large file warnings. - -**Solutions**: -```bash -# Install Git LFS -git lfs install - -# Track large files -git lfs track "*.png" -git lfs track "*.jpg" -git lfs track "*.pdf" - -# Add .gitattributes -git add .gitattributes - -# Check LFS status -git lfs status -``` - - -## Performance Issues - -### Slow Application Startup - - -**Cause**: Large codebase, slow database, or memory issues. - -**Solutions**: -```bash -# Use Spring for faster Rails commands -bundle exec spring binstub --all - -# Check Spring status -bundle exec spring status - -# Restart Spring if needed -bundle exec spring stop - -# Increase memory if needed -export RUBY_GC_HEAP_INIT_SLOTS=10000 -export RUBY_GC_HEAP_FREE_SLOTS=10000 - -# Profile startup time -time bundle exec rails runner "puts 'Rails loaded'" -``` - - - -**Cause**: Database setup, factory creation, or inefficient tests. - -**Solutions**: -```bash -# Use parallel testing -bundle exec rspec --parallel - -# Profile slow tests -bundle exec rspec --profile - -# Use database cleaner strategies -# Add to spec/rails_helper.rb: -# config.use_transactional_fixtures = true - -# Optimize factories -# Use build_stubbed instead of create when possible -``` - - -## Email and Communication Issues - -### Email Delivery Problems - - -**Cause**: SMTP configuration or email service issues. - -**Solutions**: - - - -```bash -# Install and start MailHog -brew install mailhog # macOS -mailhog - -# Configure .env -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=localhost -SMTP_PORT=1025 - -# Check web interface -open http://localhost:8025 -``` - - - -```bash -# Add to Gemfile -echo 'gem "letter_opener", group: :development' >> Gemfile -bundle install - -# Configure in development.rb -# config.action_mailer.delivery_method = :letter_opener - -# Emails will open in browser -``` - - - -```bash -# Use app password, not regular password -MAILER_SENDER_EMAIL=your-email@gmail.com -SMTP_ADDRESS=smtp.gmail.com -SMTP_PORT=587 -SMTP_USERNAME=your-email@gmail.com -SMTP_PASSWORD=your-app-password -SMTP_DOMAIN=gmail.com -SMTP_ENABLE_STARTTLS_AUTO=true -``` - - - - -### WebSocket Connection Issues - - -**Error**: Real-time features not working, WebSocket connection failed. - -**Solutions**: -```bash -# Check if ActionCable is mounted -grep -r "mount ActionCable" config/routes.rb - -# Check Redis connection -redis-cli ping - -# Configure ActionCable for development -# In config/environments/development.rb: -# config.action_cable.url = "ws://localhost:3000/cable" -# config.action_cable.allowed_request_origins = ["http://localhost:3000"] - -# Test WebSocket connection -# Open browser console and check for WebSocket errors -``` - - -## Debugging and Logging Issues - -### Log File Problems - - -**Cause**: Excessive logging in development. - -**Solutions**: -```bash -# Clear log files -> log/development.log -> log/test.log - -# Configure log rotation in development.rb -# config.logger = ActiveSupport::Logger.new("log/development.log", 5, 10.megabytes) - -# Reduce log level -# config.log_level = :info - -# Use logrotate (Linux) -sudo logrotate -f /etc/logrotate.conf -``` - - -### Debugging Tool Issues - - -**Cause**: Debugger not properly configured or running in wrong context. - -**Solutions**: -```bash -# Make sure gems are in Gemfile -echo 'gem "pry-rails", group: [:development, :test]' >> Gemfile -echo 'gem "pry-byebug", group: [:development, :test]' >> Gemfile -bundle install - -# Use correct debugger syntax -# binding.pry # for Pry -# debugger # for built-in debugger -# byebug # for byebug - -# Check if running in correct environment -puts Rails.env -``` - - -## Quick Diagnostic Commands - -### System Health Check - -```bash -#!/bin/bash -# health_check.sh - Quick system diagnostic - -echo "=== Chatwoot Development Health Check ===" - -# Check Ruby version -echo "Ruby version: $(ruby --version)" - -# Check Node.js version -echo "Node.js version: $(node --version)" - -# Check database connection -if bundle exec rails runner "ActiveRecord::Base.connection.execute('SELECT 1')" > /dev/null 2>&1; then - echo "✅ Database connection: OK" -else - echo "❌ Database connection: FAILED" -fi - -# Check Redis connection -if redis-cli ping > /dev/null 2>&1; then - echo "✅ Redis connection: OK" -else - echo "❌ Redis connection: FAILED" -fi - -# Check if services are running -echo "Running processes:" -ps aux | grep -E "(rails|sidekiq|webpack|mailhog)" | grep -v grep - -# Check ports -echo "Port usage:" -lsof -i :3000,3035,6379,5432,8025 2>/dev/null || echo "No processes found on common ports" - -echo "=== Health Check Complete ===" -``` - -### Environment Validation - -```bash -#!/bin/bash -# validate_env.sh - Validate development environment - -required_vars=( - "RAILS_ENV" - "DATABASE_URL" - "REDIS_URL" - "SECRET_KEY_BASE" - "FRONTEND_URL" -) - -echo "=== Environment Variable Check ===" -for var in "${required_vars[@]}"; do - if [ -z "${!var}" ]; then - echo "❌ Missing: $var" - else - echo "✅ Set: $var" - fi -done - -echo "=== Dependency Check ===" -commands=("ruby" "node" "psql" "redis-cli" "git") -for cmd in "${commands[@]}"; do - if command -v $cmd > /dev/null 2>&1; then - echo "✅ $cmd: $(command -v $cmd)" - else - echo "❌ $cmd: Not found" - fi -done -``` - -## Getting Additional Help - -If you're still experiencing issues after trying these solutions: - -1. **Search GitHub Issues**: Check if others have reported similar problems -2. **Check Logs**: Look at `log/development.log` for detailed error messages -3. **Discord Community**: Join the Chatwoot Discord for real-time help -4. **Documentation**: Review the official documentation -5. **Create an Issue**: If it's a bug, create a detailed GitHub issue - -### Creating a Good Bug Report - -When reporting issues, include: - -```markdown -## Environment -- OS: [e.g., macOS 13.0, Ubuntu 22.04] -- Ruby version: [e.g., 3.3.3] -- Node.js version: [e.g., 20.10.0] -- Database: [e.g., PostgreSQL 15.0] - -## Steps to Reproduce -1. Step one -2. Step two -3. Step three - -## Expected Behavior -What you expected to happen - -## Actual Behavior -What actually happened - -## Error Messages -``` -Full error message and stack trace -``` - -## Additional Context -Any other relevant information -``` - ---- - -This guide covers the most common development issues. For production deployment issues, see the [Self-hosted documentation](../../self-hosted/). \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/environment-variables.mdx b/developer-docs/contributing/project-setup/environment-variables.mdx deleted file mode 100644 index 570dcf482..000000000 --- a/developer-docs/contributing/project-setup/environment-variables.mdx +++ /dev/null @@ -1,658 +0,0 @@ ---- -title: Environment Variables for Development -description: Complete guide to environment variables for Chatwoot development and testing -sidebarTitle: Environment Variables ---- - -# Environment Variables for Development - -This guide covers environment variables specifically for development and testing environments. For production environment variables, see the [Self-hosted Environment Variables](../../self-hosted/configuration/environment-variables) guide. - -## Development Environment Setup - -### Basic Development Configuration - -Create your `.env` file from the example: - -```bash -cp .env.example .env -``` - -### Essential Development Variables - -```bash -# Rails Environment -RAILS_ENV=development -NODE_ENV=development - -# Application Configuration -FRONTEND_URL=http://localhost:3000 -FORCE_SSL=false -SECRET_KEY_BASE=your-secret-key-here - -# Database Configuration -DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development -REDIS_URL=redis://localhost:6379/0 - -# Development Features -ENABLE_DEVELOPMENT_FEATURES=true -RAILS_LOG_LEVEL=debug -LOG_LEVEL=debug -``` - -## Database Configuration - -### PostgreSQL Settings - -```bash -# Primary database connection -DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_development - -# Alternative format (individual variables) -DB_HOST=localhost -DB_PORT=5432 -DB_USERNAME=chatwoot -DB_PASSWORD=password -DB_NAME=chatwoot_development - -# Test database -TEST_DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_test -``` - -### Redis Configuration - -```bash -# Redis connection for development -REDIS_URL=redis://localhost:6379/0 - -# Redis with authentication -REDIS_URL=redis://:password@localhost:6379/0 - -# Redis Sentinel (for advanced setups) -REDIS_SENTINELS=localhost:26379 -REDIS_SENTINEL_MASTER_NAME=mymaster - -# Sidekiq Redis (can be separate) -SIDEKIQ_REDIS_URL=redis://localhost:6379/1 -``` - -## Email Configuration for Development - -### Local Email Testing - -```bash -# MailHog configuration (recommended for development) -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=localhost -SMTP_PORT=1025 -SMTP_DOMAIN=chatwoot.local -SMTP_ENABLE_STARTTLS_AUTO=false -SMTP_TLS=false - -# Alternative: Letter Opener (emails open in browser) -LETTER_OPENER=true -``` - -### Gmail SMTP (for testing real emails) - -```bash -MAILER_SENDER_EMAIL=your-email@gmail.com -SMTP_ADDRESS=smtp.gmail.com -SMTP_PORT=587 -SMTP_USERNAME=your-email@gmail.com -SMTP_PASSWORD=your-app-password -SMTP_DOMAIN=gmail.com -SMTP_ENABLE_STARTTLS_AUTO=true -SMTP_TLS=true -``` - -### Mailtrap (for testing) - -```bash -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=smtp.mailtrap.io -SMTP_PORT=2525 -SMTP_USERNAME=your-mailtrap-username -SMTP_PASSWORD=your-mailtrap-password -SMTP_DOMAIN=chatwoot.local -``` - -## File Storage Configuration - -### Local Storage (Default for Development) - -```bash -ACTIVE_STORAGE_SERVICE=local -``` - -### AWS S3 for Development - -```bash -ACTIVE_STORAGE_SERVICE=amazon -AWS_ACCESS_KEY_ID=your-access-key -AWS_SECRET_ACCESS_KEY=your-secret-key -AWS_REGION=us-east-1 -AWS_BUCKET_NAME=chatwoot-dev-bucket -``` - -### Google Cloud Storage - -```bash -ACTIVE_STORAGE_SERVICE=google -GCS_PROJECT_ID=your-project-id -GCS_CREDENTIALS=path/to/credentials.json -GCS_BUCKET=chatwoot-dev-bucket -``` - -## Development Features - -### Debug and Logging - -```bash -# Enable development features -ENABLE_DEVELOPMENT_FEATURES=true - -# Logging levels -RAILS_LOG_LEVEL=debug -LOG_LEVEL=debug -SIDEKIQ_LOG_LEVEL=debug - -# SQL query logging -ACTIVE_RECORD_VERBOSE_QUERY_LOGS=true - -# Bullet gem for N+1 query detection -BULLET_ENABLED=true -``` - -### Performance Monitoring - -```bash -# Enable query analysis -QUERY_ANALYSIS=true - -# Memory profiling -MEMORY_PROFILER=true - -# Rack Mini Profiler -RACK_MINI_PROFILER=true - -# Benchmark mode -BENCHMARK_MODE=true -``` - -### Code Quality Tools - -```bash -# RuboCop configuration -RUBOCOP_PARALLEL=true - -# Coverage reporting -COVERAGE=true -SIMPLECOV_FORMATTER=html - -# Test environment -RSPEC_RETRY_COUNT=3 -PARALLEL_TEST_PROCESSORS=4 -``` - -## Testing Environment Variables - -### Test Database Configuration - -```bash -# Test environment -RAILS_ENV=test - -# Test database -TEST_DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_test - -# Test Redis -TEST_REDIS_URL=redis://localhost:6379/15 - -# Disable external services in tests -DISABLE_EXTERNAL_HTTP=true -MOCK_EXTERNAL_SERVICES=true -``` - -### Test-Specific Settings - -```bash -# Faster tests -RAILS_ENV=test -DISABLE_SPRING=true -PARALLEL_WORKERS=4 - -# Test coverage -COVERAGE=true -COVERAGE_REPORTS=true - -# Selenium/Capybara configuration -SELENIUM_REMOTE_URL=http://localhost:4444/wd/hub -CAPYBARA_SERVER_PORT=3001 -HEADLESS_CHROME=true - -# Factory Bot settings -FACTORY_BOT_ALLOW_CLASS_LOOKUP=false -``` - -## Integration Testing - -### External Service Mocking - -```bash -# Mock external APIs -MOCK_FACEBOOK_API=true -MOCK_TWITTER_API=true -MOCK_WHATSAPP_API=true -MOCK_TELEGRAM_API=true - -# Webhook testing -WEBHOOK_TEST_URL=http://localhost:3000/webhooks/test -NGROK_TUNNEL_URL=https://your-tunnel.ngrok.io -``` - -### API Testing - -```bash -# API testing configuration -API_TEST_TOKEN=test-token-123 -API_TEST_ACCOUNT_ID=1 -API_TEST_USER_ID=1 - -# Rate limiting (disabled for tests) -RATE_LIMITING_ENABLED=false -``` - -## Development Tools - -### Code Analysis - -```bash -# Brakeman security scanner -BRAKEMAN_ENABLED=true - -# Bundle audit -BUNDLE_AUDIT_ENABLED=true - -# Reek code smell detector -REEK_ENABLED=true - -# Rails Best Practices -RAILS_BEST_PRACTICES_ENABLED=true -``` - -### Development Servers - -```bash -# Webpack dev server -WEBPACK_DEV_SERVER_HOST=localhost -WEBPACK_DEV_SERVER_PORT=3035 - -# Hot module replacement -HMR_ENABLED=true - -# Live reload -LIVE_RELOAD=true -``` - -## Third-Party Integrations (Development) - -### Social Media (Test Credentials) - -```bash -# Facebook (use test app credentials) -FB_APP_ID=your-test-app-id -FB_APP_SECRET=your-test-app-secret -FB_VERIFY_TOKEN=test-verify-token - -# Twitter (use test credentials) -TWITTER_APP_ID=your-test-app-id -TWITTER_CONSUMER_KEY=your-test-consumer-key -TWITTER_CONSUMER_SECRET=your-test-consumer-secret - -# WhatsApp (use test credentials) -WHATSAPP_VERIFY_TOKEN=test-verify-token -``` - -### Push Notifications (Development) - -```bash -# FCM (use development project) -FCM_SERVER_KEY=your-dev-server-key -FCM_PROJECT_ID=your-dev-project-id - -# Vapid keys for web push -VAPID_PUBLIC_KEY=your-dev-public-key -VAPID_PRIVATE_KEY=your-dev-private-key -``` - -## Security Settings for Development - -### Authentication - -```bash -# JWT settings -JWT_SECRET_KEY=your-dev-jwt-secret -JWT_EXPIRY=24h - -# Session configuration -SESSION_TIMEOUT=1440 -SECURE_COOKIES=false - -# CORS settings (permissive for development) -CORS_ORIGINS=http://localhost:3000,http://localhost:3001 -``` - -### Development Security - -```bash -# Disable security features for development -FORCE_SSL=false -SECURE_HEADERS=false -CSP_ENABLED=false - -# Allow insecure connections -ALLOW_HTTP=true -SKIP_SSL_VERIFICATION=true -``` - -## Environment-Specific Configurations - -### Development Environment - -```bash -# .env.development -RAILS_ENV=development -NODE_ENV=development -CACHE_CLASSES=false -EAGER_LOAD=false -CONSIDER_ALL_REQUESTS_LOCAL=true -ACTION_CONTROLLER_PERFORM_CACHING=false -``` - -### Test Environment - -```bash -# .env.test -RAILS_ENV=test -NODE_ENV=test -CACHE_CLASSES=true -EAGER_LOAD=false -PUBLIC_FILE_SERVER_ENABLED=true -SHOW_EXCEPTIONS=false -``` - -### Staging Environment - -```bash -# .env.staging -RAILS_ENV=staging -NODE_ENV=production -FORCE_SSL=true -LOG_LEVEL=info -RAILS_SERVE_STATIC_FILES=true -``` - -## Docker Development - -### Docker Compose Variables - -```bash -# Docker-specific configuration -POSTGRES_HOST=postgres -POSTGRES_PORT=5432 -POSTGRES_USER=postgres -POSTGRES_PASSWORD=postgres -POSTGRES_DB=chatwoot - -REDIS_HOST=redis -REDIS_PORT=6379 - -# Rails configuration for Docker -RAILS_ENV=development -RAILS_MAX_THREADS=5 -WEB_CONCURRENCY=2 -``` - -### Development with Docker - -```bash -# Use Docker services -DATABASE_URL=postgresql://postgres:postgres@postgres:5432/chatwoot_development -REDIS_URL=redis://redis:6379/0 - -# File permissions (for volume mounts) -DOCKER_USER_ID=1000 -DOCKER_GROUP_ID=1000 -``` - -## IDE and Editor Configuration - -### VS Code Settings - -```bash -# Ruby LSP configuration -RUBY_LSP_ENABLED=true -RUBY_LSP_EXPERIMENTAL_FEATURES=true - -# Solargraph configuration -SOLARGRAPH_ENABLED=true -``` - -### RubyMine Settings - -```bash -# RubyMine-specific settings -RUBYMINE_PROJECT_ROOT=/path/to/chatwoot -RUBYMINE_RUBY_VERSION=3.3.3 -``` - -## Performance and Monitoring - -### Development Monitoring - -```bash -# New Relic (development license) -NEW_RELIC_LICENSE_KEY=your-dev-license-key -NEW_RELIC_APP_NAME=Chatwoot Development - -# Sentry (development DSN) -SENTRY_DSN=your-dev-sentry-dsn -SENTRY_ENVIRONMENT=development - -# DataDog (development) -DD_API_KEY=your-dev-datadog-key -DD_ENV=development -``` - -### Memory and Performance - -```bash -# Memory settings -RUBY_GC_HEAP_INIT_SLOTS=10000 -RUBY_GC_HEAP_FREE_SLOTS=10000 -RUBY_GC_HEAP_GROWTH_FACTOR=1.1 - -# Puma configuration -PUMA_WORKERS=1 -PUMA_THREADS=5 -PUMA_PRELOAD_APP=false -``` - -## Common Development Scenarios - -### API Development - -```bash -# API-specific settings -API_RATE_LIMIT=1000 -API_RATE_LIMIT_WINDOW=3600 -API_PAGINATION_LIMIT=100 - -# CORS for API development -API_CORS_ORIGINS=http://localhost:3001,http://localhost:8080 -``` - -### Widget Development - -```bash -# Widget development -WIDGET_BASE_URL=http://localhost:3000 -WIDGET_API_URL=http://localhost:3000/api/v1 -WIDGET_WS_URL=ws://localhost:3000/cable -``` - -### Mobile App Development - -```bash -# Mobile API endpoints -MOBILE_API_URL=http://localhost:3000/api/v1 -MOBILE_WS_URL=ws://localhost:3000/cable - -# Push notification testing -MOBILE_PUSH_ENABLED=true -``` - -## Troubleshooting Environment Issues - -### Common Environment Problems - - -**Problem**: `ActiveRecord::ConnectionNotEstablished` - -**Check these variables**: -```bash -DATABASE_URL=postgresql://username:password@localhost:5432/chatwoot_development -DB_HOST=localhost -DB_PORT=5432 -``` - -**Verify connection**: -```bash -psql $DATABASE_URL -c "SELECT 1;" -``` - - - -**Problem**: `Redis::CannotConnectError` - -**Check these variables**: -```bash -REDIS_URL=redis://localhost:6379/0 -``` - -**Verify connection**: -```bash -redis-cli -u $REDIS_URL ping -``` - - - -**Problem**: Emails not being sent in development - -**Check these variables**: -```bash -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=localhost -SMTP_PORT=1025 -``` - -**For MailHog**: -```bash -# Start MailHog -mailhog - -# Check web interface at http://localhost:8025 -``` - - - -**Problem**: `Webpacker::Manifest::MissingEntryError` - -**Check these variables**: -```bash -NODE_ENV=development -RAILS_ENV=development -``` - -**Recompile assets**: -```bash -pnpm run dev -# or -bundle exec rails assets:precompile -``` - - -### Environment Validation - -Create a script to validate your environment: - -```bash -#!/bin/bash -# validate_env.sh - -echo "Validating development environment..." - -# Check required variables -required_vars=( - "RAILS_ENV" - "DATABASE_URL" - "REDIS_URL" - "SECRET_KEY_BASE" - "FRONTEND_URL" -) - -for var in "${required_vars[@]}"; do - if [ -z "${!var}" ]; then - echo "❌ Missing required variable: $var" - else - echo "✅ $var is set" - fi -done - -# Test database connection -if bundle exec rails runner "ActiveRecord::Base.connection.execute('SELECT 1')" > /dev/null 2>&1; then - echo "✅ Database connection successful" -else - echo "❌ Database connection failed" -fi - -# Test Redis connection -if bundle exec rails runner "Redis.new.ping" > /dev/null 2>&1; then - echo "✅ Redis connection successful" -else - echo "❌ Redis connection failed" -fi - -echo "Environment validation complete!" -``` - -## Best Practices - -### Environment File Management - -1. **Never commit `.env` files** to version control -2. **Use `.env.example`** as a template for required variables -3. **Document all variables** with comments -4. **Use different `.env` files** for different environments -5. **Validate environment** before starting development - -### Security Considerations - -1. **Use weak credentials** only in development -2. **Never use production credentials** in development -3. **Rotate test API keys** regularly -4. **Use local services** when possible -5. **Mock external services** in tests - -### Performance Tips - -1. **Use local Redis** for faster development -2. **Enable query caching** in development -3. **Use parallel testing** for faster test runs -4. **Profile memory usage** regularly -5. **Monitor database queries** for N+1 issues - ---- - -This guide covers the essential environment variables for Chatwoot development. For production deployment, refer to the [Self-hosted Environment Variables](../../self-hosted/configuration/environment-variables) guide. \ No newline at end of file diff --git a/developer-docs/contributing/project-setup/setup-guide.mdx b/developer-docs/contributing/project-setup/setup-guide.mdx deleted file mode 100644 index 2e06ffffc..000000000 --- a/developer-docs/contributing/project-setup/setup-guide.mdx +++ /dev/null @@ -1,589 +0,0 @@ ---- -title: Project Setup Guide -description: Complete guide to setting up Chatwoot for development and contribution -sidebarTitle: Setup Guide ---- - -# Project Setup Guide - -This comprehensive guide will walk you through setting up Chatwoot for development, from initial repository setup to running your first successful build. - -## Prerequisites Check - -Before starting, ensure you have completed the [Local Development Setup](../environment-setup/local-development) guide and have all required dependencies installed. - -### Quick Prerequisites Verification - -```bash -# Check Ruby version (should be 3.3.3) -ruby --version - -# Check Node.js version (should be 20+) -node --version - -# Check PostgreSQL -psql --version - -# Check Redis -redis-cli --version - -# Check Git -git --version -``` - -## Repository Setup - -### 1. Fork and Clone - -```bash -# Fork the repository on GitHub first -# Then clone your fork -git clone https://github.com/YOUR_USERNAME/chatwoot.git -cd chatwoot - -# Add upstream remote for syncing -git remote add upstream https://github.com/chatwoot/chatwoot.git - -# Verify remotes -git remote -v -# Should show: -# origin https://github.com/YOUR_USERNAME/chatwoot.git (fetch) -# origin https://github.com/YOUR_USERNAME/chatwoot.git (push) -# upstream https://github.com/chatwoot/chatwoot.git (fetch) -# upstream https://github.com/chatwoot/chatwoot.git (push) -``` - -### 2. Branch Strategy - -```bash -# Create a development branch -git checkout -b develop - -# For feature work, create feature branches -git checkout -b feature/your-feature-name - -# Keep your fork synced -git fetch upstream -git checkout develop -git merge upstream/develop -git push origin develop -``` - -## Environment Configuration - -### 1. Environment File Setup - -```bash -# Copy the example environment file -cp .env.example .env - -# Open the file for editing -nano .env -``` - -### 2. Basic Configuration - -Update your `.env` file with the following essential settings: - -```bash -# Rails Environment -RAILS_ENV=development -NODE_ENV=development - -# Application URLs -FRONTEND_URL=http://localhost:3000 -FORCE_SSL=false - -# Database Configuration -DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development -REDIS_URL=redis://localhost:6379/0 - -# Email Configuration (for development) -MAILER_SENDER_EMAIL=dev@chatwoot.local -SMTP_ADDRESS=localhost -SMTP_PORT=1025 - -# File Storage -ACTIVE_STORAGE_SERVICE=local - -# Development Features -ENABLE_DEVELOPMENT_FEATURES=true -LOG_LEVEL=debug -RAILS_LOG_LEVEL=debug - -# Disable SSL in development -SMTP_ENABLE_STARTTLS_AUTO=false -SMTP_TLS=false -``` - -### 3. Generate Secret Keys - -```bash -# Generate secret key base -bundle exec rails secret - -# Add to your .env file -echo "SECRET_KEY_BASE=your-generated-secret" >> .env -``` - -## Database Setup - -### 1. Database Creation - -```bash -# Create development and test databases -bundle exec rails db:create - -# Expected output: -# Created database 'chatwoot_development' -# Created database 'chatwoot_test' -``` - -### 2. Database Migration - -```bash -# Run database migrations -bundle exec rails db:migrate - -# Check migration status -bundle exec rails db:migrate:status -``` - -### 3. Database Seeding - -```bash -# Seed the database with sample data -bundle exec rails db:seed - -# This creates: -# - Sample account -# - Admin user -# - Sample conversations -# - Test data for development -``` - -### 4. Test Database Setup - -```bash -# Prepare test database -RAILS_ENV=test bundle exec rails db:create -RAILS_ENV=test bundle exec rails db:migrate -``` - -## Dependency Installation - -### 1. Ruby Dependencies - -```bash -# Install Ruby gems -bundle install - -# If you encounter issues, try: -bundle install --retry=3 - -# For development and test gems -bundle install --with development test -``` - -### 2. Node.js Dependencies - -```bash -# Install Node.js packages -pnpm install - -# If pnpm is not available, install it first: -npm install -g pnpm - -# Clear cache if needed -pnpm store prune -``` - -### 3. Additional Tools - -```bash -# Install Foreman for process management -gem install foreman - -# Install MailHog for email testing (optional) -# macOS -brew install mailhog - -# Ubuntu/Debian -sudo apt-get install mailhog - -# Or download binary from GitHub releases -``` - -## Application Startup - -### 1. Using Foreman (Recommended) - -```bash -# Start all services with Foreman -foreman start -f Procfile.dev - -# This starts: -# - Rails server (port 3000) -# - Webpack dev server -# - Sidekiq worker -``` - -### 2. Manual Startup - -If you prefer to run services separately: - -```bash -# Terminal 1: Rails server -bundle exec rails server -p 3000 - -# Terminal 2: Webpack dev server -pnpm run dev - -# Terminal 3: Sidekiq worker -bundle exec sidekiq - -# Terminal 4: MailHog (optional) -mailhog -``` - -### 3. Verify Installation - -Once all services are running, verify your setup: - -- **Web Application**: http://localhost:3000 -- **API Health Check**: http://localhost:3000/api -- **Sidekiq Web UI**: http://localhost:3000/sidekiq -- **MailHog**: http://localhost:8025 (if running) - -## Initial Login - -### Default Credentials - -After seeding the database, you can log in with: - -``` -Email: john@acme.inc -Password: Password1! -``` - -### Creating Additional Users - -```bash -# Access Rails console -bundle exec rails console - -# Create a new user -user = User.create!( - name: "Your Name", - email: "your.email@example.com", - password: "Password123!", - password_confirmation: "Password123!" -) - -# Make user an administrator -user.account_users.first.update!(role: 'administrator') -``` - -## Development Workflow - -### 1. Code Quality Setup - -```bash -# Install pre-commit hooks (optional but recommended) -# Create .git/hooks/pre-commit -cat > .git/hooks/pre-commit << 'EOF' -#!/bin/sh -# Run RuboCop -bundle exec rubocop --parallel - -# Run ESLint -pnpm run lint - -# Run tests -bundle exec rspec --fail-fast -EOF - -chmod +x .git/hooks/pre-commit -``` - -### 2. Running Tests - -```bash -# Run Ruby tests -bundle exec rspec - -# Run specific test file -bundle exec rspec spec/models/user_spec.rb - -# Run JavaScript tests -pnpm run test - -# Run E2E tests (requires Playwright) -pnpm exec playwright install -pnpm run test:e2e - -# Run tests with coverage -COVERAGE=true bundle exec rspec -``` - -### 3. Code Linting and Formatting - -```bash -# Ruby linting with RuboCop -bundle exec rubocop - -# Auto-fix Ruby issues -bundle exec rubocop -a - -# JavaScript linting -pnpm run lint - -# Auto-fix JavaScript issues -pnpm run lint:fix - -# Format code with Prettier -pnpm run format -``` - -## IDE Configuration - -### VS Code Setup - -Create `.vscode/settings.json`: - -```json -{ - "ruby.intellisense": "rubyLocate", - "ruby.codeCompletion": "rcodetools", - "ruby.format": "rubocop", - "editor.formatOnSave": true, - "editor.rulers": [120], - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "eslint.autoFixOnSave": true, - "prettier.requireConfig": true, - "ruby.rubocop.executePath": "./bin/", - "ruby.rubocop.onSave": true -} -``` - -Create `.vscode/extensions.json`: - -```json -{ - "recommendations": [ - "rebornix.ruby", - "wingrunr21.vscode-ruby", - "bradlc.vscode-tailwindcss", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "ms-vscode.vscode-typescript-next", - "shopify.ruby-lsp" - ] -} -``` - -### RubyMine Setup - -1. **Open Project**: File → Open → Select chatwoot directory -2. **Configure Ruby SDK**: File → Project Structure → SDKs → Add Ruby SDK -3. **Database Connection**: Database tool window → Add PostgreSQL connection -4. **Code Style**: File → Settings → Editor → Code Style → Import scheme - -## Debugging Setup - -### Rails Debugging - -Add to your code for debugging: - -```ruby -# Using Pry (recommended) -binding.pry - -# Using built-in debugger -debugger - -# Using byebug -byebug -``` - -### JavaScript Debugging - -```javascript -// Browser debugging -console.log('Debug info:', variable); -debugger; - -// Node.js debugging -console.log('Debug info:', variable); -``` - -### Database Debugging - -```bash -# Rails console -bundle exec rails console - -# Database console -bundle exec rails dbconsole - -# Check queries in development log -tail -f log/development.log | grep -E "(SELECT|INSERT|UPDATE|DELETE)" -``` - -## Performance Optimization - -### Development Performance - -```bash -# Use Spring for faster Rails commands -bundle exec spring binstub --all - -# Precompile assets for faster loading -bundle exec rails assets:precompile - -# Use parallel testing -bundle exec rspec --parallel - -# Monitor memory usage -ps aux | grep -E "(ruby|node)" | head -10 -``` - -### Database Performance - -```ruby -# Add to config/environments/development.rb for query analysis -config.active_record.verbose_query_logs = true - -# Enable query plan logging -config.active_record.dump_schema_after_migration = false -``` - -## Troubleshooting Setup Issues - -### Common Setup Problems - - -**Error**: `An error occurred while installing pg` - -**Solution**: -```bash -# macOS -brew install postgresql -bundle config build.pg --with-pg-config=/usr/local/bin/pg_config - -# Ubuntu/Debian -sudo apt-get install libpq-dev -bundle install -``` - - - -**Error**: `could not connect to server: Connection refused` - -**Solution**: -```bash -# Check if PostgreSQL is running -sudo systemctl status postgresql - -# Start PostgreSQL -sudo systemctl start postgresql - -# macOS with Homebrew -brew services start postgresql -``` - - - -**Error**: `Redis::CannotConnectError` - -**Solution**: -```bash -# Check if Redis is running -redis-cli ping - -# Start Redis -sudo systemctl start redis - -# macOS with Homebrew -brew services start redis -``` - - - -**Error**: `Module not found` or compilation errors - -**Solution**: -```bash -# Clear webpack cache -rm -rf tmp/cache/webpacker - -# Reinstall node modules -rm -rf node_modules -pnpm install - -# Restart webpack dev server -pnpm run dev -``` - - -### Verification Commands - -```bash -# Check all services are running -ps aux | grep -E "(rails|sidekiq|webpack|mailhog)" - -# Test database connection -bundle exec rails runner "puts ActiveRecord::Base.connection.execute('SELECT 1').first" - -# Test Redis connection -bundle exec rails runner "puts Redis.new.ping" - -# Check application health -curl http://localhost:3000/api -``` - -## Next Steps - -After successful setup: - -1. **Explore the Codebase**: Familiarize yourself with the project structure -2. **Read Contributing Guidelines**: Review code standards and workflow -3. **Pick Your First Issue**: Look for "good first issue" labels -4. **Join the Community**: Connect with other contributors - -### Useful Development Commands - -```bash -# Generate new migration -bundle exec rails generate migration AddColumnToTable column:type - -# Generate new model -bundle exec rails generate model ModelName attribute:type - -# Generate new controller -bundle exec rails generate controller ControllerName - -# Run specific migration -bundle exec rails db:migrate:up VERSION=20231201000000 - -# Rollback migration -bundle exec rails db:rollback STEP=1 - -# Reset database (careful!) -bundle exec rails db:drop db:create db:migrate db:seed -``` - -## Getting Help - -If you encounter issues during setup: - -- **Check Common Errors**: See [Common Errors](./common-errors) guide -- **Environment Variables**: Review [Environment Variables](./environment-variables) guide -- **GitHub Issues**: Search existing issues or create a new one -- **Discord Community**: Join the Chatwoot Discord server -- **Documentation**: Check the official documentation - ---- - -You're now ready to start developing with Chatwoot! Your development environment should be fully functional and ready for contribution. \ No newline at end of file diff --git a/developer-docs/self-hosted/architecture.mdx b/developer-docs/self-hosted/architecture.mdx deleted file mode 100644 index 98c3b0f8c..000000000 --- a/developer-docs/self-hosted/architecture.mdx +++ /dev/null @@ -1,342 +0,0 @@ ---- -title: Chatwoot Architecture -description: Understanding Chatwoot's system architecture, components, and how they work together. -sidebarTitle: Architecture ---- - -Understanding Chatwoot's architecture is crucial for successful deployment, scaling, and maintenance. This guide explains the core components and how they interact. - -## High-Level Architecture - -Chatwoot follows a modern, scalable web application architecture with clear separation of concerns: - -```mermaid -graph TB - subgraph "Client Layer" - A[Web Dashboard] - B[Mobile Apps] - C[Website Widget] - D[API Clients] - end - - subgraph "Load Balancer" - E[Nginx/ALB] - end - - subgraph "Application Layer" - F[Rails Web Server] - G[Sidekiq Workers] - H[WebSocket Server] - end - - subgraph "Data Layer" - I[PostgreSQL] - J[Redis] - K[File Storage] - end - - subgraph "External Services" - L[SMTP Server] - M[Third-party APIs] - N[CDN] - end - - A --> E - B --> E - C --> E - D --> E - E --> F - E --> H - F --> G - F --> I - F --> J - G --> I - G --> J - F --> K - F --> L - F --> M - K --> N -``` - -## Core Components - -### 1. Web Application (Rails) - -The main application server built with Ruby on Rails handles: - -- **HTTP API endpoints** for all client interactions -- **Authentication and authorization** for users and agents -- **Business logic** for conversations, contacts, and workflows -- **Real-time features** via ActionCable WebSockets -- **File uploads and processing** - -**Key characteristics:** -- Stateless design for horizontal scaling -- RESTful API architecture -- WebSocket support for real-time updates -- Multi-tenant architecture support - -### 2. Background Workers (Sidekiq) - -Sidekiq handles asynchronous processing: - -- **Email notifications** and delivery -- **Webhook processing** for integrations -- **File processing** and optimization -- **Report generation** and analytics -- **Third-party API calls** (Facebook, WhatsApp, etc.) - -**Key characteristics:** -- Redis-backed job queue -- Retry mechanisms for failed jobs -- Horizontal scaling support -- Job prioritization and scheduling - -### 3. Database (PostgreSQL) - -PostgreSQL stores all application data: - -- **User accounts and authentication** -- **Conversations and messages** -- **Contact information and profiles** -- **Configuration and settings** -- **Analytics and reporting data** - -**Key characteristics:** -- ACID compliance for data integrity -- JSON support for flexible schemas -- Full-text search capabilities -- Horizontal scaling with read replicas - -### 4. Cache and Session Store (Redis) - -Redis provides high-performance caching and session management: - -- **Session storage** for user authentication -- **Cache layer** for frequently accessed data -- **Job queue** for background processing -- **Real-time data** for WebSocket connections -- **Rate limiting** and throttling - -**Key characteristics:** -- In-memory performance -- Persistence options available -- Pub/Sub for real-time features -- Clustering support for high availability - -### 5. File Storage - -Chatwoot supports multiple storage backends: - -- **Local filesystem** (development/small deployments) -- **AWS S3** (recommended for production) -- **Google Cloud Storage** -- **Azure Blob Storage** -- **MinIO** (self-hosted S3-compatible) - -**Stored content:** -- User avatars and profile images -- Message attachments and files -- Email templates and assets -- Exported reports and backups - -### 6. Reverse Proxy (Nginx) - -Nginx serves as the front-end proxy: - -- **SSL termination** and certificate management -- **Static file serving** for assets -- **Load balancing** across application instances -- **Request routing** and filtering -- **Compression** and caching headers - -## Data Flow - -### 1. Incoming Messages - -```mermaid -sequenceDiagram - participant C as Customer - participant W as Widget/Channel - participant N as Nginx - participant R as Rails App - participant D as Database - participant Q as Redis Queue - participant S as Sidekiq - participant A as Agent Dashboard - - C->>W: Sends message - W->>N: HTTP/WebSocket request - N->>R: Forward request - R->>D: Store message - R->>Q: Queue notification job - R->>A: Real-time update (WebSocket) - Q->>S: Process notification - S->>D: Update delivery status -``` - -### 2. Agent Responses - -```mermaid -sequenceDiagram - participant A as Agent - participant D as Dashboard - participant R as Rails App - participant DB as Database - participant Q as Redis Queue - participant S as Sidekiq - participant C as Customer - - A->>D: Types response - D->>R: Send message API - R->>DB: Store message - R->>Q: Queue delivery job - R->>D: Real-time update - Q->>S: Process delivery - S->>C: Deliver via channel - S->>DB: Update status -``` - -## Scaling Considerations - -### Horizontal Scaling - -Chatwoot is designed for horizontal scaling: - -**Web Servers:** -- Stateless design allows multiple instances -- Load balancer distributes traffic -- Session data stored in Redis - -**Background Workers:** -- Multiple Sidekiq processes can run -- Jobs distributed across workers -- Queue-based processing prevents overload - -**Database:** -- Read replicas for query scaling -- Connection pooling for efficiency -- Partitioning for large datasets - -### Vertical Scaling - -For smaller deployments, vertical scaling is often sufficient: - -**CPU:** Background processing and real-time features -**Memory:** Caching and session storage -**Storage:** Database and file storage growth -**Network:** WebSocket connections and API traffic - -## Security Architecture - -### Authentication Flow - -```mermaid -graph LR - A[User Login] --> B[Rails Auth] - B --> C[JWT Token] - C --> D[API Requests] - D --> E[Token Validation] - E --> F[Authorized Access] -``` - -### Data Protection - -- **Encryption at rest** for sensitive data -- **TLS encryption** for data in transit -- **Input validation** and sanitization -- **SQL injection** protection via ORM -- **XSS protection** with content security policies - -### Access Control - -- **Role-based permissions** (Admin, Agent, etc.) -- **Account-level isolation** in multi-tenant setup -- **API rate limiting** to prevent abuse -- **Audit logging** for compliance - -## Monitoring and Observability - -### Application Metrics - -- **Response times** and throughput -- **Error rates** and exceptions -- **Background job** processing times -- **WebSocket connection** counts - -### Infrastructure Metrics - -- **CPU and memory** utilization -- **Database performance** and connections -- **Redis memory** usage and hit rates -- **Storage usage** and I/O patterns - -### Logging Strategy - -- **Structured logging** with JSON format -- **Centralized collection** (ELK, Fluentd) -- **Log levels** for different environments -- **Sensitive data** filtering - -## Deployment Patterns - -### Single Server - -Suitable for small teams and development: -- All components on one server -- SQLite or PostgreSQL database -- Local file storage -- Simple backup strategy - -### Multi-Server - -For production environments: -- Separate database server -- Dedicated Redis instance -- Load-balanced web servers -- Shared file storage (S3/NFS) - -### Containerized - -Using Docker and orchestration: -- Container images for each component -- Kubernetes or Docker Swarm -- Service discovery and networking -- Rolling updates and health checks - -### Cloud-Native - -Leveraging cloud services: -- Managed databases (RDS, Cloud SQL) -- Managed Redis (ElastiCache, MemoryStore) -- Object storage (S3, GCS) -- Load balancers and CDN - -## Performance Optimization - -### Database Optimization - -- **Indexing strategy** for common queries -- **Connection pooling** to reduce overhead -- **Query optimization** and monitoring -- **Read replicas** for scaling reads - -### Caching Strategy - -- **Application-level caching** for expensive operations -- **HTTP caching** for static assets -- **Database query caching** with Redis -- **CDN caching** for global distribution - -### Background Processing - -- **Job prioritization** for critical tasks -- **Batch processing** for bulk operations -- **Queue monitoring** and alerting -- **Resource allocation** per job type - ---- - - -Understanding this architecture helps you make informed decisions about deployment, scaling, and maintenance of your Chatwoot instance. - \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/aws.mdx b/developer-docs/self-hosted/cloud/aws.mdx deleted file mode 100644 index eb3cf9298..000000000 --- a/developer-docs/self-hosted/cloud/aws.mdx +++ /dev/null @@ -1,501 +0,0 @@ ---- -title: AWS Deployment -description: Deploy Chatwoot on Amazon Web Services with manual installation or marketplace AMI -sidebarTitle: AWS ---- - -# AWS Deployment Guide - -Deploy Chatwoot on Amazon Web Services (AWS) using either manual installation or the AWS Marketplace AMI for a scalable, production-ready setup. - -## Deployment Options - - - - Full control over the deployment with custom architecture - - - Quick deployment using pre-configured AMI - - - -## Manual Installation - -### Architecture Overview - -This guide follows a standard 3-tier architecture on AWS for high availability: - -``` -Internet Gateway - | -Application Load Balancer (Public Subnets) - | -Chatwoot Instances (Private Subnets) - | -RDS PostgreSQL + ElastiCache Redis (Private Subnets) -``` - -### Prerequisites - -- AWS account with appropriate permissions -- Domain name for your Chatwoot installation -- Basic knowledge of AWS services (VPC, EC2, RDS, etc.) - -### Step 1: Network Setup - -#### Create VPC - -1. Navigate to the VPC console in your chosen AWS region -2. Create a new VPC: - - **Name**: `chatwoot-vpc` - - **CIDR block**: `10.0.0.0/16` - - Leave other options as default - -#### Create Subnets - -Create subnets across two availability zones: - -| Name | Type | AZ | CIDR Block | -|------|------|----|-----------| -| chatwoot-public-1 | Public | us-east-1a | 10.0.0.0/24 | -| chatwoot-public-2 | Public | us-east-1b | 10.0.1.0/24 | -| chatwoot-private-1 | Private | us-east-1a | 10.0.2.0/24 | -| chatwoot-private-2 | Private | us-east-1b | 10.0.3.0/24 | - - -Enable "Auto-assign public IPv4 address" for public subnets under Actions > Subnet Settings. - - -#### Internet Gateway - -1. Create Internet Gateway named `chatwoot-igw` -2. Attach it to `chatwoot-vpc` - -#### NAT Gateways - -Create NAT gateways in each public subnet: - -1. **chatwoot-nat-1** in `chatwoot-public-1` -2. **chatwoot-nat-2** in `chatwoot-public-2` - -Allocate Elastic IPs for each NAT gateway. - -#### Route Tables - -**Public Route Table** (`chatwoot-public-rt`): -- Route: `0.0.0.0/0` → `chatwoot-igw` -- Associate with public subnets - -**Private Route Tables**: -- `chatwoot-private-a`: Route `0.0.0.0/0` → `chatwoot-nat-1` -- `chatwoot-private-b`: Route `0.0.0.0/0` → `chatwoot-nat-2` - -### Step 2: Application Load Balancer - -1. Navigate to EC2 > Load Balancers -2. Create Application Load Balancer: - - **Name**: `chatwoot-loadbalancer` - - **Scheme**: Internet-facing - - **IP address type**: IPv4 - - **VPC**: `chatwoot-vpc` - - **Subnets**: Select both public subnets - -#### Security Group for ALB - -Create `chatwoot-loadbalancer-sg` with rules: -- HTTP (80) from `0.0.0.0/0` -- HTTPS (443) from `0.0.0.0/0` -- TCP (3000) from `0.0.0.0/0` (for health checks) - -#### Target Group - -Create `chatwoot-tg` target group: -- **Target type**: Instances -- **Protocol**: HTTP -- **Port**: 3000 -- **Health check path**: `/api` - -### Step 3: Database Setup (RDS) - -#### RDS Security Group - -Create `chatwoot-rds-sg`: -- PostgreSQL (5432) from `chatwoot-loadbalancer-sg` - -#### RDS Subnet Group - -Create `chatwoot-rds-group`: -- **VPC**: `chatwoot-vpc` -- **Subnets**: Both private subnets - -#### Create RDS Instance - -1. Navigate to RDS > Databases -2. Create database: - - **Engine**: PostgreSQL - - **Template**: Production - - **DB instance identifier**: `chatwoot-db` - - **Master username**: `chatwoot` - - **Master password**: Generate secure password - - **DB instance class**: `db.t3.medium` (minimum) - - **Storage**: 100 GB GP2 (minimum) - - **Multi-AZ**: Yes - - **VPC**: `chatwoot-vpc` - - **Subnet group**: `chatwoot-rds-group` - - **Security group**: `chatwoot-rds-sg` - - -Note down the RDS endpoint, username, and password for later configuration. - - -### Step 4: Redis Setup (ElastiCache) - -#### ElastiCache Security Group - -Create `chatwoot-redis-sg`: -- Redis (6379) from `chatwoot-loadbalancer-sg` - -#### ElastiCache Subnet Group - -Create `chatwoot-redis-group`: -- **VPC**: `chatwoot-vpc` -- **Subnets**: Both private subnets - -#### Create Redis Cluster - -1. Navigate to ElastiCache > Redis clusters -2. Create cluster: - - **Name**: `chatwoot-redis` - - **Engine version**: 7.0+ - - **Node type**: `cache.t3.micro` (minimum) - - **Multi-AZ**: Yes - - **Subnet group**: `chatwoot-redis-group` - - **Security group**: `chatwoot-redis-sg` - -### Step 5: Bastion Host - -Create bastion servers for secure access to private instances: - -1. Launch EC2 instance: - - **AMI**: Ubuntu 20.04 LTS - - **Instance type**: `t3.micro` - - **VPC**: `chatwoot-vpc` - - **Subnet**: `chatwoot-public-1` - - **Auto-assign public IP**: Yes - - **Security group**: Create `chatwoot-bastion-sg` (SSH from your IP) - -### Step 6: Chatwoot Application Servers - -#### Launch Chatwoot Instance - -1. Launch EC2 instance: - - **AMI**: Ubuntu 20.04 LTS - - **Instance type**: `c5.xlarge` (minimum for production) - - **VPC**: `chatwoot-vpc` - - **Subnet**: `chatwoot-private-1` - - **Auto-assign public IP**: No - - **Storage**: 60 GB GP2 - - **Security group**: `chatwoot-loadbalancer-sg` - -#### Install Chatwoot - -1. SSH to bastion host, then to Chatwoot instance -2. Switch to root user and download installation script: - -```bash -sudo su - -wget https://get.chatwoot.app/linux/install.sh -chmod +x install.sh -./install.sh --install -``` - -#### Configure Chatwoot - -1. Switch to chatwoot user and edit environment: - -```bash -sudo -i -u chatwoot -cd chatwoot -nano .env -``` - -2. Update database and Redis configuration: - -```bash -# Database -DATABASE_URL="postgresql://chatwoot:password@your-rds-endpoint:5432/chatwoot_production" - -# Redis -REDIS_URL="redis://your-elasticache-endpoint:6379/0" - -# Frontend URL -FRONTEND_URL="https://chatwoot.yourdomain.com" - -# Force SSL -FORCE_SSL=true - -# Email configuration (example with SES) -MAILER_SENDER_EMAIL="noreply@yourdomain.com" -SMTP_ADDRESS="email-smtp.us-east-1.amazonaws.com" -SMTP_PORT=587 -SMTP_USERNAME="your-ses-username" -SMTP_PASSWORD="your-ses-password" -SMTP_AUTHENTICATION="plain" -SMTP_ENABLE_STARTTLS_AUTO=true - -# Storage (S3) -ACTIVE_STORAGE_SERVICE="amazon" -S3_BUCKET_NAME="your-chatwoot-bucket" -AWS_ACCESS_KEY_ID="your-access-key" -AWS_SECRET_ACCESS_KEY="your-secret-key" -AWS_REGION="us-east-1" -``` - -3. Run database preparation: - -```bash -RAILS_ENV=production bundle exec rake db:chatwoot_prepare -``` - -4. Restart services: - -```bash -sudo cwctl --restart -``` - -### Step 7: SSL Certificate (ACM) - -1. Navigate to Certificate Manager -2. Request public certificate for your domain -3. Validate domain ownership -4. Attach certificate to ALB HTTPS listener - -### Step 8: Auto Scaling - -#### Create AMI - -1. Stop the Chatwoot instance -2. Create AMI named `chatwoot-base-ami` -3. Terminate the original instance - -#### Launch Template - -Create launch template with: -- **AMI**: `chatwoot-base-ami` -- **Instance type**: `c5.xlarge` -- **Security group**: `chatwoot-loadbalancer-sg` -- **User data** (optional): - -```bash -#!/bin/bash -sudo cwctl --restart -``` - -#### Auto Scaling Group - -Create ASG with: -- **Launch template**: Use created template -- **VPC**: `chatwoot-vpc` -- **Subnets**: Both private subnets -- **Target group**: `chatwoot-tg` -- **Desired capacity**: 2 -- **Minimum**: 2 -- **Maximum**: 4 - -#### Scaling Policies - -Create scaling policies based on: -- CPU utilization (scale out at 70%, scale in at 30%) -- Memory utilization -- Request count per target - -## AWS Marketplace AMI - -### Quick Deployment - -1. Navigate to AWS Marketplace -2. Search for "Chatwoot" -3. Subscribe to Chatwoot AMI -4. Launch instance with recommended settings: - - **Instance type**: `t3.medium` or larger - - **Storage**: 20 GB minimum - - **Security group**: Allow HTTP, HTTPS, and SSH - -### Post-Launch Configuration - -1. SSH to the instance -2. Complete initial setup: - -```bash -sudo /opt/chatwoot/setup.sh -``` - -3. Configure domain and SSL: - -```bash -sudo /opt/chatwoot/configure-domain.sh yourdomain.com -``` - -## Production Optimizations - -### Performance Tuning - -```bash -# Optimize Rails configuration -export RAILS_MAX_THREADS=20 -export WEB_CONCURRENCY=4 -export SIDEKIQ_CONCURRENCY=25 - -# Database connection pooling -export DATABASE_POOL_SIZE=25 -``` - -### Monitoring Setup - -#### CloudWatch Metrics - -Enable detailed monitoring for: -- EC2 instances -- RDS database -- ElastiCache cluster -- Application Load Balancer - -#### Custom Metrics - -```bash -# Install CloudWatch agent -wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm -sudo rpm -U ./amazon-cloudwatch-agent.rpm - -# Configure custom metrics -sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard -``` - -### Backup Strategy - -#### RDS Automated Backups - -- Enable automated backups with 7-day retention -- Configure backup window during low-traffic hours -- Enable point-in-time recovery - -#### Application Data Backup - -```bash -#!/bin/bash -# Backup script for application data -DATE=$(date +%Y%m%d_%H%M%S) - -# Database backup -pg_dump $DATABASE_URL | gzip > "s3://your-backup-bucket/db/chatwoot_$DATE.sql.gz" - -# File uploads backup (if using local storage) -aws s3 sync /home/chatwoot/chatwoot/storage s3://your-backup-bucket/storage/ -``` - -### Security Hardening - -#### IAM Roles - -Create IAM roles with minimal permissions: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:GetObject", - "s3:PutObject", - "s3:DeleteObject" - ], - "Resource": "arn:aws:s3:::your-chatwoot-bucket/*" - }, - { - "Effect": "Allow", - "Action": [ - "ses:SendEmail", - "ses:SendRawEmail" - ], - "Resource": "*" - } - ] -} -``` - -#### Security Groups - -Implement least-privilege access: -- ALB: Only HTTP/HTTPS from internet -- App servers: Only from ALB and bastion -- Database: Only from app servers -- Redis: Only from app servers - -## Cost Optimization - -### Reserved Instances - -Purchase Reserved Instances for: -- RDS database instances -- ElastiCache clusters -- Predictable EC2 workloads - -### Spot Instances - -Use Spot Instances for: -- Development environments -- Non-critical worker processes -- Batch processing tasks - -### Storage Optimization - -- Use GP3 volumes for better price/performance -- Implement S3 lifecycle policies for old backups -- Use S3 Intelligent Tiering for file storage - -## Troubleshooting - -### Common Issues - - -Check: -- Security group rules -- Target group health -- Route table configuration -- DNS resolution - - - -Verify: -- RDS security group allows connections -- Database credentials in .env file -- Network connectivity from app servers - - - -Solutions: -- Increase instance size -- Optimize Sidekiq concurrency -- Enable swap memory -- Monitor for memory leaks - - -### Monitoring Commands - -```bash -# Check application health -curl -I http://localhost:3000/api - -# Monitor system resources -htop -iostat -x 1 -free -h - -# Check service status -sudo systemctl status chatwoot.target -``` - ---- - -This AWS deployment guide provides a comprehensive approach to hosting Chatwoot on AWS infrastructure. Choose the deployment method that best fits your requirements and scale as needed. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/azure.mdx b/developer-docs/self-hosted/cloud/azure.mdx deleted file mode 100644 index c467e28f3..000000000 --- a/developer-docs/self-hosted/cloud/azure.mdx +++ /dev/null @@ -1,663 +0,0 @@ ---- -title: Azure Deployment -description: Deploy Chatwoot on Microsoft Azure with various deployment options -sidebarTitle: Azure ---- - -# Azure Deployment Guide - -Deploy Chatwoot on Microsoft Azure using various deployment options including Virtual Machines, Container Instances, or App Service for a scalable, production-ready setup. - -## Deployment Options - - - - Full control with custom VM deployment - - - Serverless container deployment - - - Platform-as-a-Service deployment - - - -## Virtual Machines Deployment - -### Architecture Overview - -``` -Azure Load Balancer - | -Virtual Machines (Availability Set) - | -Azure Database for PostgreSQL + Azure Cache for Redis -``` - -### Prerequisites - -- Azure subscription with appropriate permissions -- Azure CLI installed and configured -- Domain name for your Chatwoot installation - -### Step 1: Resource Group and Network - -#### Create Resource Group - -```bash -# Create resource group -az group create \ - --name chatwoot-rg \ - --location eastus -``` - -#### Create Virtual Network - -```bash -# Create virtual network -az network vnet create \ - --resource-group chatwoot-rg \ - --name chatwoot-vnet \ - --address-prefix 10.0.0.0/16 \ - --subnet-name chatwoot-subnet \ - --subnet-prefix 10.0.1.0/24 -``` - -#### Create Network Security Group - -```bash -# Create NSG -az network nsg create \ - --resource-group chatwoot-rg \ - --name chatwoot-nsg - -# Add rules -az network nsg rule create \ - --resource-group chatwoot-rg \ - --nsg-name chatwoot-nsg \ - --name AllowHTTP \ - --protocol tcp \ - --priority 1000 \ - --destination-port-range 80 - -az network nsg rule create \ - --resource-group chatwoot-rg \ - --nsg-name chatwoot-nsg \ - --name AllowHTTPS \ - --protocol tcp \ - --priority 1001 \ - --destination-port-range 443 - -az network nsg rule create \ - --resource-group chatwoot-rg \ - --nsg-name chatwoot-nsg \ - --name AllowSSH \ - --protocol tcp \ - --priority 1002 \ - --destination-port-range 22 \ - --source-address-prefix "YOUR_IP_ADDRESS" -``` - -### Step 2: Database Setup - -#### Create PostgreSQL Server - -```bash -# Create PostgreSQL server -az postgres server create \ - --resource-group chatwoot-rg \ - --name chatwoot-postgres \ - --location eastus \ - --admin-user chatwoot \ - --admin-password "YourSecurePassword123!" \ - --sku-name GP_Gen5_2 \ - --version 13 - -# Create database -az postgres db create \ - --resource-group chatwoot-rg \ - --server-name chatwoot-postgres \ - --name chatwoot_production - -# Configure firewall -az postgres server firewall-rule create \ - --resource-group chatwoot-rg \ - --server chatwoot-postgres \ - --name AllowAzureServices \ - --start-ip-address 0.0.0.0 \ - --end-ip-address 0.0.0.0 -``` - -#### Create Redis Cache - -```bash -# Create Redis cache -az redis create \ - --resource-group chatwoot-rg \ - --name chatwoot-redis \ - --location eastus \ - --sku Basic \ - --vm-size c0 -``` - -### Step 3: Storage Account - -```bash -# Create storage account -az storage account create \ - --resource-group chatwoot-rg \ - --name chatwootstorage \ - --location eastus \ - --sku Standard_LRS - -# Create container for file uploads -az storage container create \ - --account-name chatwootstorage \ - --name uploads \ - --public-access blob -``` - -### Step 4: Virtual Machine - -#### Create Availability Set - -```bash -# Create availability set -az vm availability-set create \ - --resource-group chatwoot-rg \ - --name chatwoot-avset \ - --platform-fault-domain-count 2 \ - --platform-update-domain-count 2 -``` - -#### Create Virtual Machine - -```bash -# Create VM -az vm create \ - --resource-group chatwoot-rg \ - --name chatwoot-vm \ - --image UbuntuLTS \ - --size Standard_D2s_v3 \ - --availability-set chatwoot-avset \ - --vnet-name chatwoot-vnet \ - --subnet chatwoot-subnet \ - --nsg chatwoot-nsg \ - --admin-username azureuser \ - --generate-ssh-keys \ - --custom-data cloud-init.txt -``` - -#### Cloud-Init Configuration - -Create `cloud-init.txt`: - -```yaml -#cloud-config -package_upgrade: true -packages: - - curl - - wget - - git - -runcmd: - - wget https://get.chatwoot.app/linux/install.sh - - chmod +x install.sh - - ./install.sh --install -``` - -### Step 5: Load Balancer - -```bash -# Create public IP -az network public-ip create \ - --resource-group chatwoot-rg \ - --name chatwoot-lb-ip \ - --sku Standard - -# Create load balancer -az network lb create \ - --resource-group chatwoot-rg \ - --name chatwoot-lb \ - --public-ip-address chatwoot-lb-ip \ - --frontend-ip-name chatwoot-frontend \ - --backend-pool-name chatwoot-backend - -# Create health probe -az network lb probe create \ - --resource-group chatwoot-rg \ - --lb-name chatwoot-lb \ - --name chatwoot-health \ - --protocol http \ - --port 3000 \ - --path /api - -# Create load balancing rule -az network lb rule create \ - --resource-group chatwoot-rg \ - --lb-name chatwoot-lb \ - --name chatwoot-rule \ - --protocol tcp \ - --frontend-port 80 \ - --backend-port 3000 \ - --frontend-ip-name chatwoot-frontend \ - --backend-pool-name chatwoot-backend \ - --probe-name chatwoot-health -``` - -### Step 6: Configuration - -SSH to the VM and configure Chatwoot: - -```bash -# SSH to VM -ssh azureuser@ - -# Switch to chatwoot user -sudo -i -u chatwoot -cd chatwoot - -# Edit environment variables -nano .env -``` - -Update `.env` with Azure services: - -```bash -# Database -DATABASE_URL="postgresql://chatwoot:YourSecurePassword123!@chatwoot-postgres.postgres.database.azure.com:5432/chatwoot_production" - -# Redis -REDIS_URL="redis://:PRIMARY_ACCESS_KEY@chatwoot-redis.redis.cache.windows.net:6380/0?ssl=true" - -# Storage (Azure Blob) -ACTIVE_STORAGE_SERVICE="azure" -AZURE_STORAGE_ACCOUNT_NAME="chatwootstorage" -AZURE_STORAGE_ACCESS_KEY="your-access-key" -AZURE_STORAGE_CONTAINER="uploads" - -# Frontend URL -FRONTEND_URL="https://chatwoot.yourdomain.com" -FORCE_SSL=true -``` - -## Container Instances Deployment - -### Docker Compose for Azure - -Create `docker-compose.azure.yml`: - -```yaml -version: '3.8' - -services: - chatwoot-web: - image: chatwoot/chatwoot:latest - environment: - - RAILS_ENV=production - - DATABASE_URL=postgresql://chatwoot:password@postgres:5432/chatwoot_production - - REDIS_URL=redis://redis:6379/0 - - FRONTEND_URL=https://chatwoot.yourdomain.com - - FORCE_SSL=true - ports: - - "3000:3000" - depends_on: - - postgres - - redis - - chatwoot-worker: - image: chatwoot/chatwoot:latest - environment: - - RAILS_ENV=production - - DATABASE_URL=postgresql://chatwoot:password@postgres:5432/chatwoot_production - - REDIS_URL=redis://redis:6379/0 - command: bundle exec sidekiq -C config/sidekiq.yml - depends_on: - - postgres - - redis - - postgres: - image: postgres:13 - environment: - - POSTGRES_DB=chatwoot_production - - POSTGRES_USER=chatwoot - - POSTGRES_PASSWORD=password - volumes: - - postgres_data:/var/lib/postgresql/data - - redis: - image: redis:7-alpine - volumes: - - redis_data:/data - -volumes: - postgres_data: - redis_data: -``` - -### Deploy with Azure Container Instances - -```bash -# Create container group -az container create \ - --resource-group chatwoot-rg \ - --file docker-compose.azure.yml \ - --dns-name-label chatwoot-app \ - --ports 3000 -``` - -## App Service Deployment - -### Create App Service Plan - -```bash -# Create App Service plan -az appservice plan create \ - --resource-group chatwoot-rg \ - --name chatwoot-plan \ - --sku P1V2 \ - --is-linux - -# Create web app -az webapp create \ - --resource-group chatwoot-rg \ - --plan chatwoot-plan \ - --name chatwoot-app \ - --deployment-container-image-name chatwoot/chatwoot:latest -``` - -### Configure App Settings - -```bash -# Set environment variables -az webapp config appsettings set \ - --resource-group chatwoot-rg \ - --name chatwoot-app \ - --settings \ - RAILS_ENV=production \ - DATABASE_URL="postgresql://chatwoot:password@chatwoot-postgres.postgres.database.azure.com:5432/chatwoot_production" \ - REDIS_URL="redis://:key@chatwoot-redis.redis.cache.windows.net:6380/0?ssl=true" \ - FRONTEND_URL="https://chatwoot-app.azurewebsites.net" \ - FORCE_SSL=true -``` - -## Monitoring and Logging - -### Application Insights - -```bash -# Create Application Insights -az monitor app-insights component create \ - --resource-group chatwoot-rg \ - --app chatwoot-insights \ - --location eastus \ - --kind web - -# Get instrumentation key -az monitor app-insights component show \ - --resource-group chatwoot-rg \ - --app chatwoot-insights \ - --query instrumentationKey -``` - -### Log Analytics Workspace - -```bash -# Create Log Analytics workspace -az monitor log-analytics workspace create \ - --resource-group chatwoot-rg \ - --workspace-name chatwoot-logs \ - --location eastus -``` - -## Security Configuration - -### Key Vault for Secrets - -```bash -# Create Key Vault -az keyvault create \ - --resource-group chatwoot-rg \ - --name chatwoot-vault \ - --location eastus - -# Store secrets -az keyvault secret set \ - --vault-name chatwoot-vault \ - --name database-password \ - --value "YourSecurePassword123!" - -az keyvault secret set \ - --vault-name chatwoot-vault \ - --name redis-key \ - --value "your-redis-access-key" -``` - -### Managed Identity - -```bash -# Enable managed identity for VM -az vm identity assign \ - --resource-group chatwoot-rg \ - --name chatwoot-vm - -# Grant access to Key Vault -az keyvault set-policy \ - --name chatwoot-vault \ - --object-id \ - --secret-permissions get list -``` - -## Backup and Disaster Recovery - -### Database Backup - -```bash -# Enable automated backup for PostgreSQL -az postgres server configuration set \ - --resource-group chatwoot-rg \ - --server-name chatwoot-postgres \ - --name backup_retention_days \ - --value 7 - -# Create manual backup -az postgres server backup create \ - --resource-group chatwoot-rg \ - --server-name chatwoot-postgres \ - --backup-name manual-backup-$(date +%Y%m%d) -``` - -### VM Backup - -```bash -# Create Recovery Services vault -az backup vault create \ - --resource-group chatwoot-rg \ - --name chatwoot-vault \ - --location eastus - -# Enable backup for VM -az backup protection enable-for-vm \ - --resource-group chatwoot-rg \ - --vault-name chatwoot-vault \ - --vm chatwoot-vm \ - --policy-name DefaultPolicy -``` - -## Scaling and Performance - -### VM Scale Sets - -```bash -# Create VM scale set -az vmss create \ - --resource-group chatwoot-rg \ - --name chatwoot-vmss \ - --image UbuntuLTS \ - --vm-sku Standard_D2s_v3 \ - --instance-count 2 \ - --vnet-name chatwoot-vnet \ - --subnet chatwoot-subnet \ - --lb chatwoot-lb \ - --backend-pool-name chatwoot-backend \ - --custom-data cloud-init.txt - -# Configure autoscaling -az monitor autoscale create \ - --resource-group chatwoot-rg \ - --resource chatwoot-vmss \ - --resource-type Microsoft.Compute/virtualMachineScaleSets \ - --name chatwoot-autoscale \ - --min-count 2 \ - --max-count 5 \ - --count 2 - -# Add scale-out rule -az monitor autoscale rule create \ - --resource-group chatwoot-rg \ - --autoscale-name chatwoot-autoscale \ - --condition "Percentage CPU > 70 avg 5m" \ - --scale out 1 - -# Add scale-in rule -az monitor autoscale rule create \ - --resource-group chatwoot-rg \ - --autoscale-name chatwoot-autoscale \ - --condition "Percentage CPU < 30 avg 5m" \ - --scale in 1 -``` - -## SSL Certificate - -### App Service Certificate - -```bash -# Create App Service certificate -az webapp config ssl upload \ - --resource-group chatwoot-rg \ - --name chatwoot-app \ - --certificate-file certificate.pfx \ - --certificate-password "certificate-password" - -# Bind certificate to domain -az webapp config ssl bind \ - --resource-group chatwoot-rg \ - --name chatwoot-app \ - --certificate-thumbprint \ - --ssl-type SNI -``` - -### Let's Encrypt with VM - -```bash -# Install Certbot on VM -sudo apt update -sudo apt install certbot python3-certbot-nginx - -# Obtain certificate -sudo certbot --nginx -d chatwoot.yourdomain.com - -# Auto-renewal -sudo crontab -e -# Add: 0 12 * * * /usr/bin/certbot renew --quiet -``` - -## Cost Optimization - -### Reserved Instances - -```bash -# Purchase reserved capacity for VMs -az reservations reservation-order purchase \ - --reservation-order-id \ - --sku Standard_D2s_v3 \ - --location eastus \ - --quantity 2 \ - --term P1Y -``` - -### Azure Advisor - -```bash -# Get cost recommendations -az advisor recommendation list \ - --category Cost \ - --resource-group chatwoot-rg -``` - -## Troubleshooting - -### Common Issues - - -Check: -- PostgreSQL firewall rules -- Network security group rules -- Connection string format -- SSL requirements for Azure Database - - - -Verify: -- Redis access keys -- SSL configuration (required for Azure Cache) -- Network connectivity -- Port 6380 (SSL) vs 6379 (non-SSL) - - - -Solutions: -- Verify storage account access keys -- Check container permissions -- Ensure CORS settings if needed -- Validate Azure Storage configuration - - -### Diagnostic Commands - -```bash -# Check VM status -az vm get-instance-view \ - --resource-group chatwoot-rg \ - --name chatwoot-vm - -# View application logs -az webapp log tail \ - --resource-group chatwoot-rg \ - --name chatwoot-app - -# Check database connectivity -az postgres server show \ - --resource-group chatwoot-rg \ - --name chatwoot-postgres -``` - -## Best Practices - -### Security -- Use Azure Key Vault for secrets management -- Enable managed identities for Azure resources -- Implement network security groups with least privilege -- Enable Azure Security Center recommendations - -### Performance -- Use Azure CDN for static assets -- Implement Redis caching strategies -- Monitor with Application Insights -- Use proximity placement groups for low latency - -### Cost Management -- Use Azure Cost Management for monitoring -- Implement auto-shutdown for development VMs -- Consider spot instances for non-critical workloads -- Use reserved instances for predictable workloads - -### Backup and Recovery -- Enable automated backups for all data services -- Test backup restoration procedures regularly -- Implement geo-redundant storage for critical data -- Document disaster recovery procedures - ---- - -This Azure deployment guide provides multiple options for hosting Chatwoot on Microsoft Azure. Choose the deployment method that best fits your requirements, budget, and operational preferences. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/digitalocean.mdx b/developer-docs/self-hosted/cloud/digitalocean.mdx deleted file mode 100644 index 279edca3c..000000000 --- a/developer-docs/self-hosted/cloud/digitalocean.mdx +++ /dev/null @@ -1,670 +0,0 @@ ---- -title: DigitalOcean Deployment -description: Deploy Chatwoot on DigitalOcean with Droplets, App Platform, or Kubernetes -sidebarTitle: DigitalOcean ---- - -# DigitalOcean Deployment Guide - -Deploy Chatwoot on DigitalOcean using Droplets, App Platform, or DigitalOcean Kubernetes for a scalable, cost-effective solution. - -## Deployment Options - - - - Traditional VPS deployment with full control - - - Platform-as-a-Service deployment - - - Container orchestration with DOKS - - - -## Droplets Deployment - -### Quick Start with One-Click Install - -DigitalOcean offers a one-click Chatwoot installation from the Marketplace: - -1. **Navigate to DigitalOcean Marketplace** -2. **Search for "Chatwoot"** -3. **Click "Create Chatwoot Droplet"** -4. **Configure your Droplet:** - - **Plan**: Basic ($12/month minimum recommended) - - **CPU options**: Regular Intel - - **Region**: Choose closest to your users - - **Authentication**: SSH keys (recommended) - - **Hostname**: chatwoot-production - -5. **Access your installation:** - ```bash - ssh root@your-droplet-ip - ``` - -### Manual Installation - -#### Create Droplet - -```bash -# Using doctl CLI -doctl compute droplet create chatwoot-prod \ - --image ubuntu-20-04-x64 \ - --size s-2vcpu-4gb \ - --region nyc3 \ - --ssh-keys your-ssh-key-id \ - --enable-monitoring \ - --enable-ipv6 -``` - -#### Install Chatwoot - -```bash -# SSH to droplet -ssh root@your-droplet-ip - -# Download and run installation script -wget https://get.chatwoot.app/linux/install.sh -chmod +x install.sh -./install.sh --install -``` - -### Database Setup - -#### Managed PostgreSQL - -```bash -# Create managed database cluster -doctl databases create chatwoot-db \ - --engine postgres \ - --version 13 \ - --size db-s-1vcpu-1gb \ - --region nyc3 \ - --num-nodes 1 - -# Create database -doctl databases db create chatwoot-db-id chatwoot_production - -# Create user -doctl databases user create chatwoot-db-id chatwoot -``` - -#### Managed Redis - -```bash -# Create managed Redis cluster -doctl databases create chatwoot-redis \ - --engine redis \ - --version 6 \ - --size db-s-1vcpu-1gb \ - --region nyc3 \ - --num-nodes 1 -``` - -### Configuration - -Update Chatwoot configuration to use managed services: - -```bash -# Switch to chatwoot user -sudo -i -u chatwoot -cd chatwoot - -# Edit environment file -nano .env -``` - -Add managed database configuration: - -```bash -# Database (from DigitalOcean dashboard) -DATABASE_URL="postgresql://chatwoot:password@chatwoot-db-do-user-123456-0.b.db.ondigitalocean.com:25060/chatwoot_production?sslmode=require" - -# Redis (from DigitalOcean dashboard) -REDIS_URL="rediss://default:password@chatwoot-redis-do-user-123456-0.b.db.ondigitalocean.com:25061" - -# Frontend URL -FRONTEND_URL="https://chatwoot.yourdomain.com" -FORCE_SSL=true - -# Storage (DigitalOcean Spaces) -ACTIVE_STORAGE_SERVICE="amazon" -S3_BUCKET_NAME="your-chatwoot-space" -AWS_ACCESS_KEY_ID="your-spaces-key" -AWS_SECRET_ACCESS_KEY="your-spaces-secret" -AWS_REGION="nyc3" -S3_ENDPOINT="https://nyc3.digitaloceanspaces.com" -``` - -### Load Balancer Setup - -```bash -# Create load balancer -doctl compute load-balancer create \ - --name chatwoot-lb \ - --forwarding-rules entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:your-cert-id \ - --forwarding-rules entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000 \ - --health-check protocol:http,port:3000,path:/api,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:3,unhealthy_threshold:3 \ - --region nyc3 \ - --droplet-ids droplet-id-1,droplet-id-2 -``` - -## App Platform Deployment - -### App Spec Configuration - -Create `app.yaml`: - -```yaml -name: chatwoot-app -services: -- name: web - source_dir: / - github: - repo: your-username/chatwoot-fork - branch: main - run_command: bundle exec rails server -b 0.0.0.0 -p $PORT - environment_slug: ruby - instance_count: 1 - instance_size_slug: basic-xxs - envs: - - key: RAILS_ENV - value: production - - key: DATABASE_URL - value: ${chatwoot-db.DATABASE_URL} - - key: REDIS_URL - value: ${chatwoot-redis.REDIS_URL} - - key: FRONTEND_URL - value: ${APP_URL} - - key: FORCE_SSL - value: "true" - http_port: 8080 - -- name: worker - source_dir: / - github: - repo: your-username/chatwoot-fork - branch: main - run_command: bundle exec sidekiq -C config/sidekiq.yml - environment_slug: ruby - instance_count: 1 - instance_size_slug: basic-xxs - envs: - - key: RAILS_ENV - value: production - - key: DATABASE_URL - value: ${chatwoot-db.DATABASE_URL} - - key: REDIS_URL - value: ${chatwoot-redis.REDIS_URL} - -databases: -- name: chatwoot-db - engine: PG - version: "13" - size: db-s-dev-database - -- name: chatwoot-redis - engine: REDIS - version: "6" - size: db-s-dev-database - -static_sites: -- name: assets - source_dir: /public - github: - repo: your-username/chatwoot-fork - branch: main - build_command: bundle exec rails assets:precompile -``` - -### Deploy with App Platform - -```bash -# Deploy using doctl -doctl apps create --spec app.yaml - -# Or deploy via DigitalOcean Control Panel -# 1. Go to App Platform -# 2. Create App -# 3. Connect your GitHub repository -# 4. Configure build and run commands -# 5. Add environment variables -# 6. Deploy -``` - -## Kubernetes Deployment - -### Create DOKS Cluster - -```bash -# Create Kubernetes cluster -doctl kubernetes cluster create chatwoot-k8s \ - --region nyc3 \ - --version 1.24.4-do.0 \ - --count 3 \ - --size s-2vcpu-4gb \ - --auto-upgrade=true \ - --maintenance-window="saturday=06:00" - -# Get kubeconfig -doctl kubernetes cluster kubeconfig save chatwoot-k8s -``` - -### Helm Deployment - -```bash -# Add Chatwoot Helm repository -helm repo add chatwoot https://chatwoot.github.io/charts -helm repo update - -# Create namespace -kubectl create namespace chatwoot - -# Install with DigitalOcean-specific values -helm install chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --set ingress.enabled=true \ - --set ingress.className=nginx \ - --set ingress.hosts[0].host=chatwoot.yourdomain.com \ - --set postgresql.enabled=false \ - --set redis.enabled=false \ - --set env.DATABASE_URL="postgresql://..." \ - --set env.REDIS_URL="redis://..." -``` - -### DigitalOcean-Specific Values - -Create `do-values.yaml`: - -```yaml -# DigitalOcean Kubernetes values -ingress: - enabled: true - className: nginx - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - kubernetes.digitalocean.com/load-balancer-id: "your-lb-id" - hosts: - - host: chatwoot.yourdomain.com - paths: - - path: / - pathType: Prefix - -# Use DigitalOcean managed databases -postgresql: - enabled: false - -redis: - enabled: false - -# DigitalOcean Spaces for storage -env: - ACTIVE_STORAGE_SERVICE: "amazon" - S3_BUCKET_NAME: "your-chatwoot-space" - AWS_ACCESS_KEY_ID: "your-spaces-key" - AWS_SECRET_ACCESS_KEY: "your-spaces-secret" - AWS_REGION: "nyc3" - S3_ENDPOINT: "https://nyc3.digitaloceanspaces.com" - -# Resource limits for DigitalOcean -resources: - limits: - cpu: 1000m - memory: 2Gi - requests: - cpu: 500m - memory: 1Gi - -# Storage class for DigitalOcean Block Storage -persistence: - enabled: true - storageClass: "do-block-storage" - size: 20Gi -``` - -## Storage Configuration - -### DigitalOcean Spaces - -```bash -# Create Spaces bucket -doctl compute cdn create \ - --origin nyc3.digitaloceanspaces.com/your-chatwoot-space \ - --ttl 3600 - -# Configure CORS for Spaces -# Create cors.json: -{ - "CORSRules": [ - { - "AllowedOrigins": ["https://chatwoot.yourdomain.com"], - "AllowedMethods": ["GET", "PUT", "POST", "DELETE"], - "AllowedHeaders": ["*"], - "MaxAgeSeconds": 3000 - } - ] -} - -# Apply CORS configuration -s3cmd setcors cors.json s3://your-chatwoot-space -``` - -### Block Storage for Droplets - -```bash -# Create and attach block storage -doctl compute volume create chatwoot-storage \ - --size 100GiB \ - --region nyc3 - -doctl compute volume-action attach chatwoot-storage \ - --droplet-id your-droplet-id - -# Mount the volume -sudo mkdir /mnt/chatwoot-storage -sudo mount -o discard,defaults /dev/disk/by-id/scsi-0DO_Volume_chatwoot-storage /mnt/chatwoot-storage -echo '/dev/disk/by-id/scsi-0DO_Volume_chatwoot-storage /mnt/chatwoot-storage ext4 defaults,nofail,discard 0 0' | sudo tee -a /etc/fstab -``` - -## SSL Certificate - -### Let's Encrypt with Certbot - -```bash -# Install Certbot -sudo apt update -sudo apt install certbot python3-certbot-nginx - -# Obtain certificate -sudo certbot --nginx -d chatwoot.yourdomain.com - -# Auto-renewal -sudo crontab -e -# Add: 0 12 * * * /usr/bin/certbot renew --quiet -``` - -### DigitalOcean Load Balancer SSL - -```bash -# Upload certificate to DigitalOcean -doctl compute certificate create \ - --name chatwoot-cert \ - --private-key-path private.key \ - --leaf-certificate-path certificate.crt \ - --certificate-chain-path ca_bundle.crt - -# Update load balancer with certificate -doctl compute load-balancer update your-lb-id \ - --forwarding-rules entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:your-cert-id -``` - -## Monitoring and Alerting - -### DigitalOcean Monitoring - -```bash -# Enable monitoring for droplets -doctl compute droplet create chatwoot-prod \ - --enable-monitoring \ - --enable-ipv6 - -# Create alert policies -doctl monitoring alert-policy create \ - --type v1/insights/droplet/cpu \ - --description "High CPU usage" \ - --compare GreaterThan \ - --value 80 \ - --window 5m \ - --entities droplet:your-droplet-id -``` - -### Custom Metrics with Prometheus - -```yaml -# prometheus-config.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus-config - namespace: monitoring -data: - prometheus.yml: | - global: - scrape_interval: 15s - scrape_configs: - - job_name: 'chatwoot' - static_configs: - - targets: ['chatwoot-service:3000'] - metrics_path: /metrics -``` - -## Backup Strategy - -### Database Backups - -```bash -# Automated backups for managed databases are enabled by default -# Manual backup -doctl databases backups list chatwoot-db-id - -# Restore from backup -doctl databases backups restore chatwoot-db-id backup-id -``` - -### Droplet Snapshots - -```bash -# Create snapshot -doctl compute droplet-action snapshot your-droplet-id \ - --snapshot-name "chatwoot-backup-$(date +%Y%m%d)" - -# Schedule automated snapshots -doctl compute droplet-action enable-backups your-droplet-id -``` - -### Application Data Backup - -```bash -#!/bin/bash -# backup-script.sh -DATE=$(date +%Y%m%d_%H%M%S) - -# Database backup (if using managed database) -pg_dump $DATABASE_URL | gzip > "/tmp/chatwoot_db_$DATE.sql.gz" - -# Upload to Spaces -s3cmd put "/tmp/chatwoot_db_$DATE.sql.gz" s3://your-backup-space/db/ - -# File uploads backup -s3cmd sync s3://your-chatwoot-space/ s3://your-backup-space/files/ - -# Cleanup local backup -rm "/tmp/chatwoot_db_$DATE.sql.gz" -``` - -## Scaling and Performance - -### Horizontal Scaling with Load Balancer - -```bash -# Create additional droplets -for i in {2..3}; do - doctl compute droplet create chatwoot-prod-$i \ - --image ubuntu-20-04-x64 \ - --size s-2vcpu-4gb \ - --region nyc3 \ - --ssh-keys your-ssh-key-id \ - --user-data-file cloud-init.yaml -done - -# Add droplets to load balancer -doctl compute load-balancer add-droplets your-lb-id \ - --droplet-ids droplet-id-2,droplet-id-3 -``` - -### Vertical Scaling - -```bash -# Resize droplet -doctl compute droplet-action resize your-droplet-id \ - --size s-4vcpu-8gb \ - --resize-disk -``` - -### Auto-scaling with Kubernetes - -```yaml -# hpa.yaml -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: chatwoot-hpa - namespace: chatwoot -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: chatwoot - minReplicas: 2 - maxReplicas: 10 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 70 - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: 80 -``` - -## Cost Optimization - -### Reserved Instances - -```bash -# DigitalOcean doesn't offer reserved instances -# But you can optimize costs by: - -# 1. Right-sizing droplets -doctl compute size list - -# 2. Using appropriate database sizes -doctl databases options sizes - -# 3. Implementing auto-scaling to scale down during low usage -``` - -### Cost Monitoring - -```bash -# Check current usage and costs -doctl account get - -# Monitor resource usage -doctl monitoring metrics bandwidth droplet:your-droplet-id -doctl monitoring metrics cpu droplet:your-droplet-id -doctl monitoring metrics memory droplet:your-droplet-id -``` - -## Troubleshooting - -### Common Issues - - -Check: -- Firewall rules (ufw status) -- DigitalOcean Cloud Firewalls -- SSH key configuration -- Network connectivity - - - -Verify: -- Database cluster status -- Connection string format -- SSL requirements for managed databases -- Firewall rules for database access - - - -Solutions: -- Verify health check path (/api) -- Check application startup time -- Ensure proper port configuration -- Review application logs - - -### Diagnostic Commands - -```bash -# Check droplet status -doctl compute droplet get your-droplet-id - -# View load balancer status -doctl compute load-balancer get your-lb-id - -# Check database status -doctl databases get chatwoot-db-id - -# Monitor application logs -sudo journalctl -u chatwoot-web.1.service -f -sudo journalctl -u chatwoot-worker.1.service -f -``` - -### Performance Monitoring - -```bash -# System resources -htop -iostat -x 1 -free -h -df -h - -# Network monitoring -iftop -netstat -tulpn - -# Application metrics -curl http://localhost:3000/api -curl http://localhost:3000/metrics -``` - -## Best Practices - -### Security -- Enable DigitalOcean Cloud Firewalls -- Use SSH keys instead of passwords -- Enable automatic security updates -- Implement fail2ban for SSH protection -- Use managed databases for better security - -### Performance -- Use DigitalOcean Spaces CDN for static assets -- Implement Redis caching -- Monitor with DigitalOcean Monitoring -- Use SSD-backed droplets -- Place resources in the same region - -### Reliability -- Use multiple availability zones -- Implement automated backups -- Set up monitoring and alerting -- Use load balancers for high availability -- Test disaster recovery procedures - -### Cost Management -- Right-size your resources -- Use managed services to reduce operational overhead -- Implement monitoring to track usage -- Clean up unused resources regularly -- Consider using Kubernetes for better resource utilization - ---- - -This DigitalOcean deployment guide provides multiple options for hosting Chatwoot on DigitalOcean's infrastructure. Choose the deployment method that best fits your technical requirements and budget constraints. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/gcp.mdx b/developer-docs/self-hosted/cloud/gcp.mdx deleted file mode 100644 index a4770107e..000000000 --- a/developer-docs/self-hosted/cloud/gcp.mdx +++ /dev/null @@ -1,745 +0,0 @@ ---- -title: Google Cloud Platform (GCP) Deployment -description: Deploy Chatwoot on Google Cloud Platform with Compute Engine, Cloud Run, or GKE -sidebarTitle: GCP ---- - -# Google Cloud Platform Deployment Guide - -Deploy Chatwoot on Google Cloud Platform using Compute Engine, Cloud Run, or Google Kubernetes Engine for a scalable, enterprise-ready solution. - -## Deployment Options - - - - Traditional VM deployment with full control - - - Serverless container deployment - - - Managed Kubernetes deployment - - - -## Compute Engine Deployment - -### Prerequisites - -```bash -# Install and configure gcloud CLI -curl https://sdk.cloud.google.com | bash -exec -l $SHELL -gcloud init - -# Set project and region -gcloud config set project your-project-id -gcloud config set compute/region us-central1 -gcloud config set compute/zone us-central1-a -``` - -### Network Setup - -```bash -# Create VPC network -gcloud compute networks create chatwoot-vpc --subnet-mode=custom - -# Create subnet -gcloud compute networks subnets create chatwoot-subnet \ - --network=chatwoot-vpc \ - --range=10.0.1.0/24 \ - --region=us-central1 - -# Create firewall rules -gcloud compute firewall-rules create chatwoot-allow-http \ - --network=chatwoot-vpc \ - --allow=tcp:80,tcp:443,tcp:3000 \ - --source-ranges=0.0.0.0/0 \ - --target-tags=chatwoot-server - -gcloud compute firewall-rules create chatwoot-allow-ssh \ - --network=chatwoot-vpc \ - --allow=tcp:22 \ - --source-ranges=0.0.0.0/0 \ - --target-tags=chatwoot-server -``` - -### Database Setup - -#### Cloud SQL PostgreSQL - -```bash -# Create Cloud SQL instance -gcloud sql instances create chatwoot-db \ - --database-version=POSTGRES_13 \ - --tier=db-g1-small \ - --region=us-central1 \ - --storage-type=SSD \ - --storage-size=100GB \ - --storage-auto-increase \ - --backup-start-time=03:00 \ - --enable-bin-log \ - --maintenance-window-day=SUN \ - --maintenance-window-hour=04 - -# Create database -gcloud sql databases create chatwoot_production --instance=chatwoot-db - -# Create user -gcloud sql users create chatwoot \ - --instance=chatwoot-db \ - --password=your-secure-password - -# Get connection name -gcloud sql instances describe chatwoot-db --format="value(connectionName)" -``` - -#### Memorystore Redis - -```bash -# Create Redis instance -gcloud redis instances create chatwoot-redis \ - --size=1 \ - --region=us-central1 \ - --redis-version=redis_6_x \ - --network=chatwoot-vpc -``` - -### Storage Setup - -```bash -# Create Cloud Storage bucket -gsutil mb -p your-project-id -c STANDARD -l us-central1 gs://your-chatwoot-bucket - -# Set bucket permissions -gsutil iam ch allUsers:objectViewer gs://your-chatwoot-bucket - -# Enable CORS -cat > cors.json << EOF -[ - { - "origin": ["https://chatwoot.yourdomain.com"], - "method": ["GET", "PUT", "POST", "DELETE"], - "responseHeader": ["Content-Type"], - "maxAgeSeconds": 3600 - } -] -EOF - -gsutil cors set cors.json gs://your-chatwoot-bucket -``` - -### Compute Instance - -#### Create Instance Template - -```bash -# Create startup script -cat > startup-script.sh << 'EOF' -#!/bin/bash -apt-get update -apt-get install -y wget curl - -# Download and install Chatwoot -wget https://get.chatwoot.app/linux/install.sh -chmod +x install.sh -./install.sh --install - -# Configure environment -sudo -u chatwoot bash << 'INNER_EOF' -cd /home/chatwoot/chatwoot -cat > .env << 'ENV_EOF' -RAILS_ENV=production -NODE_ENV=production -FRONTEND_URL=https://chatwoot.yourdomain.com -FORCE_SSL=true - -# Database -DATABASE_URL=postgresql://chatwoot:password@/chatwoot_production?host=/cloudsql/your-project:us-central1:chatwoot-db - -# Redis -REDIS_URL=redis://10.0.0.3:6379/0 - -# Storage -ACTIVE_STORAGE_SERVICE=google -GCS_PROJECT=your-project-id -GCS_BUCKET=your-chatwoot-bucket - -# Email (using SendGrid) -MAILER_SENDER_EMAIL=noreply@yourdomain.com -SMTP_ADDRESS=smtp.sendgrid.net -SMTP_PORT=587 -SMTP_USERNAME=apikey -SMTP_PASSWORD=your-sendgrid-api-key -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true -ENV_EOF - -# Prepare database -RAILS_ENV=production bundle exec rake db:chatwoot_prepare -INNER_EOF - -# Restart services -systemctl restart chatwoot.target -EOF - -# Create instance template -gcloud compute instance-templates create chatwoot-template \ - --machine-type=e2-standard-2 \ - --network-interface=network=chatwoot-vpc,subnet=chatwoot-subnet \ - --boot-disk-size=50GB \ - --boot-disk-type=pd-ssd \ - --image-family=ubuntu-2004-lts \ - --image-project=ubuntu-os-cloud \ - --tags=chatwoot-server \ - --metadata-from-file startup-script=startup-script.sh \ - --service-account=chatwoot-sa@your-project-id.iam.gserviceaccount.com \ - --scopes=https://www.googleapis.com/auth/cloud-platform -``` - -#### Create Managed Instance Group - -```bash -# Create instance group -gcloud compute instance-groups managed create chatwoot-ig \ - --template=chatwoot-template \ - --size=2 \ - --zone=us-central1-a - -# Configure autoscaling -gcloud compute instance-groups managed set-autoscaling chatwoot-ig \ - --max-num-replicas=5 \ - --min-num-replicas=2 \ - --target-cpu-utilization=0.7 \ - --zone=us-central1-a -``` - -### Load Balancer - -```bash -# Create health check -gcloud compute health-checks create http chatwoot-health-check \ - --port=3000 \ - --request-path=/api - -# Create backend service -gcloud compute backend-services create chatwoot-backend \ - --protocol=HTTP \ - --health-checks=chatwoot-health-check \ - --global - -# Add instance group to backend service -gcloud compute backend-services add-backend chatwoot-backend \ - --instance-group=chatwoot-ig \ - --instance-group-zone=us-central1-a \ - --global - -# Create URL map -gcloud compute url-maps create chatwoot-map \ - --default-service=chatwoot-backend - -# Create SSL certificate -gcloud compute ssl-certificates create chatwoot-ssl \ - --domains=chatwoot.yourdomain.com - -# Create HTTPS proxy -gcloud compute target-https-proxies create chatwoot-https-proxy \ - --url-map=chatwoot-map \ - --ssl-certificates=chatwoot-ssl - -# Create global forwarding rule -gcloud compute forwarding-rules create chatwoot-https-rule \ - --global \ - --target-https-proxy=chatwoot-https-proxy \ - --ports=443 - -# Create HTTP to HTTPS redirect -gcloud compute url-maps create chatwoot-redirect \ - --default-url-redirect-response-code=301 \ - --default-url-redirect-https-redirect - -gcloud compute target-http-proxies create chatwoot-http-proxy \ - --url-map=chatwoot-redirect - -gcloud compute forwarding-rules create chatwoot-http-rule \ - --global \ - --target-http-proxy=chatwoot-http-proxy \ - --ports=80 -``` - -## Cloud Run Deployment - -### Containerize Chatwoot - -Create `Dockerfile`: - -```dockerfile -FROM chatwoot/chatwoot:latest - -# Set environment variables -ENV RAILS_ENV=production -ENV NODE_ENV=production -ENV PORT=8080 - -# Expose port -EXPOSE 8080 - -# Start command -CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "8080"] -``` - -### Build and Deploy - -```bash -# Build container image -gcloud builds submit --tag gcr.io/your-project-id/chatwoot - -# Deploy to Cloud Run -gcloud run deploy chatwoot \ - --image gcr.io/your-project-id/chatwoot \ - --platform managed \ - --region us-central1 \ - --allow-unauthenticated \ - --memory 2Gi \ - --cpu 2 \ - --max-instances 10 \ - --set-env-vars RAILS_ENV=production \ - --set-env-vars DATABASE_URL="postgresql://..." \ - --set-env-vars REDIS_URL="redis://..." \ - --set-env-vars FRONTEND_URL="https://chatwoot.yourdomain.com" - -# Deploy worker service -gcloud run deploy chatwoot-worker \ - --image gcr.io/your-project-id/chatwoot \ - --platform managed \ - --region us-central1 \ - --no-allow-unauthenticated \ - --memory 1Gi \ - --cpu 1 \ - --max-instances 5 \ - --command "bundle,exec,sidekiq,-C,config/sidekiq.yml" \ - --set-env-vars RAILS_ENV=production \ - --set-env-vars DATABASE_URL="postgresql://..." \ - --set-env-vars REDIS_URL="redis://..." -``` - -### Custom Domain - -```bash -# Map custom domain -gcloud run domain-mappings create \ - --service chatwoot \ - --domain chatwoot.yourdomain.com \ - --region us-central1 -``` - -## Google Kubernetes Engine (GKE) - -### Create GKE Cluster - -```bash -# Create GKE cluster -gcloud container clusters create chatwoot-cluster \ - --zone us-central1-a \ - --num-nodes 3 \ - --machine-type e2-standard-2 \ - --disk-size 50GB \ - --disk-type pd-ssd \ - --enable-autoscaling \ - --min-nodes 1 \ - --max-nodes 5 \ - --enable-autorepair \ - --enable-autoupgrade \ - --network chatwoot-vpc \ - --subnetwork chatwoot-subnet - -# Get credentials -gcloud container clusters get-credentials chatwoot-cluster --zone us-central1-a -``` - -### Helm Deployment - -```bash -# Add Chatwoot Helm repository -helm repo add chatwoot https://chatwoot.github.io/charts -helm repo update - -# Create namespace -kubectl create namespace chatwoot - -# Create values file for GCP -cat > gcp-values.yaml << EOF -# GCP-specific values -ingress: - enabled: true - className: gce - annotations: - kubernetes.io/ingress.global-static-ip-name: "chatwoot-ip" - networking.gke.io/managed-certificates: "chatwoot-ssl" - kubernetes.io/ingress.allow-http: "false" - hosts: - - host: chatwoot.yourdomain.com - paths: - - path: / - pathType: Prefix - -# Use Cloud SQL and Memorystore -postgresql: - enabled: false - -redis: - enabled: false - -env: - DATABASE_URL: "postgresql://chatwoot:password@/chatwoot_production?host=/cloudsql/your-project:us-central1:chatwoot-db" - REDIS_URL: "redis://10.0.0.3:6379/0" - ACTIVE_STORAGE_SERVICE: "google" - GCS_PROJECT: "your-project-id" - GCS_BUCKET: "your-chatwoot-bucket" - -# Resource limits -resources: - limits: - cpu: 1000m - memory: 2Gi - requests: - cpu: 500m - memory: 1Gi - -# Workload Identity -serviceAccount: - create: true - annotations: - iam.gke.io/gcp-service-account: chatwoot-sa@your-project-id.iam.gserviceaccount.com -EOF - -# Install Chatwoot -helm install chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --values gcp-values.yaml -``` - -### SSL Certificate - -```yaml -# managed-cert.yaml -apiVersion: networking.gke.io/v1 -kind: ManagedCertificate -metadata: - name: chatwoot-ssl - namespace: chatwoot -spec: - domains: - - chatwoot.yourdomain.com -``` - -```bash -kubectl apply -f managed-cert.yaml -``` - -## Service Account and IAM - -### Create Service Account - -```bash -# Create service account -gcloud iam service-accounts create chatwoot-sa \ - --display-name="Chatwoot Service Account" - -# Grant necessary permissions -gcloud projects add-iam-policy-binding your-project-id \ - --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ - --role="roles/cloudsql.client" - -gcloud projects add-iam-policy-binding your-project-id \ - --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ - --role="roles/storage.objectAdmin" - -gcloud projects add-iam-policy-binding your-project-id \ - --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ - --role="roles/redis.editor" - -# Create and download key -gcloud iam service-accounts keys create chatwoot-key.json \ - --iam-account=chatwoot-sa@your-project-id.iam.gserviceaccount.com -``` - -## Monitoring and Logging - -### Cloud Monitoring - -```bash -# Enable APIs -gcloud services enable monitoring.googleapis.com -gcloud services enable logging.googleapis.com - -# Create notification channel -gcloud alpha monitoring channels create \ - --display-name="Email Alerts" \ - --type=email \ - --channel-labels=email_address=admin@yourdomain.com -``` - -### Custom Metrics - -```yaml -# monitoring.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus-config - namespace: chatwoot -data: - prometheus.yml: | - global: - scrape_interval: 15s - scrape_configs: - - job_name: 'chatwoot' - static_configs: - - targets: ['chatwoot-service:3000'] - metrics_path: /metrics -``` - -### Alerting Policies - -```bash -# Create alerting policy for high CPU -gcloud alpha monitoring policies create \ - --policy-from-file=cpu-alert-policy.yaml - -# cpu-alert-policy.yaml -cat > cpu-alert-policy.yaml << EOF -displayName: "High CPU Usage" -conditions: - - displayName: "CPU usage above 80%" - conditionThreshold: - filter: 'resource.type="gce_instance"' - comparison: COMPARISON_GREATER_THAN - thresholdValue: 0.8 - duration: 300s -combiner: OR -enabled: true -notificationChannels: - - projects/your-project-id/notificationChannels/CHANNEL_ID -EOF -``` - -## Backup and Disaster Recovery - -### Database Backups - -```bash -# Cloud SQL automatic backups are enabled by default -# Create on-demand backup -gcloud sql backups create --instance=chatwoot-db - -# List backups -gcloud sql backups list --instance=chatwoot-db - -# Restore from backup -gcloud sql backups restore BACKUP_ID --restore-instance=chatwoot-db-restore -``` - -### Application Backups - -```bash -#!/bin/bash -# backup-script.sh -DATE=$(date +%Y%m%d_%H%M%S) - -# Database backup -gcloud sql export sql chatwoot-db gs://your-backup-bucket/db/chatwoot_$DATE.sql - -# File storage backup -gsutil -m rsync -r -d gs://your-chatwoot-bucket gs://your-backup-bucket/files/ - -# Kubernetes configuration backup -kubectl get all -n chatwoot -o yaml > k8s-backup-$DATE.yaml -gsutil cp k8s-backup-$DATE.yaml gs://your-backup-bucket/k8s/ -``` - -## Security Best Practices - -### Network Security - -```bash -# Create private cluster -gcloud container clusters create chatwoot-private \ - --enable-private-nodes \ - --master-ipv4-cidr-block 172.16.0.0/28 \ - --enable-ip-alias \ - --enable-network-policy - -# Create firewall rules for private access -gcloud compute firewall-rules create allow-chatwoot-private \ - --network chatwoot-vpc \ - --allow tcp:443,tcp:80 \ - --source-ranges 10.0.0.0/8 -``` - -### Secret Management - -```bash -# Create secrets in Secret Manager -gcloud secrets create database-password --data-file=db-password.txt -gcloud secrets create redis-password --data-file=redis-password.txt - -# Grant access to service account -gcloud secrets add-iam-policy-binding database-password \ - --member="serviceAccount:chatwoot-sa@your-project-id.iam.gserviceaccount.com" \ - --role="roles/secretmanager.secretAccessor" -``` - -### Binary Authorization - -```bash -# Enable Binary Authorization -gcloud container binauthz policy import policy.yaml - -# policy.yaml -cat > policy.yaml << EOF -defaultAdmissionRule: - requireAttestationsBy: - - projects/your-project-id/attestors/prod-attestor - enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG -globalPolicyEvaluationMode: ENABLE -EOF -``` - -## Cost Optimization - -### Preemptible Instances - -```bash -# Create preemptible node pool -gcloud container node-pools create preemptible-pool \ - --cluster=chatwoot-cluster \ - --zone=us-central1-a \ - --machine-type=e2-standard-2 \ - --preemptible \ - --num-nodes=2 \ - --enable-autoscaling \ - --min-nodes=0 \ - --max-nodes=5 -``` - -### Committed Use Discounts - -```bash -# Purchase committed use discount -gcloud compute commitments create chatwoot-commitment \ - --plan=12-month \ - --region=us-central1 \ - --resources=type=VCPU,amount=4 \ - --resources=type=MEMORY,amount=16 -``` - -### Resource Optimization - -```yaml -# resource-quota.yaml -apiVersion: v1 -kind: ResourceQuota -metadata: - name: chatwoot-quota - namespace: chatwoot -spec: - hard: - requests.cpu: "4" - requests.memory: 8Gi - limits.cpu: "8" - limits.memory: 16Gi - persistentvolumeclaims: "4" -``` - -## Troubleshooting - -### Common Issues - - -Check: -- Cloud SQL Proxy configuration -- Service account permissions -- Network connectivity -- SSL requirements - - - -Verify: -- Resource quotas and limits -- Image pull permissions -- Service account configuration -- Network policies - - - -Solutions: -- Verify health check path (/api) -- Check firewall rules -- Ensure proper backend configuration -- Review application startup time - - -### Diagnostic Commands - -```bash -# Check Compute Engine instances -gcloud compute instances list - -# View Cloud Run services -gcloud run services list - -# Check GKE cluster status -gcloud container clusters describe chatwoot-cluster --zone us-central1-a - -# View logs -gcloud logging read "resource.type=gce_instance" --limit 50 -gcloud logging read "resource.type=cloud_run_revision" --limit 50 - -# Check Cloud SQL status -gcloud sql instances describe chatwoot-db -``` - -### Performance Monitoring - -```bash -# View metrics -gcloud monitoring metrics list --filter="metric.type:compute" - -# Create dashboard -gcloud monitoring dashboards create --config-from-file=dashboard.json -``` - -## Best Practices - -### Security -- Use private GKE clusters -- Enable Workload Identity -- Implement Binary Authorization -- Use Secret Manager for sensitive data -- Enable audit logging - -### Performance -- Use Cloud CDN for static assets -- Implement Cloud Memorystore for caching -- Use SSD persistent disks -- Enable HTTP/2 and gRPC -- Optimize container images - -### Reliability -- Deploy across multiple zones -- Use managed services (Cloud SQL, Memorystore) -- Implement proper health checks -- Set up monitoring and alerting -- Test disaster recovery procedures - -### Cost Management -- Use preemptible instances for non-critical workloads -- Implement resource quotas -- Purchase committed use discounts -- Monitor usage with Cloud Billing -- Use Cloud Functions for event-driven tasks - ---- - -This GCP deployment guide provides comprehensive options for hosting Chatwoot on Google Cloud Platform. Choose the deployment method that best aligns with your scalability, security, and operational requirements. \ No newline at end of file diff --git a/developer-docs/self-hosted/cloud/heroku.mdx b/developer-docs/self-hosted/cloud/heroku.mdx deleted file mode 100644 index 2d78df5ad..000000000 --- a/developer-docs/self-hosted/cloud/heroku.mdx +++ /dev/null @@ -1,505 +0,0 @@ ---- -title: Heroku Deployment -description: Deploy Chatwoot on Heroku with one-click deployment and managed services -sidebarTitle: Heroku ---- - -# Heroku Deployment Guide - -Deploy Chatwoot on Heroku using the one-click deployment option for a quick and managed hosting solution. This guide covers deployment, configuration, and maintenance on Heroku's platform. - - -Heroku has discontinued free dynos, postgres and redis. [Chatwoot will use basic/mini plans](https://blog.heroku.com/new-low-cost-plans) for all new Heroku deployments going forward. - - -## Quick Deployment - -### One-Click Deploy - -The fastest way to get Chatwoot running on Heroku is using the one-click deploy button: - - - Click here to deploy Chatwoot to Heroku with one click - - -### Deployment Steps - -1. **Click the Deploy Button**: Use the one-click deploy button above -2. **Configure App Settings**: - - Choose an app name (or let Heroku generate one) - - Select your region (US or Europe) - - Review the default configuration - -3. **Deploy the Application**: Click "Deploy app" and wait for the build to complete - -4. **Enable Worker Dynos**: - - Go to the **Resources** tab in your Heroku app dashboard - - Ensure the **worker** dynos are turned on - - This is crucial for background job processing - -5. **Configure Environment Variables**: - - Go to **Settings** tab in Heroku app dashboard - - Click **Reveal Config Vars** - - Configure additional variables as needed - -6. **Access Your Installation**: Navigate to `yourapp.herokuapp.com` - -## Configuration - -### Required Environment Variables - -Heroku automatically sets up basic configuration, but you'll need to configure additional variables: - -#### Email Configuration - -```bash -# SMTP Settings (required for notifications) -MAILER_SENDER_EMAIL=noreply@yourdomain.com -SMTP_ADDRESS=smtp.sendgrid.net -SMTP_PORT=587 -SMTP_USERNAME=apikey -SMTP_PASSWORD=your-sendgrid-api-key -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true -``` - -#### File Storage Configuration - - -Heroku has an "ephemeral" hard disk. Files uploaded to Chatwoot will not persist after application restarts. You must configure cloud storage. - - -**Amazon S3 Configuration:** - -```bash -ACTIVE_STORAGE_SERVICE=amazon -S3_BUCKET_NAME=your-chatwoot-bucket -AWS_ACCESS_KEY_ID=your-access-key -AWS_SECRET_ACCESS_KEY=your-secret-key -AWS_REGION=us-east-1 -``` - -**Google Cloud Storage Configuration:** - -```bash -ACTIVE_STORAGE_SERVICE=google -GCS_PROJECT=your-project-id -GCS_BUCKET=your-chatwoot-bucket -GOOGLE_APPLICATION_CREDENTIALS={"type":"service_account",...} -``` - -#### Frontend URL - -```bash -FRONTEND_URL=https://yourapp.herokuapp.com -FORCE_SSL=true -``` - -### Setting Environment Variables - -#### Via Heroku Dashboard - -1. Go to your app's **Settings** tab -2. Click **Reveal Config Vars** -3. Add each variable name and value -4. Click **Add** for each variable - -#### Via Heroku CLI - -```bash -# Install Heroku CLI -npm install -g heroku - -# Login to Heroku -heroku login - -# Set environment variables -heroku config:set MAILER_SENDER_EMAIL=noreply@yourdomain.com -a your-app-name -heroku config:set SMTP_ADDRESS=smtp.sendgrid.net -a your-app-name -heroku config:set SMTP_PORT=587 -a your-app-name - -# Set storage configuration -heroku config:set ACTIVE_STORAGE_SERVICE=amazon -a your-app-name -heroku config:set S3_BUCKET_NAME=your-bucket -a your-app-name -heroku config:set AWS_ACCESS_KEY_ID=your-key -a your-app-name -heroku config:set AWS_SECRET_ACCESS_KEY=your-secret -a your-app-name -``` - -## Add-ons and Services - -### Database (PostgreSQL) - -Heroku automatically provisions a PostgreSQL database: - -```bash -# Check database info -heroku pg:info -a your-app-name - -# Access database console -heroku pg:psql -a your-app-name - -# Create database backup -heroku pg:backups:capture -a your-app-name - -# Download backup -heroku pg:backups:download -a your-app-name -``` - -### Redis - -Heroku automatically provisions Redis for caching and background jobs: - -```bash -# Check Redis info -heroku redis:info -a your-app-name - -# Access Redis CLI -heroku redis:cli -a your-app-name - -# Monitor Redis -heroku redis:monitor -a your-app-name -``` - -### Email Service (SendGrid) - -Add SendGrid for email delivery: - -```bash -# Add SendGrid add-on -heroku addons:create sendgrid:starter -a your-app-name - -# Get SendGrid credentials -heroku config:get SENDGRID_USERNAME -a your-app-name -heroku config:get SENDGRID_PASSWORD -a your-app-name -``` - -## Updating Your Deployment - -### Method 1: GitHub Integration (Recommended) - -1. **Connect GitHub Repository**: - - Go to the **Deploy** tab in your Heroku app dashboard - - Choose **GitHub** as the deployment method - - Connect the `chatwoot/chatwoot` repository - -2. **Enable Automatic Deploys** (Optional): - - Enable automatic deploys from the `master` branch - - This will automatically deploy when new releases are available - -3. **Manual Deploy**: - - Go to **Manual deploy** section - - Choose `master` branch - - Click **Deploy Branch** - -### Method 2: Heroku CLI - -```bash -# Clone the Chatwoot repository -git clone https://github.com/chatwoot/chatwoot.git -cd chatwoot - -# Add Heroku remote -heroku git:remote -a your-app-name - -# Deploy latest version -git push heroku master -``` - -### Method 3: Docker Deployment - -```bash -# Login to Heroku Container Registry -heroku container:login - -# Build and push Docker image -heroku container:push web -a your-app-name - -# Release the image -heroku container:release web -a your-app-name -``` - -## Scaling and Performance - -### Dyno Management - -```bash -# Scale web dynos -heroku ps:scale web=2 -a your-app-name - -# Scale worker dynos -heroku ps:scale worker=1 -a your-app-name - -# Check dyno status -heroku ps -a your-app-name -``` - -### Performance Monitoring - -```bash -# View application metrics -heroku logs --tail -a your-app-name - -# Monitor dyno performance -heroku ps:exec -a your-app-name - -# Check memory usage -heroku logs --source app --tail -a your-app-name | grep "Memory usage" -``` - -## Monitoring and Logging - -### Application Logs - -```bash -# View recent logs -heroku logs -a your-app-name - -# Tail logs in real-time -heroku logs --tail -a your-app-name - -# Filter logs by source -heroku logs --source app -a your-app-name -heroku logs --source heroku -a your-app-name -``` - -### Add Monitoring Services - -#### Papertrail (Log Management) - -```bash -# Add Papertrail -heroku addons:create papertrail:choklad -a your-app-name - -# View logs in Papertrail -heroku addons:open papertrail -a your-app-name -``` - -#### New Relic (Application Monitoring) - -```bash -# Add New Relic -heroku addons:create newrelic:wayne -a your-app-name - -# Configure New Relic -heroku config:set NEW_RELIC_APP_NAME="Chatwoot Production" -a your-app-name - -# Open New Relic dashboard -heroku addons:open newrelic -a your-app-name -``` - -## Security Configuration - -### SSL/TLS - -Heroku automatically provides SSL certificates for custom domains: - -```bash -# Add custom domain -heroku domains:add chatwoot.yourdomain.com -a your-app-name - -# Check SSL certificate status -heroku certs -a your-app-name - -# Enable Automated Certificate Management -heroku certs:auto:enable -a your-app-name -``` - -### Environment Security - -```bash -# Rotate database credentials -heroku pg:credentials:rotate -a your-app-name - -# Rotate Redis credentials -heroku redis:credentials:rotate -a your-app-name - -# Review security settings -heroku config -a your-app-name -``` - -## Backup and Recovery - -### Database Backups - -```bash -# Schedule automatic backups -heroku pg:backups:schedule DATABASE_URL --at '02:00 America/Los_Angeles' -a your-app-name - -# Create manual backup -heroku pg:backups:capture -a your-app-name - -# List all backups -heroku pg:backups -a your-app-name - -# Restore from backup -heroku pg:backups:restore b001 DATABASE_URL -a your-app-name -``` - -### File Storage Backups - -Since Heroku has ephemeral storage, ensure your cloud storage has backup policies: - -**For S3:** -```bash -# Enable versioning on S3 bucket -aws s3api put-bucket-versioning \ - --bucket your-chatwoot-bucket \ - --versioning-configuration Status=Enabled - -# Set up lifecycle policy for old versions -aws s3api put-bucket-lifecycle-configuration \ - --bucket your-chatwoot-bucket \ - --lifecycle-configuration file://lifecycle.json -``` - -## Troubleshooting - -### Common Issues - - -**Symptoms**: App crashes on startup, H10 errors - -**Solutions**: -- Check that worker dynos are enabled in Resources tab -- Verify all required environment variables are set -- Check application logs: `heroku logs --tail -a your-app-name` -- Ensure database migrations have run: `heroku run rails db:migrate -a your-app-name` - - - -**Symptoms**: Files upload but disappear after app restart - -**Solutions**: -- Configure cloud storage (S3, GCS, etc.) -- Verify storage credentials are correct -- Check CORS settings on your storage bucket -- Test storage configuration: `heroku run rails console -a your-app-name` - - - -**Symptoms**: Users not receiving email notifications - -**Solutions**: -- Verify SMTP configuration in config vars -- Check SendGrid add-on status -- Test email configuration: `heroku run rails console -a your-app-name` -- Review email logs in SendGrid dashboard - - - -**Symptoms**: Settings page shows "unknown" build version - -**Solution**: -Enable runtime dyno metadata: -```bash -heroku labs:enable runtime-dyno-metadata -a your-app-name -``` - - -### Performance Issues - - -**Solutions**: -- Scale up web dynos: `heroku ps:scale web=2 -a your-app-name` -- Upgrade to higher performance dynos -- Monitor database performance with `heroku pg:diagnose -a your-app-name` -- Check Redis performance with `heroku redis:info -a your-app-name` - - - -**Solutions**: -- Ensure worker dynos are running: `heroku ps -a your-app-name` -- Scale worker dynos if needed: `heroku ps:scale worker=1 -a your-app-name` -- Check Sidekiq logs: `heroku logs --source app --tail -a your-app-name | grep sidekiq` - - -### Diagnostic Commands - -```bash -# Check app status -heroku ps -a your-app-name - -# View configuration -heroku config -a your-app-name - -# Check add-ons -heroku addons -a your-app-name - -# Run Rails console -heroku run rails console -a your-app-name - -# Run database migrations -heroku run rails db:migrate -a your-app-name - -# Check database status -heroku pg:info -a your-app-name - -# Check Redis status -heroku redis:info -a your-app-name -``` - -## Known Limitations - -### Platform Limitations - -1. **Ephemeral File System**: Files uploaded to local storage will be lost on dyno restart -2. **Dyno Sleep**: Free tier dynos sleep after 30 minutes of inactivity (upgrade to paid tier to avoid) -3. **Request Timeout**: Heroku has a 30-second request timeout limit -4. **Memory Limits**: Dynos have memory limits based on the plan selected - -### Workarounds - -1. **File Storage**: Use cloud storage (S3, GCS) instead of local storage -2. **Dyno Sleep**: Upgrade to paid dynos or use external monitoring to keep app awake -3. **Long Requests**: Implement background job processing for long-running tasks -4. **Memory Usage**: Monitor and optimize application memory usage - -## Cost Optimization - -### Dyno Sizing - -```bash -# Check current dyno usage -heroku ps -a your-app-name - -# Optimize dyno allocation -heroku ps:scale web=1:standard-1x worker=1:standard-1x -a your-app-name -``` - -### Add-on Optimization - -- Use appropriate add-on tiers based on usage -- Monitor add-on usage and costs in Heroku dashboard -- Consider consolidating services where possible - -## Best Practices - -### Security -- Use environment variables for all sensitive configuration -- Enable Automated Certificate Management for SSL -- Regularly rotate database and Redis credentials -- Monitor access logs and set up alerts - -### Performance -- Use appropriate dyno types for your workload -- Monitor application performance with New Relic or similar -- Implement caching strategies -- Optimize database queries - -### Reliability -- Set up automatic database backups -- Monitor application health with external services -- Implement proper error handling and logging -- Use multiple dynos for high availability - -### Cost Management -- Monitor dyno usage and scale appropriately -- Use scheduler add-on for periodic tasks instead of always-on workers -- Review and optimize add-on usage regularly -- Consider reserved capacity for predictable workloads - ---- - -This Heroku deployment guide provides a complete solution for hosting Chatwoot on Heroku's platform. The managed infrastructure and add-on ecosystem make it an excellent choice for teams who want to focus on using Chatwoot rather than managing infrastructure. - -For more information, visit the [official Chatwoot Heroku documentation](https://www.chatwoot.com/docs/self-hosted/deployment/heroku). \ No newline at end of file diff --git a/developer-docs/self-hosted/configuration/environment-variables.mdx b/developer-docs/self-hosted/configuration/environment-variables.mdx deleted file mode 100644 index 4515edd87..000000000 --- a/developer-docs/self-hosted/configuration/environment-variables.mdx +++ /dev/null @@ -1,748 +0,0 @@ ---- -title: Environment Variables -description: Complete reference for Chatwoot environment variables and configuration options -sidebarTitle: Environment Variables ---- - -# Environment Variables Reference - -Chatwoot uses environment variables for configuration. This guide provides a comprehensive reference for all available environment variables and their usage. - -## Core Application Settings - -### Basic Configuration - -```bash -# Rails Environment -RAILS_ENV=production - -# Node Environment -NODE_ENV=production - -# Frontend URL (required) -FRONTEND_URL=https://chatwoot.yourdomain.com - -# Force SSL (recommended for production) -FORCE_SSL=true - -# Secret Key Base (auto-generated during installation) -SECRET_KEY_BASE=your-secret-key-base - -# Rails Log Level -RAILS_LOG_LEVEL=info - -# Rails Max Threads -RAILS_MAX_THREADS=5 - -# Web Concurrency (Puma workers) -WEB_CONCURRENCY=2 -``` - -### Application Behavior - -```bash -# Enable/disable account signup -ENABLE_ACCOUNT_SIGNUP=false - -# Auto-assign conversations to online agents -AUTO_ASSIGN_CONVERSATIONS=true - -# Enable conversation continuity (link conversations across sessions) -CONVERSATION_CONTINUITY=true - -# Maximum file upload size (in MB) -MAXIMUM_FILE_UPLOAD_SIZE=40 - -# Enable IP-based rate limiting -ENABLE_IP_RATE_LIMIT=true - -# Rate limit per IP (requests per minute) -IP_RATE_LIMIT=100 -``` - -## Database Configuration - -### PostgreSQL - -```bash -# Database URL (primary configuration method) -DATABASE_URL=postgresql://username:password@hostname:port/database_name - -# Alternative: Individual components -POSTGRES_HOST=localhost -POSTGRES_PORT=5432 -POSTGRES_USERNAME=chatwoot -POSTGRES_PASSWORD=your-password -POSTGRES_DATABASE=chatwoot_production - -# Database pool size -DATABASE_POOL_SIZE=5 - -# Database timeout (seconds) -DATABASE_TIMEOUT=5000 - -# Enable prepared statements -DATABASE_PREPARED_STATEMENTS=true -``` - -### Database SSL Configuration - -```bash -# SSL Mode (disable, allow, prefer, require, verify-ca, verify-full) -DATABASE_SSL_MODE=require - -# SSL Certificate paths (for verify-ca and verify-full modes) -DATABASE_SSL_CERT=/path/to/client-cert.pem -DATABASE_SSL_KEY=/path/to/client-key.pem -DATABASE_SSL_ROOT_CERT=/path/to/ca-cert.pem -``` - -## Redis Configuration - -### Basic Redis Settings - -```bash -# Redis URL (primary configuration method) -REDIS_URL=redis://localhost:6379/0 - -# Alternative: Individual components -REDIS_HOST=localhost -REDIS_PORT=6379 -REDIS_DB=0 -REDIS_PASSWORD=your-redis-password - -# Redis connection pool size -REDIS_POOL_SIZE=5 - -# Redis timeout (seconds) -REDIS_TIMEOUT=1 -``` - -### Redis SSL Configuration - -```bash -# Enable SSL for Redis -REDIS_SSL=true - -# Redis SSL certificate verification -REDIS_SSL_VERIFY=true - -# Redis SSL certificate paths -REDIS_SSL_CERT=/path/to/redis-client.crt -REDIS_SSL_KEY=/path/to/redis-client.key -REDIS_SSL_CA=/path/to/redis-ca.crt -``` - -### Sidekiq Configuration - -```bash -# Sidekiq concurrency (number of worker threads) -SIDEKIQ_CONCURRENCY=10 - -# Sidekiq Redis namespace -SIDEKIQ_REDIS_NAMESPACE=chatwoot_sidekiq - -# Sidekiq log level -SIDEKIQ_LOG_LEVEL=info - -# Enable Sidekiq web UI -SIDEKIQ_WEB_UI=true - -# Sidekiq web UI username/password -SIDEKIQ_WEB_USERNAME=admin -SIDEKIQ_WEB_PASSWORD=your-password -``` - -## Email Configuration - -### SMTP Settings - -```bash -# Sender email address -MAILER_SENDER_EMAIL=noreply@yourdomain.com - -# SMTP server configuration -SMTP_ADDRESS=smtp.gmail.com -SMTP_PORT=587 -SMTP_USERNAME=your-email@gmail.com -SMTP_PASSWORD=your-app-password -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true -SMTP_OPENSSL_VERIFY_MODE=peer - -# SMTP domain (for HELO command) -SMTP_DOMAIN=yourdomain.com - -# Force TLS -SMTP_TLS=true -``` - -### Email Provider Examples - - - - ```bash - SMTP_ADDRESS=smtp.gmail.com - SMTP_PORT=587 - SMTP_USERNAME=your-email@gmail.com - SMTP_PASSWORD=your-app-password - SMTP_AUTHENTICATION=plain - SMTP_ENABLE_STARTTLS_AUTO=true - ``` - - - - ```bash - SMTP_ADDRESS=smtp.sendgrid.net - SMTP_PORT=587 - SMTP_USERNAME=apikey - SMTP_PASSWORD=your-sendgrid-api-key - SMTP_AUTHENTICATION=plain - SMTP_ENABLE_STARTTLS_AUTO=true - ``` - - - - ```bash - SMTP_ADDRESS=smtp.mailgun.org - SMTP_PORT=587 - SMTP_USERNAME=postmaster@mg.yourdomain.com - SMTP_PASSWORD=your-mailgun-password - SMTP_AUTHENTICATION=plain - SMTP_ENABLE_STARTTLS_AUTO=true - ``` - - - - ```bash - SMTP_ADDRESS=email-smtp.us-east-1.amazonaws.com - SMTP_PORT=587 - SMTP_USERNAME=your-ses-username - SMTP_PASSWORD=your-ses-password - SMTP_AUTHENTICATION=plain - SMTP_ENABLE_STARTTLS_AUTO=true - ``` - - - -### Email Templates - -```bash -# Custom email template path -CUSTOM_EMAIL_TEMPLATE_PATH=/path/to/custom/templates - -# Email template language -EMAIL_TEMPLATE_LANGUAGE=en - -# Enable email tracking -EMAIL_TRACKING_ENABLED=true - -# Email delivery method (smtp, sendmail, test) -EMAIL_DELIVERY_METHOD=smtp -``` - -## File Storage Configuration - -### Local Storage - -```bash -# Active storage service -ACTIVE_STORAGE_SERVICE=local - -# Local storage path -LOCAL_STORAGE_PATH=/home/chatwoot/chatwoot/storage -``` - -### Amazon S3 - -```bash -# Active storage service -ACTIVE_STORAGE_SERVICE=amazon - -# S3 configuration -S3_BUCKET_NAME=your-chatwoot-bucket -AWS_ACCESS_KEY_ID=your-access-key -AWS_SECRET_ACCESS_KEY=your-secret-key -AWS_REGION=us-east-1 - -# S3 endpoint (for S3-compatible services) -S3_ENDPOINT=https://s3.amazonaws.com - -# S3 force path style (for MinIO and other S3-compatible services) -S3_FORCE_PATH_STYLE=false - -# S3 public URL (for CDN) -S3_PUBLIC_URL=https://cdn.yourdomain.com -``` - -### Google Cloud Storage - -```bash -# Active storage service -ACTIVE_STORAGE_SERVICE=google - -# GCS configuration -GCS_PROJECT=your-project-id -GCS_BUCKET=your-chatwoot-bucket - -# GCS credentials (JSON key file path) -GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json - -# GCS public URL (for CDN) -GCS_PUBLIC_URL=https://cdn.yourdomain.com -``` - -### Azure Blob Storage - -```bash -# Active storage service -ACTIVE_STORAGE_SERVICE=azure - -# Azure configuration -AZURE_STORAGE_ACCOUNT_NAME=your-storage-account -AZURE_STORAGE_ACCESS_KEY=your-access-key -AZURE_STORAGE_CONTAINER=your-container-name - -# Azure public URL (for CDN) -AZURE_PUBLIC_URL=https://cdn.yourdomain.com -``` - -## Third-Party Integrations - -### Facebook - -```bash -# Facebook App ID and Secret -FB_APP_ID=your-facebook-app-id -FB_APP_SECRET=your-facebook-app-secret - -# Facebook Verify Token -FB_VERIFY_TOKEN=your-verify-token - -# Facebook API Version -FB_API_VERSION=v13.0 -``` - -### Twitter - -```bash -# Twitter API credentials -TWITTER_APP_ID=your-twitter-app-id -TWITTER_CONSUMER_KEY=your-consumer-key -TWITTER_CONSUMER_SECRET=your-consumer-secret -TWITTER_ENVIRONMENT=your-twitter-environment -``` - -### Slack - -```bash -# Slack App credentials -SLACK_CLIENT_ID=your-slack-client-id -SLACK_CLIENT_SECRET=your-slack-client-secret -``` - -### Google OAuth - -```bash -# Google OAuth credentials -GOOGLE_OAUTH_CLIENT_ID=your-google-client-id -GOOGLE_OAUTH_CLIENT_SECRET=your-google-client-secret -``` - -### Microsoft OAuth - -```bash -# Microsoft OAuth credentials -MICROSOFT_APP_ID=your-microsoft-app-id -MICROSOFT_APP_SECRET=your-microsoft-app-secret -``` - -## Push Notifications - -### FCM (Firebase Cloud Messaging) - -```bash -# FCM Server Key -FCM_SERVER_KEY=your-fcm-server-key - -# FCM Project ID -FCM_PROJECT_ID=your-firebase-project-id - -# FCM credentials file -GOOGLE_APPLICATION_CREDENTIALS=/path/to/firebase-service-account.json -``` - -### Vapid Keys (Web Push) - -```bash -# Vapid public and private keys -VAPID_PUBLIC_KEY=your-vapid-public-key -VAPID_PRIVATE_KEY=your-vapid-private-key - -# Vapid subject (email or URL) -VAPID_SUBJECT=mailto:admin@yourdomain.com -``` - -## Analytics and Monitoring - -### Application Monitoring - -```bash -# Enable application metrics -ENABLE_METRICS=true - -# Metrics endpoint path -METRICS_PATH=/metrics - -# Prometheus exporter -PROMETHEUS_EXPORTER=true -PROMETHEUS_EXPORTER_PORT=9394 - -# New Relic -NEW_RELIC_LICENSE_KEY=your-newrelic-license-key -NEW_RELIC_APP_NAME=Chatwoot - -# Sentry error tracking -SENTRY_DSN=your-sentry-dsn -``` - -### Google Analytics - -```bash -# Google Analytics tracking ID -GOOGLE_ANALYTICS_ID=UA-XXXXXXXXX-X - -# Google Tag Manager ID -GOOGLE_TAG_MANAGER_ID=GTM-XXXXXXX -``` - -### Hotjar - -```bash -# Hotjar site ID -HOTJAR_SITE_ID=your-hotjar-site-id -``` - -## Security Configuration - -### Authentication - -```bash -# JWT secret key -JWT_SECRET_KEY=your-jwt-secret-key - -# Session timeout (in seconds) -SESSION_TIMEOUT=86400 - -# Password minimum length -PASSWORD_MIN_LENGTH=8 - -# Enable two-factor authentication -ENABLE_2FA=true - -# TOTP issuer name -TOTP_ISSUER_NAME=Chatwoot -``` - -### CORS Configuration - -```bash -# Allowed origins for CORS -CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com - -# Enable CORS credentials -CORS_CREDENTIALS=true -``` - -### Content Security Policy - -```bash -# Enable CSP -ENABLE_CSP=true - -# CSP report URI -CSP_REPORT_URI=/csp-report - -# CSP directives -CSP_DEFAULT_SRC='self' -CSP_SCRIPT_SRC='self' 'unsafe-inline' 'unsafe-eval' -CSP_STYLE_SRC='self' 'unsafe-inline' -``` - -## Performance Configuration - -### Caching - -```bash -# Enable caching -ENABLE_CACHING=true - -# Cache store (memory_store, redis_cache_store) -CACHE_STORE=redis_cache_store - -# Cache namespace -CACHE_NAMESPACE=chatwoot_cache - -# Cache TTL (seconds) -CACHE_TTL=3600 -``` - -### Rate Limiting - -```bash -# Enable rate limiting -ENABLE_RATE_LIMITING=true - -# Rate limit store (memory_store, redis_store) -RATE_LIMIT_STORE=redis_store - -# API rate limit (requests per minute) -API_RATE_LIMIT=100 - -# Login rate limit (attempts per minute) -LOGIN_RATE_LIMIT=5 -``` - -### Asset Configuration - -```bash -# Asset host (for CDN) -ASSET_HOST=https://cdn.yourdomain.com - -# Enable asset compression -ENABLE_ASSET_COMPRESSION=true - -# Asset cache TTL (seconds) -ASSET_CACHE_TTL=31536000 -``` - -## Development and Testing - -### Development Settings - -```bash -# Enable development features -ENABLE_DEVELOPMENT_FEATURES=false - -# Development email delivery -DEVELOPMENT_EMAIL_DELIVERY=true - -# Development file storage -DEVELOPMENT_FILE_STORAGE=local - -# Enable SQL logging -ENABLE_SQL_LOGGING=false -``` - -### Testing Configuration - -```bash -# Test database URL -TEST_DATABASE_URL=postgresql://username:password@localhost/chatwoot_test - -# Test Redis URL -TEST_REDIS_URL=redis://localhost:6379/1 - -# Enable test coverage -ENABLE_TEST_COVERAGE=true - -# Test email delivery -TEST_EMAIL_DELIVERY=test -``` - -## Logging Configuration - -### Log Settings - -```bash -# Log level (debug, info, warn, error, fatal) -LOG_LEVEL=info - -# Log format (text, json) -LOG_FORMAT=text - -# Log to stdout -LOG_TO_STDOUT=true - -# Log file path -LOG_FILE_PATH=/var/log/chatwoot/chatwoot.log - -# Log rotation -LOG_ROTATION=daily -LOG_RETENTION=30 -``` - -### Structured Logging - -```bash -# Enable structured logging -ENABLE_STRUCTURED_LOGGING=true - -# Log correlation ID -LOG_CORRELATION_ID=true - -# Log request ID -LOG_REQUEST_ID=true - -# Log user context -LOG_USER_CONTEXT=true -``` - -## Feature Flags - -### Experimental Features - -```bash -# Enable experimental features -ENABLE_EXPERIMENTAL_FEATURES=false - -# Feature flags -FEATURE_FLAG_CONVERSATION_CONTINUITY=true -FEATURE_FLAG_AUTO_RESOLVE=false -FEATURE_FLAG_CUSTOM_ATTRIBUTES=true -FEATURE_FLAG_TEAM_MANAGEMENT=true -``` - -## Webhook Configuration - -```bash -# Webhook URL for external integrations -WEBHOOK_URL=https://your-webhook-endpoint.com/chatwoot - -# Webhook secret for verification -WEBHOOK_SECRET=your-webhook-secret - -# Webhook timeout (seconds) -WEBHOOK_TIMEOUT=30 - -# Webhook retry attempts -WEBHOOK_RETRY_ATTEMPTS=3 -``` - -## Custom Branding - -```bash -# Custom brand name -BRAND_NAME=Your Company - -# Custom logo URL -BRAND_LOGO_URL=https://yourdomain.com/logo.png - -# Custom favicon URL -BRAND_FAVICON_URL=https://yourdomain.com/favicon.ico - -# Custom primary color -BRAND_PRIMARY_COLOR=#1f93ff - -# Custom secondary color -BRAND_SECONDARY_COLOR=#f0f0f0 -``` - -## Environment-Specific Examples - -### Production Environment - -```bash -# Production .env example -RAILS_ENV=production -NODE_ENV=production -FRONTEND_URL=https://chat.yourcompany.com -FORCE_SSL=true -SECRET_KEY_BASE=your-production-secret-key - -# Database -DATABASE_URL=postgresql://chatwoot:secure-password@db.yourcompany.com:5432/chatwoot_production - -# Redis -REDIS_URL=redis://redis.yourcompany.com:6379/0 - -# Email -MAILER_SENDER_EMAIL=noreply@yourcompany.com -SMTP_ADDRESS=smtp.yourcompany.com -SMTP_PORT=587 -SMTP_USERNAME=noreply@yourcompany.com -SMTP_PASSWORD=your-smtp-password - -# Storage -ACTIVE_STORAGE_SERVICE=amazon -S3_BUCKET_NAME=yourcompany-chatwoot -AWS_ACCESS_KEY_ID=your-aws-key -AWS_SECRET_ACCESS_KEY=your-aws-secret -AWS_REGION=us-east-1 - -# Security -ENABLE_2FA=true -ENABLE_RATE_LIMITING=true -CORS_ORIGINS=https://yourcompany.com - -# Monitoring -SENTRY_DSN=your-sentry-dsn -NEW_RELIC_LICENSE_KEY=your-newrelic-key -``` - -### Development Environment - -```bash -# Development .env example -RAILS_ENV=development -NODE_ENV=development -FRONTEND_URL=http://localhost:3000 -FORCE_SSL=false - -# Database -DATABASE_URL=postgresql://chatwoot:password@localhost:5432/chatwoot_development - -# Redis -REDIS_URL=redis://localhost:6379/0 - -# Email (development) -MAILER_SENDER_EMAIL=dev@localhost -EMAIL_DELIVERY_METHOD=test - -# Storage (local) -ACTIVE_STORAGE_SERVICE=local - -# Development features -ENABLE_DEVELOPMENT_FEATURES=true -ENABLE_SQL_LOGGING=true -LOG_LEVEL=debug -``` - -## Validation and Best Practices - -### Required Variables - - -These environment variables are required for Chatwoot to function properly: -- `FRONTEND_URL` -- `SECRET_KEY_BASE` -- `DATABASE_URL` or individual database components -- `REDIS_URL` or individual Redis components - - -### Security Best Practices - - -**Security Recommendations:** -- Use strong, unique passwords for all services -- Enable SSL/TLS for all external connections -- Use environment-specific secret keys -- Enable rate limiting and CORS protection -- Regularly rotate API keys and passwords -- Use managed services for databases when possible - - -### Performance Optimization - - -**Performance Tips:** -- Adjust `SIDEKIQ_CONCURRENCY` based on your server resources -- Use Redis for caching and session storage -- Configure CDN for static assets -- Enable compression and caching -- Monitor and adjust database pool sizes - - ---- - -This comprehensive environment variables reference covers all aspects of Chatwoot configuration. Customize these settings based on your specific deployment requirements and infrastructure setup. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx b/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx deleted file mode 100644 index 91b6f31ee..000000000 --- a/developer-docs/self-hosted/deployment/chatwoot-ctl.mdx +++ /dev/null @@ -1,416 +0,0 @@ ---- -title: Chatwoot CTL (cwctl) -description: Command-line tool for managing Chatwoot installations with ease -sidebarTitle: Chatwoot CTL ---- - -# Chatwoot CTL (cwctl) - -Chatwoot CTL (`cwctl`) is a command-line tool that simplifies the management of your Chatwoot installation. It provides convenient commands for common administrative tasks like upgrades, restarts, console access, and log viewing. - -## Installation - -### Automatic Installation - -`cwctl` is automatically installed when you use the Linux installation script (v2.7.0+): - -```bash -wget https://get.chatwoot.app/linux/install.sh -chmod +x install.sh -./install.sh --install -``` - -### Manual Installation - -If you have an older installation or need to install `cwctl` separately: - -```bash -# Download and install cwctl -wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl -chmod +x /usr/local/bin/cwctl - -# Verify installation -cwctl --help -``` - - -The manual installation requires root access to install `cwctl` to `/usr/local/bin`. - - -## Available Commands - -### Help and Version - -```bash -# Display help information -cwctl --help -cwctl -h - -# Show version information -cwctl --version -cwctl -v -``` - -### Installation Management - -```bash -# Install Chatwoot (same as running install.sh --install) -cwctl --install - -# Upgrade to the latest version -cwctl --upgrade - -# Restart Chatwoot services -cwctl --restart -cwctl -r -``` - -### Console and Debugging - -```bash -# Access Rails console -cwctl --console -cwctl -c - -# View web server logs -cwctl --logs web -cwctl -l web - -# View worker logs -cwctl --logs worker -cwctl -l worker - -# View all logs -cwctl --logs -cwctl -l -``` - -### Service Management - -```bash -# Check service status -cwctl --status -cwctl -s - -# Stop Chatwoot services -cwctl --stop - -# Start Chatwoot services -cwctl --start -``` - -## Detailed Command Usage - -### Upgrading Chatwoot - -The upgrade command handles the complete upgrade process: - -```bash -cwctl --upgrade -``` - -This command performs the following steps: -1. Switches to the chatwoot user -2. Navigates to the Chatwoot directory -3. Pulls the latest code from the master branch -4. Updates Ruby version if needed -5. Installs/updates dependencies (bundle, pnpm) -6. Precompiles assets -7. Runs database migrations -8. Updates systemd service files -9. Restarts services - - -Always backup your database before upgrading: -```bash -# Create a backup before upgrading -sudo -u postgres pg_dump chatwoot_production > chatwoot_backup_$(date +%Y%m%d).sql -``` - - -### Console Access - -Access the Rails console for debugging and administration: - -```bash -cwctl --console -``` - -This opens an interactive Ruby console where you can: - -```ruby -# Check application version -Rails.application.config.version - -# List all accounts -Account.all - -# Find a specific user -User.find_by(email: 'admin@example.com') - -# Check system statistics -Account.count -User.count -Conversation.count - -# Clear cache -Rails.cache.clear -``` - -### Log Management - -View real-time logs for troubleshooting: - -```bash -# Web server logs (Rails application) -cwctl -l web - -# Worker logs (Sidekiq background jobs) -cwctl -l worker - -# All logs (both web and worker) -cwctl -l -``` - -### Service Management - -Control Chatwoot services: - -```bash -# Check if services are running -cwctl --status - -# Restart all services (web + worker) -cwctl --restart - -# Stop all services -cwctl --stop - -# Start all services -cwctl --start -``` - -## Configuration - -### Environment Variables - -`cwctl` respects the same environment variables as your Chatwoot installation. Key variables include: - -```bash -# Chatwoot installation directory -CHATWOOT_DIR="/home/chatwoot/chatwoot" - -# Rails environment -RAILS_ENV="production" - -# Database configuration -DATABASE_URL="postgresql://..." - -# Redis configuration -REDIS_URL="redis://..." -``` - -### Custom Installation Paths - -If Chatwoot is installed in a non-standard location, you can specify the path: - -```bash -# Set custom Chatwoot directory -export CHATWOOT_DIR="/opt/chatwoot" -cwctl --restart -``` - -## Troubleshooting - -### Common Issues - - -If `cwctl` is not found, ensure it's installed and in your PATH: - -```bash -# Check if cwctl exists -which cwctl - -# If not found, install it -wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl -chmod +x /usr/local/bin/cwctl - -# Add to PATH if needed -echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc -source ~/.bashrc -``` - - - -Ensure you have the necessary permissions: - -```bash -# Run with sudo if needed -sudo cwctl --restart - -# Or ensure your user is in the chatwoot group -sudo usermod -a -G chatwoot $USER -``` - - - -If services fail to restart, check the logs: - -```bash -# Check systemd status -sudo systemctl status chatwoot.target -sudo systemctl status chatwoot-web.1.service -sudo systemctl status chatwoot-worker.1.service - -# View detailed logs -sudo journalctl -u chatwoot-web.1.service -f -sudo journalctl -u chatwoot-worker.1.service -f -``` - - -### Debug Mode - -For verbose output during operations: - -```bash -# Enable debug mode -export CWCTL_DEBUG=1 -cwctl --upgrade -``` - -### Manual Operations - -If `cwctl` fails, you can perform operations manually: - -```bash -# Manual upgrade process -sudo -i -u chatwoot -cd chatwoot -git checkout master && git pull -rvm use 3.3.3 --default -bundle install -pnpm install -RAILS_ENV=production bundle exec rake assets:precompile -RAILS_ENV=production bundle exec rake db:migrate -exit - -# Restart services manually -sudo systemctl restart chatwoot.target -``` - -## Best Practices - -### Regular Maintenance - -```bash -# Weekly upgrade check -cwctl --upgrade - -# Daily log monitoring -cwctl -l | grep ERROR - -# Monthly service restart -cwctl --restart -``` - -### Backup Before Operations - -```bash -# Create backup script -#!/bin/bash -DATE=$(date +%Y%m%d_%H%M%S) -sudo -u postgres pg_dump chatwoot_production > "/backup/chatwoot_$DATE.sql" -cwctl --upgrade -``` - -### Monitoring - -```bash -# Check service health -cwctl --status - -# Monitor logs for errors -cwctl -l | grep -E "(ERROR|FATAL|Exception)" - -# Check disk space before upgrades -df -h /home/chatwoot -``` - -## Integration with System Tools - -### Systemd Integration - -`cwctl` works seamlessly with systemd: - -```bash -# These commands are equivalent -cwctl --restart -sudo systemctl restart chatwoot.target - -cwctl --status -sudo systemctl status chatwoot.target -``` - -### Cron Jobs - -Automate maintenance tasks: - -```bash -# Add to crontab -# Weekly upgrade (Sundays at 2 AM) -0 2 * * 0 /usr/local/bin/cwctl --upgrade - -# Daily restart (to clear memory leaks) -0 3 * * * /usr/local/bin/cwctl --restart -``` - -### Monitoring Scripts - -```bash -#!/bin/bash -# Health check script -if ! cwctl --status > /dev/null 2>&1; then - echo "Chatwoot services are down, attempting restart..." - cwctl --restart - # Send alert notification -fi -``` - -## Advanced Usage - -### Custom Commands - -You can extend `cwctl` functionality by creating wrapper scripts: - -```bash -#!/bin/bash -# custom-cwctl.sh - Extended cwctl with additional features - -case "$1" in - --backup) - echo "Creating backup..." - sudo -u postgres pg_dump chatwoot_production > "backup_$(date +%Y%m%d).sql" - ;; - --health-check) - echo "Performing health check..." - curl -f http://localhost:3000/api || echo "Health check failed" - ;; - *) - cwctl "$@" - ;; -esac -``` - -### Environment-Specific Operations - -```bash -# Development environment -RAILS_ENV=development cwctl --console - -# Staging environment -RAILS_ENV=staging cwctl --restart -``` - ---- - -`cwctl` simplifies Chatwoot administration by providing a unified interface for common tasks. Use it regularly to maintain your installation and troubleshoot issues efficiently. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/docker.mdx b/developer-docs/self-hosted/deployment/docker.mdx deleted file mode 100644 index a083eddf5..000000000 --- a/developer-docs/self-hosted/deployment/docker.mdx +++ /dev/null @@ -1,572 +0,0 @@ ---- -title: Docker Deployment Guide -description: Complete guide to deploy Chatwoot using Docker containers for production environments. -sidebarTitle: Docker ---- - -Docker provides a consistent, portable way to deploy Chatwoot across different environments. This guide covers production deployment using Docker Compose with best practices for security, performance, and maintenance. - -## Prerequisites - -Before starting, ensure you have: - -- Docker 20.10+ installed -- Docker Compose 2.0+ installed -- At least 4GB RAM and 2 CPU cores -- Domain name with DNS configured (recommended) -- Basic understanding of Docker concepts - -### Version Check - -Verify your Docker installation: - -```bash -$ docker --version -Docker version 25.0.4, build 1a576c5 - -$ docker compose version -Docker Compose version v2.24.7 -``` - - -Container names use dashes instead of underscores by default with newer Docker Compose versions. If using an older version, replace `-` with `_` and use `docker-compose` instead of `docker compose`. - - -## Quick Start - -### 1. Install Docker - -**Ubuntu/Debian:** -```bash -# Update package index -apt-get update && apt-get upgrade -y - -# Install Docker -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh - -# Install Docker Compose plugin -apt install docker-compose-plugin - -# Add user to docker group (optional) -sudo usermod -aG docker $USER -``` - -**CentOS/RHEL:** -```bash -# Install Docker -sudo yum install -y yum-utils -sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo -sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin - -# Start Docker service -sudo systemctl start docker -sudo systemctl enable docker -``` - -### 2. Download Configuration Files - -```bash -# Create project directory -mkdir chatwoot && cd chatwoot - -# Download environment template -wget -O .env https://raw.githubusercontent.com/chatwoot/chatwoot/develop/.env.example - -# Download Docker Compose configuration -wget -O docker-compose.yaml https://raw.githubusercontent.com/chatwoot/chatwoot/develop/docker-compose.production.yaml -``` - -### 3. Configure Environment - -Edit the `.env` file with your settings: - -```bash -nano .env -``` - -**Essential configurations:** - -```env -# Database Configuration -POSTGRES_PASSWORD=your_secure_postgres_password -REDIS_PASSWORD=your_secure_redis_password - -# Application Configuration -SECRET_KEY_BASE=your_secret_key_base_64_chars_long -FRONTEND_URL=https://your-domain.com - -# Email Configuration (required for notifications) -MAILER_SENDER_EMAIL=noreply@your-domain.com -SMTP_ADDRESS=smtp.your-provider.com -SMTP_PORT=587 -SMTP_USERNAME=your-smtp-username -SMTP_PASSWORD=your-smtp-password -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true - -# File Storage (optional - defaults to local) -ACTIVE_STORAGE_SERVICE=local -# For S3: ACTIVE_STORAGE_SERVICE=amazon -# AWS_ACCESS_KEY_ID=your_access_key -# AWS_SECRET_ACCESS_KEY=your_secret_key -# AWS_REGION=us-east-1 -# AWS_BUCKET=your-bucket-name -``` - -### 4. Update Docker Compose - -Edit `docker-compose.yaml` to match your `.env` passwords: - -```yaml -services: - postgres: - environment: - - POSTGRES_PASSWORD=your_secure_postgres_password # Match .env - - redis: - command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"] -``` - -### 5. Initialize Database - -```bash -# Prepare the database -docker compose run --rm rails bundle exec rails db:chatwoot_prepare -``` - -### 6. Start Services - -```bash -# Start all services in background -docker compose up -d - -# Check service status -docker compose ps -``` - -### 7. Verify Installation - -```bash -# Check if Chatwoot is responding -curl -I localhost:3000/api - -# Should return: HTTP/1.1 200 OK -``` - -## Production Configuration - -### Docker Compose Setup - -Here's a complete production-ready `docker-compose.yaml`: - -```yaml -version: '3.8' - -services: - base: &base - image: chatwoot/chatwoot:latest - env_file: .env - volumes: - - ./data/storage:/app/storage - depends_on: - - postgres - - redis - - rails: - <<: *base - container_name: chatwoot-rails - command: ["sh", "-c", "bundle exec rails s -b 0.0.0.0 -p 3000"] - ports: - - "127.0.0.1:3000:3000" - environment: - - NODE_ENV=production - - RAILS_ENV=production - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/api"] - interval: 30s - timeout: 10s - retries: 3 - - sidekiq: - <<: *base - container_name: chatwoot-sidekiq - command: ["sh", "-c", "bundle exec sidekiq -C config/sidekiq.yml"] - restart: unless-stopped - healthcheck: - test: ["CMD", "pgrep", "-f", "sidekiq"] - interval: 30s - timeout: 10s - retries: 3 - - postgres: - image: postgres:14-alpine - container_name: chatwoot-postgres - restart: unless-stopped - ports: - - "127.0.0.1:5432:5432" - volumes: - - ./data/postgres:/var/lib/postgresql/data - environment: - - POSTGRES_DB=chatwoot - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=your_secure_postgres_password - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 30s - timeout: 10s - retries: 3 - - redis: - image: redis:7-alpine - container_name: chatwoot-redis - restart: unless-stopped - command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"] - ports: - - "127.0.0.1:6379:6379" - volumes: - - ./data/redis:/data - healthcheck: - test: ["CMD", "redis-cli", "--raw", "incr", "ping"] - interval: 30s - timeout: 10s - retries: 3 - -volumes: - postgres_data: - redis_data: - storage_data: -``` - -### Nginx Reverse Proxy - -Create `/etc/nginx/sites-available/chatwoot.conf`: - -```nginx -server { - server_name your-domain.com; - - # Point upstream to Chatwoot App Server - set $upstream 127.0.0.1:3000; - - # Nginx strips out underscore in headers by default - # Chatwoot relies on underscore in headers for API - underscores_in_headers on; - - # Increase client max body size for file uploads - client_max_body_size 50M; - - location /.well-known { - alias /var/www/ssl-proof/chatwoot/.well-known; - } - - location / { - proxy_pass_header Authorization; - proxy_pass http://$upstream; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Ssl on; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - proxy_http_version 1.1; - proxy_buffering off; - proxy_read_timeout 36000s; - proxy_redirect off; - } - - listen 80; -} -``` - -Enable the site and configure SSL: - -```bash -# Enable site -sudo ln -s /etc/nginx/sites-available/chatwoot.conf /etc/nginx/sites-enabled/ -sudo nginx -t -sudo systemctl reload nginx - -# Install Certbot and get SSL certificate -sudo apt install certbot python3-certbot-nginx -sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known -sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx -``` - -## Advanced Configuration - -### Environment Variables - -Key environment variables for production: - -```env -# Application -RAILS_ENV=production -NODE_ENV=production -SECRET_KEY_BASE=generate_64_character_secret -FRONTEND_URL=https://your-domain.com - -# Database -DATABASE_URL=postgresql://postgres:password@postgres:5432/chatwoot -REDIS_URL=redis://redis:6379/0 -REDIS_PASSWORD=your_redis_password - -# Email -MAILER_SENDER_EMAIL=noreply@your-domain.com -SMTP_ADDRESS=smtp.your-provider.com -SMTP_PORT=587 -SMTP_USERNAME=your_username -SMTP_PASSWORD=your_password -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true - -# File Storage -ACTIVE_STORAGE_SERVICE=amazon -AWS_ACCESS_KEY_ID=your_access_key -AWS_SECRET_ACCESS_KEY=your_secret_key -AWS_REGION=us-east-1 -AWS_BUCKET=your-bucket-name - -# Security -FORCE_SSL=true -RAILS_LOG_TO_STDOUT=true - -# Performance -RAILS_MAX_THREADS=5 -WEB_CONCURRENCY=2 -``` - -### Resource Limits - -Add resource limits to your `docker-compose.yaml`: - -```yaml -services: - rails: - deploy: - resources: - limits: - cpus: '2.0' - memory: 2G - reservations: - cpus: '1.0' - memory: 1G - - sidekiq: - deploy: - resources: - limits: - cpus: '1.0' - memory: 1G - reservations: - cpus: '0.5' - memory: 512M - - postgres: - deploy: - resources: - limits: - cpus: '1.0' - memory: 1G - reservations: - cpus: '0.5' - memory: 512M - - redis: - deploy: - resources: - limits: - cpus: '0.5' - memory: 512M - reservations: - cpus: '0.25' - memory: 256M -``` - -### Logging Configuration - -Configure centralized logging: - -```yaml -services: - rails: - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - - sidekiq: - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" -``` - -## Maintenance Operations - -### Upgrading Chatwoot - -```bash -# Pull latest images -docker compose pull - -# Stop services -docker compose down - -# Start with new images -docker compose up -d - -# Run database migrations -docker compose run --rm rails bundle exec rails db:chatwoot_prepare -``` - -### Backup and Restore - -**Database Backup:** -```bash -# Create backup -docker compose exec postgres pg_dump -U postgres chatwoot > backup_$(date +%Y%m%d_%H%M%S).sql - -# Restore backup -docker compose exec -T postgres psql -U postgres chatwoot < backup_file.sql -``` - -**File Storage Backup:** -```bash -# Backup storage directory -tar -czf storage_backup_$(date +%Y%m%d_%H%M%S).tar.gz ./data/storage/ -``` - -### Monitoring and Logs - -**View logs:** -```bash -# All services -docker compose logs -f - -# Specific service -docker compose logs -f rails -docker compose logs -f sidekiq - -# Last 100 lines -docker compose logs --tail=100 rails -``` - -**Monitor resources:** -```bash -# Container stats -docker stats - -# Service health -docker compose ps -``` - -### Rails Console Access - -```bash -# Access Rails console -docker compose exec rails bundle exec rails console - -# Run one-off commands -docker compose run --rm rails bundle exec rails runner "puts User.count" -``` - -## Troubleshooting - -### Common Issues - -**1. Permission Issues:** -```bash -# Fix file permissions -sudo chown -R 1000:1000 ./data/ -``` - -**2. Database Connection Issues:** -```bash -# Check database connectivity -docker compose exec rails bundle exec rails db:version -``` - -**3. Memory Issues:** -```bash -# Check memory usage -docker stats --no-stream -``` - -**4. SSL Certificate Issues:** -```bash -# Renew certificates -sudo certbot renew --dry-run -``` - -### Performance Optimization - -**1. Database Optimization:** -```sql --- Connect to database -docker compose exec postgres psql -U postgres chatwoot - --- Check slow queries -SELECT query, mean_time, calls -FROM pg_stat_statements -ORDER BY mean_time DESC -LIMIT 10; -``` - -**2. Redis Optimization:** -```bash -# Check Redis memory usage -docker compose exec redis redis-cli info memory -``` - -### Security Hardening - -**1. Network Security:** -```yaml -# Add to docker-compose.yaml -networks: - chatwoot: - driver: bridge - internal: true - -services: - rails: - networks: - - chatwoot - - default # Only rails needs external access -``` - -**2. Secrets Management:** -```bash -# Use Docker secrets for sensitive data -echo "your_secret_password" | docker secret create postgres_password - -``` - -## Community Edition vs Enterprise - -This guide covers Chatwoot Community Edition (CE). For Enterprise features: - -**CE Docker Tags:** -- `chatwoot/chatwoot:latest-ce` (latest CE) -- `chatwoot/chatwoot:v2.3.2-ce` (specific version CE) - -**Enterprise Features:** -- Advanced reporting and analytics -- SAML SSO integration -- Advanced automation rules -- Priority support - ---- - - -Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and file storage. - - - -For high-availability deployments, consider using Docker Swarm or Kubernetes instead of Docker Compose. - \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/kubernetes.mdx b/developer-docs/self-hosted/deployment/kubernetes.mdx deleted file mode 100644 index 30c45b96b..000000000 --- a/developer-docs/self-hosted/deployment/kubernetes.mdx +++ /dev/null @@ -1,537 +0,0 @@ ---- -title: Kubernetes Deployment -description: Deploy Chatwoot on Kubernetes using Helm charts for scalable, production-ready installations -sidebarTitle: Kubernetes ---- - -# Kubernetes Deployment Guide - -Deploy Chatwoot on Kubernetes using our official Helm charts for a scalable, production-ready installation. - -## Prerequisites - -Before deploying Chatwoot on Kubernetes, ensure you have: - -- **Kubernetes cluster** (v1.19+) with sufficient resources -- **Helm 3.x** installed and configured -- **kubectl** configured to access your cluster -- **Ingress controller** (nginx, traefik, etc.) for external access -- **Cert-manager** (optional, for automatic SSL certificates) - -### Minimum Resource Requirements - -- **CPU**: 2 cores minimum (4+ cores recommended) -- **Memory**: 4GB RAM minimum (8GB+ recommended) -- **Storage**: 20GB persistent storage for PostgreSQL -- **Nodes**: 3+ nodes for high availability - -## Quick Start - -### 1. Add Chatwoot Helm Repository - -```bash -helm repo add chatwoot https://chatwoot.github.io/charts -helm repo update -``` - -### 2. Create Namespace - -```bash -kubectl create namespace chatwoot -``` - -### 3. Install with Default Values - -```bash -helm install chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --set ingress.enabled=true \ - --set ingress.hosts[0].host=chatwoot.yourdomain.com \ - --set ingress.hosts[0].paths[0].path=/ \ - --set ingress.hosts[0].paths[0].pathType=Prefix -``` - -## Production Configuration - -### Custom Values File - -Create a `values.yaml` file for production deployment: - -```yaml -# values.yaml -replicaCount: 3 - -image: - repository: chatwoot/chatwoot - tag: "latest" - pullPolicy: IfNotPresent - -env: - RAILS_ENV: production - NODE_ENV: production - FRONTEND_URL: "https://chatwoot.yourdomain.com" - FORCE_SSL: "true" - -# Database Configuration -postgresql: - enabled: true - auth: - postgresPassword: "your-secure-password" - database: "chatwoot_production" - primary: - persistence: - enabled: true - size: 50Gi - storageClass: "fast-ssd" - metrics: - enabled: true - -# Redis Configuration -redis: - enabled: true - auth: - enabled: true - password: "your-redis-password" - master: - persistence: - enabled: true - size: 10Gi - metrics: - enabled: true - -# Ingress Configuration -ingress: - enabled: true - className: "nginx" - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - nginx.ingress.kubernetes.io/proxy-body-size: "50m" - nginx.ingress.kubernetes.io/proxy-read-timeout: "300" - nginx.ingress.kubernetes.io/proxy-send-timeout: "300" - hosts: - - host: chatwoot.yourdomain.com - paths: - - path: / - pathType: Prefix - tls: - - secretName: chatwoot-tls - hosts: - - chatwoot.yourdomain.com - -# Resource Limits -resources: - limits: - cpu: 2000m - memory: 4Gi - requests: - cpu: 1000m - memory: 2Gi - -# Horizontal Pod Autoscaler -autoscaling: - enabled: true - minReplicas: 3 - maxReplicas: 10 - targetCPUUtilizationPercentage: 70 - targetMemoryUtilizationPercentage: 80 - -# Storage Configuration -persistence: - enabled: true - storageClass: "fast-ssd" - size: 20Gi - -# Service Configuration -service: - type: ClusterIP - port: 3000 - -# Worker Configuration -worker: - enabled: true - replicaCount: 2 - resources: - limits: - cpu: 1000m - memory: 2Gi - requests: - cpu: 500m - memory: 1Gi - -# Monitoring -serviceMonitor: - enabled: true - namespace: monitoring -``` - -### Deploy with Custom Configuration - -```bash -helm install chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --values values.yaml -``` - -## External Dependencies - -### Using External PostgreSQL - -```yaml -postgresql: - enabled: false - -env: - DATABASE_URL: "postgresql://username:password@postgres-host:5432/chatwoot_production" -``` - -### Using External Redis - -```yaml -redis: - enabled: false - -env: - REDIS_URL: "redis://redis-host:6379/0" -``` - -### Using Cloud Storage - -```yaml -env: - # AWS S3 - ACTIVE_STORAGE_SERVICE: "amazon" - S3_BUCKET_NAME: "your-chatwoot-bucket" - AWS_ACCESS_KEY_ID: "your-access-key" - AWS_SECRET_ACCESS_KEY: "your-secret-key" - AWS_REGION: "us-east-1" - - # Google Cloud Storage - # ACTIVE_STORAGE_SERVICE: "google" - # GCS_PROJECT: "your-project" - # GCS_BUCKET: "your-bucket" -``` - -## High Availability Setup - -### Multi-Zone Deployment - -```yaml -# Spread pods across availability zones -affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app.kubernetes.io/name - operator: In - values: - - chatwoot - topologyKey: topology.kubernetes.io/zone - -# Node selection -nodeSelector: - node-type: "application" - -# Tolerations for dedicated nodes -tolerations: -- key: "dedicated" - operator: "Equal" - value: "chatwoot" - effect: "NoSchedule" -``` - -### Database High Availability - -```yaml -postgresql: - enabled: true - architecture: replication - auth: - replicationPassword: "replication-password" - primary: - persistence: - enabled: true - size: 100Gi - readReplicas: - replicaCount: 2 - persistence: - enabled: true - size: 100Gi -``` - -## Security Configuration - -### Network Policies - -```yaml -# network-policy.yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: chatwoot-network-policy - namespace: chatwoot -spec: - podSelector: - matchLabels: - app.kubernetes.io/name: chatwoot - policyTypes: - - Ingress - - Egress - ingress: - - from: - - namespaceSelector: - matchLabels: - name: ingress-nginx - ports: - - protocol: TCP - port: 3000 - egress: - - to: - - podSelector: - matchLabels: - app.kubernetes.io/name: postgresql - ports: - - protocol: TCP - port: 5432 - - to: - - podSelector: - matchLabels: - app.kubernetes.io/name: redis - ports: - - protocol: TCP - port: 6379 -``` - -### Pod Security Standards - -```yaml -securityContext: - runAsNonRoot: true - runAsUser: 1001 - fsGroup: 1001 - seccompProfile: - type: RuntimeDefault - -containerSecurityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1001 - capabilities: - drop: - - ALL -``` - -## Monitoring and Observability - -### Prometheus Monitoring - -```yaml -serviceMonitor: - enabled: true - labels: - app: chatwoot - interval: 30s - scrapeTimeout: 10s - path: /metrics - -# Custom metrics -env: - PROMETHEUS_EXPORTER: "true" - PROMETHEUS_EXPORTER_PORT: "9394" -``` - -### Logging Configuration - -```yaml -# Structured logging -env: - LOG_LEVEL: "info" - LOG_FORMAT: "json" - -# Log aggregation with Fluentd/Fluent Bit -annotations: - fluentbit.io/parser: "json" - fluentbit.io/exclude: "false" -``` - -### Health Checks - -```yaml -livenessProbe: - httpGet: - path: /api - port: 3000 - initialDelaySeconds: 60 - periodSeconds: 30 - timeoutSeconds: 10 - failureThreshold: 3 - -readinessProbe: - httpGet: - path: /api - port: 3000 - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 -``` - -## Backup and Disaster Recovery - -### Database Backup - -```yaml -# CronJob for database backup -apiVersion: batch/v1 -kind: CronJob -metadata: - name: chatwoot-db-backup - namespace: chatwoot -spec: - schedule: "0 2 * * *" # Daily at 2 AM - jobTemplate: - spec: - template: - spec: - containers: - - name: postgres-backup - image: postgres:15 - command: - - /bin/bash - - -c - - | - pg_dump $DATABASE_URL | gzip > /backup/chatwoot-$(date +%Y%m%d-%H%M%S).sql.gz - # Upload to S3 or other storage - env: - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: chatwoot-secrets - key: database-url - volumeMounts: - - name: backup-storage - mountPath: /backup - volumes: - - name: backup-storage - persistentVolumeClaim: - claimName: backup-pvc - restartPolicy: OnFailure -``` - -## Upgrading Chatwoot - -### Rolling Update - -```bash -# Update to latest version -helm upgrade chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --values values.yaml - -# Update to specific version -helm upgrade chatwoot chatwoot/chatwoot \ - --namespace chatwoot \ - --values values.yaml \ - --set image.tag="v2.15.0" -``` - -### Database Migration - -```bash -# Run migrations after upgrade -kubectl exec -it deployment/chatwoot -n chatwoot -- \ - bundle exec rails db:migrate RAILS_ENV=production -``` - -## Troubleshooting - -### Common Issues - - -**Pod Startup Issues**: Check resource limits and node capacity -```bash -kubectl describe pod -n chatwoot -kubectl top nodes -``` - - - -**Database Connection Issues**: Verify database credentials and network policies -```bash -kubectl logs deployment/chatwoot -n chatwoot -kubectl exec -it deployment/chatwoot -n chatwoot -- nc -zv postgres-host 5432 -``` - - -### Debug Commands - -```bash -# Check pod status -kubectl get pods -n chatwoot - -# View logs -kubectl logs -f deployment/chatwoot -n chatwoot - -# Access pod shell -kubectl exec -it deployment/chatwoot -n chatwoot -- /bin/bash - -# Check service endpoints -kubectl get endpoints -n chatwoot - -# Describe ingress -kubectl describe ingress chatwoot -n chatwoot -``` - -### Performance Tuning - -```yaml -# Optimize for high traffic -env: - RAILS_MAX_THREADS: "20" - WEB_CONCURRENCY: "4" - SIDEKIQ_CONCURRENCY: "25" - -resources: - limits: - cpu: 4000m - memory: 8Gi - requests: - cpu: 2000m - memory: 4Gi - -# Database connection pooling -env: - DATABASE_POOL_SIZE: "25" -``` - -## Best Practices - -### Resource Management -- Set appropriate resource requests and limits -- Use horizontal pod autoscaling for dynamic scaling -- Monitor resource usage and adjust as needed - -### Security -- Use network policies to restrict traffic -- Enable pod security standards -- Regularly update container images -- Use secrets for sensitive configuration - -### Monitoring -- Enable Prometheus metrics collection -- Set up alerting for critical metrics -- Monitor application and infrastructure health -- Use distributed tracing for complex issues - -### Backup -- Implement automated database backups -- Test backup restoration procedures -- Store backups in multiple locations -- Document recovery procedures - ---- - -This Kubernetes deployment guide provides a solid foundation for running Chatwoot in production. Customize the configuration based on your specific requirements and infrastructure setup. \ No newline at end of file diff --git a/developer-docs/self-hosted/deployment/linux-vm.mdx b/developer-docs/self-hosted/deployment/linux-vm.mdx deleted file mode 100644 index d3f30b297..000000000 --- a/developer-docs/self-hosted/deployment/linux-vm.mdx +++ /dev/null @@ -1,675 +0,0 @@ ---- -title: Linux VM Deployment Guide -description: Complete guide to deploy Chatwoot on Linux virtual machines using the automated installation script. -sidebarTitle: Linux VM ---- - -This guide covers deploying Chatwoot on Linux virtual machines using our automated installation script. This method is ideal for traditional server environments and provides full control over the installation process. - -## Prerequisites - -Before starting, ensure you have: - -- Ubuntu 20.04 LTS or later (recommended) -- At least 4GB RAM and 2 CPU cores -- 50GB+ available disk space -- Root or sudo access -- Domain name with DNS configured (optional but recommended) -- SMTP server for email notifications - -### Supported Operating Systems - -| OS | Version | Status | -|---|---|---| -| **Ubuntu** | 20.04 LTS, 22.04 LTS, 24.04 LTS | ✅ Recommended | -| **Debian** | 10, 11, 12 | ✅ Supported | -| **CentOS** | 8, 9 | ✅ Supported | -| **RHEL** | 8, 9 | ✅ Supported | -| **Amazon Linux** | 2 | ✅ Supported | - -## Quick Installation - -### 1. Download Installation Script - -```bash -# Download the installation script -wget https://get.chatwoot.app/linux/install.sh - -# Make it executable -chmod +x install.sh -``` - -### 2. Run Installation - -```bash -# Run the installation script -./install.sh --install -``` - -The script will: -- Install all required dependencies -- Set up PostgreSQL and Redis -- Install Ruby, Node.js, and other runtime dependencies -- Clone and configure Chatwoot -- Set up systemd services -- Configure Nginx (if domain is provided) -- Set up SSL with Let's Encrypt (if domain is provided) - -### 3. Domain Configuration (Optional) - -If you have a domain name: - -1. **Create DNS A Record**: Point your domain to your server's IP address -2. **During installation**: Enter `yes` when prompted about domain setup -3. **Enter your domain**: The script will configure Nginx and SSL automatically - -### 4. Access Your Installation - -- **With domain**: `https://your-domain.com` -- **Without domain**: `http://your-server-ip:3000` - -**Default login credentials:** -``` -URL: https://your-domain.com -Email: john@acme.inc -Password: Password1! -``` - -## Manual Installation - -For more control over the installation process, you can install manually: - -### 1. System Preparation - -```bash -# Update system packages -sudo apt update && sudo apt upgrade -y - -# Install essential packages -sudo apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates lsb-release -``` - -### 2. Install Dependencies - -**PostgreSQL:** -```bash -# Install PostgreSQL -sudo apt install -y postgresql postgresql-contrib - -# Start and enable PostgreSQL -sudo systemctl start postgresql -sudo systemctl enable postgresql - -# Create database and user -sudo -u postgres psql << EOF -CREATE DATABASE chatwoot; -CREATE USER chatwoot WITH ENCRYPTED PASSWORD 'your_secure_password'; -GRANT ALL PRIVILEGES ON DATABASE chatwoot TO chatwoot; -ALTER USER chatwoot CREATEDB; -\q -EOF -``` - -**Redis:** -```bash -# Install Redis -sudo apt install -y redis-server - -# Configure Redis -sudo sed -i 's/^# requirepass foobared/requirepass your_redis_password/' /etc/redis/redis.conf - -# Start and enable Redis -sudo systemctl start redis-server -sudo systemctl enable redis-server -``` - -**Ruby (using RVM):** -```bash -# Install RVM -curl -sSL https://get.rvm.io | bash -s stable -source ~/.rvm/scripts/rvm - -# Install Ruby -rvm install 3.3.3 -rvm use 3.3.3 --default -``` - -**Node.js:** -```bash -# Install Node.js 20.x -curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - -sudo apt install -y nodejs - -# Install pnpm -npm install -g pnpm -``` - -**Additional Dependencies:** -```bash -# Install build tools and libraries -sudo apt install -y git build-essential libssl-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libyaml-dev libsqlite3-dev libgdbm-compat-dev libncurses5-dev libreadline6-dev - -# Install ImageMagick for image processing -sudo apt install -y imagemagick libmagickwand-dev - -# Install FFmpeg for media processing -sudo apt install -y ffmpeg -``` - -### 3. Install Chatwoot - -```bash -# Create chatwoot user -sudo adduser --disabled-login --gecos "" chatwoot - -# Switch to chatwoot user -sudo -i -u chatwoot - -# Clone Chatwoot repository -git clone https://github.com/chatwoot/chatwoot.git -cd chatwoot - -# Checkout latest stable version -git checkout master - -# Install Ruby dependencies -bundle install - -# Install Node.js dependencies -pnpm install - -# Copy environment file -cp .env.example .env -``` - -### 4. Configure Environment - -Edit the `.env` file: - -```bash -nano .env -``` - -**Essential configurations:** - -```env -# Database Configuration -DATABASE_URL=postgresql://chatwoot:your_secure_password@localhost:5432/chatwoot - -# Redis Configuration -REDIS_URL=redis://localhost:6379/0 -REDIS_PASSWORD=your_redis_password - -# Application Configuration -SECRET_KEY_BASE=generate_a_64_character_secret_key -FRONTEND_URL=https://your-domain.com - -# Email Configuration -MAILER_SENDER_EMAIL=noreply@your-domain.com -SMTP_ADDRESS=smtp.your-provider.com -SMTP_PORT=587 -SMTP_USERNAME=your-smtp-username -SMTP_PASSWORD=your-smtp-password -SMTP_AUTHENTICATION=plain -SMTP_ENABLE_STARTTLS_AUTO=true - -# File Storage (optional) -ACTIVE_STORAGE_SERVICE=local -# For S3: ACTIVE_STORAGE_SERVICE=amazon -# AWS_ACCESS_KEY_ID=your_access_key -# AWS_SECRET_ACCESS_KEY=your_secret_key -# AWS_REGION=us-east-1 -# AWS_BUCKET=your-bucket-name - -# Security -FORCE_SSL=true -RAILS_ENV=production -NODE_ENV=production -``` - -### 5. Setup Database - -```bash -# Prepare the database -RAILS_ENV=production bundle exec rails db:chatwoot_prepare - -# Precompile assets -RAILS_ENV=production bundle exec rails assets:precompile -``` - -### 6. Configure Systemd Services - -Create systemd service files: - -**Web Service (`/etc/systemd/system/chatwoot-web.1.service`):** -```ini -[Unit] -Description=Chatwoot web server -After=network.target - -[Service] -Type=simple -User=chatwoot -WorkingDirectory=/home/chatwoot/chatwoot -Environment=RAILS_ENV=production -Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile -ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec rails server -b 0.0.0.0 -p 3000 -e production -Restart=always -RestartSec=1 - -[Install] -WantedBy=multi-user.target -``` - -**Worker Service (`/etc/systemd/system/chatwoot-worker.1.service`):** -```ini -[Unit] -Description=Chatwoot sidekiq worker -After=network.target - -[Service] -Type=simple -User=chatwoot -WorkingDirectory=/home/chatwoot/chatwoot -Environment=RAILS_ENV=production -Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile -ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec sidekiq -C config/sidekiq.yml -Restart=always -RestartSec=1 - -[Install] -WantedBy=multi-user.target -``` - -**Target Service (`/etc/systemd/system/chatwoot.target`):** -```ini -[Unit] -Description=Chatwoot services -Wants=chatwoot-web.1.service chatwoot-worker.1.service - -[Install] -WantedBy=multi-user.target -``` - -Enable and start services: -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable and start Chatwoot services -sudo systemctl enable chatwoot.target -sudo systemctl start chatwoot.target - -# Check status -sudo systemctl status chatwoot.target -``` - -### 7. Configure Nginx - -Install and configure Nginx: - -```bash -# Install Nginx -sudo apt install -y nginx - -# Create Nginx configuration -sudo nano /etc/nginx/sites-available/chatwoot -``` - -**Nginx configuration:** -```nginx -server { - server_name your-domain.com; - - # Point upstream to Chatwoot App Server - set $upstream 127.0.0.1:3000; - - # Nginx strips out underscore in headers by default - # Chatwoot relies on underscore in headers for API - underscores_in_headers on; - - # Increase client max body size for file uploads - client_max_body_size 50M; - - location /.well-known { - alias /var/www/ssl-proof/chatwoot/.well-known; - } - - location / { - proxy_pass_header Authorization; - proxy_pass http://$upstream; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Ssl on; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - proxy_http_version 1.1; - proxy_buffering off; - proxy_read_timeout 36000s; - proxy_redirect off; - } - - listen 80; -} -``` - -Enable the site: -```bash -# Enable site -sudo ln -s /etc/nginx/sites-available/chatwoot /etc/nginx/sites-enabled/ - -# Test configuration -sudo nginx -t - -# Restart Nginx -sudo systemctl restart nginx -``` - -### 8. Setup SSL with Let's Encrypt - -```bash -# Install Certbot -sudo apt install -y certbot python3-certbot-nginx - -# Create directory for SSL verification -sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known - -# Get SSL certificate -sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx - -# Test automatic renewal -sudo certbot renew --dry-run -``` - -## Chatwoot CLI (cwctl) - -Starting with Chatwoot v2.7.0, the installation includes the Chatwoot CLI for easier management: - -### Installation - -If you don't have `cwctl` installed: - -```bash -# Download and install cwctl -sudo wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl -sudo chmod +x /usr/local/bin/cwctl - -# Verify installation -cwctl --help -``` - -### Usage - -```bash -# Restart Chatwoot services -cwctl -r - -# Upgrade Chatwoot -cwctl --upgrade - -# Access Rails console -cwctl -c - -# View logs -cwctl -l web # Web server logs -cwctl -l worker # Worker logs - -# Get help -cwctl --help -``` - -## Maintenance Operations - -### Upgrading Chatwoot - -**Using cwctl (recommended):** -```bash -cwctl --upgrade -``` - -**Manual upgrade:** -```bash -# Switch to chatwoot user -sudo -i -u chatwoot -cd chatwoot - -# Pull latest changes -git checkout master && git pull - -# Update Ruby version if needed -rvm install "ruby-3.3.3" -rvm use 3.3.3 --default - -# Update dependencies -bundle install -pnpm install - -# Precompile assets -RAILS_ENV=production bundle exec rails assets:precompile - -# Run database migrations -RAILS_ENV=production bundle exec rails db:migrate - -# Exit to root user -exit - -# Update systemd service files -sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/ -sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/ -sudo cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/ - -# Reload and restart services -sudo systemctl daemon-reload -sudo systemctl restart chatwoot.target -``` - -### Backup and Restore - -**Database Backup:** -```bash -# Create backup -sudo -u postgres pg_dump chatwoot > chatwoot_backup_$(date +%Y%m%d_%H%M%S).sql - -# Restore backup -sudo -u postgres psql chatwoot < chatwoot_backup_file.sql -``` - -**File Storage Backup:** -```bash -# Backup storage directory -sudo tar -czf chatwoot_storage_$(date +%Y%m%d_%H%M%S).tar.gz /home/chatwoot/chatwoot/storage/ -``` - -**Complete System Backup:** -```bash -# Create backup script -cat > /home/chatwoot/backup.sh << 'EOF' -#!/bin/bash -BACKUP_DIR="/backup/chatwoot/$(date +%Y%m%d_%H%M%S)" -mkdir -p $BACKUP_DIR - -# Database backup -sudo -u postgres pg_dump chatwoot > $BACKUP_DIR/database.sql - -# Application files -tar -czf $BACKUP_DIR/application.tar.gz /home/chatwoot/chatwoot/ - -# Storage files -tar -czf $BACKUP_DIR/storage.tar.gz /home/chatwoot/chatwoot/storage/ - -# Environment file -cp /home/chatwoot/chatwoot/.env $BACKUP_DIR/ - -echo "Backup completed: $BACKUP_DIR" -EOF - -chmod +x /home/chatwoot/backup.sh -``` - -### Monitoring and Logs - -**View logs:** -```bash -# Web server logs -sudo journalctl -u chatwoot-web.1.service -f - -# Worker logs -sudo journalctl -u chatwoot-worker.1.service -f - -# Nginx logs -sudo tail -f /var/log/nginx/access.log -sudo tail -f /var/log/nginx/error.log - -# PostgreSQL logs -sudo tail -f /var/log/postgresql/postgresql-*.log -``` - -**System monitoring:** -```bash -# Check service status -sudo systemctl status chatwoot.target - -# Check resource usage -htop -df -h -free -h - -# Check database connections -sudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity;" -``` - -### Rails Console Access - -```bash -# Using cwctl -cwctl -c - -# Manual access -sudo -i -u chatwoot -cd chatwoot -RAILS_ENV=production bundle exec rails console -``` - -## Troubleshooting - -### Common Issues - -**1. Asset Precompilation Fails:** -```bash -# Clear and rebuild assets -sudo -i -u chatwoot -cd chatwoot -RAILS_ENV=production bundle exec rails assets:clean assets:clobber assets:precompile -``` - -**2. Database Connection Issues:** -```bash -# Check PostgreSQL status -sudo systemctl status postgresql - -# Test database connection -sudo -u postgres psql -c "SELECT version();" - -# Check database configuration -sudo -i -u chatwoot -cd chatwoot -RAILS_ENV=production bundle exec rails db:version -``` - -**3. Permission Issues:** -```bash -# Fix file permissions -sudo chown -R chatwoot:chatwoot /home/chatwoot/chatwoot/ -``` - -**4. Service Won't Start:** -```bash -# Check service logs -sudo journalctl -u chatwoot-web.1.service --no-pager -sudo journalctl -u chatwoot-worker.1.service --no-pager - -# Check configuration -sudo systemctl status chatwoot.target -``` - -### Performance Optimization - -**1. Database Optimization:** -```sql --- Connect to database -sudo -u postgres psql chatwoot - --- Check database size -SELECT pg_size_pretty(pg_database_size('chatwoot')); - --- Check slow queries (if pg_stat_statements is enabled) -SELECT query, mean_time, calls -FROM pg_stat_statements -ORDER BY mean_time DESC -LIMIT 10; -``` - -**2. System Optimization:** -```bash -# Increase file limits for chatwoot user -echo "chatwoot soft nofile 65536" | sudo tee -a /etc/security/limits.conf -echo "chatwoot hard nofile 65536" | sudo tee -a /etc/security/limits.conf - -# Optimize PostgreSQL configuration -sudo nano /etc/postgresql/*/main/postgresql.conf -# Adjust shared_buffers, effective_cache_size, work_mem based on available RAM -``` - -### Security Hardening - -**1. Firewall Configuration:** -```bash -# Install and configure UFW -sudo ufw enable -sudo ufw default deny incoming -sudo ufw default allow outgoing -sudo ufw allow ssh -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp -``` - -**2. Fail2ban Setup:** -```bash -# Install Fail2ban -sudo apt install -y fail2ban - -# Configure Fail2ban for SSH -sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local -sudo systemctl enable fail2ban -sudo systemctl start fail2ban -``` - -**3. Regular Updates:** -```bash -# Create update script -cat > /home/chatwoot/update_system.sh << 'EOF' -#!/bin/bash -sudo apt update -sudo apt upgrade -y -sudo apt autoremove -y -sudo apt autoclean -EOF - -chmod +x /home/chatwoot/update_system.sh - -# Add to crontab for weekly updates -echo "0 2 * * 0 /home/chatwoot/update_system.sh" | sudo crontab - -``` - ---- - - -Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and application files. - - - -For high-availability deployments, consider setting up multiple servers with load balancing and database replication. - \ No newline at end of file diff --git a/developer-docs/self-hosted/introduction.mdx b/developer-docs/self-hosted/introduction.mdx deleted file mode 100644 index 32078651d..000000000 --- a/developer-docs/self-hosted/introduction.mdx +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: Self-Hosted Installation Guide -description: Complete guide to install and setup a production-ready Chatwoot instance on your own infrastructure. -sidebarTitle: Introduction ---- - -Welcome to the Chatwoot self-hosted installation guide. This comprehensive documentation will help you deploy, configure, and maintain your own Chatwoot instance with full control over your data and infrastructure. - -## Why Self-Host Chatwoot? - -Self-hosting Chatwoot gives you complete control over your customer support platform: - -- **Data Privacy**: Keep all customer data on your own servers -- **Customization**: Modify the platform to fit your specific needs -- **Cost Control**: No per-agent pricing - scale as much as you need -- **Compliance**: Meet specific regulatory requirements -- **Integration**: Deep integration with your existing infrastructure - -## Deployment Options - -Chatwoot supports multiple deployment methods to fit different infrastructure needs: - -### 🐧 Linux VM Deployment -Deploy directly on Ubuntu/Linux virtual machines with our automated installation script. -- **Best for**: Traditional server environments -- **Complexity**: Low to Medium -- **Maintenance**: Manual updates required - -### 🐳 Docker Deployment -Use Docker containers for consistent, portable deployments. -- **Best for**: Containerized environments -- **Complexity**: Medium -- **Maintenance**: Easy updates with container pulls - -### ☸️ Kubernetes Deployment -Deploy on Kubernetes clusters for enterprise-scale operations. -- **Best for**: Large-scale, high-availability deployments -- **Complexity**: High -- **Maintenance**: Automated with proper CI/CD - -### ☁️ Cloud Provider Deployments -One-click deployments on major cloud platforms: -- **AWS**: EC2, ECS, and Marketplace options -- **Azure**: Container Instances and VM deployments -- **DigitalOcean**: Droplets and App Platform -- **Google Cloud**: Compute Engine and Cloud Run -- **Heroku**: Simple one-click deployment - -## System Requirements - -### Minimum Requirements -- **CPU**: 2 cores -- **RAM**: 4GB -- **Storage**: 20GB SSD -- **OS**: Ubuntu 20.04+ or compatible Linux distribution - -### Recommended for Production -- **CPU**: 4+ cores -- **RAM**: 8GB+ -- **Storage**: 50GB+ SSD -- **Database**: PostgreSQL 12+ -- **Cache**: Redis 6+ -- **Reverse Proxy**: Nginx or similar - -## What You'll Need - -Before starting your Chatwoot installation, ensure you have: - -### Technical Requirements -- [ ] Server or cloud instance meeting minimum requirements -- [ ] Domain name (recommended for production) -- [ ] SSL certificate (Let's Encrypt recommended) -- [ ] SMTP server for email notifications - -### Access Requirements -- [ ] SSH access to your server -- [ ] Root or sudo privileges -- [ ] Firewall configuration access - -### Optional but Recommended -- [ ] Object storage (AWS S3, Google Cloud Storage, etc.) -- [ ] CDN for static assets -- [ ] Monitoring tools (APM, logging) -- [ ] Backup solution - -## Security Considerations - -When self-hosting Chatwoot, consider these security aspects: - -- **Regular Updates**: Keep Chatwoot and system packages updated -- **Firewall Configuration**: Only expose necessary ports -- **SSL/TLS**: Always use HTTPS in production -- **Database Security**: Secure PostgreSQL with strong passwords -- **Backup Encryption**: Encrypt sensitive backup data -- **Access Control**: Implement proper user access controls - -## Getting Started - -Ready to deploy Chatwoot? Choose your preferred deployment method: - - - - Get up and running quickly with Docker containers - - - Traditional server deployment with our automated script - - - Enterprise-scale deployment on Kubernetes - - - One-click deployments on major cloud platforms - - - -## Community and Support - -- **Documentation**: Comprehensive guides and API references -- **GitHub**: [Source code and issue tracking](https://github.com/chatwoot/chatwoot) -- **Discord**: [Community chat and support](https://discord.gg/cJXdrwS) -- **Forum**: [Community discussions and Q&A](https://github.com/chatwoot/chatwoot/discussions) - ---- - - -This documentation covers Chatwoot Community Edition (CE). For Enterprise features and support, visit [Chatwoot Enterprise](https://www.chatwoot.com/pricing). - \ No newline at end of file diff --git a/developer-docs/self-hosted/requirements.mdx b/developer-docs/self-hosted/requirements.mdx deleted file mode 100644 index da816e55f..000000000 --- a/developer-docs/self-hosted/requirements.mdx +++ /dev/null @@ -1,339 +0,0 @@ ---- -title: System Requirements -description: Hardware, software, and infrastructure requirements for deploying Chatwoot in different environments. -sidebarTitle: Requirements ---- - -Before deploying Chatwoot, ensure your infrastructure meets the minimum requirements for your expected usage. This guide covers requirements for different deployment scenarios and scales. - -## Minimum System Requirements - -### Development Environment - -For local development and testing: - -| Component | Requirement | -|-----------|-------------| -| **CPU** | 2 cores (2.0 GHz+) | -| **RAM** | 4GB | -| **Storage** | 20GB available space | -| **OS** | Ubuntu 20.04+, macOS 10.15+, Windows 10+ | -| **Network** | Broadband internet connection | - -### Small Production (1-10 agents) - -For small teams and low-volume usage: - -| Component | Requirement | -|-----------|-------------| -| **CPU** | 2 cores (2.4 GHz+) | -| **RAM** | 4GB | -| **Storage** | 50GB SSD | -| **Network** | 100 Mbps bandwidth | -| **Concurrent Users** | Up to 100 | - -### Medium Production (10-50 agents) - -For growing teams with moderate usage: - -| Component | Requirement | -|-----------|-------------| -| **CPU** | 4 cores (2.4 GHz+) | -| **RAM** | 8GB | -| **Storage** | 100GB SSD | -| **Network** | 500 Mbps bandwidth | -| **Concurrent Users** | Up to 500 | - -### Large Production (50+ agents) - -For enterprise deployments with high volume: - -| Component | Requirement | -|-----------|-------------| -| **CPU** | 8+ cores (2.4 GHz+) | -| **RAM** | 16GB+ | -| **Storage** | 200GB+ SSD | -| **Network** | 1 Gbps+ bandwidth | -| **Concurrent Users** | 1000+ | - -## Software Requirements - -### Operating System - -**Supported Linux Distributions:** -- Ubuntu 20.04 LTS or later (recommended) -- Ubuntu 22.04 LTS -- Debian 10 or later -- CentOS 8 or later -- RHEL 8 or later -- Amazon Linux 2 - -**Container Platforms:** -- Docker 20.10+ with Docker Compose 2.0+ -- Kubernetes 1.20+ -- OpenShift 4.6+ - -### Runtime Dependencies - -| Component | Version | Purpose | -|-----------|---------|---------| -| **Ruby** | 3.3.3+ | Application runtime | -| **Node.js** | 20.x LTS | Frontend build tools | -| **PostgreSQL** | 12+ | Primary database | -| **Redis** | 6.0+ | Cache and job queue | -| **Nginx** | 1.18+ | Reverse proxy | - -### Development Dependencies - -For building from source: - -| Component | Version | Purpose | -|-----------|---------|---------| -| **Git** | 2.25+ | Source code management | -| **Build tools** | Latest | Compiling native extensions | -| **ImageMagick** | 7.0+ | Image processing | -| **FFmpeg** | 4.0+ | Video/audio processing | - -## Database Requirements - -### PostgreSQL Configuration - -**Minimum Version:** PostgreSQL 12+ -**Recommended Version:** PostgreSQL 14+ - -**Required Extensions:** -- `pg_stat_statements` (performance monitoring) -- `uuid-ossp` (UUID generation) -- `pg_trgm` (full-text search) - -**Configuration Recommendations:** - -```sql --- Memory settings (adjust based on available RAM) -shared_buffers = 256MB # 25% of RAM for small instances -effective_cache_size = 1GB # 75% of RAM -work_mem = 4MB # Per connection -maintenance_work_mem = 64MB # For maintenance operations - --- Connection settings -max_connections = 100 # Adjust based on expected load -max_prepared_transactions = 100 # For prepared statements - --- Write-ahead logging -wal_buffers = 16MB # WAL buffer size -checkpoint_completion_target = 0.9 # Checkpoint target -``` - -### Redis Configuration - -**Minimum Version:** Redis 6.0+ -**Recommended Version:** Redis 7.0+ - -**Memory Requirements:** -- **Small deployment:** 512MB -- **Medium deployment:** 2GB -- **Large deployment:** 4GB+ - -**Configuration Recommendations:** - -```redis -# Memory management -maxmemory 2gb -maxmemory-policy allkeys-lru - -# Persistence (choose one) -save 900 1 # RDB snapshots -# appendonly yes # AOF logging - -# Security -requirepass your_secure_password -``` - -## Network Requirements - -### Ports - -| Port | Protocol | Purpose | External Access | -|------|----------|---------|-----------------| -| **80** | HTTP | Web traffic (redirect to HTTPS) | Yes | -| **443** | HTTPS | Secure web traffic | Yes | -| **3000** | HTTP | Application server (behind proxy) | No | -| **5432** | TCP | PostgreSQL database | No | -| **6379** | TCP | Redis cache | No | -| **22** | SSH | Server administration | Admin only | - -### Firewall Configuration - -**Inbound Rules:** -```bash -# Allow HTTP and HTTPS -ufw allow 80/tcp -ufw allow 443/tcp - -# Allow SSH (restrict to admin IPs) -ufw allow from YOUR_ADMIN_IP to any port 22 - -# Deny all other inbound traffic -ufw default deny incoming -``` - -**Outbound Rules:** -```bash -# Allow all outbound (for updates, integrations) -ufw default allow outgoing - -# Or restrict to specific services -ufw allow out 53/udp # DNS -ufw allow out 80/tcp # HTTP -ufw allow out 443/tcp # HTTPS -ufw allow out 587/tcp # SMTP -``` - -### Bandwidth Estimation - -**Per Agent (monthly):** -- **Light usage:** 1-2 GB -- **Medium usage:** 3-5 GB -- **Heavy usage:** 8-10 GB - -**Per Customer Conversation:** -- **Text only:** 10-50 KB -- **With images:** 500 KB - 2 MB -- **With files:** 1-10 MB - -## Storage Requirements - -### Disk Space Planning - -**Base Installation:** 5-10 GB -**Database Growth:** 100 MB - 1 GB per 1000 conversations -**File Attachments:** Varies by usage (plan for 10-50 GB) -**Logs:** 1-5 GB per month -**Backups:** 2x database size + file storage - -### Storage Performance - -| Deployment Size | IOPS | Throughput | -|-----------------|------|------------| -| **Small** | 1,000 IOPS | 50 MB/s | -| **Medium** | 3,000 IOPS | 150 MB/s | -| **Large** | 10,000+ IOPS | 500+ MB/s | - -### File Storage Options - -**Local Storage:** -- Suitable for small deployments -- Requires backup strategy -- Limited scalability - -**Object Storage (Recommended):** -- AWS S3, Google Cloud Storage, Azure Blob -- Unlimited scalability -- Built-in redundancy -- CDN integration - -## Security Requirements - -### SSL/TLS Certificates - -**Required for Production:** -- Valid SSL certificate for your domain -- TLS 1.2 or higher -- Strong cipher suites - -**Certificate Options:** -- Let's Encrypt (free, automated) -- Commercial certificates -- Wildcard certificates for subdomains - -### Access Control - -**Server Access:** -- SSH key-based authentication -- Disable password authentication -- Regular security updates -- Fail2ban or similar intrusion prevention - -**Application Security:** -- Strong database passwords -- Redis authentication -- Regular security updates -- Web Application Firewall (optional) - -## Cloud Provider Specifications - -### AWS EC2 Instance Types - -| Use Case | Instance Type | vCPU | RAM | Storage | -|----------|---------------|------|-----|---------| -| **Development** | t3.medium | 2 | 4 GB | 20 GB gp3 | -| **Small Production** | t3.large | 2 | 8 GB | 50 GB gp3 | -| **Medium Production** | m5.xlarge | 4 | 16 GB | 100 GB gp3 | -| **Large Production** | m5.2xlarge | 8 | 32 GB | 200 GB gp3 | - -### DigitalOcean Droplets - -| Use Case | Droplet Size | vCPU | RAM | Storage | -|----------|--------------|------|-----|---------| -| **Development** | 2 GB | 1 | 2 GB | 50 GB SSD | -| **Small Production** | 4 GB | 2 | 4 GB | 80 GB SSD | -| **Medium Production** | 8 GB | 4 | 8 GB | 160 GB SSD | -| **Large Production** | 16 GB | 6 | 16 GB | 320 GB SSD | - -### Google Cloud Compute Engine - -| Use Case | Machine Type | vCPU | RAM | Storage | -|----------|--------------|------|-----|---------| -| **Development** | e2-medium | 2 | 4 GB | 50 GB SSD | -| **Small Production** | e2-standard-2 | 2 | 8 GB | 100 GB SSD | -| **Medium Production** | e2-standard-4 | 4 | 16 GB | 200 GB SSD | -| **Large Production** | e2-standard-8 | 8 | 32 GB | 500 GB SSD | - -## Performance Benchmarks - -### Expected Performance - -| Metric | Small | Medium | Large | -|--------|-------|--------|-------| -| **Concurrent Users** | 100 | 500 | 1000+ | -| **Messages/minute** | 1,000 | 5,000 | 20,000+ | -| **Response Time** | <200ms | <300ms | <500ms | -| **Uptime** | 99.5% | 99.9% | 99.95% | - -### Load Testing - -Before production deployment, consider load testing: - -```bash -# Example using Apache Bench -ab -n 1000 -c 10 https://your-chatwoot-domain.com/api/v1/accounts - -# Example using wrk -wrk -t12 -c400 -d30s https://your-chatwoot-domain.com/ -``` - -## Monitoring Requirements - -### Essential Metrics - -- **System:** CPU, memory, disk, network -- **Application:** Response times, error rates -- **Database:** Connection count, query performance -- **Redis:** Memory usage, hit rates - -### Recommended Tools - -- **System Monitoring:** Prometheus + Grafana, DataDog, New Relic -- **Log Management:** ELK Stack, Fluentd, Splunk -- **Uptime Monitoring:** Pingdom, UptimeRobot -- **APM:** New Relic, DataDog APM, Scout - ---- - - -These requirements are guidelines. Your actual needs may vary based on usage patterns, integrations, and performance expectations. Monitor your deployment and adjust resources accordingly. - - - -For high-availability deployments, consider redundancy in all components and implement proper backup and disaster recovery procedures. - \ No newline at end of file From 5bbda8e348a747e5f4a9eea44de9459ac5b2268a Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Fri, 13 Jun 2025 22:37:45 +0530 Subject: [PATCH 05/11] add conversation attributes for llm context --- .../llm_formatter/conversation_llm_formatter.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/services/llm_formatter/conversation_llm_formatter.rb b/app/services/llm_formatter/conversation_llm_formatter.rb index 1444d75c1..af56cfee3 100644 --- a/app/services/llm_formatter/conversation_llm_formatter.rb +++ b/app/services/llm_formatter/conversation_llm_formatter.rb @@ -11,6 +11,8 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter end sections << "Contact Details: #{@record.contact.to_llm_text}" if config[:include_contact_details] + sections << 'Conversation Attributes:' + sections << build_attributes sections.join("\n") end @@ -30,4 +32,12 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter sender = message.message_type == 'incoming' ? 'User' : 'Support agent' "#{sender}: #{message.content}\n" end + + def build_attributes + attributes = [] + @record.account.custom_attribute_definitions.with_attribute_model('conversation_attribute').each do |attribute| + attributes << "#{attribute.attribute_display_name}: #{@record.custom_attributes[attribute.attribute_key]}" + end + attributes.join("\n") + end end From c60b47fd57dfb1e9469f50fbffcd7aa9ad90bf7d Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Sat, 14 Jun 2025 00:49:26 +0530 Subject: [PATCH 06/11] feat: update message content and include 'Conversation Attributes' --- .../conversation_llm_formatter_spec.rb | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/spec/services/llm_formatter/conversation_llm_formatter_spec.rb b/spec/services/llm_formatter/conversation_llm_formatter_spec.rb index 93fec14f7..9f570d23d 100644 --- a/spec/services/llm_formatter/conversation_llm_formatter_spec.rb +++ b/spec/services/llm_formatter/conversation_llm_formatter_spec.rb @@ -12,7 +12,9 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do "Conversation ID: ##{conversation.display_id}", "Channel: #{conversation.inbox.channel.name}", 'Message History:', - 'No messages in this conversation' + 'No messages in this conversation', + 'Conversation Attributes:', + '' ].join("\n") expect(formatter.format).to eq(expected_output) @@ -41,6 +43,8 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do 'Message History:', 'User: Hello, I need help', 'Support agent: How can I assist you today?', + '', + 'Conversation Attributes:', '' ].join("\n") @@ -55,11 +59,38 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do "Channel: #{conversation.inbox.channel.name}", 'Message History:', 'No messages in this conversation', - "Contact Details: #{conversation.contact.to_llm_text}" + "Contact Details: #{conversation.contact.to_llm_text}", + 'Conversation Attributes:', + '' ].join("\n") expect(formatter.format(include_contact_details: true)).to eq(expected_output) end end + + context 'when conversation has custom attributes' do + it 'includes formatted custom attributes in the output' do + create( + :custom_attribute_definition, + account: account, + attribute_display_name: 'Order ID', + attribute_key: 'order_id', + attribute_model: :conversation_attribute + ) + + conversation.update(custom_attributes: { 'order_id' => '12345' }) + + expected_output = [ + "Conversation ID: ##{conversation.display_id}", + "Channel: #{conversation.inbox.channel.name}", + 'Message History:', + 'No messages in this conversation', + 'Conversation Attributes:', + 'Order ID: 12345' + ].join("\n") + + expect(formatter.format).to eq(expected_output) + end + end end end From 848b833bc1e05faca7d61ca45284482aac35b1ac Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Sat, 14 Jun 2025 01:30:49 +0530 Subject: [PATCH 07/11] add private message for copilot analysis --- app/services/llm_formatter/conversation_llm_formatter.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/llm_formatter/conversation_llm_formatter.rb b/app/services/llm_formatter/conversation_llm_formatter.rb index af56cfee3..d9f184659 100644 --- a/app/services/llm_formatter/conversation_llm_formatter.rb +++ b/app/services/llm_formatter/conversation_llm_formatter.rb @@ -22,7 +22,7 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter return "No messages in this conversation\n" if @record.messages.empty? message_text = '' - @record.messages.chat.order(created_at: :asc).each do |message| + @record.messages.where.not(message_type: :activity).order(created_at: :asc).each do |message| message_text << format_message(message) end message_text @@ -30,13 +30,13 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter def format_message(message) sender = message.message_type == 'incoming' ? 'User' : 'Support agent' + sender = "[Private] #{sender}" if message.private? "#{sender}: #{message.content}\n" end def build_attributes - attributes = [] - @record.account.custom_attribute_definitions.with_attribute_model('conversation_attribute').each do |attribute| - attributes << "#{attribute.attribute_display_name}: #{@record.custom_attributes[attribute.attribute_key]}" + attributes = @record.account.custom_attribute_definitions.with_attribute_model('conversation_attribute').map do |attribute| + "#{attribute.attribute_display_name}: #{@record.custom_attributes[attribute.attribute_key]}" end attributes.join("\n") end From 3fd054fcc8a5fe9ba1febfccb5e8004ac15dc150 Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Tue, 17 Jun 2025 11:50:26 +0530 Subject: [PATCH 08/11] feat: add OpenaiMultimodalContentService for content generation --- .../conversation_llm_formatter.rb | 13 +++- .../openai_multimodal_content_service.rb | 74 +++++++++++++++++++ enterprise/app/helpers/captain/chat_helper.rb | 12 --- .../conversation/response_builder_job.rb | 71 ++---------------- .../tools/copilot/get_conversation_service.rb | 2 +- enterprise/lib/chat_gpt.rb | 6 +- 6 files changed, 94 insertions(+), 84 deletions(-) create mode 100644 app/services/openai_multimodal_content_service.rb diff --git a/app/services/llm_formatter/conversation_llm_formatter.rb b/app/services/llm_formatter/conversation_llm_formatter.rb index d9f184659..d7e7a1cdb 100644 --- a/app/services/llm_formatter/conversation_llm_formatter.rb +++ b/app/services/llm_formatter/conversation_llm_formatter.rb @@ -5,7 +5,7 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter sections << "Channel: #{@record.inbox.channel.name}" sections << 'Message History:' sections << if @record.messages.any? - build_messages + build_messages(config) else 'No messages in this conversation' end @@ -18,11 +18,16 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter private - def build_messages + def build_messages(config = {}) return "No messages in this conversation\n" if @record.messages.empty? message_text = '' - @record.messages.where.not(message_type: :activity).order(created_at: :asc).each do |message| + messages = @record.messages.where.not(message_type: :activity).order(created_at: :asc) + + messages.each do |message| + # Skip private messages unless explicitly included in config + next if message.private? && !config[:include_private_messages] + message_text << format_message(message) end message_text @@ -30,7 +35,7 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter def format_message(message) sender = message.message_type == 'incoming' ? 'User' : 'Support agent' - sender = "[Private] #{sender}" if message.private? + sender = "[Private Note] #{sender}" if message.private? "#{sender}: #{message.content}\n" end diff --git a/app/services/openai_multimodal_content_service.rb b/app/services/openai_multimodal_content_service.rb new file mode 100644 index 000000000..11bf3c98e --- /dev/null +++ b/app/services/openai_multimodal_content_service.rb @@ -0,0 +1,74 @@ +class OpenaiMultimodalContentService + def initialize(message) + @message = message + end + + def generate_content + parts = [] + + parts << text_part(@message.content) if @message.content.present? + parts.concat(attachment_parts(@message.attachments)) if @message.attachments.any? + + finalize_content_parts(parts) + end + + private + + def text_part(text) + { type: 'text', text: text } + end + + def attachment_parts(attachments) + [].tap do |parts| + parts.concat(image_parts(attachments.where(file_type: :image))) + + transcription = extract_audio_transcriptions(attachments) + parts << text_part(transcription) if transcription.present? + + parts << text_part('User has shared an attachment') if attachments.where.not(file_type: %i[image audio]).exists? + end + end + + def image_parts(image_attachments) + image_attachments.each_with_object([]) do |attachment, parts| + url = get_attachment_url(attachment) + next if url.blank? + + parts << { + type: 'image_url', + image_url: { url: url } + } + end + end + + def finalize_content_parts(parts) + return 'Message without content' if parts.blank? + return parts.first[:text] if single_text_part?(parts) + + parts + end + + def single_text_part?(parts) + parts.one? && parts.first[:type] == 'text' + end + + def get_attachment_url(attachment) + return attachment.external_url if attachment.external_url.present? + + return unless attachment.file.attached? + + attachment.file_url + end + + def extract_audio_transcriptions(attachments) + audio_attachments = attachments.where(file_type: :audio) + return '' if audio_attachments.blank? + + transcriptions = '' + audio_attachments.each do |attachment| + result = Messages::AudioTranscriptionService.new(attachment).perform + transcriptions += result[:transcriptions] if result[:success] + end + transcriptions + end +end \ No newline at end of file diff --git a/enterprise/app/helpers/captain/chat_helper.rb b/enterprise/app/helpers/captain/chat_helper.rb index baff0a209..f90b8d07e 100644 --- a/enterprise/app/helpers/captain/chat_helper.rb +++ b/enterprise/app/helpers/captain/chat_helper.rb @@ -18,18 +18,6 @@ module Captain::ChatHelper raise e end - def extract_audio_transcriptions(attachments) - audio_attachments = attachments.where(file_type: :audio) - return '' if audio_attachments.blank? - - transcriptions = '' - audio_attachments.each do |attachment| - result = Messages::AudioTranscriptionService.new(attachment).perform - transcriptions += result[:transcriptions] if result[:success] - end - transcriptions - end - private def handle_response(response) diff --git a/enterprise/app/jobs/captain/conversation/response_builder_job.rb b/enterprise/app/jobs/captain/conversation/response_builder_job.rb index eea8b934e..976743f74 100644 --- a/enterprise/app/jobs/captain/conversation/response_builder_job.rb +++ b/enterprise/app/jobs/captain/conversation/response_builder_job.rb @@ -38,14 +38,12 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob account.increment_response_usage end - def collect_previous_messages(include_all: false) - messages_query = @conversation - .messages - .where(message_type: [:incoming, :outgoing]) - - messages_query = messages_query.where(private: false) unless include_all - - messages_query.map do |message| + def collect_previous_messages + @conversation + .messages + .where(message_type: [:incoming, :outgoing]) + .where(private: false) + .map do |message| { content: message_content_multimodal(message), role: determine_role(message) @@ -60,62 +58,7 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob end def message_content_multimodal(message) - parts = [] - - parts << text_part(message.content) if message.content.present? - parts.concat(attachment_parts(message.attachments)) if message.attachments.any? - - finalize_content_parts(parts) - end - - def text_part(text) - { type: 'text', text: text } - end - - def attachment_parts(attachments) - [].tap do |parts| - parts.concat(image_parts(attachments.where(file_type: :image))) - - transcription = extract_audio_transcriptions(attachments) - parts << text_part(transcription) if transcription.present? - - parts << text_part('User has shared an attachment') if attachments.where.not(file_type: %i[image audio]).exists? - end - end - - def image_parts(image_attachments) - image_attachments.each_with_object([]) do |attachment, parts| - url = get_attachment_url(attachment) - next if url.blank? - - parts << { - type: 'image_url', - image_url: { url: url } - } - end - end - - def finalize_content_parts(parts) - return 'Message without content' if parts.blank? - return parts.first[:text] if single_text_part?(parts) - - parts - end - - def single_text_part?(parts) - parts.one? && parts.first[:type] == 'text' - end - - def get_attachment_url(attachment) - return attachment.external_url if attachment.external_url.present? - - return unless attachment.file.attached? - - begin - attachment.file_url - rescue ActiveStorage::FileNotFoundError - nil - end + OpenaiMultimodalContentService.new(message).generate_content end def handoff_requested? diff --git a/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb index 64b52d012..6f942ee8e 100644 --- a/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb +++ b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb @@ -30,7 +30,7 @@ class Captain::Tools::Copilot::GetConversationService < Captain::Tools::BaseServ conversation = Conversation.find_by(display_id: conversation_id, account_id: @assistant.account_id) return 'Conversation not found' if conversation.blank? - conversation.to_llm_text + conversation.to_llm_text(include_private_messages: true) end def active? diff --git a/enterprise/lib/chat_gpt.rb b/enterprise/lib/chat_gpt.rb index ad77159cf..44afbd641 100644 --- a/enterprise/lib/chat_gpt.rb +++ b/enterprise/lib/chat_gpt.rb @@ -8,9 +8,9 @@ class ChatGpt @messages = [system_message(context_sections)] end - def generate_response(additional_message: nil, message_history: [], role: 'user') - @messages += message_history - @messages << { 'role': role, 'content': additional_message } if additional_message.present? + def generate_response(input, previous_messages = [], role = 'user') + @messages += previous_messages + @messages << { 'role': role, 'content': input } if input.present? response = request_gpt JSON.parse(response['choices'][0]['message']['content'].strip) From aafd99bed1e3cea34e02b11be1eb2e91cb21b14c Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Thu, 19 Jun 2025 12:56:24 +0530 Subject: [PATCH 09/11] refactor: refactor OpenaiMultimodalContentService and ResponseBuilderJob --- .../conversation_llm_formatter.rb | 21 +- .../openai_multimodal_content_service.rb | 74 ----- .../conversation/response_builder_job.rb | 6 +- .../open_ai_message_builder_service.rb | 59 ++++ .../tools/copilot/get_conversation_service.rb | 2 +- .../open_ai_message_builder_service_spec.rb | 309 ++++++++++++++++++ 6 files changed, 375 insertions(+), 96 deletions(-) delete mode 100644 app/services/openai_multimodal_content_service.rb create mode 100644 enterprise/app/services/captain/open_ai_message_builder_service.rb create mode 100644 spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb diff --git a/app/services/llm_formatter/conversation_llm_formatter.rb b/app/services/llm_formatter/conversation_llm_formatter.rb index d7e7a1cdb..1444d75c1 100644 --- a/app/services/llm_formatter/conversation_llm_formatter.rb +++ b/app/services/llm_formatter/conversation_llm_formatter.rb @@ -5,29 +5,22 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter sections << "Channel: #{@record.inbox.channel.name}" sections << 'Message History:' sections << if @record.messages.any? - build_messages(config) + build_messages else 'No messages in this conversation' end sections << "Contact Details: #{@record.contact.to_llm_text}" if config[:include_contact_details] - sections << 'Conversation Attributes:' - sections << build_attributes sections.join("\n") end private - def build_messages(config = {}) + def build_messages return "No messages in this conversation\n" if @record.messages.empty? message_text = '' - messages = @record.messages.where.not(message_type: :activity).order(created_at: :asc) - - messages.each do |message| - # Skip private messages unless explicitly included in config - next if message.private? && !config[:include_private_messages] - + @record.messages.chat.order(created_at: :asc).each do |message| message_text << format_message(message) end message_text @@ -35,14 +28,6 @@ class LlmFormatter::ConversationLlmFormatter < LlmFormatter::DefaultLlmFormatter def format_message(message) sender = message.message_type == 'incoming' ? 'User' : 'Support agent' - sender = "[Private Note] #{sender}" if message.private? "#{sender}: #{message.content}\n" end - - def build_attributes - attributes = @record.account.custom_attribute_definitions.with_attribute_model('conversation_attribute').map do |attribute| - "#{attribute.attribute_display_name}: #{@record.custom_attributes[attribute.attribute_key]}" - end - attributes.join("\n") - end end diff --git a/app/services/openai_multimodal_content_service.rb b/app/services/openai_multimodal_content_service.rb deleted file mode 100644 index 11bf3c98e..000000000 --- a/app/services/openai_multimodal_content_service.rb +++ /dev/null @@ -1,74 +0,0 @@ -class OpenaiMultimodalContentService - def initialize(message) - @message = message - end - - def generate_content - parts = [] - - parts << text_part(@message.content) if @message.content.present? - parts.concat(attachment_parts(@message.attachments)) if @message.attachments.any? - - finalize_content_parts(parts) - end - - private - - def text_part(text) - { type: 'text', text: text } - end - - def attachment_parts(attachments) - [].tap do |parts| - parts.concat(image_parts(attachments.where(file_type: :image))) - - transcription = extract_audio_transcriptions(attachments) - parts << text_part(transcription) if transcription.present? - - parts << text_part('User has shared an attachment') if attachments.where.not(file_type: %i[image audio]).exists? - end - end - - def image_parts(image_attachments) - image_attachments.each_with_object([]) do |attachment, parts| - url = get_attachment_url(attachment) - next if url.blank? - - parts << { - type: 'image_url', - image_url: { url: url } - } - end - end - - def finalize_content_parts(parts) - return 'Message without content' if parts.blank? - return parts.first[:text] if single_text_part?(parts) - - parts - end - - def single_text_part?(parts) - parts.one? && parts.first[:type] == 'text' - end - - def get_attachment_url(attachment) - return attachment.external_url if attachment.external_url.present? - - return unless attachment.file.attached? - - attachment.file_url - end - - def extract_audio_transcriptions(attachments) - audio_attachments = attachments.where(file_type: :audio) - return '' if audio_attachments.blank? - - transcriptions = '' - audio_attachments.each do |attachment| - result = Messages::AudioTranscriptionService.new(attachment).perform - transcriptions += result[:transcriptions] if result[:success] - end - transcriptions - end -end \ No newline at end of file diff --git a/enterprise/app/jobs/captain/conversation/response_builder_job.rb b/enterprise/app/jobs/captain/conversation/response_builder_job.rb index 976743f74..bceece6c1 100644 --- a/enterprise/app/jobs/captain/conversation/response_builder_job.rb +++ b/enterprise/app/jobs/captain/conversation/response_builder_job.rb @@ -45,7 +45,7 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob .where(private: false) .map do |message| { - content: message_content_multimodal(message), + content: prepare_multimodal_message_content(message), role: determine_role(message) } end @@ -57,8 +57,8 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob message.message_type == 'incoming' ? 'user' : 'system' end - def message_content_multimodal(message) - OpenaiMultimodalContentService.new(message).generate_content + def prepare_multimodal_message_content(message) + OpenAiMessageBuilderService.new(message: message).generate_content end def handoff_requested? diff --git a/enterprise/app/services/captain/open_ai_message_builder_service.rb b/enterprise/app/services/captain/open_ai_message_builder_service.rb new file mode 100644 index 000000000..3320ad537 --- /dev/null +++ b/enterprise/app/services/captain/open_ai_message_builder_service.rb @@ -0,0 +1,59 @@ +class Captain::OpenAiMessageBuilderService + pattr_initialize [:message!] + + def generate_content + parts = [] + parts << text_part(@message.content) if @message.content.present? + parts.concat(attachment_parts(@message.attachments)) if @message.attachments.any? + + return 'Message without content' if parts.blank? + return parts.first[:text] if parts.one? && parts.first[:type] == 'text' + + parts + end + + private + + def text_part(text) + { type: 'text', text: text } + end + + def image_part(image_url) + { type: 'image_url', image_url: { url: image_url } } + end + + def attachment_parts(attachments) + image_attachments = attachments.where(file_type: :image) + image_content = image_parts(image_attachments) + + transcription = extract_audio_transcriptions(attachments) + transcription_part = text_part(transcription) if transcription.present? + + attachment_part = text_part('User has shared an attachment') if attachments.where.not(file_type: %i[image audio]).exists? + + [image_content, transcription_part, attachment_part].flatten.compact + end + + def image_parts(image_attachments) + image_attachments.each_with_object([]) do |attachment, parts| + url = get_attachment_url(attachment) + parts << image_part(url) if url.present? + end + end + + def get_attachment_url(attachment) + return attachment.external_url if attachment.external_url.present? + + attachment.file.attached? ? attachment.file_url : nil + end + + def extract_audio_transcriptions(attachments) + audio_attachments = attachments.where(file_type: :audio) + return '' if audio_attachments.blank? + + audio_attachments.map do |attachment| + result = Messages::AudioTranscriptionService.new(attachment).perform + result[:success] ? result[:transcriptions] : '' + end.join + end +end \ No newline at end of file diff --git a/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb index 6f942ee8e..64b52d012 100644 --- a/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb +++ b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb @@ -30,7 +30,7 @@ class Captain::Tools::Copilot::GetConversationService < Captain::Tools::BaseServ conversation = Conversation.find_by(display_id: conversation_id, account_id: @assistant.account_id) return 'Conversation not found' if conversation.blank? - conversation.to_llm_text(include_private_messages: true) + conversation.to_llm_text end def active? diff --git a/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb b/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb new file mode 100644 index 000000000..1cbc41955 --- /dev/null +++ b/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb @@ -0,0 +1,309 @@ +require 'rails_helper' + +RSpec.describe Captain::OpenAiMessageBuilderService do + subject(:service) { described_class.new(message: message) } + + let(:message) { create(:message, content: 'Hello world') } + + describe '#generate_content' do + context 'when message has only text content' do + it 'returns the text content directly' do + expect(service.generate_content).to eq('Hello world') + end + end + + context 'when message has no content and no attachments' do + let(:message) { create(:message, content: nil) } + + it 'returns default message' do + expect(service.generate_content).to eq('Message without content') + end + end + + context 'when message has text content and attachments' do + before do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image.jpg') + attachment.save! + end + + it 'returns an array of content parts' do + result = service.generate_content + expect(result).to be_an(Array) + expect(result).to include({ type: 'text', text: 'Hello world' }) + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }) + end + end + + context 'when message has only non-text attachments' do + let(:message) { create(:message, content: nil) } + + before do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image.jpg') + attachment.save! + end + + it 'returns an array of content parts without text' do + result = service.generate_content + expect(result).to be_an(Array) + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }) + expect(result).not_to include(hash_including(type: 'text', text: 'Hello world')) + end + end + end + + describe '#attachment_parts' do + let(:message) { create(:message, content: nil) } + let(:attachments) { message.attachments } + + context 'with image attachments' do + before do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image.jpg') + attachment.save! + end + + it 'includes image parts' do + result = service.send(:attachment_parts, attachments) + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }) + end + end + + context 'with audio attachments' do + let(:audio_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :audio) + attachment.save! + attachment + end + + before do + allow(Messages::AudioTranscriptionService).to receive(:new).with(audio_attachment).and_return( + instance_double(Messages::AudioTranscriptionService, perform: { success: true, transcriptions: 'Audio transcription text' }) + ) + end + + it 'includes transcription text part' do + audio_attachment # trigger creation + result = service.send(:attachment_parts, attachments) + expect(result).to include({ type: 'text', text: 'Audio transcription text' }) + end + end + + context 'with other file types' do + before do + attachment = message.attachments.build(account_id: message.account_id, file_type: :file) + attachment.save! + end + + it 'includes generic attachment message' do + result = service.send(:attachment_parts, attachments) + expect(result).to include({ type: 'text', text: 'User has shared an attachment' }) + end + end + + context 'with mixed attachment types' do + let(:image_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image.jpg') + attachment.save! + attachment + end + + let(:audio_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :audio) + attachment.save! + attachment + end + + let(:document_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :file) + attachment.save! + attachment + end + + before do + allow(Messages::AudioTranscriptionService).to receive(:new).with(audio_attachment).and_return( + instance_double(Messages::AudioTranscriptionService, perform: { success: true, transcriptions: 'Audio text' }) + ) + end + + it 'includes all relevant parts' do + image_attachment # trigger creation + audio_attachment # trigger creation + document_attachment # trigger creation + + result = service.send(:attachment_parts, attachments) + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }) + expect(result).to include({ type: 'text', text: 'Audio text' }) + expect(result).to include({ type: 'text', text: 'User has shared an attachment' }) + end + end + end + + describe '#image_parts' do + let(:message) { create(:message, content: nil) } + + context 'with valid image attachments' do + let(:image1) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image1.jpg') + attachment.save! + attachment + end + + let(:image2) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: 'https://example.com/image2.jpg') + attachment.save! + attachment + end + + it 'returns image parts for all valid images' do + image1 # trigger creation + image2 # trigger creation + + image_attachments = message.attachments.where(file_type: :image) + result = service.send(:image_parts, image_attachments) + + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image1.jpg' } }) + expect(result).to include({ type: 'image_url', image_url: { url: 'https://example.com/image2.jpg' } }) + end + end + + context 'with image attachments without URLs' do + let(:image_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image, external_url: nil) + attachment.save! + attachment + end + + before do + allow(image_attachment).to receive(:file).and_return(instance_double(ActiveStorage::Attached::One, attached?: false)) + end + + it 'skips images without valid URLs' do + image_attachment # trigger creation + + image_attachments = message.attachments.where(file_type: :image) + result = service.send(:image_parts, image_attachments) + + expect(result).to be_empty + end + end + end + + describe '#get_attachment_url' do + let(:attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :image) + attachment.save! + attachment + end + + context 'when attachment has external_url' do + before { attachment.update(external_url: 'https://example.com/image.jpg') } + + it 'returns external_url' do + expect(service.send(:get_attachment_url, attachment)).to eq('https://example.com/image.jpg') + end + end + + context 'when attachment has attached file' do + before do + attachment.update(external_url: nil) + allow(attachment).to receive(:file).and_return(instance_double(ActiveStorage::Attached::One, attached?: true)) + allow(attachment).to receive(:file_url).and_return('https://local.com/file.jpg') + end + + it 'returns file_url' do + expect(service.send(:get_attachment_url, attachment)).to eq('https://local.com/file.jpg') + end + end + + context 'when attachment has no URL or file' do + before do + attachment.update(external_url: nil) + allow(attachment).to receive(:file).and_return(instance_double(ActiveStorage::Attached::One, attached?: false)) + end + + it 'returns nil' do + expect(service.send(:get_attachment_url, attachment)).to be_nil + end + end + end + + describe '#extract_audio_transcriptions' do + let(:message) { create(:message, content: nil) } + + context 'with no audio attachments' do + it 'returns empty string' do + result = service.send(:extract_audio_transcriptions, message.attachments) + expect(result).to eq('') + end + end + + context 'with successful audio transcriptions' do + let(:audio1) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :audio) + attachment.save! + attachment + end + + let(:audio2) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :audio) + attachment.save! + attachment + end + + before do + allow(Messages::AudioTranscriptionService).to receive(:new).with(audio1).and_return( + instance_double(Messages::AudioTranscriptionService, perform: { success: true, transcriptions: 'First audio text. ' }) + ) + allow(Messages::AudioTranscriptionService).to receive(:new).with(audio2).and_return( + instance_double(Messages::AudioTranscriptionService, perform: { success: true, transcriptions: 'Second audio text.' }) + ) + end + + it 'concatenates all successful transcriptions' do + audio1 # trigger creation + audio2 # trigger creation + + attachments = message.attachments + result = service.send(:extract_audio_transcriptions, attachments) + expect(result).to eq('First audio text. Second audio text.') + end + end + + context 'with failed audio transcriptions' do + let(:audio_attachment) do + attachment = message.attachments.build(account_id: message.account_id, file_type: :audio) + attachment.save! + attachment + end + + before do + allow(Messages::AudioTranscriptionService).to receive(:new).with(audio_attachment).and_return( + instance_double(Messages::AudioTranscriptionService, perform: { success: false, transcriptions: nil }) + ) + end + + it 'returns empty string for failed transcriptions' do + audio_attachment # trigger creation + + attachments = message.attachments + result = service.send(:extract_audio_transcriptions, attachments) + expect(result).to eq('') + end + end + end + + describe 'private helper methods' do + describe '#text_part' do + it 'returns correct text part format' do + result = service.send(:text_part, 'Hello world') + expect(result).to eq({ type: 'text', text: 'Hello world' }) + end + end + + describe '#image_part' do + it 'returns correct image part format' do + result = service.send(:image_part, 'https://example.com/image.jpg') + expect(result).to eq({ type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }) + end + end + end +end \ No newline at end of file From 3af9e8714a3c7d4ecc844c117af0a1ca3b6209e4 Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Thu, 19 Jun 2025 13:00:59 +0530 Subject: [PATCH 10/11] fix the spec for conversation llm formatter --- .../open_ai_message_builder_service_spec.rb | 2 +- .../conversation_llm_formatter_spec.rb | 35 ++----------------- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb b/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb index 1cbc41955..13c29f756 100644 --- a/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb +++ b/spec/enterprise/services/captain/open_ai_message_builder_service_spec.rb @@ -306,4 +306,4 @@ RSpec.describe Captain::OpenAiMessageBuilderService do end end end -end \ No newline at end of file +end diff --git a/spec/services/llm_formatter/conversation_llm_formatter_spec.rb b/spec/services/llm_formatter/conversation_llm_formatter_spec.rb index 9f570d23d..93fec14f7 100644 --- a/spec/services/llm_formatter/conversation_llm_formatter_spec.rb +++ b/spec/services/llm_formatter/conversation_llm_formatter_spec.rb @@ -12,9 +12,7 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do "Conversation ID: ##{conversation.display_id}", "Channel: #{conversation.inbox.channel.name}", 'Message History:', - 'No messages in this conversation', - 'Conversation Attributes:', - '' + 'No messages in this conversation' ].join("\n") expect(formatter.format).to eq(expected_output) @@ -43,8 +41,6 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do 'Message History:', 'User: Hello, I need help', 'Support agent: How can I assist you today?', - '', - 'Conversation Attributes:', '' ].join("\n") @@ -59,38 +55,11 @@ RSpec.describe LlmFormatter::ConversationLlmFormatter do "Channel: #{conversation.inbox.channel.name}", 'Message History:', 'No messages in this conversation', - "Contact Details: #{conversation.contact.to_llm_text}", - 'Conversation Attributes:', - '' + "Contact Details: #{conversation.contact.to_llm_text}" ].join("\n") expect(formatter.format(include_contact_details: true)).to eq(expected_output) end end - - context 'when conversation has custom attributes' do - it 'includes formatted custom attributes in the output' do - create( - :custom_attribute_definition, - account: account, - attribute_display_name: 'Order ID', - attribute_key: 'order_id', - attribute_model: :conversation_attribute - ) - - conversation.update(custom_attributes: { 'order_id' => '12345' }) - - expected_output = [ - "Conversation ID: ##{conversation.display_id}", - "Channel: #{conversation.inbox.channel.name}", - 'Message History:', - 'No messages in this conversation', - 'Conversation Attributes:', - 'Order ID: 12345' - ].join("\n") - - expect(formatter.format).to eq(expected_output) - end - end end end From 245e00d7a82d342b80ea7493968599a6e22f83ec Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Thu, 19 Jun 2025 17:13:03 +0530 Subject: [PATCH 11/11] fix the spec for conversation llm formatter --- .../app/jobs/captain/conversation/response_builder_job.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/enterprise/app/jobs/captain/conversation/response_builder_job.rb b/enterprise/app/jobs/captain/conversation/response_builder_job.rb index bceece6c1..431945896 100644 --- a/enterprise/app/jobs/captain/conversation/response_builder_job.rb +++ b/enterprise/app/jobs/captain/conversation/response_builder_job.rb @@ -1,6 +1,4 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob - include Captain::ChatHelper - MAX_MESSAGE_LENGTH = 10_000 retry_on ActiveStorage::FileNotFoundError, attempts: 3 @@ -58,7 +56,7 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob end def prepare_multimodal_message_content(message) - OpenAiMessageBuilderService.new(message: message).generate_content + Captain::OpenAiMessageBuilderService.new(message: message).generate_content end def handoff_requested?