Skip to content

Deploying FoodCoopShop

Introduction

FoodCoopShop is a user-friendly open-source software platform designed specifically for food cooperatives and local shops. Built with CakePHP, this comprehensive solution empowers communities to manage online ordering, inventory, member management, and producer relationships all in one place. Whether you’re running a food co-op or a local farm shop, FoodCoopShop provides the tools you need to connect producers directly with consumers.

FoodCoopShop is known for:

  • Cooperative-First Design: Purpose-built for food cooperatives with features that match real-world workflows
  • Multi-Producer Support: Manage products from multiple local producers and farmers in one platform
  • Flexible Delivery Rhythms: Configure various delivery schedules (weekly, bi-weekly, monthly, or custom)
  • Member Management: Complete member registration, order tracking, and account management
  • Cashless Payment System: Built-in payment tracking based on bank account transfers
  • Order Adaptations: Easy order cancellation and price/weight adjustments
  • Self-Service Mode: Optional self-service functionality with barcode scanning support
  • Decentralized Network: Synchronize products across multiple FoodCoopShop installations
  • Multi-Language: Available in German and English with growing language support
  • Admin Dashboard: Comprehensive admin area for both manufacturers and cooperative administrators

Common use cases include food cooperatives, farm-to-table initiatives, community-supported agriculture (CSA) programs, local food shops, farmers’ markets, and regional food networks.

This comprehensive guide walks you through deploying FoodCoopShop on Klutch.sh using Docker, including MySQL database configuration, persistent storage setup, environment variables, and production-ready best practices.

Why Deploy FoodCoopShop on Klutch.sh?

  • Simplified Infrastructure: No need to manage servers, databases, or complex configurations manually
  • Persistent Storage: Reliable volume storage for product images, documents, and uploads
  • MySQL Integration: Easy database setup with persistent data storage
  • Automatic HTTPS: Secure connections out of the box for safe transactions
  • Environment Variables: Secure configuration management without hardcoding credentials
  • Easy Scaling: Scale resources as your cooperative grows
  • Cost-Effective: Pay only for what you use with transparent pricing

Prerequisites

Before you begin, ensure you have the following:


Installation and Setup

Step 1: Create Your Project Directory

First, create a new directory for your FoodCoopShop deployment project:

Terminal window
mkdir foodcoopshop-klutch
cd foodcoopshop-klutch
git init

Step 2: Create the Dockerfile

Create a Dockerfile in your project root directory. This will define your FoodCoopShop container configuration using the official Docker image:

FROM foodcoopshop/foodcoopshop:latest
# FoodCoopShop runs on Apache with PHP-FPM
# The official image already includes Apache and all required PHP extensions
EXPOSE 80
# The base image includes:
# - Apache 2.4 with mod_rewrite enabled
# - PHP 8.4+ with required extensions (intl, imagick, gd, bzip2, pdo_mysql)
# - CakePHP 5.x framework
# - All FoodCoopShop application code
# Persistent volumes should be mounted at:
# /var/www/html/files_private - for uploaded files and documents
# /var/www/html/webroot/files - for public assets and product images
# /var/www/html/tmp - for cache and temporary files
# Environment variables for database connection
# These should be configured in the Klutch.sh dashboard
# DATABASE_URL format: mysql://username:password@host:3306/database_name

Key points about the Dockerfile:

  • Uses the official foodcoopshop/foodcoopshop:latest image
  • Exposes port 80 for HTTP traffic
  • Requires MySQL database connection via environment variables
  • Needs persistent volumes for file storage and caching

Step 3: Create a Configuration Template

Create a custom_config.example.php file to document the required configuration. This file serves as a template and should NOT contain actual credentials:

