mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-25 16:55:08 +00:00
style: apply pre-commit formatting
- Fix end-of-file newline - Apply prettier markdown formatting
This commit is contained in:
parent
2926e183bc
commit
1447e2e997
1 changed files with 172 additions and 80 deletions
|
|
@ -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_
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue