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
*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
- [Understanding Frappe Docker Architecture](#understanding-frappe-docker-architecture)
- [Repository Structure](#repository-structure)
- [Custom Apps Explained](#custom-apps-explained)
@ -19,9 +21,13 @@
## 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
- **backend** - Gunicorn WSGI server running Frappe applications
- **frontend** - Nginx for static files and reverse proxy
- **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
```
```text
User Request
[frontend (Nginx)] → Static files served directly
@ -40,7 +46,7 @@ User Request
[backend (Gunicorn)] → Dynamic content processing
↓ ↓
[db (MariaDB)] [redis-cache]
Background Tasks:
[scheduler] → [redis-queue] → [queue-short/long workers]
@ -51,39 +57,56 @@ Real-time:
## Repository Structure
### 📁 Core Configuration Files
- **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
- **pwd.yml** - "Play with Docker" - simplified single-file setup for quick
testing
- **docker-bake.hcl** - Advanced Docker Buildx configuration for
multi-architecture builds
### 📁 images/ - Docker Image Definitions
- **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/layered/** - Optimized layered builds for faster rebuilds
### 📁 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.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.https.yaml** - Adds SSL/TLS certificate management
### 📁 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
- **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
### 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
```
```text
my_custom_app/
├── hooks.py # App configuration and hooks into Frappe lifecycle
├── modules.txt # List of business modules in this app
@ -105,7 +128,9 @@ my_custom_app/
```
### 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
@ -117,6 +142,7 @@ Every Frappe app automatically includes:
- **File attachments** - Document attachment management
### Creating Custom Apps
```bash
# Enter the development container
docker exec -it <container_name> bash
@ -136,11 +162,12 @@ bench --site mysite.com console
## 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
cd frappe_docker
docker compose -f pwd.yml up -d
# Monitor site creation (takes ~5 minutes)
@ -152,17 +179,21 @@ docker compose -f pwd.yml logs -f create-site
```
### 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
@ -170,12 +201,14 @@ For active development with hot-reload and debugging:
```
4. **Access development files:**
```
```text
development/frappe-bench/ # Your live development environment
```
### Development File Locations
```
```text
development/
├── frappe-bench/ # Your actual Frappe installation
│ ├── apps/ # All installed Frappe applications
@ -194,6 +227,7 @@ development/
```
### Common Development Commands
```bash
# Inside container
bench start # Start development server with hot-reload
@ -223,6 +257,7 @@ bench mariadb # Database console
## File Locations and Access
### Accessing Container Files
```bash
# Enter backend container shell
docker compose -f pwd.yml exec backend bash
@ -238,18 +273,23 @@ cd /home/frappe/frappe-bench/
```
### 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/
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/
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/
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
@ -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
# 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
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
# 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
### 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
| Type | Syntax | Use Case | Persistence |
|------|--------|----------|-------------|
| **Bind Mount** | `./local/path:/container/path` | Development, config files | On host filesystem |
| **Named Volume** | `volume_name:/container/path` | Production data, databases | Docker-managed |
| **Anonymous Volume** | `/container/path` | Temporary/cache data | Docker-managed, auto-deleted |
| Type | Syntax | Use Case | Persistence |
| -------------------- | ------------------------------ | -------------------------- | ---------------------------- |
| **Bind Mount** | `./local/path:/container/path` | Development, config files | On host filesystem |
| **Named Volume** | `volume_name:/container/path` | Production data, databases | Docker-managed |
| **Anonymous Volume** | `/container/path` | Temporary/cache data | Docker-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
# :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:/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
# Managed by Docker, survives container deletion
- db_data:/var/lib/mysql
volumes:
db_data: # Define named volume
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
```
@ -329,6 +379,7 @@ volumes:
## Fork Management Best Practices
### Initial Fork Setup
```bash
# 1. Fork on GitHub (use the Fork button)
@ -351,7 +402,8 @@ git checkout -b my-custom-setup
### Safe Customization Zones
**✅ Safe (Won't conflict with upstream):**
```
```text
development/ # Your entire dev environment
├── frappe-bench/ # Local installation
└── .vscode/ # Your editor settings
@ -364,20 +416,23 @@ docs/my-*.md # Your custom documentation
```
**⚠️ Modification Needed (May conflict):**
```
```text
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):**
```
```text
.github/workflows/ # CI/CD pipelines
images/production/ # Production containers
resources/ # Core templates
```
### Keeping Fork Updated
```bash
# Regularly sync with upstream (weekly recommended)
git checkout main
@ -397,6 +452,7 @@ git rebase main # Or: git merge main
```
### Custom Environment Pattern
Create override files for your customizations:
```yaml
@ -413,7 +469,7 @@ services:
# 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
@ -421,12 +477,12 @@ services:
- "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
@ -459,6 +515,7 @@ docs/internal-*.md
```
### Contributing Back to Upstream
```bash
# 1. Create feature branch from main
git checkout main
@ -480,6 +537,7 @@ git push origin feature/my-improvement
## Quick Start Examples
### 1. Quick Test (5 minutes)
**Goal:** Try Frappe/ERPNext without any local setup
```bash
@ -501,6 +559,7 @@ docker compose -f pwd.yml down -v
```
### 2. Development Environment (15 minutes)
**Goal:** Set up for daily development with hot-reload
```bash
@ -530,6 +589,7 @@ bench start
```
### 3. Custom App Development (30 minutes)
**Goal:** Create and develop a custom Frappe application
```bash
@ -559,6 +619,7 @@ bench build --app library_management
```
### 4. Production Deployment (1 hour)
**Goal:** Deploy Frappe in production with SSL
```bash
@ -590,6 +651,7 @@ docker compose \
```
### 5. Multi-Site Hosting
**Goal:** Host multiple Frappe sites on one server
```bash
@ -609,13 +671,16 @@ bench new-site site2.com
## 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
#### Project Structure Comparison
**Django Project:**
```python
myproject/
├── myproject/ # Project settings
@ -631,7 +696,8 @@ myproject/
```
**Frappe Bench:**
```
```text
bench/
├── apps/
│ ├── frappe/ # Core framework (comparable to Django itself)
@ -646,31 +712,35 @@ bench/
#### Conceptual Mapping
| Django | Frappe | Notes |
|--------|--------|-------|
| Model | DocType | But includes UI, permissions, API automatically |
| View | Controller method | Much less code needed |
| Admin | Desk | More powerful, auto-generated |
| DRF Serializer | Built-in | Automatic from DocType |
| Celery task | Background job | Built-in, no separate setup |
| signals | hooks.py | More structured |
| Management command | bench command | More discoverable |
| Django | Frappe | Notes |
| ------------------ | ----------------- | ----------------------------------------------- |
| Model | DocType | But includes UI, permissions, API automatically |
| View | Controller method | Much less code needed |
| Admin | Desk | More powerful, auto-generated |
| DRF Serializer | Built-in | Automatic from DocType |
| Celery task | Background job | Built-in, no separate setup |
| signals | hooks.py | More structured |
| Management command | bench command | More 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
@ -683,20 +753,21 @@ bench/
**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)
@ -707,16 +778,18 @@ 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}
]
"name": "Customer",
"fields": [
{ "fieldname": "customer_name", "fieldtype": "Data" },
{ "fieldname": "email", "fieldtype": "Data", "unique": 1 }
]
}
```
```python
# customer.py (only for custom business logic)
import frappe
@ -729,6 +802,7 @@ class Customer(Document):
```
✅ **Automatically includes:**
- REST API (`/api/resource/Customer`)
- List view, Form view
- Search, Filters, Sorting
@ -739,6 +813,7 @@ class Customer(Document):
#### 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
@ -746,6 +821,7 @@ class Customer(Document):
- 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
@ -753,32 +829,42 @@ class Customer(Document):
- Building API-only services
**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
### 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
- [ERPNext Documentation](https://docs.erpnext.com) - ERPNext user and developer docs
- [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
- [ERPNext Documentation](https://docs.erpnext.com) - ERPNext user and
developer docs
- [Docker Documentation](https://docs.docker.com) - Docker fundamentals
### Key Files in This Repository
- [`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
- [`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
- [`compose.yaml`](../compose.yaml) - Base Docker Compose configuration
### Community Resources
- [Frappe Forum](https://discuss.frappe.io) - Community Q&A
- [Frappe School](https://frappe.school) - Video tutorials
- [Frappe GitHub](https://github.com/frappe/frappe) - Framework source code
### Essential Docker Commands Reference
```bash
# Service Management
docker compose up -d # Start all services in background
@ -805,6 +891,7 @@ docker image prune # Remove unused images
```
### Essential Bench Commands Reference
```bash
# Site Operations
bench new-site <site_name> # Create new site
@ -847,21 +934,22 @@ bench update # Update framework and apps
### Troubleshooting Quick Reference
| Issue | Solution |
|-------|----------|
| Port 8080 already in use | Change `PWD_PORT` in `.env` or stop other service |
| Container won't start | Check logs: `docker compose logs <service>` |
| Site creation fails | Check `create-site` logs, ensure DB is ready |
| Can't connect to site | Wait 5 min for initialization, check container health |
| Permission errors | Check volume permissions, may need `chown` |
| Out of disk space | `docker system prune -a --volumes` (CAREFUL!) |
| Python packages missing | `bench pip install <package>` inside container |
| Frontend not building | `bench build --force`, check Node.js errors |
| Issue | Solution |
| ------------------------- | ----------------------------------------------------- |
| Port 8080 already in use | Change `PWD_PORT` in `.env` or stop other service |
| Container won't start | Check logs: `docker compose logs <service>` |
| Site creation fails | Check `create-site` logs, ensure DB is ready |
| Can't connect to site | Wait 5 min for initialization, check container health |
| Permission errors | Check volume permissions, may need `chown` |
| Out of disk space | `docker system prune -a --volumes` (CAREFUL!) |
| Python packages missing | `bench pip install <package>` inside container |
| Frontend not building | `bench build --force`, check Node.js errors |
| Database connection fails | Check `common_site_config.json`, Redis/MariaDB status |
### 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)
3. **GitHub Issues** - Search existing issues first
4. **Discord/Telegram** - Community real-time chat (links in main repo)
@ -869,11 +957,15 @@ bench update # Update framework and apps
### Contributing
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)
---
*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_