<?php
/**
* FoodCoopShop Custom Configuration Template
*
* Copy this file to custom_config.php and update with your actual values.
* DO NOT commit custom_config.php with real credentials to version control.
*/
return [
// Database Configuration
'Datasources' => [
'default' => [
'host' => 'your-mysql-host.klutch.sh',
'port' => 8000, // TCP port for Klutch.sh MySQL service
'username' => 'your_database_user',
'password' => 'your_database_password',
'database' => 'foodcoopshop_production',
],
],
// Application Configuration
'App' => [
'fullBaseUrl' => 'https://example-app.klutch.sh',
'cakeServerName' => 'Klutch Production',
'EmailTransport' => [
'default' => [
'className' => 'Smtp',
'host' => 'your-smtp-host',
'port' => 587,
'username' => 'your-smtp-username',
'password' => 'your-smtp-password',
'tls' => true,
],
],
],
// Security
'Security' => [
'salt' => 'your-unique-security-salt-here',
],
// Session Configuration
'Session' => [
'timeout' => 2592000, // 30 days in seconds
'cookieTimeout' => 2592000,
],
];

Step 4: Create a README for Documentation

Create a README.md file to document your deployment:

# FoodCoopShop Deployment
This repository contains the Docker configuration for deploying FoodCoopShop on Klutch.sh.
## Environment Variables Required
Configure these in the Klutch.sh dashboard:
- `DATABASE_URL`: MySQL connection string (format: mysql://user:pass@host:port/db_name)
- `APP_FULL_BASE_URL`: Your application URL (e.g., https://example-app.klutch.sh)
- `SECURITY_SALT`: Random string for encryption (generate with: openssl rand -base64 32)
- `EMAIL_HOST`: SMTP server hostname
- `EMAIL_PORT`: SMTP server port (usually 587 for TLS)
- `EMAIL_USERNAME`: SMTP authentication username
- `EMAIL_PASSWORD`: SMTP authentication password
## Persistent Volumes
Mount these paths in Klutch.sh:
1. `/var/www/html/files_private` - Private uploaded files (minimum 5GB recommended)
2. `/var/www/html/webroot/files` - Public product images (minimum 10GB recommended)
3. `/var/www/html/tmp` - Cache and temporary files (minimum 1GB)
## Database Setup
Before deploying, ensure you have a MySQL 8.0+ database ready.
See the Klutch.sh MySQL deployment guide for setup instructions.
## First-Time Setup
After deployment, access your FoodCoopShop instance and follow the setup wizard to:
1. Create the admin account
2. Configure cooperative settings
3. Set up payment methods
4. Add producers and product categories

Step 5: Create a .gitignore File

Create a .gitignore file to exclude sensitive files from version control:

# Custom configuration with credentials
custom_config.php
# Local development files
*.local
.env
# PHP dependencies (if using composer locally)
vendor/
composer.lock
# Temporary and cache files
tmp/
logs/
# IDE files
.vscode/
.idea/
*.swp
*.swo
# OS files
.DS_Store
Thumbs.db

Step 6: Commit to GitHub

Push your configuration to GitHub:

Terminal window
git add Dockerfile custom_config.example.php README.md .gitignore
git commit -m "Add FoodCoopShop deployment configuration"
git remote add origin https://github.com/yourusername/foodcoopshop-klutch.git
git push -u origin main

Deploying to Klutch.sh

Now that your FoodCoopShop project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh.

Deployment Steps

    1. Prepare Your MySQL Database

      FoodCoopShop requires a MySQL 8.0+ database. You have two options:

      Option A: Deploy MySQL on Klutch.sh

      • Follow our MySQL deployment guide
      • Note the connection details (host, port 8000, username, password, database name)

      Option B: Use an External MySQL Service

      • Use a managed MySQL service like Amazon RDS, DigitalOcean Managed Databases, or PlanetScale
      • Ensure the service allows connections from Klutch.sh
      • Note the connection details
    2. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    3. Create a New Project

      Go to Create Project and give your project a meaningful name (e.g., “FoodCoopShop Production”).

    4. Create a New App

      Navigate to Create App within your project.

    5. Connect Your Repository

      • Select GitHub as your Git source
      • Choose the repository containing your Dockerfile
      • Select the branch you want to deploy (typically main or master)
    6. Configure Traffic Settings

      • Traffic Type: Select HTTP (FoodCoopShop is a web application)
      • Internal Port: Set to 80 (Apache listens on port 80 in the container)
    7. Set Environment Variables

      Add the following environment variables in the Klutch.sh dashboard. Mark sensitive values as secrets:

      Database Configuration:

      • DATABASE_HOST: Your MySQL host (e.g., mysql-app.klutch.sh or external host)
      • DATABASE_PORT: 8000 (for Klutch.sh MySQL) or your external database port
      • DATABASE_NAME: foodcoopshop_production
      • DATABASE_USER: Your database username
      • DATABASE_PASSWORD: Your database password (mark as secret)
      • DATABASE_URL: Full connection string: mysql://user:password@host:port/database_name

      Application Configuration:

      • APP_FULL_BASE_URL: Your application URL (e.g., https://example-app.klutch.sh)
      • SECURITY_SALT: Generate with openssl rand -base64 32 (mark as secret)
      • APP_ENV: production
      • DEBUG: false

      Email Configuration (SMTP):

      • EMAIL_HOST: Your SMTP server hostname
      • EMAIL_PORT: SMTP port (typically 587 for TLS or 465 for SSL)
      • EMAIL_USERNAME: SMTP username
      • EMAIL_PASSWORD: SMTP password (mark as secret)
      • EMAIL_FROM: Sender email address (e.g., noreply@yourfoodcoop.org)
      • EMAIL_FROM_NAME: Sender name (e.g., Your Food Coop)

      Optional Configuration:

      • SESSION_TIMEOUT: Session timeout in seconds (default: 2592000 = 30 days)
      • LOCALE: Default language (en for English, de for German)
    8. Attach Persistent Volumes

      FoodCoopShop requires persistent storage for uploaded files, product images, and cache. Create three volumes:

      Volume 1: Private Files

      • Mount Path: /var/www/html/files_private
      • Size: 5GB minimum (increase based on expected document uploads)
      • Purpose: Stores private uploaded documents, invoices, and member files

      Volume 2: Public Files (Product Images)

      • Mount Path: /var/www/html/webroot/files
      • Size: 10GB minimum (increase based on product catalog size)
      • Purpose: Stores product images, category images, and public assets

      Volume 3: Cache and Temporary Files

      • Mount Path: /var/www/html/tmp
      • Size: 1GB minimum
      • Purpose: Stores CakePHP cache, sessions, and temporary files
    9. Configure Resources

      • CPU: Start with 1 CPU, scale up if needed
      • Memory: Minimum 1GB RAM recommended, 2GB+ for production workloads
      • Instances: Start with 1, scale horizontally as your cooperative grows
    10. Deploy Your Application

      Click “Create” to start the deployment. Klutch.sh will:

      • Detect your Dockerfile automatically
      • Build the Docker image with FoodCoopShop
      • Configure the environment variables
      • Mount the persistent volumes
      • Start the Apache/PHP container
      • Assign a public URL
    11. Initialize the Database

      After deployment completes:

      • Access your FoodCoopShop URL (e.g., https://example-app.klutch.sh)
      • The first-time setup wizard will guide you through:
        • Database schema creation and migration
        • Initial admin account creation
        • Basic cooperative configuration
        • Email settings verification
    12. Complete Initial Configuration

      In the admin dashboard, configure:

      • Cooperative Information: Name, address, contact details, logo
      • Payment Methods: Bank account details for cashless payment system
      • Delivery Rhythms: Weekly, bi-weekly, or custom delivery schedules
      • Product Categories: Organize your product catalog
      • Tax Rates: Configure applicable tax rates for your region
      • Member Groups: Set up member types and permissions
      • Email Templates: Customize notification emails

Post-Deployment Configuration

Adding Producers

  1. Navigate to AdminProducers in the dashboard
  2. Click “Add New Producer”
  3. Fill in producer details:
    • Name and contact information
    • Bank account details (for payments)
    • Delivery settings
    • Commission rates
  4. Assign product categories the producer can use
  5. Configure notification preferences

Creating Product Catalog

  1. Go to ProductsAdd New Product
  2. Configure product details:
    • Name and description
    • Producer/manufacturer
    • Category and subcategory
    • Price and tax rate
    • Unit (kg, g, piece, liter, etc.)
    • Stock quantity (if using inventory management)
    • Product image upload
  3. Set delivery rhythm (weekly, bi-weekly, specific days)
  4. Configure purchase limits if needed
  5. Set product status (active/inactive)

Member Registration

FoodCoopShop supports two registration modes:

Self-Registration:

  • Enable public registration on the website
  • New members fill out registration form
  • Admin approval required before account activation
  • Members receive welcome email with login credentials

Admin-Created Accounts:

  • Admin creates member accounts directly
  • Useful for existing cooperatives migrating to the platform
  • Members receive invitation email

Payment System Setup

FoodCoopShop uses a cashless payment system based on bank transfers:

  1. Configure Bank Details: Add your cooperative’s bank account information
  2. Credit System: Members pre-pay credit to their account
  3. Order Deductions: Orders automatically deduct from member credit
  4. Payment Tracking: Admin can match bank transfers with member payments
  5. Balance Reports: Members see their current credit balance

Email Notifications

FoodCoopShop sends automated emails for:

  • Order confirmations
  • Order status changes
  • Payment reminders
  • Product availability notifications
  • Weekly order reminders
  • Producer order summaries

Configure email templates in AdminEmail Templates.


Sample API Integration

While FoodCoopShop primarily uses its web interface, you can interact with the CakePHP backend programmatically for custom integrations.

PHP Example: Custom Product Import Script

<?php
/**
* Example: Bulk Product Import Script
* This demonstrates how to interact with FoodCoopShop's database
*/
// Database connection using PDO
$host = getenv('DATABASE_HOST');
$port = getenv('DATABASE_PORT');
$dbname = getenv('DATABASE_NAME');
$username = getenv('DATABASE_USER');
$password = getenv('DATABASE_PASSWORD');
try {
$pdo = new PDO(
"mysql:host=$host;port=$port;dbname=$dbname;charset=utf8mb4",
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
// Example: Insert a new product
$stmt = $pdo->prepare("
INSERT INTO fcs_product (
name,
description,
manufacturer_id,
category_id,
price,
tax_rate,
active,
created,
modified
) VALUES (
:name,
:description,
:manufacturer_id,
:category_id,
:price,
:tax_rate,
1,
NOW(),
NOW()
)
");
$stmt->execute([
'name' => 'Organic Apples',
'description' => 'Fresh organic apples from local farm',
'manufacturer_id' => 1,
'category_id' => 2,
'price' => 3.50,
'tax_rate' => 10.0,
]);
echo "Product inserted successfully with ID: " . $pdo->lastInsertId();
} catch (PDOException $e) {
echo "Database Error: " . $e->getMessage();
}

Python Example: Order Export Script

#!/usr/bin/env python3
"""
Example: Export orders to CSV for reporting
"""
import os
import csv
import mysql.connector
from datetime import datetime
def export_orders_to_csv():
# Database connection
connection = mysql.connector.connect(
host=os.getenv('DATABASE_HOST'),
port=int(os.getenv('DATABASE_PORT', 3306)),
user=os.getenv('DATABASE_USER'),
password=os.getenv('DATABASE_PASSWORD'),
database=os.getenv('DATABASE_NAME')
)
cursor = connection.cursor(dictionary=True)
# Query orders from the last week
query = """
SELECT
o.id AS order_id,
o.created AS order_date,
m.firstname,
m.lastname,
m.email,
p.name AS product_name,
od.product_amount,
od.total_price_tax_incl
FROM fcs_order o
JOIN fcs_member m ON o.member_id = m.id
JOIN fcs_order_detail od ON o.id = od.order_id
JOIN fcs_product p ON od.product_id = p.id
WHERE o.created >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY o.created DESC
"""
cursor.execute(query)
orders = cursor.fetchall()
# Export to CSV
filename = f'orders_export_{datetime.now().strftime("%Y%m%d")}.csv'
with open(filename, 'w', newline='') as csvfile:
if orders:
fieldnames = orders[0].keys()
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(orders)
print(f"Exported {len(orders)} orders to {filename}")
cursor.close()
connection.close()
if __name__ == '__main__':
export_orders_to_csv()

JavaScript Example: Member Balance Check

// Example: Check member account balance via API call
const axios = require('axios');
const FOODCOOPSHOP_URL = 'https://example-app.klutch.sh';
async function checkMemberBalance(memberId) {
try {
// FoodCoopShop uses session-based authentication
// This example assumes you've authenticated first
const response = await axios.get(
`${FOODCOOPSHOP_URL}/admin/members/view/${memberId}.json`,
{
withCredentials: true,
headers: {
'Content-Type': 'application/json',
}
}
);
const member = response.data.member;
console.log(`Member: ${member.firstname} ${member.lastname}`);
console.log(`Current Balance: €${member.credit_balance}`);
console.log(`Status: ${member.active ? 'Active' : 'Inactive'}`);
return member;
} catch (error) {
console.error('Error fetching member data:', error.message);
}
}
// Usage
checkMemberBalance(123);

Production Best Practices

Security Recommendations

  • Strong Passwords: Use strong, unique passwords for MySQL database and admin accounts
  • Security Salt: Generate a secure random string for SECURITY_SALT (never reuse across environments)
  • Environment Variables: Store all credentials as environment variables, never in code
  • HTTPS Only: Klutch.sh provides automatic HTTPS - ensure all links use https://
  • Regular Backups: Implement automated database backups (see Database Backups section)
  • Session Security: Configure secure session settings with appropriate timeouts
  • File Upload Limits: Set reasonable file size limits to prevent abuse
  • Admin Access: Use strong passwords and consider IP restrictions for admin accounts
  • Email Security: Use TLS/SSL for SMTP connections to protect credentials
  • Database Security: Use least-privilege database accounts with only necessary permissions

Performance Optimization

  • PHP OPcache: The official image includes OPcache enabled by default for better PHP performance
  • Database Indexing: Ensure proper database indexes on frequently queried columns
  • Image Optimization: Compress product images before uploading (recommended max 1MB per image)
  • Caching: FoodCoopShop uses CakePHP’s built-in caching - ensure /tmp volume has adequate space
  • Resource Allocation: Monitor CPU and memory usage, scale resources as needed
  • Database Connection Pooling: Use persistent database connections (configured by default)
  • CDN for Images: Consider using a CDN for serving product images to reduce load
  • Session Storage: Consider using database-backed sessions for multi-instance deployments

Database Backup Strategy

Implement a comprehensive backup strategy for your MySQL database:

#!/bin/bash
# Example: Automated MySQL backup script
# Run this via cron job or scheduled task
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/mysql"
DB_HOST="${DATABASE_HOST}"
DB_PORT="${DATABASE_PORT}"
DB_NAME="${DATABASE_NAME}"
DB_USER="${DATABASE_USER}"
DB_PASS="${DATABASE_PASSWORD}"
# Create backup directory
mkdir -p $BACKUP_DIR
# Dump database
mysqldump -h $DB_HOST \
-P $DB_PORT \
-u $DB_USER \
-p$DB_PASS \
--single-transaction \
--routines \
--triggers \
$DB_NAME | gzip > $BACKUP_DIR/foodcoopshop_$DATE.sql.gz
# Keep only last 30 days of backups
find $BACKUP_DIR -name "foodcoopshop_*.sql.gz" -mtime +30 -delete
echo "Backup completed: foodcoopshop_$DATE.sql.gz"

Volume Management

Monitor and manage persistent volumes:

  • Regular Cleanup: Periodically remove old temporary files from /tmp
  • Image Optimization: Compress uploaded images to save space
  • Archive Old Data: Archive old orders and invoices to separate storage
  • Monitor Usage: Use Klutch.sh dashboard to track volume usage
  • Expansion Planning: Plan for volume expansion before reaching capacity

Monitoring

Monitor your FoodCoopShop deployment for:

  • Application Health: Check that the web interface loads correctly
  • Response Times: Monitor page load times and database query performance
  • Error Logs: Review Apache and PHP error logs regularly
  • Database Performance: Monitor MySQL slow query log and connection pool
  • Disk Usage: Track persistent volume usage on all three mount points
  • Memory Usage: Monitor PHP-FPM memory consumption
  • Email Delivery: Verify SMTP connections and email delivery success
  • User Activity: Track member logins and order patterns
  • Payment Processing: Monitor member credit balances and payment tracking

Scaling Considerations

As your food cooperative grows, consider:

  • Vertical Scaling: Increase CPU and memory resources for the container
  • Database Optimization: Tune MySQL configuration for larger datasets
  • Horizontal Scaling: Run multiple FoodCoopShop instances behind a load balancer
  • Read Replicas: Configure MySQL read replicas for improved read performance
  • Session Management: Use database-backed sessions or Redis for multi-instance deployments
  • File Storage: Consider object storage (S3-compatible) for product images
  • Caching Layer: Implement Redis or Memcached for additional caching
  • Queue System: Use background job processing for email sending and report generation

Troubleshooting

Cannot Access FoodCoopShop

  • Verify HTTP traffic type is selected (not TCP)
  • Ensure internal port is set to 80
  • Check deployment logs in Klutch.sh dashboard for startup errors
  • Verify environment variables are correctly set
  • Confirm the application has completed its first startup (can take 2-3 minutes)

Database Connection Errors

  • Verify MySQL database is running and accessible
  • Check DATABASE_URL format: mysql://user:password@host:port/database_name
  • For Klutch.sh MySQL, ensure port is 8000
  • Test database connection from another tool (e.g., MySQL Workbench)
  • Check MySQL user has appropriate permissions
  • Verify firewall rules allow database connections

File Upload Issues

  • Check persistent volumes are correctly mounted at all three paths
  • Verify volume sizes have adequate free space
  • Ensure PHP upload limits are sufficient in Apache config
  • Review Apache error logs for permission issues
  • Check that directories are writable by the web server user

Email Not Sending

  • Verify SMTP credentials are correct
  • Test SMTP connection with a tool like telnet or swaks
  • Check SMTP port (587 for TLS, 465 for SSL)
  • Ensure EMAIL_FROM is a valid email address
  • Review PHP mail logs for delivery errors
  • Verify your SMTP provider allows the connection from Klutch.sh

Performance Issues

  • Monitor CPU and memory usage in Klutch.sh dashboard
  • Check MySQL slow query log for unoptimized queries
  • Review Apache access logs for high-traffic patterns
  • Consider increasing container resources (CPU/RAM)
  • Optimize product images (compress before upload)
  • Clear CakePHP cache: rm -rf /var/www/html/tmp/cache/*

Session Timeout Problems

  • Check SESSION_TIMEOUT environment variable
  • Verify SESSION_COOKIE_TIMEOUT matches session timeout
  • Ensure members aren’t accessing from multiple devices simultaneously
  • Review PHP session configuration in custom_config.php

Product Images Not Displaying

  • Verify /var/www/html/webroot/files volume is mounted correctly
  • Check file permissions on uploaded images
  • Ensure images are uploaded in supported formats (JPEG, PNG, GIF)
  • Review Apache access logs for 404 errors on image requests
  • Verify APP_FULL_BASE_URL is set correctly

Additional Resources


Conclusion

Deploying FoodCoopShop to Klutch.sh provides your food cooperative with a robust, scalable platform for managing online orders, producer relationships, and member accounts. With MySQL database integration, persistent file storage, and automated HTTPS, you have everything needed to run a successful food cooperative. The platform’s cooperative-first design ensures that features like delivery rhythms, cashless payments, and multi-producer support work seamlessly to connect local producers with community members. Your FoodCoopShop deployment is now ready to support sustainable local food systems and strengthen community connections through technology.