style: apply pre-commit formatting

- Fix end-of-file newline
- Apply prettier markdown formatting
This commit is contained in:
duthink 2025-10-23 23:26:42 +05:30
parent 2926e183bc
commit 1447e2e997

View file

@ -1,8 +1,10 @@
# Getting Started with Frappe Docker # Getting Started with Frappe Docker
*A comprehensive guide for developers getting started with Frappe Docker, with comparisons to Django for developers familiar with that framework* _A comprehensive guide for developers getting started with Frappe Docker, with
comparisons to Django for developers familiar with that framework_
## Table of Contents ## Table of Contents
- [Understanding Frappe Docker Architecture](#understanding-frappe-docker-architecture) - [Understanding Frappe Docker Architecture](#understanding-frappe-docker-architecture)
- [Repository Structure](#repository-structure) - [Repository Structure](#repository-structure)
- [Custom Apps Explained](#custom-apps-explained) - [Custom Apps Explained](#custom-apps-explained)
@ -19,9 +21,13 @@
## Understanding Frappe Docker Architecture ## 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. 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 ### Core Services
- **backend** - Gunicorn WSGI server running Frappe applications - **backend** - Gunicorn WSGI server running Frappe applications
- **frontend** - Nginx for static files and reverse proxy - **frontend** - Nginx for static files and reverse proxy
- **queue-short/long** - Background job workers for asynchronous task processing - **queue-short/long** - Background job workers for asynchronous task processing
@ -32,7 +38,7 @@ Frappe Docker provides a comprehensive containerized environment for developing
### How Services Work Together ### How Services Work Together
``` ```text
User Request User Request
[frontend (Nginx)] → Static files served directly [frontend (Nginx)] → Static files served directly
@ -40,7 +46,7 @@ User Request
[backend (Gunicorn)] → Dynamic content processing [backend (Gunicorn)] → Dynamic content processing
↓ ↓ ↓ ↓
[db (MariaDB)] [redis-cache] [db (MariaDB)] [redis-cache]
Background Tasks: Background Tasks:
[scheduler] → [redis-queue] → [queue-short/long workers] [scheduler] → [redis-queue] → [queue-short/long workers]
@ -51,39 +57,56 @@ Real-time:
## Repository Structure ## Repository Structure
### 📁 Core Configuration Files ### 📁 Core Configuration Files
- **compose.yaml** - Main Docker Compose file defining all services - **compose.yaml** - Main Docker Compose file defining all services
- **example.env** - Environment variables template (copy to `.env`) - **example.env** - Environment variables template (copy to `.env`)
- **pwd.yml** - "Play with Docker" - simplified single-file setup for quick testing - **pwd.yml** - "Play with Docker" - simplified single-file setup for quick
- **docker-bake.hcl** - Advanced Docker Buildx configuration for multi-architecture builds testing
- **docker-bake.hcl** - Advanced Docker Buildx configuration for
multi-architecture builds
### 📁 images/ - Docker Image Definitions ### 📁 images/ - Docker Image Definitions
- **images/bench/** - Development container with full Frappe tooling and CLI - **images/bench/** - Development container with full Frappe tooling and CLI
- **images/production/** - Production-optimized containers (smaller, security-hardened) - **images/production/** - Production-optimized containers (smaller,
security-hardened)
- **images/custom/** - Build custom apps using apps.json configuration - **images/custom/** - Build custom apps using apps.json configuration
- **images/layered/** - Optimized layered builds for faster rebuilds - **images/layered/** - Optimized layered builds for faster rebuilds
### 📁 overrides/ - Compose File Extensions ### 📁 overrides/ - Compose File Extensions
Docker Compose "overrides" that extend the base compose.yaml for different scenarios:
Docker Compose "overrides" that extend the base compose.yaml for different
scenarios:
- **compose.mariadb.yaml** - Adds MariaDB database service - **compose.mariadb.yaml** - Adds MariaDB database service
- **compose.redis.yaml** - Adds Redis caching service - **compose.redis.yaml** - Adds Redis caching service
- **compose.proxy.yaml** - Adds Traefik reverse proxy for multi-site hosting - **compose.proxy.yaml** - Adds Traefik reverse proxy for multi-site hosting
- **compose.https.yaml** - Adds SSL/TLS certificate management - **compose.https.yaml** - Adds SSL/TLS certificate management
### 📁 development/ - Dev Environment ### 📁 development/ - Dev Environment
- **development/installer.py** - Automated bench/site creation and configuration script
- Contains your local development files (git-ignored to prevent accidental commits) - **development/installer.py** - Automated bench/site creation and configuration
script
- Contains your local development files (git-ignored to prevent accidental
commits)
### 📁 resources/ - Runtime Templates ### 📁 resources/ - Runtime Templates
- **nginx-entrypoint.sh** - Dynamic Nginx configuration generator script - **nginx-entrypoint.sh** - Dynamic Nginx configuration generator script
- **nginx-template.conf** - Nginx configuration template with variable substitution - **nginx-template.conf** - Nginx configuration template with variable
substitution
## Custom Apps Explained ## Custom Apps Explained
### What Are Frappe Custom Apps? ### 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 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 ### Custom App Structure
```
```text
my_custom_app/ my_custom_app/
├── hooks.py # App configuration and hooks into Frappe lifecycle ├── hooks.py # App configuration and hooks into Frappe lifecycle
├── modules.txt # List of business modules in this app ├── modules.txt # List of business modules in this app
@ -105,7 +128,9 @@ my_custom_app/
``` ```
### Built-in Features (Auto-generated) ### Built-in Features (Auto-generated)
Every Frappe app automatically includes: Every Frappe app automatically includes:
- **REST API** - Automatic CRUD endpoints from DocType definitions - **REST API** - Automatic CRUD endpoints from DocType definitions
- **Permissions system** - Row-level and field-level access control - **Permissions system** - Row-level and field-level access control
- **Audit trails** - Automatic version tracking and change history - **Audit trails** - Automatic version tracking and change history
@ -117,6 +142,7 @@ Every Frappe app automatically includes:
- **File attachments** - Document attachment management - **File attachments** - Document attachment management
### Creating Custom Apps ### Creating Custom Apps
```bash ```bash
# Enter the development container # Enter the development container
docker exec -it <container_name> bash docker exec -it <container_name> bash
@ -136,11 +162,12 @@ bench --site mysite.com console
## Development Workflow ## Development Workflow
### Quick Test Setup (pwd.yml) ### Quick Test Setup (pwd.yml)
Perfect for evaluating Frappe Docker without any local setup: Perfect for evaluating Frappe Docker without any local setup:
```bash ```bash
git clone https://github.com/frappe/frappe_docker git clone https://github.com/frappe/frappe_docker
cd frappe_docker cd frappe_docker
docker compose -f pwd.yml up -d docker compose -f pwd.yml up -d
# Monitor site creation (takes ~5 minutes) # Monitor site creation (takes ~5 minutes)
@ -152,17 +179,21 @@ docker compose -f pwd.yml logs -f create-site
``` ```
### Full Development Setup ### Full Development Setup
For active development with hot-reload and debugging: For active development with hot-reload and debugging:
1. **Copy devcontainer configuration:** 1. **Copy devcontainer configuration:**
```bash ```bash
cp -R devcontainer-example .devcontainer cp -R devcontainer-example .devcontainer
``` ```
2. **Open in VSCode with Dev Containers extension** (Remote - Containers) 2. **Open in VSCode with Dev Containers extension** (Remote - Containers)
- VSCode will detect `.devcontainer` and prompt to reopen in container - VSCode will detect `.devcontainer` and prompt to reopen in container
3. **Run automated installer:** 3. **Run automated installer:**
```bash ```bash
cd /workspace/development cd /workspace/development
python installer.py python installer.py
@ -170,12 +201,14 @@ For active development with hot-reload and debugging:
``` ```
4. **Access development files:** 4. **Access development files:**
```
```text
development/frappe-bench/ # Your live development environment development/frappe-bench/ # Your live development environment
``` ```
### Development File Locations ### Development File Locations
```
```text
development/ development/
├── frappe-bench/ # Your actual Frappe installation ├── frappe-bench/ # Your actual Frappe installation
│ ├── apps/ # All installed Frappe applications │ ├── apps/ # All installed Frappe applications
@ -194,6 +227,7 @@ development/
``` ```
### Common Development Commands ### Common Development Commands
```bash ```bash
# Inside container # Inside container
bench start # Start development server with hot-reload bench start # Start development server with hot-reload
@ -223,6 +257,7 @@ bench mariadb # Database console
## File Locations and Access ## File Locations and Access
### Accessing Container Files ### Accessing Container Files
```bash ```bash
# Enter backend container shell # Enter backend container shell
docker compose -f pwd.yml exec backend bash docker compose -f pwd.yml exec backend bash
@ -238,18 +273,23 @@ cd /home/frappe/frappe-bench/
``` ```
### Copying Files from Containers ### Copying Files from Containers
```bash ```bash
# Copy entire app from container to host # Copy entire app from container to host
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/apps/my_app ./local-apps/ docker compose -f pwd.yml cp \
backend:/home/frappe/frappe-bench/apps/my_app ./local-apps/
# Copy logs # Copy logs
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/logs/ ./debug-logs/ docker compose -f pwd.yml cp \
backend:/home/frappe/frappe-bench/logs/ ./debug-logs/
# Copy site files # Copy site files
docker compose -f pwd.yml cp backend:/home/frappe/frappe-bench/sites/mysite.com ./backup/ docker compose -f pwd.yml cp \
backend:/home/frappe/frappe-bench/sites/mysite.com ./backup/
``` ```
### Useful Container Commands ### Useful Container Commands
```bash ```bash
# List all sites # List all sites
docker compose -f pwd.yml exec backend bench list-sites docker compose -f pwd.yml exec backend bench list-sites
@ -258,7 +298,8 @@ docker compose -f pwd.yml exec backend bench list-sites
docker compose -f pwd.yml exec backend bench --site mysite.com list-apps docker compose -f pwd.yml exec backend bench --site mysite.com list-apps
# View site configuration # View site configuration
docker compose -f pwd.yml exec backend cat /home/frappe/frappe-bench/sites/common_site_config.json docker compose -f pwd.yml exec backend \
cat /home/frappe/frappe-bench/sites/common_site_config.json
# Check logs in real-time # Check logs in real-time
docker compose -f pwd.yml logs -f backend docker compose -f pwd.yml logs -f backend
@ -267,59 +308,68 @@ docker compose -f pwd.yml logs -f backend
docker compose -f pwd.yml exec backend bench --site mysite.com console docker compose -f pwd.yml exec backend bench --site mysite.com console
# Backup site # Backup site
docker compose -f pwd.yml exec backend bench --site mysite.com backup --with-files docker compose -f pwd.yml exec backend \
bench --site mysite.com backup --with-files
``` ```
## Docker Concepts: Bind Mounts ## Docker Concepts: Bind Mounts
### What Are 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 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 ### Bind Mount vs Named Volume vs Anonymous Volume
| Type | Syntax | Use Case | Persistence | | Type | Syntax | Use Case | Persistence |
|------|--------|----------|-------------| | -------------------- | ------------------------------ | -------------------------- | ---------------------------- |
| **Bind Mount** | `./local/path:/container/path` | Development, config files | On host filesystem | | **Bind Mount** | `./local/path:/container/path` | Development, config files | On host filesystem |
| **Named Volume** | `volume_name:/container/path` | Production data, databases | Docker-managed | | **Named Volume** | `volume_name:/container/path` | Production data, databases | Docker-managed |
| **Anonymous Volume** | `/container/path` | Temporary/cache data | Docker-managed, auto-deleted | | **Anonymous Volume** | `/container/path` | Temporary/cache data | Docker-managed, auto-deleted |
### Bind Mount Examples ### Bind Mount Examples
```yaml ```yaml
services: services:
backend: backend:
volumes: volumes:
# Development: Edit code on host, run in container # Development: Edit code on host, run in container
- ./my_custom_app:/home/frappe/frappe-bench/apps/my_custom_app - ./my_custom_app:/home/frappe/frappe-bench/apps/my_custom_app
# Configuration: Override container config with host file # Configuration: Override container config with host file
- ./custom-config.json:/home/frappe/frappe-bench/sites/common_site_config.json:ro # :ro = read-only # :ro = read-only
- ./custom-config.json:/home/frappe/frappe-bench/sites/common_site_config.json:ro
# Logs: Access container logs on host for debugging # Logs: Access container logs on host for debugging
- ./logs:/home/frappe/frappe-bench/logs - ./logs:/home/frappe/frappe-bench/logs
# Database (not recommended for production) # Database (not recommended for production)
- ./data/mysql:/var/lib/mysql - ./data/mysql:/var/lib/mysql
# Named volume for production database # Named volume for production database
db: db:
volumes: volumes:
- db_data:/var/lib/mysql # Managed by Docker, survives container deletion # Managed by Docker, survives container deletion
- db_data:/var/lib/mysql
volumes: volumes:
db_data: # Define named volume db_data: # Define named volume
``` ```
### Performance Optimization (macOS/Windows) ### Performance Optimization (macOS/Windows)
Docker on macOS/Windows uses a VM, making bind mounts slower. Use these flags: Docker on macOS/Windows uses a VM, making bind mounts slower. Use these flags:
```yaml ```yaml
volumes: volumes:
# :cached - Host writes are buffered (good for general development) # :cached - Host writes are buffered (good for general development)
- ./development:/home/frappe/frappe-bench:cached - ./development:/home/frappe/frappe-bench:cached
# :delegated - Container writes are buffered (best when container writes heavily) # :delegated - Container writes are buffered (best when container writes heavily)
- ./development:/home/frappe/frappe-bench:delegated - ./development:/home/frappe/frappe-bench:delegated
# :consistent - Full synchronization (slowest but safest) # :consistent - Full synchronization (slowest but safest)
- ./development:/home/frappe/frappe-bench:consistent - ./development:/home/frappe/frappe-bench:consistent
``` ```
@ -329,6 +379,7 @@ volumes:
## Fork Management Best Practices ## Fork Management Best Practices
### Initial Fork Setup ### Initial Fork Setup
```bash ```bash
# 1. Fork on GitHub (use the Fork button) # 1. Fork on GitHub (use the Fork button)
@ -351,7 +402,8 @@ git checkout -b my-custom-setup
### Safe Customization Zones ### Safe Customization Zones
**✅ Safe (Won't conflict with upstream):** **✅ Safe (Won't conflict with upstream):**
```
```text
development/ # Your entire dev environment development/ # Your entire dev environment
├── frappe-bench/ # Local installation ├── frappe-bench/ # Local installation
└── .vscode/ # Your editor settings └── .vscode/ # Your editor settings
@ -364,20 +416,23 @@ docs/my-*.md # Your custom documentation
``` ```
**⚠️ Modification Needed (May conflict):** **⚠️ Modification Needed (May conflict):**
```
```text
compose.yaml # Core - use overrides instead compose.yaml # Core - use overrides instead
docker-bake.hcl # Build config - use custom files docker-bake.hcl # Build config - use custom files
images/*/Dockerfile # Core images - extend rather than modify images/*/Dockerfile # Core images - extend rather than modify
``` ```
**❌ Never Modify (Will break upstream sync):** **❌ Never Modify (Will break upstream sync):**
```
```text
.github/workflows/ # CI/CD pipelines .github/workflows/ # CI/CD pipelines
images/production/ # Production containers images/production/ # Production containers
resources/ # Core templates resources/ # Core templates
``` ```
### Keeping Fork Updated ### Keeping Fork Updated
```bash ```bash
# Regularly sync with upstream (weekly recommended) # Regularly sync with upstream (weekly recommended)
git checkout main git checkout main
@ -397,6 +452,7 @@ git rebase main # Or: git merge main
``` ```
### Custom Environment Pattern ### Custom Environment Pattern
Create override files for your customizations: Create override files for your customizations:
```yaml ```yaml
@ -413,7 +469,7 @@ services:
# Your custom bind mounts # Your custom bind mounts
- ./development/my-scripts:/home/frappe/my-scripts - ./development/my-scripts:/home/frappe/my-scripts
- ./development/my-config:/home/frappe/config - ./development/my-config:/home/frappe/config
# Your additional services # Your additional services
my-monitoring: my-monitoring:
image: prom/prometheus image: prom/prometheus
@ -421,12 +477,12 @@ services:
- "9090:9090" - "9090:9090"
volumes: volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
# Use it: # Use it:
# docker compose -f compose.yaml -f compose.my-env.yaml up # docker compose -f compose.yaml -f compose.my-env.yaml up
``` ```
### .gitignore Strategy ### .gitignore Strategy
Add to `.gitignore` (or create `.gitignore.local`): Add to `.gitignore` (or create `.gitignore.local`):
```gitignore ```gitignore
@ -459,6 +515,7 @@ docs/internal-*.md
``` ```
### Contributing Back to Upstream ### Contributing Back to Upstream
```bash ```bash
# 1. Create feature branch from main # 1. Create feature branch from main
git checkout main git checkout main
@ -480,6 +537,7 @@ git push origin feature/my-improvement
## Quick Start Examples ## Quick Start Examples
### 1. Quick Test (5 minutes) ### 1. Quick Test (5 minutes)
**Goal:** Try Frappe/ERPNext without any local setup **Goal:** Try Frappe/ERPNext without any local setup
```bash ```bash
@ -501,6 +559,7 @@ docker compose -f pwd.yml down -v
``` ```
### 2. Development Environment (15 minutes) ### 2. Development Environment (15 minutes)
**Goal:** Set up for daily development with hot-reload **Goal:** Set up for daily development with hot-reload
```bash ```bash
@ -530,6 +589,7 @@ bench start
``` ```
### 3. Custom App Development (30 minutes) ### 3. Custom App Development (30 minutes)
**Goal:** Create and develop a custom Frappe application **Goal:** Create and develop a custom Frappe application
```bash ```bash
@ -559,6 +619,7 @@ bench build --app library_management
``` ```
### 4. Production Deployment (1 hour) ### 4. Production Deployment (1 hour)
**Goal:** Deploy Frappe in production with SSL **Goal:** Deploy Frappe in production with SSL
```bash ```bash
@ -590,6 +651,7 @@ docker compose \
``` ```
### 5. Multi-Site Hosting ### 5. Multi-Site Hosting
**Goal:** Host multiple Frappe sites on one server **Goal:** Host multiple Frappe sites on one server
```bash ```bash
@ -609,13 +671,16 @@ bench new-site site2.com
## Framework Comparisons ## 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. > **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 ### Frappe vs Django Concepts
#### Project Structure Comparison #### Project Structure Comparison
**Django Project:** **Django Project:**
```python ```python
myproject/ myproject/
├── myproject/ # Project settings ├── myproject/ # Project settings
@ -631,7 +696,8 @@ myproject/
``` ```
**Frappe Bench:** **Frappe Bench:**
```
```text
bench/ bench/
├── apps/ ├── apps/
│ ├── frappe/ # Core framework (comparable to Django itself) │ ├── frappe/ # Core framework (comparable to Django itself)
@ -646,31 +712,35 @@ bench/
#### Conceptual Mapping #### Conceptual Mapping
| Django | Frappe | Notes | | Django | Frappe | Notes |
|--------|--------|-------| | ------------------ | ----------------- | ----------------------------------------------- |
| Model | DocType | But includes UI, permissions, API automatically | | Model | DocType | But includes UI, permissions, API automatically |
| View | Controller method | Much less code needed | | View | Controller method | Much less code needed |
| Admin | Desk | More powerful, auto-generated | | Admin | Desk | More powerful, auto-generated |
| DRF Serializer | Built-in | Automatic from DocType | | DRF Serializer | Built-in | Automatic from DocType |
| Celery task | Background job | Built-in, no separate setup | | Celery task | Background job | Built-in, no separate setup |
| signals | hooks.py | More structured | | signals | hooks.py | More structured |
| Management command | bench command | More discoverable | | Management command | bench command | More discoverable |
#### Key Architectural Differences #### Key Architectural Differences
1. **Multi-tenancy** 1. **Multi-tenancy**
- Django: One app = one database (typically) - Django: One app = one database (typically)
- Frappe: One installation = many sites, each with own database - Frappe: One installation = many sites, each with own database
2. **Background Jobs** 2. **Background Jobs**
- Django: Requires Celery + Redis + worker setup - Django: Requires Celery + Redis + worker setup
- Frappe: Built-in queue system, just use `enqueue()` - Frappe: Built-in queue system, just use `enqueue()`
3. **Real-time** 3. **Real-time**
- Django: Requires Channels + Redis + ASGI setup - Django: Requires Channels + Redis + ASGI setup
- Frappe: Socket.IO built-in, automatic for DocType updates - Frappe: Socket.IO built-in, automatic for DocType updates
4. **Admin/Management** 4. **Admin/Management**
- Django: Admin for models, basic CRUD - Django: Admin for models, basic CRUD
- Frappe: Full-featured Desk with reports, dashboards, permissions - Frappe: Full-featured Desk with reports, dashboards, permissions
@ -683,20 +753,21 @@ bench/
**Creating a "Customer" model:** **Creating a "Customer" model:**
Django (requires ~50+ lines): Django (requires ~50+ lines):
```python ```python
# models.py # models.py
class Customer(models.Model): class Customer(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
email = models.EmailField(unique=True) email = models.EmailField(unique=True)
# serializers.py # serializers.py
class CustomerSerializer(serializers.ModelSerializer): class CustomerSerializer(serializers.ModelSerializer):
# ... # ...
# views.py # views.py
class CustomerViewSet(viewsets.ModelViewSet): class CustomerViewSet(viewsets.ModelViewSet):
# ... # ...
# urls.py # urls.py
router.register(r'customers', CustomerViewSet) router.register(r'customers', CustomerViewSet)
@ -707,16 +778,18 @@ class CustomerAdmin(admin.ModelAdmin):
``` ```
Frappe (DocType JSON + ~10 lines Python): Frappe (DocType JSON + ~10 lines Python):
```json ```json
// customer.json (auto-generated via UI or code) // customer.json (auto-generated via UI or code)
{ {
"name": "Customer", "name": "Customer",
"fields": [ "fields": [
{"fieldname": "customer_name", "fieldtype": "Data"}, { "fieldname": "customer_name", "fieldtype": "Data" },
{"fieldname": "email", "fieldtype": "Data", "unique": 1} { "fieldname": "email", "fieldtype": "Data", "unique": 1 }
] ]
} }
``` ```
```python ```python
# customer.py (only for custom business logic) # customer.py (only for custom business logic)
import frappe import frappe
@ -729,6 +802,7 @@ class Customer(Document):
``` ```
✅ **Automatically includes:** ✅ **Automatically includes:**
- REST API (`/api/resource/Customer`) - REST API (`/api/resource/Customer`)
- List view, Form view - List view, Form view
- Search, Filters, Sorting - Search, Filters, Sorting
@ -739,6 +813,7 @@ class Customer(Document):
#### When to Choose Frappe vs Django #### When to Choose Frappe vs Django
**Choose Frappe when:** **Choose Frappe when:**
- Building business applications (ERP, CRM, project management) - Building business applications (ERP, CRM, project management)
- Need multi-tenancy out-of-the-box - Need multi-tenancy out-of-the-box
- Want rapid development with auto-generated UI - Want rapid development with auto-generated UI
@ -746,6 +821,7 @@ class Customer(Document):
- Building for non-technical users who need customization - Building for non-technical users who need customization
**Choose Django when:** **Choose Django when:**
- Building consumer web apps (social media, e-commerce frontend) - Building consumer web apps (social media, e-commerce frontend)
- Need full control over every aspect - Need full control over every aspect
- Have highly custom UI requirements - Have highly custom UI requirements
@ -753,32 +829,42 @@ class Customer(Document):
- Building API-only services - Building API-only services
**Hybrid Approach:** **Hybrid Approach:**
Many teams use both: Frappe for back-office/admin tools, Django for customer-facing web apps. Many teams use both: Frappe for back-office/admin tools, Django for
customer-facing web apps.
--- ---
## Resources and References ## Resources and References
### Official Documentation ### Official Documentation
- [Frappe Framework Docs](https://frappeframework.com/docs) - Core framework documentation
- [Frappe Docker Docs](https://github.com/frappe/frappe_docker/tree/main/docs) - This repository's docs - [Frappe Framework Docs](https://frappeframework.com/docs) - Core framework
- [ERPNext Documentation](https://docs.erpnext.com) - ERPNext user and developer docs documentation
- [Frappe Docker Docs](https://github.com/frappe/frappe_docker/tree/main/docs) -
This repository's docs
- [ERPNext Documentation](https://docs.erpnext.com) - ERPNext user and
developer docs
- [Docker Documentation](https://docs.docker.com) - Docker fundamentals - [Docker Documentation](https://docs.docker.com) - Docker fundamentals
### Key Files in This Repository ### Key Files in This Repository
- [`docs/development.md`](development.md) - Detailed development setup - [`docs/development.md`](development.md) - Detailed development setup
- [`docs/single-server-example.md`](single-server-example.md) - Production deployment guide - [`docs/single-server-example.md`](single-server-example.md) - Production
deployment guide
- [`docs/site-operations.md`](site-operations.md) - Common site management tasks - [`docs/site-operations.md`](site-operations.md) - Common site management tasks
- [`development/installer.py`](../development/installer.py) - Automated setup script - [`development/installer.py`](../development/installer.py) - Automated setup
script
- [`pwd.yml`](../pwd.yml) - Quick test configuration - [`pwd.yml`](../pwd.yml) - Quick test configuration
- [`compose.yaml`](../compose.yaml) - Base Docker Compose configuration - [`compose.yaml`](../compose.yaml) - Base Docker Compose configuration
### Community Resources ### Community Resources
- [Frappe Forum](https://discuss.frappe.io) - Community Q&A - [Frappe Forum](https://discuss.frappe.io) - Community Q&A
- [Frappe School](https://frappe.school) - Video tutorials - [Frappe School](https://frappe.school) - Video tutorials
- [Frappe GitHub](https://github.com/frappe/frappe) - Framework source code - [Frappe GitHub](https://github.com/frappe/frappe) - Framework source code
### Essential Docker Commands Reference ### Essential Docker Commands Reference
```bash ```bash
# Service Management # Service Management
docker compose up -d # Start all services in background docker compose up -d # Start all services in background
@ -805,6 +891,7 @@ docker image prune # Remove unused images
``` ```
### Essential Bench Commands Reference ### Essential Bench Commands Reference
```bash ```bash
# Site Operations # Site Operations
bench new-site <site_name> # Create new site bench new-site <site_name> # Create new site
@ -847,21 +934,22 @@ bench update # Update framework and apps
### Troubleshooting Quick Reference ### Troubleshooting Quick Reference
| Issue | Solution | | Issue | Solution |
|-------|----------| | ------------------------- | ----------------------------------------------------- |
| Port 8080 already in use | Change `PWD_PORT` in `.env` or stop other service | | Port 8080 already in use | Change `PWD_PORT` in `.env` or stop other service |
| Container won't start | Check logs: `docker compose logs <service>` | | Container won't start | Check logs: `docker compose logs <service>` |
| Site creation fails | Check `create-site` logs, ensure DB is ready | | Site creation fails | Check `create-site` logs, ensure DB is ready |
| Can't connect to site | Wait 5 min for initialization, check container health | | Can't connect to site | Wait 5 min for initialization, check container health |
| Permission errors | Check volume permissions, may need `chown` | | Permission errors | Check volume permissions, may need `chown` |
| Out of disk space | `docker system prune -a --volumes` (CAREFUL!) | | Out of disk space | `docker system prune -a --volumes` (CAREFUL!) |
| Python packages missing | `bench pip install <package>` inside container | | Python packages missing | `bench pip install <package>` inside container |
| Frontend not building | `bench build --force`, check Node.js errors | | Frontend not building | `bench build --force`, check Node.js errors |
| Database connection fails | Check `common_site_config.json`, Redis/MariaDB status | | Database connection fails | Check `common_site_config.json`, Redis/MariaDB status |
### Getting Help ### Getting Help
1. **Check existing docs** - Most issues covered in [`docs/troubleshoot.md`](troubleshoot.md) 1. **Check existing docs** - Most issues covered in
[`docs/troubleshoot.md`](troubleshoot.md)
2. **Search Frappe Forum** - [discuss.frappe.io](https://discuss.frappe.io) 2. **Search Frappe Forum** - [discuss.frappe.io](https://discuss.frappe.io)
3. **GitHub Issues** - Search existing issues first 3. **GitHub Issues** - Search existing issues first
4. **Discord/Telegram** - Community real-time chat (links in main repo) 4. **Discord/Telegram** - Community real-time chat (links in main repo)
@ -869,11 +957,15 @@ bench update # Update framework and apps
### Contributing ### Contributing
Found issues or improvements for this guide? Found issues or improvements for this guide?
- Create an issue: [frappe_docker/issues](https://github.com/frappe/frappe_docker/issues)
- Create an issue:
[frappe_docker/issues](https://github.com/frappe/frappe_docker/issues)
- Submit a PR: See [CONTRIBUTING.md](../CONTRIBUTING.md) - Submit a PR: See [CONTRIBUTING.md](../CONTRIBUTING.md)
--- ---
*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.* _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* _Last updated: October 2025_