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