Skip to content

Deploying CiviCRM

Introduction

CiviCRM is a powerful, open-source constituent relationship management (CRM) platform designed specifically for nonprofits, advocacy groups, and civic organizations. It provides comprehensive tools for managing contacts, donations, memberships, events, email campaigns, case management, and grant tracking—all in one unified platform. Built on PHP and supporting multiple database backends, CiviCRM integrates seamlessly with popular content management systems like WordPress, Drupal, and Joomla.

Deploying CiviCRM on Klutch.sh gives you a reliable, scalable platform for hosting your nonprofit’s CRM infrastructure with production-grade performance, persistent storage for critical constituent data, and streamlined deployment workflows. Whether you’re managing donor relationships, coordinating volunteers, organizing advocacy campaigns, or tracking program outcomes, this guide walks you through deploying CiviCRM using Docker to ensure a reproducible, secure, and maintainable setup.

This comprehensive guide covers everything you need to deploy CiviCRM successfully on Klutch.sh: from creating your Dockerfile to configuring database connections, setting up persistent volumes for uploads and data, managing environment variables for security, and implementing production best practices for reliable nonprofit operations.


Prerequisites

Before you begin deploying CiviCRM on Klutch.sh, ensure you have the following:

  • A Klutch.sh account (sign up here)
  • A GitHub account and repository for your CiviCRM project
  • Basic familiarity with Docker, environment variables, and database management
  • A MySQL 5.7+ or MariaDB 10.2+ database (you can provision one on Klutch.sh or use an external managed database service)
  • Understanding of PHP applications and web servers (helpful but not required)

What You’ll Deploy

By the end of this guide, you’ll have:

  • A fully functional CiviCRM installation running on Klutch.sh
  • Persistent storage for file uploads, attachments, custom data, and application assets
  • Database connectivity to MySQL or MariaDB for storing constituent and organizational data
  • Secure environment variable configuration for credentials and API keys
  • Production-ready setup with proper permissions and security configurations
  • A Docker-based deployment that’s reproducible and easy to maintain

Understanding CiviCRM Architecture

CiviCRM is built on PHP and requires:

  • PHP 7.3 or higher (PHP 7.4+ recommended) with required extensions (MySQLi/PDO, Multibyte String, SOAP, cURL, Zip, GD, DOM, XML)
  • Web server (Apache with mod_rewrite or Nginx)
  • MySQL 5.7+ or MariaDB 10.2+ database for storing all CRM data
  • File storage for uploads, attachments, templates, and custom data
  • Composer for dependency management (when building from source)

CiviCRM typically runs on port 80 (HTTP) when using Apache, which we’ll configure for routing on Klutch.sh. For this deployment, we’ll use the internal port 80 for HTTP traffic routing.


