Skip to content

Getting Started with Frappe Docker ​

A comprehensive guide for developers getting started with Frappe Docker, with comparisons to Django for teams familiar with that framework

Table of Contents ​


How to Use This Guide ​

Walk through the sections sequentially if you're onboarding from scratch, or jump directly using the Table of Contents.

Understanding Frappe Docker Architecture ​

Frappe Docker provides a comprehensive containerized environment for developing and deploying Frappe/ERPNext applications. It uses a multi-service architecture that handles everything from web serving to background job processing.

Core Services ​

The base compose file includes these essential services:

  • configurator - Initialization service that configures database and Redis connections; runs on startup and exits
  • backend - Werkzeug development server for dynamic content processing
  • frontend - Nginx reverse proxy that serves static assets and routes requests
  • websocket - Node.js server running Socket.IO for real-time communications
  • queue-short/long - Python workers using RQ (Redis Queue) for asynchronous background job processing
  • scheduler - Python service that runs scheduled tasks using the schedule library

Additional services are added through compose overrides:

  • db - MariaDB or PostgreSQL database server (via compose.mariadb.yaml or compose.postgres.yaml)
  • redis-cache/queue - Redis instances for caching and job queues (via compose.redis.yaml)

How Services Work Together ​

User Request
    ↓
[frontend (Nginx)] → Static files served directly
    ↓
[backend (Werkzeug)] → Dynamic content processing
    ↓                    ↓
[db (MariaDB)]      [redis-cache]

Background Tasks:
[scheduler] → [redis-queue] → [queue-short/long workers]

Real-time:
[websocket (Socket.IO)] ←→ [redis-cache]

Repository Structure ​

📁 Core Configuration Files ​

⚠️ Before deploying, read Choosing a Deployment Method to understand the differences between pwd.yml, development setup, the Easy Install script and the production setup.

  • compose.yaml - Main Docker Compose file defining all services
  • example.env - Environment variables template (copy to .env)
  • pwd.yml - "Play with Docker" - simplified single-file setup for quick testing
  • docker-bake.hcl - Advanced Docker Buildx configuration for multi-architecture builds
  • docs/container-setup/env-variables.md - Central reference for environment configuration logic and defaults

📁 images/ - Docker Image Definitions ​

Four predefined Dockerfiles are available, each serving different use cases:

  • images/bench/ - Sets up only the Bench CLI for development or debugging; does not include runtime services
  • images/custom/ - Multi-purpose Python backend built from plain Python base image; installs apps from apps.json; suitable for production and testing; ideal when you need control over Python/Node versions
  • images/layered/ - Same final contents as custom but based on prebuilt images from Docker Hub; faster builds for production when using Frappe-managed dependency versions
  • images/production/ - Installs only Frappe and ERPNext (not customizable with apps.json); best for quick starts or exploration; for real deployments, use custom or layered

Note: For detailed build arguments and advanced configuration options, see docs/02-setup/01-overview.md.

📁 overrides/ - Compose File Extensions ​

Docker Compose "overrides" that extend the base compose.yaml for different scenarios:

  • compose.mariadb.yaml - Adds MariaDB database service
  • compose.redis.yaml - Adds Redis caching service
  • compose.proxy.yaml - Adds Traefik reverse proxy for multi-site hosting (label-based routing)
  • compose.https.yaml - Adds Traefik HTTPS + automatic certs (uses SITES_RULE)
  • compose.nginxproxy.yaml - Adds nginx-proxy reverse proxy (HTTP, env-based VIRTUAL_HOST)
  • compose.nginxproxy-ssl.yaml - Adds nginx-proxy + acme-companion (HTTPS, env-based LETSENCRYPT_HOST)

Proxy choice:

  • Traefik is more flexible for advanced routing and multi-bench setups
  • nginx-proxy is simpler for a single bench with host-based routing.

📁 development/ - Dev Environment ​

  • development/installer.py - Automated bench/site creation and configuration script
  • Contains your local development files (git-ignored to prevent accidental commits)

📁 resources/ - Runtime Templates ​

  • core/nginx/nginx-entrypoint.sh - Dynamic Nginx configuration generator script
  • core/nginx/nginx-template.conf - Nginx configuration template with variable substitution

Custom Apps Explained ​

What Are Frappe Custom Apps? ​

