Deploying Concrete5 CMS
Introduction
Concrete5 is an open-source, PHP-based content management system that stands out for its intuitive interface and powerful in-context editing capabilities. Unlike many CMSs that separate content editing from page preview, Concrete5 allows you to edit content directly on the page you’re viewing—a feature that significantly reduces the learning curve for content editors.
Built with flexibility in mind, Concrete5 is designed to serve businesses of all sizes. Whether you’re running a small corporate website, a large-scale e-commerce platform, or a complex multi-site installation, Concrete5 provides the tools you need without unnecessary complexity.
Key Strengths of Concrete5:
In-Context Editing: The standout feature that makes Concrete5 unique. Edit your website content directly in the page editor, seeing exactly how it will appear to visitors.
User-Friendly Interface: A clean, intuitive dashboard that doesn’t require extensive training. Content editors can focus on creating rather than learning complicated workflows.
Enterprise-Grade CMS: Despite its ease of use, Concrete5 is built on solid architecture with version control, workflow management, and granular permission controls.
Extensible Architecture: A robust system for extending functionality through add-ons, themes, and custom code. The community has built thousands of add-ons.
Powerful Content Management: Support for multiple sites, complex page hierarchies, version control, scheduling, and workflow approval systems.
Flexible Theming: Create responsive, modern themes using HTML, CSS, and JavaScript without deep Concrete5 knowledge.
Multi-Language Support: Built-in internationalization for managing content in multiple languages.
SEO-Friendly: Clean URL structures, XML sitemaps, meta tag management, and structured data support out of the box.
This guide walks you through deploying Concrete5 on Klutch.sh using Docker. You’ll learn how to configure the application with persistent storage for uploads and content, set up the database, optimize performance, implement security measures, and troubleshoot common deployment issues.
Prerequisites
Before deploying Concrete5 to Klutch.sh, ensure you have:
- A Klutch.sh account with dashboard access
- A GitHub account for repository hosting
- Docker installed locally for testing (optional but recommended)
- Basic PHP and web server knowledge
- Understanding of MySQL/PostgreSQL databases
- A domain name for your site (recommended for production)
- SMTP server credentials for email (optional but recommended)
- Basic understanding of content management systems
Understanding Concrete5 Architecture
Technology Stack
Concrete5 is built on proven web technologies:
Backend:
- PHP 7.4+ with object-oriented architecture
- MySQL 5.7+ or PostgreSQL 10+ for data storage
- Doctrine ORM for database abstraction
- Zend Framework components
- RESTful API with JSON responses
Frontend:
- HTML5 and CSS3 for responsive design
- jQuery and modern JavaScript
- Bootstrap integration for default theme
- Built-in WYSIWYG editor (CKEditor)
File Storage:
- Local filesystem for content uploads
- File versioning and management
- Image optimization and thumbnails
- Media library organization
Core Components
Dashboard: Administrative interface for managing site configuration, users, and content
Page Builder: Visual editor for creating page layouts without code
Content Library: Manage all images, videos, and downloadable files
Users and Permissions: Granular access control with role-based permissions
Add-ons Marketplace: Thousands of community and commercial extensions
Theming System: Template-based design with full Concrete5 API access
Installation and Setup
Step 1: Create Your Project Directory
Start with a dedicated directory for your Concrete5 deployment:
mkdir concrete5-deploymentcd concrete5-deploymentgit initStep 2: Create Directory Structure
Set up the necessary directories:
mkdir -p public html config cache var/filesYour project structure will look like:
concrete5-deployment/├── Dockerfile├── docker-entrypoint.sh├── .dockerignore├── .gitignore├── public/│ └── (web root)├── config/│ └── (configuration files)└── var/ └── files/ └── (user uploads - persistent)Step 3: Create the Dockerfile
Create a Dockerfile in your project root:
# Use official PHP image with ApacheFROM php:8.2-apache
# Install system dependenciesRUN apt-get update && apt-get install -y --no-install-recommends \ mysql-client \ postgresql-client \ curl \ git \ zip \ unzip \ libzip-dev \ libjpeg-dev \ libpng-dev \ libfreetype6-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) \ gd \ mysqli \ pdo \ pdo_mysql \ pdo_pgsql \ zip \ bcmath \ intl \ opcache \ && rm -rf /var/lib/apt/lists/*
# Install ComposerRUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Enable Apache modulesRUN a2enmod rewrite \ && a2enmod headers \ && a2enmod expires
# Set working directoryWORKDIR /var/www/html
# Copy Apache configurationCOPY apache.conf /etc/apache2/sites-available/000-default.conf
# Copy entrypoint scriptCOPY docker-entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Create necessary directoriesRUN mkdir -p /var/www/html/application/files \ && mkdir -p /var/www/html/packages \ && mkdir -p /var/www/html/updates
# Set permissionsRUN chown -R www-data:www-data /var/www/html
# Expose port 80EXPOSE 80
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost/ || exit 1
# Use entrypoint scriptENTRYPOINT ["docker-entrypoint.sh"]CMD ["apache2-foreground"]Step 4: Create Apache Configuration
Create apache.conf for proper URL rewriting:
<VirtualHost *:80> ServerAdmin admin@localhost DocumentRoot /var/www/html
<Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory>
# Enable mod_rewrite for pretty URLs <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
# Logging ErrorLog ${APACHE_LOG_DIR}/concrete5-error.log CustomLog ${APACHE_LOG_DIR}/concrete5-access.log combined
# Performance headers <IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" </IfModule>
# Security headers Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin"</VirtualHost>Step 5: Create Entrypoint Script
Create docker-entrypoint.sh for initialization:
#!/bin/bashset -e
echo "Starting Concrete5 initialization..."
# Wait for database to be readyif [ ! -z "$DB_HOST" ]; then echo "Waiting for database at $DB_HOST:$DB_PORT..."
until nc -z "$DB_HOST" "${DB_PORT:-3306}" 2>/dev/null; do echo "Database is unavailable - sleeping" sleep 2 done
echo "Database is available"fi
# Download and install Concrete5 if not already presentif [ ! -f "/var/www/html/concrete/bootstrap.php" ]; then echo "Installing Concrete5..."
cd /var/www/html
# Use Composer to create new Concrete5 project # This installs Concrete5 from composer if [ -f "composer.json" ]; then composer install --no-interaction --prefer-dist --optimize-autoloader fifi
# Set correct permissionsecho "Setting permissions..."chown -R www-data:www-data /var/www/html/applicationchown -R www-data:www-data /var/www/html/packageschown -R www-data:www-data /var/www/html/updates
# Create config directory if neededmkdir -p /var/www/html/application/configchown -R www-data:www-data /var/www/html/application/config
echo "Concrete5 initialization complete. Starting Apache..."
# Execute the main commandexec "$@"Make it executable:
chmod +x docker-entrypoint.shStep 6: Create .dockerignore
Create .dockerignore to exclude unnecessary files:
.git.gitignore.env.env.local*.lognode_modulesnpm-debug.log.DS_Store.vscode.ideaREADME.mddocs/tests/updates/Step 7: Create .gitignore
Create .gitignore to prevent committing sensitive files:
# Environment.env.env.local.env.*.local
# Concrete5 uploadsapplication/files/*application/config/database.phpapplication/config/site.php
# Composercomposer.lockvendor/
# Logs*.loglogs/
# Cachetmp/cache/updates/
# OS.DS_StoreThumbs.db
# IDE.vscode/.idea/*.swp*.swo
# Nodenode_modules/npm-debug.logStep 8: Create Composer Configuration
Create composer.json for Concrete5:
{ "name": "concrete5/concrete5", "description": "Concrete5 CMS Installation", "require": { "php": ">=7.4", "concrete5/core": "^9.1" }, "require-dev": { "phpunit/phpunit": "^9.5" }, "config": { "platform": { "php": "8.2" }, "optimize-autoloader": true }, "scripts": { "post-install-cmd": [], "post-update-cmd": [] }}Step 9: Local Testing (Optional)
Test your Concrete5 setup locally:
# Build the imagedocker build -t concrete5-test .
# Create a test networkdocker network create concrete5-network
# Run MySQL for testingdocker run -d \ --name concrete5-mysql \ --network concrete5-network \ -e MYSQL_ROOT_PASSWORD=root_password \ -e MYSQL_DATABASE=concrete5 \ -e MYSQL_USER=concrete5_user \ -e MYSQL_PASSWORD=concrete5_pass \ mysql:8.0
# Wait for MySQLsleep 30
# Run Concrete5docker run -d \ --name concrete5-app \ --network concrete5-network \ -p 8080:80 \ -e DB_HOST=concrete5-mysql \ -e DB_USER=concrete5_user \ -e DB_PASSWORD=concrete5_pass \ -e DB_NAME=concrete5 \ -e DB_PORT=3306 \ -v $(pwd)/application:/var/www/html/application \ concrete5-test
# Access the application# Open http://localhost:8080 in your browser
# View logsdocker logs -f concrete5-app
# Cleanupdocker stop concrete5-app concrete5-mysqldocker rm concrete5-app concrete5-mysqldocker network rm concrete5-networkStep 10: Commit to GitHub
Push your configuration to GitHub:
git add Dockerfile docker-entrypoint.sh apache.conf composer.json .dockerignore .gitignoregit commit -m "Add Concrete5 Docker configuration"git branch -M maingit remote add origin https://github.com/yourusername/concrete5-deployment.gitgit push -u origin mainDeploying to Klutch.sh
Now let’s deploy Concrete5 to Klutch.sh with proper database configuration and persistent storage.
Deployment Steps
-
Access Klutch.sh Dashboard
Navigate to klutch.sh/app and sign in with your GitHub account.
-
Create a New Project
In the Projects section, click “Create Project” and name it something like “Concrete5 Website” or “CMS Platform”.
-
Create a New App
Within your project, click “Create App” to begin configuring your Concrete5 deployment.
-
Connect Your Repository
- Select GitHub as your Git source
- Choose your repository with the Concrete5 Dockerfile
- Select the branch to deploy (typically
main)
Klutch.sh will automatically detect the Dockerfile in your repository root.
-
Configure Traffic Settings
- Traffic Type: Select HTTP (Concrete5 serves web traffic via HTTP)
- Internal Port: Set to
80(Apache’s default port)
-
Configure Environment Variables
Add the following environment variables to configure your Concrete5 instance:
Database Configuration:
Terminal window # MySQL configurationDB_HOST=your-mysql-host.comDB_PORT=3306DB_USER=concrete5_userDB_PASSWORD=your-secure-database-passwordDB_NAME=concrete5# Or PostgreSQLDB_DRIVER=postgresDB_HOST=your-postgres-host.comDB_PORT=5432DB_USER=concrete5_userDB_PASSWORD=your-secure-database-passwordDB_NAME=concrete5Application Configuration:
Terminal window # Site URL (your Klutch.sh app URL)APP_URL=https://example-app.klutch.sh# Application environmentAPP_ENV=production# Debug mode (disable in production)APP_DEBUG=false# Security key for sessions and encryptionAPP_KEY=your-random-security-key-here# Generate with: php -r "echo bin2hex(random_bytes(32));"Email Configuration (SMTP for notifications):
Terminal window MAIL_DRIVER=smtpMAIL_HOST=smtp.example.comMAIL_PORT=587MAIL_USERNAME=your-email@example.comMAIL_PASSWORD=your-email-passwordMAIL_ENCRYPTION=tlsMAIL_FROM_ADDRESS=noreply@yourdomain.comMAIL_FROM_NAME="Concrete5 Site"Additional Configuration:
Terminal window # LoggingLOG_LEVEL=warningLOG_CHANNEL=stack# Cache configurationCACHE_DRIVER=file# Session settingsSESSION_DRIVER=fileSESSION_LIFETIME=120# File upload limits (in bytes)MAX_UPLOAD_SIZE=104857600# 100MB# PHP settingsPHP_MEMORY_LIMIT=512MPHP_MAX_EXECUTION_TIME=300Security Recommendations:
- Generate a strong, unique
APP_KEY - Use a strong database password
- Never commit
.envfiles to Git - Keep
APP_DEBUG=falsein production - Use HTTPS for your site (Klutch.sh provides this automatically)
- Generate a strong, unique
-
Configure Persistent Storage
Concrete5 needs persistent volumes for user uploads, theme files, and application data:
Volume 1 - Application Files:
- Mount Path:
/var/www/html/application/files - Size: 10-50 GB (depending on expected uploads)
Volume 2 - Themes and Packages:
- Mount Path:
/var/www/html/packages - Size: 5-10 GB
Important: Persistent volumes are essential. Without them, all user uploads and customizations will be lost when the container restarts.
- Mount Path:
-
Configure Compute Resources
Choose appropriate resources based on expected traffic:
Small Site (< 1,000 monthly visitors):
- CPU: 1 core
- RAM: 1 GB
- Suitable for: Personal blogs, small business sites
Medium Site (1,000-10,000 monthly visitors):
- CPU: 2 cores
- RAM: 2 GB
- Suitable for: Growing businesses, community sites
Large Site (10,000-100,000 monthly visitors):
- CPU: 4 cores
- RAM: 4 GB
- Suitable for: Large organizations, popular sites
Enterprise (100,000+ monthly visitors):
- CPU: 8+ cores
- RAM: 8+ GB
- Suitable for: Enterprise deployments, high-traffic sites
You can scale up or down based on actual usage patterns.
-
Deploy the Application
Click “Create” to start the deployment. Klutch.sh will:
- Clone your repository
- Build the Docker image
- Configure environment variables
- Set up persistent volumes
- Start the Concrete5 container
- Assign a public URL (e.g.,
example-app.klutch.sh) - Configure automatic HTTPS with SSL certificates
Deployment typically takes 3-5 minutes.
-
Monitor Deployment Progress
Track the deployment:
- Go to the Deployments tab
- View real-time build logs
- Wait for status to show “Running”
- Check for any errors or warnings
-
Complete Concrete5 Installation
Once deployed, complete the Concrete5 setup wizard:
- Navigate to your app URL:
https://example-app.klutch.sh - You should see the Concrete5 installation wizard
- Follow the setup steps:
- Accept the license
- Verify database configuration
- Create admin user account
- Configure basic site settings
- The wizard will initialize the database with required tables
- Complete the setup to access the dashboard
- Navigate to your app URL:
-
Verify Installation
After setup completes, verify everything is working:
- Access the admin dashboard:
https://example-app.klutch.sh/dashboard - Log in with your admin credentials
- Check that the home page loads
- Test creating a page
- Verify file uploads work (try uploading an image)
- Check that the theme loads properly
- Test the website from a different browser to confirm it works
- Access the admin dashboard:
Database Configuration
Concrete5 requires a database for storing content, users, and configuration. You have several options:
Option 1: External Database Service
Use a managed database service for ease of management:
Recommended Providers:
Setup Process:
- Create database instance with your provider
- Create database named
concrete5 - Create user with full permissions
- Note connection details (host, port, user, password)
- Add to environment variables in Klutch.sh
Option 2: MySQL/PostgreSQL on Klutch.sh
Deploy the database separately on Klutch.sh:
- Create a new app using MySQL or PostgreSQL image
- Configure with persistent storage
- Set a secure root password
- Use TCP traffic on port 8000
- Connect Concrete5 app to database via internal URL
Database Setup
Create Database and User (if using manual setup):
-- For MySQLCREATE DATABASE concrete5 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE USER 'concrete5_user'@'%' IDENTIFIED BY 'secure_password';GRANT ALL PRIVILEGES ON concrete5.* TO 'concrete5_user'@'%';FLUSH PRIVILEGES;
-- For PostgreSQLCREATE DATABASE concrete5;CREATE USER concrete5_user WITH PASSWORD 'secure_password';GRANT ALL PRIVILEGES ON DATABASE concrete5 TO concrete5_user;Connection String Format:
- MySQL:
mysql://user:password@host:3306/concrete5 - PostgreSQL:
postgresql://user:password@host:5432/concrete5
Database Requirements:
- MySQL 5.7+ or PostgreSQL 10+
- At least 100MB initial storage (scales with content)
- SSL/TLS encryption recommended for production
- Regular backups essential
Concrete5 automatically creates all necessary tables during installation.
Getting Started with Concrete5
First Login and Site Setup
-
Access the Dashboard
Navigate to
https://example-app.klutch.sh/dashboardand log in with your admin credentials. -
Understand the Dashboard
The Concrete5 dashboard shows:
- Site pages and structure
- User management
- System settings
- Page attributes and metadata
- Add-ons and extensions
-
Configure Basic Settings
Go to Dashboard → System & Settings → Site:
- Set site name and tagline
- Configure timezone
- Set default language
- Configure canonical URLs for SEO
Creating and Managing Content
Creating a Page:
- Click “Add Page” in the Dashboard
- Select a template (or use default)
- Enter page name and description
- Set URL slug for SEO-friendly URLs
- Click “Create”
- You’ll be taken to edit the new page
In-Context Editing:
This is where Concrete5 really shines. When you click on any editable block on the page:
- A floating toolbar appears above it
- You can edit content directly in context
- Click elsewhere to save changes
- No need to visit a separate admin page
Working with Blocks:
Concrete5 organizes content into blocks:
- Text block: Simple paragraphs and formatted text
- Image block: Single image with alt text
- Content block: Full WYSIWYG editor
- File block: Downloadable documents
- Video block: YouTube, Vimeo, or self-hosted
- Feature block: Showcase items with images
- Automated list: Dynamic content from pages
To add a block:
- Click the ”+” icon on the page
- Select block type
- Configure block settings
- Click to add content
User Management
Creating Users:
- Go to Dashboard → Users & Groups → Users
- Click “Add User”
- Enter email, username, and password
- Select user group (determines permissions)
- Assign roles: Admin, Editor, Member, Guest
- User receives welcome email
User Groups and Permissions:
- Administrators: Full system access
- Editors: Can create/edit pages and content
- Members: Limited editing permissions
- Guests: View-only access
Site Structure and Navigation
Managing the Page Tree:
Concrete5 uses a hierarchical page structure:
Home├── About│ ├── Team│ └── History├── Products│ ├── Product A│ └── Product B├── Blog│ ├── Post 1│ └── Post 2└── ContactModify Page Structure:
- Right-click any page in the page tree
- Options: Add Sibling, Add Child, Edit, Delete
- Drag-and-drop to reorganize
- Click expand/collapse arrows to view children
Page Properties:
For each page, set:
- Page Type: Determines which blocks can be used
- Template: Controls the layout
- Attributes: Custom metadata (author, date, category, etc.)
- Publishing: Schedule publication dates
- Versions: Track and restore previous versions
Working with Themes
Installing a Theme:
- Go to Dashboard → Themes
- Click “Browse Marketplace” or upload custom theme
- Select theme and click “Install”
- Click “Activate” to use it site-wide
- Preview changes before applying
Customizing a Theme:
- Go to Marketplace → Find Themes
- Browse available themes
- Each theme has:
- Live preview
- Documentation
- Customization options
- User reviews
Popular Themes:
- Elemental Pro: Modern, highly customizable
- Supreme: Feature-rich, professional
- Radiance: Lightweight, responsive
- Auberge: Design-focused
Add-ons and Extensions
Concrete5 has a rich ecosystem of add-ons for extended functionality:
Installing Add-ons:
- Go to Dashboard → Extend Concrete5 → Find More Add-ons
- Browse the marketplace
- Click “Install” on desired add-on
- Review requirements and permissions
- Confirm installation
- Activate from Installed Add-ons
Popular Add-ons:
- Page List: Display dynamic lists of pages
- Social Media: Add social media integrations
- Email Forms: Create contact forms
- Advanced Custom Attributes: Custom page fields
- Calendar: Event management
- Blog: Structured blog functionality
- E-commerce: Simple store capabilities
- Member Registration: User account registration
- Newsletter: Email subscription management
Content Editing Tips
Bulk Page Updates:
- Select multiple pages in the tree
- Right-click and choose “Bulk Edit”
- Apply changes to multiple pages at once
- Useful for updating templates or attributes
Version Control:
- Concrete5 maintains version history
- Click “Version History” on any page
- Restore previous versions if needed
- Useful for content rollback
Scheduling:
- Set publish dates for future content
- Schedule page removal
- Automatic publishing/unpublishing
- Useful for planned releases
Search and Metadata:
- Configure page metadata for SEO
- Set canonical URLs
- Add custom meta tags
- Configure XML sitemap
Performance Optimization
Caching
Concrete5 includes multiple caching strategies:
Full-Page Caching:
- Cache entire HTML output
- Dramatically speeds up page load
- Automatically clears when content changes
- Most effective for content-heavy sites
Block Cache:
- Cache individual blocks
- Reduces database queries
- Fine-grained control
- Configure per-block
Enable Caching:
- Go to Dashboard → System & Settings → Optimization → Caching
- Select caching method: File, Database, Redis, Memcached
- Configure cache lifetime
- Enable all cache types
Cache Configuration:
# In environment variablesCACHE_DRIVER=fileCACHE_LIFETIME=3600Image Optimization
Concrete5 automatically handles image optimization:
Automatic Thumbnails:
- Generates thumbnails when uploading
- Responsive images for different screen sizes
- Reduces bandwidth usage
- Improves page load times
Image Attributes:
- Set image quality
- Configure thumbnail sizes
- Enable WEBP format support
- Set maximum dimensions
Configure Image Settings:
- Go to Dashboard → System & Settings → File Management
- Set thumbnail sizes
- Configure image quality
- Enable optimization options
Database Optimization
Regular Maintenance:
-- Analyze tables for query optimizationANALYZE TABLE pages;ANALYZE TABLE areas;ANALYZE TABLE blocks;
-- Optimize tables to free spaceOPTIMIZE TABLE pages;
-- Check for errorsCHECK TABLE pages;Indexing:
Concrete5 comes with appropriate indexes. Avoid adding indexes without understanding query patterns.
Query Performance:
- Monitor slow query log
- Review Concrete5 logs for database errors
- Profile heavy pages
- Optimize custom code
Server-Side Optimization
PHP Settings:
Configure in environment variables:
PHP_MEMORY_LIMIT=512MPHP_MAX_EXECUTION_TIME=300PHP_POST_MAX_SIZE=100MPHP_UPLOAD_MAX_FILESIZE=100MOpcode Caching:
PHP 8.2 includes OPcache by default. Enable aggressive caching:
OPCACHE_ENABLE=1OPCACHE_MEMORY_CONSUMPTION=256OPCACHE_MAX_ACCELERATED_FILES=4000OPCACHE_REVALIDATE_FREQ=60Compression:
Enable GZIP compression in Apache (configured in apache.conf).
Security Best Practices
User Authentication
Strong Passwords:
- Enforce minimum length (12+ characters)
- Require complexity (uppercase, numbers, symbols)
- Implement password expiration
- Prevent password reuse
Two-Factor Authentication:
- Enable 2FA for admin users
- Use authenticator apps (Google, Authy)
- Backup recovery codes required
Session Management:
- Configure session timeout (recommended 30-60 minutes)
- Secure session cookies (HttpOnly, Secure flags)
- Implement concurrent session limits
Access Control
Role-Based Permissions:
Assign appropriate roles:
- Administrators: Full system access
- Editors: Content management only
- Authors: Create/edit own content
- Viewers: Read-only access
Granular Permissions:
Configure page-level permissions:
- Set who can view specific pages
- Restrict editing to specific users
- Control publishing permissions
- Manage file access
Audit Logging:
- Enable audit logs in System & Settings
- Track user actions
- Monitor failed logins
- Review permission changes
Data Security
Backups:
Regular backups are critical:
- Database backups (daily recommended)
- File uploads backup
- Configuration files backup
- Test restore procedures regularly
SSL/TLS:
Klutch.sh provides automatic HTTPS. Ensure:
- All traffic uses HTTPS
- Redirect HTTP to HTTPS
- Valid SSL certificate installed
- HSTS headers enabled
File Uploads:
Control what users can upload:
- Whitelist safe file types
- Limit file size
- Store uploads outside web root
- Scan uploads for malware
Regular Updates
Keep Concrete5 secure:
Check for Updates:
- Go to Dashboard → System & Settings → Update
- Review available updates
- Read release notes for security issues
- Update core and extensions
Backup Before Updating:
- Backup database
- Backup application files
- Note current version
- Document custom modifications
- Test in staging environment first
Update Process:
- Navigate to Updates section
- Click “Update” on core or extensions
- Monitor update progress
- Verify site works after update
- Clear all caches
Troubleshooting
Issue 1: Installation Wizard Won’t Load
Symptoms: Blank page or 500 error on first access
Solutions:
-
Check Database Connection:
- Verify database host is correct
- Test credentials with another tool
- Ensure database user has all permissions
- Check database exists
-
Review Logs:
- Check Klutch.sh application logs
- Look for PHP errors
- Review database connection errors
-
Verify Permissions:
- Check file permissions on
/var/www/html/application - Should be writable by www-data user
- Run:
chown -R www-data:www-data /var/www/html
- Check file permissions on
-
Check PHP Configuration:
- Verify required PHP extensions are loaded
- Check memory limit is sufficient
- Ensure extensions are installed in Dockerfile
Issue 2: Pages Return 404 Errors
Symptoms: Valid pages show 404 “not found”
Solutions:
-
Check .htaccess and URL Rewriting:
- Verify Apache mod_rewrite is enabled
- Check
.htaccessfile exists in webroot - Verify Apache configuration allows rewriting
-
Verify Page Settings:
- Check page is published
- Verify page has correct URL slug
- Ensure page isn’t restricted by permissions
-
Clear Cache:
- Go to Dashboard → Optimization → Caching
- Clear all caches
- Rebuild cache
-
Check Database:
- Verify pages exist in database
- Review database tables for corruption
- Check page publish status
Issue 3: File Uploads Fail
Symptoms: “Upload failed” errors, files not saved
Solutions:
-
Check Permissions:
- Verify
/var/www/html/application/filesis writable - Check ownership is www-data:www-data
- Verify persistent volume is mounted
- Verify
-
Check File Size Limits:
- Set in environment:
MAX_UPLOAD_SIZE=104857600 - Verify PHP max upload in
.htaccess - Check server upload limits
- Set in environment:
-
Verify Storage:
- Check persistent volume has free space
- Monitor volume usage in Klutch.sh dashboard
- Expand volume if approaching capacity
-
Review Logs:
- Check Apache error logs
- Review PHP error logs
- Look for permission or disk space errors
Issue 4: Site Is Slow
Symptoms: Slow page load times, delays in admin
Solutions:
-
Enable Caching:
- Enable full-page cache
- Enable block cache
- Configure cache lifetime
-
Check Resource Usage:
- Monitor CPU and memory in Klutch.sh dashboard
- Identify resource-intensive operations
- Upgrade instance if consistently maxed out
-
Optimize Database:
- Run database optimization queries
- Check for slow queries in logs
- Verify appropriate indexes exist
-
Reduce Page Complexity:
- Audit page blocks
- Remove unnecessary blocks
- Optimize images (use appropriate sizes)
- Minimize database queries per page
-
Review Add-ons:
- Disable unused add-ons
- Check add-on performance
- Remove poorly-optimized extensions
Issue 5: Memory Errors
Symptoms: “Fatal error: allowed memory size exhausted”, “Out of memory”
Solutions:
-
Increase Memory Limit:
Terminal window PHP_MEMORY_LIMIT=512M# Or higher if neededPHP_MEMORY_LIMIT=1024M -
Identify Memory Leaks:
- Review error logs
- Check for specific operations that cause errors
- Profile memory usage with PHP tools
-
Optimize Code:
- Avoid loading large datasets into memory
- Use pagination for large lists
- Unset variables after use
- Avoid infinite loops
-
Upgrade Resources:
- Increase instance RAM in Klutch.sh
- More memory allows larger operations
- Prevents timeout errors
Issue 6: Database Connection Issues
Symptoms: “Could not connect to database”, connection errors
Solutions:
-
Verify Credentials:
- Check
DB_HOST,DB_USER,DB_PASSWORD - Ensure credentials are correct
- Try connecting with MySQL client
- Check
-
Check Network:
- Verify database host is reachable
- Test connectivity from Klutch.sh instance
- Check firewall rules
- Verify database port is correct
-
Database Status:
- Confirm database service is running
- Check for database errors in logs
- Verify database user has proper permissions
- Ensure database exists
-
Connection Pool:
- Check max connections limit
- Monitor active connections
- Restart application if stalled
Issue 7: Theme or Add-on Errors
Symptoms: Broken styling, missing functionality, blank pages
Solutions:
-
Revert to Default Theme:
- Go to Dashboard → Themes
- Select default theme
- Verify site works
-
Disable Problematic Add-ons:
- Go to Dashboard → Add-ons
- Disable recently installed add-ons
- Test if issue resolves
-
Clear Cache:
- Clear all caches in Optimization → Caching
- Refresh browser cache (Ctrl+Shift+R)
- Rebuild all caches
-
Check Compatibility:
- Verify theme/add-on supports your PHP version
- Check Concrete5 version compatibility
- Review marketplace reviews for issues
-
Review Logs:
- Check error logs for PHP errors
- Look for JavaScript errors in browser console
- Review Concrete5 logs
Issue 8: Admin Dashboard Unresponsive
Symptoms: Dashboard loads slowly, timing out, freezes
Solutions:
-
Check Resource Usage:
- Upgrade instance CPU/RAM
- Monitor resource usage patterns
- Identify peak usage times
-
Disable Cache:
- Temporarily disable full-page cache
- Test dashboard responsiveness
- Re-enable if dashboard works
-
Clear Cache:
- Go to Optimization → Caching
- Clear all caches
- Clear browser cache
-
Reduce Operations:
- Close unnecessary browser tabs
- Disable real-time preview
- Limit simultaneous admin users
-
Profile Performance:
- Check slow query logs
- Identify expensive operations
- Optimize or defer heavy operations
Issue 9: Email Delivery Issues
Symptoms: Password reset emails not received, notifications not sending
Solutions:
-
Verify SMTP Configuration:
- Check
MAIL_HOST,MAIL_PORT,MAIL_USERNAME,MAIL_PASSWORD - Verify credentials with email provider
- Test SMTP connection manually
- Check
-
Check Email Settings:
- Go to System & Settings → Email
- Verify from address and name
- Test send functionality
-
Review Logs:
- Check application logs for email errors
- Review SMTP server logs
- Look for authentication failures
-
Spam Filters:
- Check spam/junk folder
- Verify SPF, DKIM, DMARC records
- Use reputable SMTP provider
-
Port and Security:
- Verify correct SMTP port (587 or 465)
- Check TLS/SSL configuration
- Ensure firewall allows SMTP
Issue 10: Unexpected Downtime
Symptoms: Site unavailable, returns 502 or 503 errors
Solutions:
-
Check Application Status:
- Verify app is running in Klutch.sh dashboard
- Check deployment status
- Review logs for errors
-
Restart Application:
- Restart from Klutch.sh dashboard
- Monitor restart progress
- Check logs after restart
-
Check Database:
- Verify database connection
- Check database service is running
- Review database logs
-
Review Logs:
- Check Klutch.sh application logs
- Look for fatal errors
- Review system logs
-
Increase Resources:
- Upgrade instance if running out of resources
- Monitor CPU and memory usage
- Plan capacity for expected growth
Custom Domains
Using a custom domain makes your site professional and brand-friendly.
Step 1: Add Domain in Klutch.sh
- Go to your app in Klutch.sh dashboard
- Navigate to Domains section
- Click “Add Custom Domain”
- Enter your domain (e.g.,
www.yourdomain.com) - Save the configuration
Step 2: Update DNS
Configure DNS with your domain provider:
Type: CNAMEName: www (or leave empty for root)Value: example-app.klutch.shTTL: 3600DNS Examples:
www.yourdomain.com. CNAME example-app.klutch.sh.yourdomain.com. CNAME example-app.klutch.sh.Step 3: Update Concrete5 Configuration
Update the site URL setting:
- Go to Dashboard → System & Settings → Site
- Set “Site URL” to
https://www.yourdomain.com - Save changes
Also set in environment variables:
APP_URL=https://www.yourdomain.comStep 4: Verify Setup
-
Wait for DNS propagation (5-60 minutes)
-
Test DNS resolution:
Terminal window nslookup yourdomain.com# Should show example-app.klutch.sh -
Access
https://yourdomain.comin browser -
Verify SSL certificate is valid
-
Check site loads correctly
Production Best Practices
Backup Strategy
What to Backup:
- Database: Core of your site
- Uploads: User files and images
- Custom Code: Themes and add-ons
- Configuration: Environment settings
Backup Schedule:
- Daily: Database backups
- Weekly: Complete system backup
- Monthly: Archival backup
Backup Implementation:
# Automated database backup0 2 * * * mysqldump -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME | gzip > /backups/concrete5-$(date +%Y%m%d).sql.gz
# Backup uploads0 3 * * * tar -czf /backups/uploads-$(date +%Y%m%d).tar.gz /var/www/html/application/files/
# Verify backups0 5 * * * ls -lh /backups/Backup Testing:
- Monthly restore tests
- Verify backup integrity
- Document recovery procedures
- Practice disaster recovery
Monitoring and Logging
Key Metrics to Monitor:
- CPU usage
- Memory usage
- Disk space (especially uploads)
- Database connection count
- Page load times
- Failed logins
- Database errors
Logging Configuration:
LOG_LEVEL=warningLOG_CHANNEL=stackMonitor logs for:
- PHP errors
- Database errors
- Failed authentication
- Permission issues
- Deployment errors
Scaling Strategy
Identify Bottlenecks:
- Monitor CPU usage during peak times
- Check memory utilization
- Review database query performance
- Measure page load times
Vertical Scaling (Recommended First):
- Increase CPU cores
- Increase RAM
- Upgrade storage
- Simplest approach for most sites
Horizontal Scaling (Advanced):
- Multiple application instances
- Load balancer distribution
- Shared database
- Shared storage (S3 or NFS)
- More complex setup
Cache Optimization:
- Aggressive caching strategy
- CDN for static assets
- Browser caching headers
- Reduced database queries
Security Maintenance
Regular Tasks:
Daily:
- Monitor error logs
- Check failed logins
- Verify backups completed
Weekly:
- Review user accounts
- Check for suspicious activity
- Test critical functionality
Monthly:
- Security audit
- Verify permissions
- Review access logs
- Update documentation
Quarterly:
- Full security scan
- Penetration testing (if applicable)
- Compliance audit
- Disaster recovery test
Annually:
- Major version updates
- Security assessment
- Capacity planning
- Strategy review
Additional Resources
- Concrete5 Official Website
- Concrete5 Documentation
- Concrete5 Marketplace
- Concrete5 Community Forums
- Concrete5 GitHub Repository
- Klutch.sh Official Website
- Klutch.sh Dashboard
- Klutch.sh Documentation
- Klutch.sh Custom Domains Guide
- Klutch.sh Persistent Storage Guide
Conclusion
Deploying Concrete5 on Klutch.sh gives you a powerful, flexible content management system with complete control over your infrastructure. You’ve learned how to build a production-ready Dockerfile with proper Apache configuration, set up the application with persistent storage for uploads and files, configure database connectivity, optimize performance through caching and code optimization, implement security best practices for user authentication and data protection, troubleshoot common deployment issues, and scale resources as your site grows.
Concrete5’s in-context editing makes content management intuitive for your team. Unlike traditional CMSs that separate editing from viewing, Concrete5 lets content creators edit pages directly in context—reducing training time and improving efficiency.
With Klutch.sh’s straightforward deployment process, you can focus on creating great content rather than managing infrastructure. Your site is now running on reliable, globally-distributed infrastructure with automatic HTTPS, scalable resources, and professional-grade hosting.
The flexibility of Concrete5 combined with Klutch.sh’s ease of deployment creates an excellent foundation for websites of any size—from small business sites to large enterprise deployments. Start small, scale as needed, and adjust your approach based on actual usage patterns and performance data.
For questions, community support, or marketplace add-ons, check out the Concrete5 website and active community forums. The passionate community and extensive marketplace ensure you can find solutions for virtually any requirement.