1. Prepare Your CiviCRM Repository

    1. Create a new GitHub repository for your CiviCRM deployment. This will house your Dockerfile and any custom configuration.

    2. In your repository root, you’ll create a Dockerfile that defines the container image for CiviCRM. This ensures reproducible builds and consistent deployments.

    3. Keep sensitive data (database credentials, API keys, SMTP passwords) out of your repository. We’ll use Klutch.sh environment variables to manage secrets securely.

    4. Organize your repository structure:

      civicrm-deployment/
      ├── Dockerfile
      ├── .dockerignore
      ├── docker-compose.yml (for local development only)
      ├── config/
      │ └── civicrm.settings.php.template (optional)
      └── README.md
    5. Create a .dockerignore file to exclude unnecessary files from the Docker build:

      .git
      .github
      .env
      .env.local
      node_modules
      */temp/*
      */cache/*
      */logs/*

For more details on setting up your repository and connecting to GitHub, refer to the Klutch.sh Quick Start Guide.


2. Sample Dockerfile for CiviCRM

Below is a production-ready Dockerfile that sets up CiviCRM with Apache, all required PHP extensions, and proper permissions. This Dockerfile uses the official CiviCRM installation method with WordPress as the base CMS (you can adapt this for Drupal or standalone installations).

Option 1: CiviCRM with WordPress

FROM wordpress:php8.1-apache
# Set working directory
WORKDIR /var/www/html
# Install system dependencies and required PHP extensions
RUN apt-get update && apt-get install -y \
wget \
unzip \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
libxml2-dev \
libonig-dev \
libcurl4-openssl-dev \
git \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
mysqli \
pdo_mysql \
zip \
curl \
soap \
mbstring \
xml \
dom \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Enable Apache modules required for CiviCRM
RUN a2enmod rewrite headers expires ssl
# Set recommended PHP settings for CiviCRM
RUN { \
echo 'memory_limit = 256M'; \
echo 'upload_max_filesize = 32M'; \
echo 'post_max_size = 32M'; \
echo 'max_execution_time = 300'; \
echo 'max_input_time = 300'; \
echo 'max_input_vars = 3000'; \
} > /usr/local/etc/php/conf.d/civicrm.ini
# Set proper file permissions
RUN chown -R www-data:www-data /var/www/html
# Expose port 80 for HTTP traffic
EXPOSE 80
# Start Apache
CMD ["apache2-foreground"]

Option 2: Standalone CiviCRM with Nginx and PHP-FPM

For a more lightweight deployment without a CMS:

FROM php:8.1-fpm
# Set working directory
WORKDIR /var/www/html
# Install system dependencies
RUN apt-get update && apt-get install -y \
nginx \
wget \
unzip \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
libxml2-dev \
libonig-dev \
libcurl4-openssl-dev \
git \
supervisor \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
mysqli \
pdo_mysql \
zip \
curl \
soap \
mbstring \
xml \
dom \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Download and install CiviCRM
ARG CIVICRM_VERSION=5.69.2
RUN cd /tmp && \
wget https://download.civicrm.org/civicrm-${CIVICRM_VERSION}-wordpress.zip && \
unzip civicrm-${CIVICRM_VERSION}-wordpress.zip -d /var/www/html/ && \
rm civicrm-${CIVICRM_VERSION}-wordpress.zip
# Configure Nginx
COPY nginx.conf /etc/nginx/sites-available/default
# Set PHP configuration for CiviCRM
RUN { \
echo 'memory_limit = 256M'; \
echo 'upload_max_filesize = 32M'; \
echo 'post_max_size = 32M'; \
echo 'max_execution_time = 300'; \
echo 'max_input_time = 300'; \
echo 'max_input_vars = 3000'; \
} > /usr/local/etc/php/conf.d/civicrm.ini
# Configure supervisor to run both PHP-FPM and Nginx
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Set proper permissions
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

3. Required Configuration Files

nginx.conf (for Option 2)

server {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html;
client_max_body_size 32M;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}

supervisord.conf (for Option 2)

[supervisord]
nodaemon=true
user=root
[program:php-fpm]
command=/usr/local/sbin/php-fpm
autostart=true
autorestart=true
stdout_logfile=/var/log/php-fpm.log
stderr_logfile=/var/log/php-fpm-error.log
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/var/log/nginx.log
stderr_logfile=/var/log/nginx-error.log

4. Persistent Storage and Volumes

CiviCRM requires persistent storage for several critical directories:

  • File uploads and attachments: /var/www/html/wp-content/uploads/civicrm (WordPress) or /var/www/html/sites/default/files/civicrm (Drupal)
  • Templates cache: CiviCRM template compilation directory
  • Custom data and extensions: Custom PHP extensions and configurations
    1. In the Klutch.sh dashboard at klutch.sh/app, navigate to your project and go to the Volumes section.

    2. Create a new persistent volume with an appropriate size (start with 10GB, adjust based on your expected data growth).

    3. For WordPress-based CiviCRM, attach the volume to mount path: /var/www/html/wp-content/uploads

    4. For standalone installations, attach to: /var/www/html/sites/default/files

    5. You may also want separate volumes for:

      • Configuration files: /var/www/html/sites/default (mount path)
      • Size: 1GB

Important: Ensure the directories within the container have proper permissions (www-data:www-data ownership) after mounting volumes.

For more details on managing persistent storage, see the Klutch.sh Volumes Guide.


5. Database Configuration

CiviCRM requires a MySQL or MariaDB database. You have two options:

Option A: Use Klutch.sh Managed MySQL

    1. In the Klutch.sh dashboard, navigate to the Databases section
    2. Create a new MySQL instance
    3. Note the connection details (host, port, username, password, database name)
    4. The internal database host will be accessible from your CiviCRM app

See the MySQL deployment guide for detailed instructions.

Option B: Use External Managed MySQL

Use a managed MySQL service from your cloud provider (AWS RDS, Google Cloud SQL, Azure Database for MySQL) and note the connection credentials.


6. Environment Variables and Configuration

Set these environment variables in your Klutch.sh app settings at klutch.sh/app:

Required Database Variables

WORDPRESS_DB_HOST=your-mysql-host
WORDPRESS_DB_USER=civicrm_user
WORDPRESS_DB_PASSWORD=your-secure-password
WORDPRESS_DB_NAME=civicrm_db

CiviCRM-Specific Variables

CIVICRM_DB_HOST=your-mysql-host
CIVICRM_DB_USER=civicrm_user
CIVICRM_DB_PASSWORD=your-secure-password
CIVICRM_DB_NAME=civicrm_db
# Site configuration
CIVICRM_SITE_KEY=generate-a-random-32-character-key
CIVICRM_SITE_URL=https://example-app.klutch.sh
# Email/SMTP Configuration (optional but recommended)
CIVICRM_SMTP_SERVER=smtp.example.com
CIVICRM_SMTP_PORT=587
CIVICRM_SMTP_USERNAME=your-smtp-user
CIVICRM_SMTP_PASSWORD=your-smtp-password
CIVICRM_SMTP_AUTH=true

Optional Performance and Security Variables

# Memory and resource limits
PHP_MEMORY_LIMIT=256M
PHP_MAX_EXECUTION_TIME=300
PHP_UPLOAD_MAX_FILESIZE=32M
# Cron configuration
CIVICRM_CRON_KEY=generate-another-random-key
# Logging
CIVICRM_LOG_LEVEL=error

Security Note: Always mark sensitive variables (passwords, API keys, SMTP credentials) as secrets in the Klutch.sh dashboard. Never commit secrets to your repository.


7. Deploying to Klutch.sh

    1. Push your repository (including Dockerfile and any configuration files) to GitHub.

    2. Log in to the Klutch.sh dashboard at klutch.sh/app.

    3. Create a new project (if you haven’t already) and give it a descriptive name like “CiviCRM Production”.

    4. Within your project, create a new app:

      • Connect your GitHub repository
      • Klutch.sh will automatically detect the Dockerfile in the root directory
      • Set the app name (e.g., “civicrm-app”)
    5. Configure the traffic settings:

      • Select HTTP traffic type
      • The internal port for traffic routing should be set to 80 (this is where Apache or Nginx listens inside the container)
    6. Attach persistent volumes:

      • Add the volume you created earlier
      • Set the mount path to /var/www/html/wp-content/uploads (or your configured path)
      • Specify the volume size as configured earlier
    7. Configure environment variables:

      • Add all the database, CiviCRM, and optional variables from section 6
      • Mark all passwords and sensitive keys as secrets
    8. (Optional) Configure custom domain:

    9. Review your configuration and click Create to deploy.

    10. Klutch.sh will build your Docker image and start the container. Monitor the build logs for any errors.

    11. Once deployed, visit your app URL (e.g., https://example-app.klutch.sh) to access CiviCRM.


8. Post-Deployment: CiviCRM Installation

After your container is running, complete the CiviCRM installation:

    1. Navigate to your app URL in a web browser: https://example-app.klutch.sh

    2. If using WordPress, first complete the WordPress installation:

      • Follow the WordPress setup wizard
      • Create an admin account
      • Complete the basic site configuration
    3. Install the CiviCRM plugin:

      • For WordPress: Download the CiviCRM plugin from civicrm.org
      • Upload and activate the plugin through the WordPress admin interface
      • Navigate to the CiviCRM installer URL: https://example-app.klutch.sh/wp-admin/admin.php?page=civicrm-install
    4. Run the CiviCRM installer:

      • Verify that all system requirements are met (PHP extensions, file permissions)
      • Enter your database credentials (these should match your environment variables)
      • Set the site name and default language
      • Complete the installation
    5. Configure CiviCRM settings:

      • Set up your organization information
      • Configure email settings (SMTP)
      • Set up payment processors if accepting donations
      • Configure user permissions and roles
    6. Test core functionality:

      • Create a test contact
      • Send a test email
      • Test file uploads
      • Verify database connectivity

9. Getting Started with CiviCRM

Once installation is complete, here are some essential first steps:

Create Your First Contact

  1. Navigate to ContactsNew Individual
  2. Fill in basic contact information (name, email, phone)
  3. Save the contact

Set Up Custom Fields

  1. Go to AdministerCustom Data and ScreensCustom Fields
  2. Create custom field sets for your organization’s specific needs
  3. Add fields for donor information, volunteer data, or program-specific details

Configure Email Settings

  1. Navigate to AdministerSystem SettingsOutbound Email
  2. Enter your SMTP server details
  3. Send a test email to verify configuration

Import Existing Data

  1. Go to ContactsImport Contacts
  2. Upload a CSV file with your existing contact data
  3. Map CSV columns to CiviCRM fields
  4. Complete the import process

10. Production Best Practices

Security

  • Always use HTTPS for your CiviCRM deployment (Klutch.sh provides this automatically)
  • Keep PHP, CiviCRM, and all extensions up to date
  • Implement strong password policies for admin users
  • Regularly review user permissions and roles
  • Enable two-factor authentication for admin accounts
  • Restrict access to sensitive data and financial information
  • Use secure SMTP with TLS/SSL for email delivery

Backups

  • Implement regular database backups (daily recommended for production)
  • Back up persistent volumes containing file uploads and custom data
  • Test restore procedures regularly
  • Store backups in a separate location from your production environment
  • Consider automated backup solutions for critical data

Performance Optimization

  • Enable CiviCRM caching mechanisms
  • Optimize database queries and indexes
  • Use a CDN for static assets if serving a large user base
  • Monitor resource usage (CPU, memory, disk) in the Klutch.sh dashboard
  • Consider scaling up instance size for larger organizations
  • Implement database connection pooling for high-traffic deployments

Monitoring and Maintenance

  • Set up monitoring for database connections and application health
  • Monitor disk usage for persistent volumes and expand as needed
  • Review CiviCRM logs regularly for errors or warnings
  • Schedule regular maintenance windows for updates
  • Test updates in a staging environment before production deployment

Data Management

  • Implement data retention policies
  • Archive old records and activities periodically
  • Clean up duplicate contacts regularly
  • Optimize database tables monthly
  • Export critical data for offline backup

11. Customizing CiviCRM

Installing Extensions

  1. Navigate to AdministerSystem SettingsExtensions
  2. Browse available extensions or upload custom ones
  3. Install extensions that meet your organization’s needs
  4. Configure extension settings as required

Custom Templates and Themes

For WordPress-based installations:

  • Customize the WordPress theme to match your branding
  • Use CiviCRM’s template override system for custom layouts
  • Store custom templates in your persistent volume

API Access

CiviCRM provides a robust REST API for integrations:

  • Generate API keys in AdministerUsers and PermissionsAPI Keys
  • Use the API for custom integrations with other systems
  • Implement webhooks for real-time data synchronization

12. Troubleshooting Common Issues

Database Connection Errors

Symptoms: Error messages about database connectivity or “Cannot connect to database”

Solutions:

  • Verify database credentials in environment variables match your MySQL instance
  • Ensure the CiviCRM app can reach the database host (check network connectivity)
  • Confirm the database user has proper permissions
  • Check MySQL logs for connection attempts and errors

File Permission Issues

Symptoms: Unable to upload files, “Permission denied” errors, cache errors

Solutions:

  • Verify persistent volumes are properly mounted
  • Ensure the web server user (www-data) owns the upload directories
  • Run chown -R www-data:www-data /var/www/html/wp-content/uploads inside the container
  • Check that volume mount points have proper read/write permissions

Memory Limit Exceeded

Symptoms: “Allowed memory size exhausted” errors, especially during large imports

Solutions:

  • Increase PHP_MEMORY_LIMIT environment variable to 512M or higher
  • Use the Nixpacks runtime environment variable: NIXPACKS_PHP_MEMORY_LIMIT=512M
  • For very large operations, temporarily increase limits and scale back after completion

Email Delivery Issues

Symptoms: Emails not being sent, timeout errors, SMTP authentication failures

Solutions:

  • Verify SMTP credentials and server settings
  • Test SMTP connection using the CiviCRM email settings page
  • Ensure SMTP port is accessible from your Klutch.sh deployment
  • Check spam/junk folders for test emails
  • Review email logs in CiviCRM for detailed error messages

Application Performance Issues

Symptoms: Slow page loads, timeouts, unresponsive interface

Solutions:

  • Enable CiviCRM caching in AdministerSystem SettingsCleanup Caches and Update Paths
  • Review and optimize custom reports and searches
  • Consider upgrading instance size in Klutch.sh dashboard
  • Optimize database queries and add appropriate indexes
  • Clear CiviCRM caches regularly

13. Scaling and Advanced Configurations

Horizontal Scaling

For organizations with high traffic or large user bases:

  • Consider separating the database onto a dedicated instance
  • Use external object storage (S3-compatible) for file uploads
  • Implement read replicas for the database to distribute query load
  • Use Redis or Memcached for session and cache storage

Advanced Database Configuration

For optimal performance with large datasets:

  • Configure database connection pooling
  • Implement regular database optimization and VACUUM operations
  • Set up database monitoring and slow query logging
  • Consider partitioning large tables for better performance

Custom Buildtime Configuration

If you need to customize the build process, use Nixpacks environment variables:

  • NIXPACKS_PHP_VERSION=8.1 - Specify PHP version
  • NIXPACKS_BUILD_CMD=custom-build-script.sh - Custom build command
  • NIXPACKS_START_CMD=custom-start-script.sh - Custom start command

14. Integration Examples

WordPress Integration

CiviCRM integrates seamlessly with WordPress:

  • Use CiviCRM shortcodes in WordPress pages
  • Create custom contribution pages
  • Display upcoming events on your website
  • Synchronize WordPress users with CiviCRM contacts

Drupal Integration

For Drupal-based deployments:

  • Use CiviCRM Views integration for custom displays
  • Implement Drupal Rules for automation
  • Leverage Drupal’s permissions system with CiviCRM
  • Create custom content types linked to CiviCRM entities

External Service Integrations

  • Payment Processors: PayPal, Stripe, Authorize.Net
  • Email Marketing: Mailchimp, SendGrid
  • Accounting: QuickBooks, Xero
  • Communication: Twilio for SMS, Zoom for virtual events

15. Migrating Existing CiviCRM Installation

If you’re migrating from an existing CiviCRM installation:

    1. Export existing data:

      • Create a full database backup using mysqldump
      • Archive all file uploads and custom extensions
      • Export any custom templates or configurations
    2. Prepare your Klutch.sh environment:

      • Set up the database instance
      • Create persistent volumes for uploads
      • Configure environment variables
    3. Import database:

      • Restore the database backup to your new MySQL instance
      • Update site configuration paths in civicrm.settings.php
      • Update database connection strings
    4. Upload files:

      • Transfer file uploads to the persistent volume
      • Ensure proper permissions on all directories
    5. Update configuration:

      • Run CiviCRM’s configuration update utility
      • Clear all caches
      • Verify all paths and URLs are correct
    6. Test thoroughly:

      • Verify contact data integrity
      • Test email functionality
      • Confirm payment processing works
      • Check custom reports and searches

Resources


Deploying CiviCRM on Klutch.sh provides your nonprofit organization with a robust, scalable platform for constituent relationship management. With Docker-based deployment, persistent storage, and production-grade infrastructure, you can focus on your mission while Klutch.sh handles the hosting complexity. For questions or support, reach out to the Klutch.sh community or consult the CiviCRM forums for application-specific guidance.