Custom apps are self-contained, modular business applications that extend Frappe's functionality. They follow a convention-over-configuration approach where the framework provides most boilerplate automatically.

Custom App Structure ​

my_custom_app/
├── hooks.py                    # App configuration and hooks into Frappe lifecycle
├── modules.txt                 # List of business modules in this app
├── my_custom_app/
│   ├── __init__.py
│   ├── config/
│   │   └── desktop.py          # Desktop workspace icons and shortcuts
│   ├── my_module/              # Business domain module (e.g., sales, inventory)
│   │   ├── doctype/           # Document Types (data models)
│   │   │   ├── customer/
│   │   │   │   ├── customer.py      # Python controller (business logic)
│   │   │   │   ├── customer.json    # Model definition (schema, validation)
│   │   │   │   └── customer.js      # Frontend logic (UI interactions)
│   │   └── page/              # Custom pages (dashboards, reports)
│   ├── public/               # Static assets (CSS, JS, images)
│   ├── templates/            # Jinja2 templates for web pages
│   └── www/                  # Web pages accessible via routes
└── requirements.txt          # Python package dependencies

Built-in Features (Auto-generated) ​

Every Frappe app automatically includes:

  • REST API - Automatic CRUD endpoints from DocType definitions
  • Permissions system - Row-level and field-level access control
  • Audit trails - Automatic version tracking and change history
  • Custom fields - Runtime field additions without code changes
  • Workflows - Configurable approval and state management
  • Reports - Query builder and report designer
  • Print formats - PDF generation with custom templates
  • Email integration - Template-based email sending
  • File attachments - Document attachment management

Creating Custom Apps ​

bash
# Enter the development container
docker exec -it <container_name> bash

# Create new app (interactive prompts will ask for details)
bench new-app my_custom_app

# Install app to a site
bench --site mysite.com install-app my_custom_app

# Create a new DocType (data model)
bench --site mysite.com console
>>> bench.new_doc("DocType", {...})
# Or use the web UI: Setup → Customize → DocType → New

Development Workflow ​

Quick Test Setup (pwd.yml) ​

Perfect for evaluating Frappe Docker without any local setup:

bash
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
docker compose -f pwd.yml up -d

# Monitor site creation (takes ~5 minutes)
docker compose -f pwd.yml logs -f create-site

# Access once "create-site" container exits successfully
# Visit http://localhost:8080
# Login: Administrator / admin

Full Development Setup ​

For active development with hot-reload and debugging:

  1. Copy devcontainer configuration:

    bash
    cp -R devcontainer-example .devcontainer
  2. Open in VSCode with Dev Containers extension (Remote - Containers)

    • VSCode will detect .devcontainer and prompt to reopen in container
  3. Run automated installer:

    bash
    cd /workspace/development
    python installer.py
    # Follow interactive prompts for site name, apps to install, etc.
  4. Access development files:

    development/frappe-bench/  # Your live development environment

Development File Locations ​

development/
├── frappe-bench/           # Your actual Frappe installation
│   ├── apps/              # All installed Frappe applications
│   │   ├── frappe/        # Core framework (don't modify directly)
│   │   ├── erpnext/       # ERPNext application (if installed)
│   │   └── my_custom_app/ # Your custom apps (edit freely)
│   ├── sites/             # Multi-tenant sites
│   │   ├── development.localhost/     # Default dev site
│   │   │   ├── site_config.json      # Site-specific config
│   │   │   └── private/files/        # Uploaded files
│   │   └── common_site_config.json   # Shared configuration
│   ├── env/               # Python virtual environment
│   ├── logs/              # Application logs
│   └── config/            # Bench-level configuration
└── .vscode/               # VSCode workspace settings

Common Development Commands ​

bash
# Inside container
bench start  # Start development server with hot-reload

# Database operations
bench migrate  # Run database migrations
bench --site mysite.com migrate  # Site-specific migration

# Frontend builds
bench build  # Build all app assets
bench build --app my_custom_app  # Build specific app

# Code generation
bench new-app <app_name>  # Create new app
bench new-site <site_name>  # Create new site

# App management
bench get-app <git_url>  # Download app from git
bench install-app <app_name>  # Install app to current site
bench uninstall-app <app_name>  # Remove app from site

# Debugging
bench console  # Python REPL with Frappe context
bench mariadb  # Database console

Platform Notes ​

ARM64 and Apple Silicon ​

  • Enable Docker Desktop's Rosetta emulation for initial builds when running on Apple Silicon with x86-only images.
  • Prefer published multi-arch images (frappe/bench, frappe/erpnext) or build locally with docker buildx bake --set *.platform=linux/amd64,linux/arm64 to cover both architectures in one pass.
  • When using pwd.yml, export DOCKER_DEFAULT_PLATFORM=linux/arm64 (or select the provided compose profile) to avoid unexpected emulation.
  • Keep bind mounts under your user home directory and apply :cached or :delegated consistency flags for better performance on macOS.

File Locations and Access ​

Accessing Container Files ​

bash
# Enter backend container shell
docker compose -f pwd.yml exec backend bash

# Navigate to bench directory
cd /home/frappe/frappe-bench/

# Key directories:
/home/frappe/frappe-bench/apps/     # All Frappe apps
/home/frappe/frappe-bench/sites/    # Site data and configuration
/home/frappe/frappe-bench/logs/     # Application logs
/home/frappe/frappe-bench/env/      # Python virtual environment

Copying Files from Containers ​

bash
# Copy entire app from container to host
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/apps/my_app ./local-apps/

# Copy logs
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/logs/ ./debug-logs/

# Copy site files
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/sites/mysite.com ./backup/

Useful Container Commands ​

bash
# List all sites
docker compose -f pwd.yml exec backend bench list-sites

# List installed apps for a site
docker compose -f pwd.yml exec backend bench --site mysite.com list-apps

# View site configuration
docker compose -f pwd.yml exec backend cat /home/frappe/frappe-bench/sites/common_site_config.json

# Check logs in real-time
docker compose -f pwd.yml logs -f backend

# Execute bench command
docker compose -f pwd.yml exec backend bench --site mysite.com console

# Backup site
docker compose -f pwd.yml exec backend bench --site mysite.com backup --with-files

Docker Concepts: Bind Mounts ​

What Are Bind Mounts? ​

Bind mounts create a direct connection between a directory on your host machine and a directory inside a container. Changes in either location are immediately reflected in the other - perfect for development where you want to edit code on your host and see changes in the container.

Bind Mount vs Named Volume vs Anonymous Volume ​

TypeSyntaxUse CasePersistence
Bind Mount./local/path:/container/pathDevelopment, config filesOn host filesystem
Named Volumevolume_name:/container/pathProduction data, databasesDocker-managed
Anonymous Volume/container/pathTemporary/cache dataDocker-managed, auto-deleted

Bind Mount Examples ​

yaml
services:
  backend:
    volumes:
      # Development: Edit code on host, run in container
      - ./my_custom_app:/home/frappe/frappe-bench/apps/my_custom_app

      # Configuration: Override container config with host file
      - ./custom-config.json:/home/frappe/frappe-bench/sites/common_site_config.json:ro # :ro = read-only

      # Logs: Access container logs on host for debugging
      - ./logs:/home/frappe/frappe-bench/logs

      # Database (not recommended for production)
      - ./data/mysql:/var/lib/mysql

  # Named volume for production database
  db:
    volumes:
      - db_data:/var/lib/mysql # Managed by Docker, survives container deletion

volumes:
  db_data: # Define named volume

Performance Optimization (macOS/Windows) ​

Docker on macOS/Windows uses a VM, making bind mounts slower. Use these flags:

yaml
volumes:
  # :cached - Host writes are buffered (good for general development)
  - ./development:/home/frappe/frappe-bench:cached

  # :delegated - Container writes are buffered (best when container writes heavily)
  - ./development:/home/frappe/frappe-bench:delegated

  # :consistent - Full synchronization (slowest but safest)
  - ./development:/home/frappe/frappe-bench:consistent

Recommendation: Use :cached for most development work on macOS/Windows.

Fork Management Best Practices ​

Initial Fork Setup ​

bash
# 1. Fork on GitHub (use the Fork button)

# 2. Clone YOUR fork
git clone https://github.com/YOUR_USERNAME/frappe_docker
cd frappe_docker

# 3. Add upstream remote (original repo)
git remote add upstream https://github.com/frappe/frappe_docker.git

# 4. Verify remotes
git remote -v
# origin    https://github.com/YOUR_USERNAME/frappe_docker (your fork)
# upstream  https://github.com/frappe/frappe_docker (original)

# 5. Create development branch
git checkout -b my-custom-setup

Safe Customization Zones ​

✅ Safe (Won't conflict with upstream):

development/                    # Your entire dev environment
  ├── frappe-bench/            # Local installation
  └── .vscode/                 # Your editor settings

compose.my-*.yaml              # Your custom compose overrides
scripts/my-*.sh                # Your custom scripts
docs/my-*.md                   # Your custom documentation
.env.local                     # Local environment overrides
.gitignore.local              # Additional gitignore rules

⚠️ Modification Needed (May conflict):

compose.yaml                   # Core - use overrides instead
docker-bake.hcl               # Build config - use custom files
images/*/Dockerfile           # Core images - extend rather than modify

❌ Never Modify (Will break upstream sync):

.github/workflows/            # CI/CD pipelines
images/*/                     # Core image definitions
resources/                    # Core templates

Keeping Fork Updated ​

bash
# Regularly sync with upstream (weekly recommended)
git checkout main
git fetch upstream
git merge upstream/main
git push origin main

# Update your development branch
git checkout my-custom-setup
git rebase main  # Or: git merge main

# If conflicts occur during rebase:
# 1. Fix conflicts in files
# 2. git add <fixed-files>
# 3. git rebase --continue
# Or: git rebase --abort  (to cancel)

Custom Environment Pattern ​

Create override files for your customizations:

yaml
# compose.my-env.yaml
version: "3.7"

services:
  backend:
    environment:
      # Your custom environment variables
      - DEVELOPER_MODE=true
      - MY_API_KEY=${MY_API_KEY}
    volumes:
      # Your custom bind mounts
      - ./development/my-scripts:/home/frappe/my-scripts
      - ./development/my-config:/home/frappe/config

  # Your additional services
  my-monitoring:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
# Use it:
# docker compose -f compose.yaml -f compose.my-env.yaml up

.gitignore Strategy ​

Add to .gitignore (or create .gitignore.local):

gitignore
# Local environment files
.env.local
*.local.yaml
compose.my-*.yaml

# Development artifacts
development/frappe-bench/sites/*
development/frappe-bench/apps/*
!development/frappe-bench/apps.json
development/frappe-bench/logs/
development/frappe-bench/env/

# Local customizations
my-local-configs/
scripts/my-*.sh
docs/internal-*.md

# IDE
.vscode/settings.json.local
.idea/

# Temporary files
*.swp
*.swo
*~
.DS_Store

Contributing Back to Upstream ​

bash
# 1. Create feature branch from main
git checkout main
git pull upstream main
git checkout -b feature/my-improvement

# 2. Make changes and commit
git add .
git commit -m "feat: add awesome feature"

# 3. Push to YOUR fork
git push origin feature/my-improvement

# 4. Create Pull Request on GitHub
# Go to: https://github.com/frappe/frappe_docker
# Click "Compare & pull request"

Quick Start Examples ​

1. Quick Test (5 minutes) ​

Goal: Try Frappe/ERPNext without any local setup

bash
# Clone and run
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
docker compose -f pwd.yml up -d

# Monitor setup progress (~5 minutes)
docker compose -f pwd.yml logs -f create-site

# When complete, access:
# URL: http://localhost:8080
# Username: Administrator
# Password: admin

# Cleanup when done
docker compose -f pwd.yml down -v

2. Development Environment (15 minutes) ​

Goal: Set up for daily development with hot-reload

bash
# Copy devcontainer config
cp -R devcontainer-example .devcontainer

# Open in VSCode
# 1. Install "Dev Containers" extension
# 2. Command Palette (Ctrl+Shift+P) → "Reopen in Container"
# 3. Wait for container build (~5 min first time)

# Inside container terminal:
cd /workspace/development
python installer.py

# Follow prompts:
# - Site name: development.localhost
# - Install ERPNext: Yes
# - Version: version-15

# Start development server
cd frappe-bench
bench start

# Access: http://localhost:8000
# Edit files in: development/frappe-bench/apps/

3. Custom App Development (30 minutes) ​

Goal: Create and develop a custom Frappe application

bash
# Prerequisite: Complete Example 2 first

# Inside development container
cd /workspace/development/frappe-bench

# Create new app
bench new-app library_management
# Follow prompts (title, description, publisher, etc.)

# Install to site
bench --site development.localhost install-app library_management

# Create DocTypes via web UI:
# 1. Go to: http://localhost:8000
# 2. Setup → Customize → DocType → New
# 3. Create: Book, Author, Borrower, etc.

# Or create via code:
# Edit: apps/library_management/library_management/library_management/doctype/

# Build and reload
bench build --app library_management
# Server auto-reloads (bench start watches for changes)

4. Production Deployment (1 hour) ​

Goal: Deploy Frappe in production with SSL

bash
# Follow detailed guide
# See: docs/single-server-example.md

# Quick overview:
# 1. Setup server with Docker
# 2. Clone frappe_docker
# 3. Configure environment variables
# 4. Use compose.yaml + production overrides
# 5. Setup SSL with Traefik/Let's Encrypt
# 6. Deploy and monitor

# Key files:
# - compose.yaml
# - compose.mariadb.yaml
# - compose.redis.yaml
# - compose.proxy.yaml
# - compose.https.yaml

# Deploy command:
docker compose \
  -f compose.yaml \
  -f overrides/compose.mariadb.yaml \
  -f overrides/compose.redis.yaml \
  -f overrides/compose.https.yaml \
  up -d

5. Multi-Site Hosting ​

Goal: Host multiple Frappe sites on one server

bash
# See: docs/port-based-multi-tenancy.md

# Quick example:
# 1. Create multiple sites in development
bench new-site site1.com
bench new-site site2.com

# 2. Configure Nginx/Traefik for routing
# 3. Each site gets own database
# 4. Shared Redis and application code

Framework Comparisons ​

Note: This section provides comparisons to other frameworks for developers familiar with them. If you're new to all frameworks, you can skip this section - the rest of the guide is self-contained.

Frappe vs Django Concepts ​

Project Structure Comparison ​

Django Project:

python
myproject/
├── myproject/          # Project settings
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── blog/              # Django app
│   ├── models.py
│   ├── views.py
│   └── urls.py
├── shop/              # Django app
└── users/             # Django app

Frappe Bench:

bench/
├── apps/
│   ├── frappe/        # Core framework (comparable to Django itself)
│   ├── erpnext/       # Complete business app (like Django + DRF + Celery + admin)
│   ├── hrms/          # HR Management app
│   └── my_custom_app/ # YOUR custom app
└── sites/
    └── mysite.com/    # Site instance (like Django project + database)
        ├── site_config.json
        └── private/files/

Conceptual Mapping ​

DjangoFrappeNotes
ModelDocTypeBut includes UI, permissions, API automatically
ViewController methodMuch less code needed
AdminDeskMore powerful, auto-generated
DRF SerializerBuilt-inAutomatic from DocType
Celery taskBackground jobBuilt-in, no separate setup
signalshooks.pyMore structured
Management commandbench commandMore discoverable

Key Architectural Differences ​

  1. Multi-tenancy

    • Django: One app = one database (typically)
    • Frappe: One installation = many sites, each with own database
  2. Background Jobs

    • Django: Requires Celery + Redis + worker setup
    • Frappe: Built-in queue system, just use enqueue()
  3. Real-time

    • Django: Requires Channels + Redis + ASGI setup
    • Frappe: Socket.IO built-in, automatic for DocType updates
  4. Admin/Management

    • Django: Admin for models, basic CRUD
    • Frappe: Full-featured Desk with reports, dashboards, permissions
  5. API

    • Django: Manual DRF setup, serializers, views
    • Frappe: Automatic REST + RPC from DocType definitions

Code Comparison Example ​

Creating a "Customer" model:

Django (requires ~50+ lines):

python
# models.py
class Customer(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

# serializers.py
class CustomerSerializer(serializers.ModelSerializer):
    # ...

# views.py
class CustomerViewSet(viewsets.ModelViewSet):
    # ...

# urls.py
router.register(r'customers', CustomerViewSet)

# admin.py
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    # ...

Frappe (DocType JSON + ~10 lines Python):

json
// customer.json (auto-generated via UI or code)
{
  "name": "Customer",
  "fields": [
    { "fieldname": "customer_name", "fieldtype": "Data" },
    { "fieldname": "email", "fieldtype": "Data", "unique": 1 }
  ]
}
python
# customer.py (only for custom business logic)
import frappe
from frappe.model.document import Document

class Customer(Document):
    def validate(self):
        # Custom validation logic only
        pass

✅ Automatically includes:

  • REST API (/api/resource/Customer)
  • List view, Form view
  • Search, Filters, Sorting
  • Permissions (Create, Read, Update, Delete)
  • Audit trail (created_by, modified_by, versions)
  • Print formats, Email templates

When to Choose Frappe vs Django ​

Choose Frappe when:

  • Building business applications (ERP, CRM, project management)
  • Need multi-tenancy out-of-the-box
  • Want rapid development with auto-generated UI
  • Need role-based permissions and workflows
  • Building for non-technical users who need customization

Choose Django when:

  • Building consumer web apps (social media, e-commerce frontend)
  • Need full control over every aspect
  • Have highly custom UI requirements
  • Team is already Django-expert
  • Building API-only services

Hybrid Approach: Many teams use both: Frappe for back-office/admin tools, Django for customer-facing web apps.


Resources and References ​

Official Documentation ​

Key Files in This Repository ​

Community Resources ​

Essential Docker Commands Reference ​

bash
# Service Management
docker compose up -d              # Start all services in background
docker compose down               # Stop and remove containers
docker compose down -v            # Stop and remove volumes (data loss!)
docker compose restart <service>  # Restart specific service
docker compose ps                 # List running services
docker compose logs -f <service>  # Follow logs for service

# Container Access
docker compose exec <service> bash    # Open shell in running container
docker compose exec <service> <cmd>   # Run command in container
docker compose run <service> <cmd>    # Run one-off command (creates new container)

# Debugging
docker compose logs --tail=100 <service>  # Last 100 log lines
docker compose top                        # Show running processes
docker inspect <container_name>           # Detailed container info

# Cleanup
docker system prune              # Remove unused containers/networks
docker volume prune              # Remove unused volumes (BE CAREFUL!)
docker image prune               # Remove unused images

Essential Bench Commands Reference ​

bash
# Site Operations
bench new-site <site_name>                    # Create new site
bench drop-site <site_name>                   # Delete site (asks confirmation)
bench list-sites                              # List all sites
bench use <site_name>                         # Set default site

# App Operations
bench get-app <git_url>                       # Download app from git
bench get-app <app_name>                      # Download from Frappe registry
bench install-app <app_name>                  # Install to default site
bench install-app <app_name> --site <site>   # Install to specific site
bench uninstall-app <app_name>               # Uninstall from default site
bench list-apps                              # List installed apps

# Development
bench start                      # Start development server (hot-reload)
bench build                      # Build frontend assets
bench build --app <app_name>    # Build specific app
bench migrate                    # Run database migrations
bench clear-cache                # Clear Redis cache
bench clear-website-cache        # Clear website route cache

# Database
bench mariadb                    # Open MariaDB console
bench backup                     # Backup default site
bench backup --with-files        # Backup with uploaded files
bench restore <path>             # Restore backup

# Code Generation
bench new-app <app_name>                      # Create new app
bench --site <site> console                   # Python REPL with Frappe context
bench --site <site> execute "<python_code>"   # Execute Python code

# Deployment
bench setup production <user>    # Setup for production (supervisor, nginx)
bench restart                    # Restart bench processes
bench update                     # Update framework and apps

Troubleshooting Quick Reference ​

IssueSolution
Port 8080 already in useChange PWD_PORT in .env or stop other service
Container won't startCheck logs: docker compose logs <service>
Site creation failsCheck create-site logs, ensure DB is ready
Can't connect to siteWait 5 min for initialization, check container health
Permission errorsCheck volume permissions, may need chown
Out of disk spacedocker system prune -a --volumes (CAREFUL!)
Python packages missingbench pip install <package> inside container
Frontend not buildingbench build --force, check Node.js errors
Database connection failsCheck common_site_config.json, Redis/MariaDB status

Getting Help ​

  1. Check existing docs - Most issues covered in `docs/07-troubleshooting/01-troubleshoot.md
  2. Search Frappe Forum - discuss.frappe.io
  3. GitHub Issues - Search existing issues first
  4. Discord/Telegram - Community real-time chat (links in main repo)

Contributing ​

Found issues or improvements for this guide?

  • Create an issue: frappe_docker/issues
  • Submit focused PRs: keep updates scoped and split large efforts across multiple pull requests.
  • Review CONTRIBUTING.md: for coding standards and review expectations.

This guide provides a comprehensive overview of Frappe Docker for developers of all backgrounds. For specific use cases or advanced topics, refer to the linked documentation.

Last updated: October 2025