From c1e545f3e530089d4fb276dc185ba3772b5c1369 Mon Sep 17 00:00:00 2001 From: adithya Date: Mon, 16 Mar 2026 00:02:01 +0530 Subject: [PATCH] refactor: Migrating Comprehensive Guide The Comprehensive Getting Started guide is broken into smaller pieces and added to respective sections. --- docs/01-getting-started/00-introduction.md | 92 ++++++++++ docs/05-development/01-development.md | 20 +++ .../03-arm64-apple-silicon.md | 10 ++ docs/08-reference/02-configuring-vitepress.md | 4 +- docs/08-reference/03-fork-management.md | 161 ++++++++++++++++++ docs/08-reference/04-framework-comparisons.md | 159 +++++++++++++++++ docs/08-reference/05-external-links.md | 18 ++ docs/09-concepts/01-custom-app.md | 64 +++++++ docs/09-concepts/02-docker-bind-mounts.md | 62 +++++++ docs/09-concepts/index.md | 3 + 10 files changed, 591 insertions(+), 2 deletions(-) create mode 100644 docs/01-getting-started/00-introduction.md create mode 100644 docs/07-troubleshooting/03-arm64-apple-silicon.md create mode 100644 docs/08-reference/03-fork-management.md create mode 100644 docs/08-reference/04-framework-comparisons.md create mode 100644 docs/08-reference/05-external-links.md create mode 100644 docs/09-concepts/01-custom-app.md create mode 100644 docs/09-concepts/02-docker-bind-mounts.md create mode 100644 docs/09-concepts/index.md diff --git a/docs/01-getting-started/00-introduction.md b/docs/01-getting-started/00-introduction.md new file mode 100644 index 00000000..4b3d9c3c --- /dev/null +++ b/docs/01-getting-started/00-introduction.md @@ -0,0 +1,92 @@ +--- +title: Introduction +--- + +# Introduction to Frappe Docker + +This is the documentation for the Frappe Docker repository, which contains all the information on how to develop, deploy and share Frappe app, using Docker containers. + +## Repository Architecture + +Frappe Docker provides a comprehensive containerized environment for developing and deploying Frappe/ERPNext applications. It uses a **multi-service architecture** that handles everything from web serving to background job processing. + +### Core Services + +The base compose file includes these essential services: + +- **configurator** - Initialization service that configures database and Redis connections; runs on startup and exits +- **backend** - Werkzeug development server for dynamic content processing +- **frontend** - Nginx reverse proxy that serves static assets and routes requests +- **websocket** - Node.js server running Socket.IO for real-time communications +- **queue-short/long** - Python workers using RQ (Redis Queue) for asynchronous background job processing +- **scheduler** - Python service that runs scheduled tasks using the schedule library + +Additional services are added through compose overrides: + +- **db** - MariaDB or PostgreSQL database server (via `compose.mariadb.yaml` or `compose.postgres.yaml`) +- **redis-cache/queue** - Redis instances for caching and job queues (via `compose.redis.yaml`) + +### How Services Work Together + +``` +User Request + ↓ +[frontend (Nginx)] → Static files served directly + ↓ +[backend (Werkzeug)] → Dynamic content processing + ↓ ↓ +[db (MariaDB)] [redis-cache] + +Background Tasks: +[scheduler] → [redis-queue] → [queue-short/long workers] + +Real-time: +[websocket (Socket.IO)] ←→ [redis-cache] +``` + +## Repository Structure + +### `/` Root: 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 +- **docs/container-setup/env-variables.md** - Central reference for environment configuration logic and defaults + +### `images/`: Docker Image Definitions + +Four predefined Dockerfiles are available, each serving different use cases: + +- **images/bench/** - Sets up only the Bench CLI for development or debugging; does not include runtime services +- **images/custom/** - Multi-purpose Python backend built from plain Python base image; installs apps from `apps.json`; suitable for **production** and testing; ideal when you need control over Python/Node versions +- **images/layered/** - Same final contents as `custom` but based on prebuilt images from Docker Hub; faster builds for production when using Frappe-managed dependency versions +- **images/production/** - Installs only Frappe and ERPNext (not customizable with `apps.json`); best for **quick starts or exploration**; for real deployments, use `custom` or `layered` + +> **Note:** For detailed build arguments and advanced configuration options, see [Setup Overview](../02-setup/01-overview.md). + +### `overrides/`: Compose File Extensions + +Docker Compose "overrides" that extend the base compose.yaml for different scenarios: + +- **compose.mariadb.yaml** - Adds MariaDB database service +- **compose.redis.yaml** - Adds Redis caching service +- **compose.proxy.yaml** - Adds Traefik reverse proxy for multi-site hosting (label-based routing) +- **compose.https.yaml** - Adds Traefik HTTPS + automatic certs (uses `SITES_RULE`) +- **compose.nginxproxy.yaml** - Adds nginx-proxy reverse proxy (HTTP, env-based `VIRTUAL_HOST`) +- **compose.nginxproxy-ssl.yaml** - Adds nginx-proxy + acme-companion (HTTPS, env-based `LETSENCRYPT_HOST`) + +**Proxy choice:** + +- Traefik is more flexible for advanced routing and multi-bench setups +- nginx-proxy is simpler for a single bench with host-based routing. + +### `development/`: Dev Environment + +- **development/installer.py** - Automated bench/site creation and configuration script +- Contains your local development files (git-ignored to prevent accidental commits) + +### `resources/`: Runtime Templates + +- **core/nginx/nginx-entrypoint.sh** - Dynamic Nginx configuration generator script +- **core/nginx/nginx-template.conf** - Nginx configuration template with variable substitution diff --git a/docs/05-development/01-development.md b/docs/05-development/01-development.md index 99df7254..df22e4b0 100644 --- a/docs/05-development/01-development.md +++ b/docs/05-development/01-development.md @@ -101,6 +101,26 @@ PYENV_VERSION=3.9.17 bench init --skip-redis-config-generation --frappe-branch v cd frappe-bench ``` +At this point the the directory structure will be very close to this, if not exact, + +``` +development/ +├── frappe-bench/ # Your actual Frappe installation +│ ├── apps/ # All installed Frappe applications +│ │ ├── frappe/ # Core framework (don't modify directly) +│ │ ├── erpnext/ # ERPNext application (if installed) +│ │ └── my_custom_app/ # Your custom apps (edit freely) +│ ├── sites/ # Multi-tenant sites +│ │ ├── development.localhost/ # Default dev site +│ │ │ ├── site_config.json # Site-specific config +│ │ │ └── private/files/ # Uploaded files +│ │ └── common_site_config.json # Shared configuration +│ ├── env/ # Python virtual environment +│ ├── logs/ # Application logs +│ └── config/ # Bench-level configuration +└── .vscode/ # VSCode workspace settings +``` + ### Setup hosts We need to tell bench to use the right containers instead of localhost. Run the following commands inside the container: diff --git a/docs/07-troubleshooting/03-arm64-apple-silicon.md b/docs/07-troubleshooting/03-arm64-apple-silicon.md new file mode 100644 index 00000000..bafbf76e --- /dev/null +++ b/docs/07-troubleshooting/03-arm64-apple-silicon.md @@ -0,0 +1,10 @@ +--- +title: ARM64 / Apple Silicon +--- + +## Notes on ARM64 and Apple Silicon + +- Enable Docker Desktop's Rosetta emulation for initial builds when running on Apple Silicon with x86-only images. +- Prefer published multi-arch images (`frappe/bench`, `frappe/erpnext`) or build locally with `docker buildx bake --set *.platform=linux/amd64,linux/arm64` to cover both architectures in one pass. +- When using `pwd.yml`, export `DOCKER_DEFAULT_PLATFORM=linux/arm64` (or select the provided compose profile) to avoid unexpected emulation. +- Keep bind mounts under your user home directory and apply `:cached` or `:delegated` consistency flags for better performance on macOS. diff --git a/docs/08-reference/02-configuring-vitepress.md b/docs/08-reference/02-configuring-vitepress.md index 9e396e35..af400095 100644 --- a/docs/08-reference/02-configuring-vitepress.md +++ b/docs/08-reference/02-configuring-vitepress.md @@ -33,11 +33,11 @@ pnpm install pnpm run docs:dev ``` -4. Open `http://localhost:5173` in your browser to see the development version which will update the preview as you make changes. +4. Open `http://localhost:5173/frappe_docker` in your browser to see the development version which will update the preview as you make changes. ## Configurations -1. Public assets related to VitePress site is added in the `docs/public` folder. This folder should not be used for adding images added inside the `.md` file. +1. Public assets related to VitePress site is added in the `docs/public` folder. This folder should **NOT** be used for adding images added inside the `.md` file. 2. VitePress uses `index.md` files to do some special things. For example the home page is configured using the `docs/index.md` file. Checkout the file for more details. 3. VitePress uses 'file based routing', meaning the URL paths mimics the directory and file structure inside the `docs/` directory. 4. VitePress specific config is `docs/.vitepress/config.mts`. diff --git a/docs/08-reference/03-fork-management.md b/docs/08-reference/03-fork-management.md new file mode 100644 index 00000000..16ee2110 --- /dev/null +++ b/docs/08-reference/03-fork-management.md @@ -0,0 +1,161 @@ +--- +title: Fork Management +--- + +# Fork Management Best Practices + +## Initial Fork Setup + +```bash +# 1. Fork on GitHub (use the Fork button) + +# 2. Clone YOUR fork +git clone https://github.com/YOUR_USERNAME/frappe_docker +cd frappe_docker + +# 3. Add upstream remote (original repo) +git remote add upstream https://github.com/frappe/frappe_docker.git + +# 4. Verify remotes +git remote -v +# origin https://github.com/YOUR_USERNAME/frappe_docker (your fork) +# upstream https://github.com/frappe/frappe_docker (original) + +# 5. Create development branch +git checkout -b my-custom-setup +``` + +## Safe Customization Zones + +**✅ Safe (Won't conflict with upstream):** + +``` +development/ # Your entire dev environment + ├── frappe-bench/ # Local installation + └── .vscode/ # Your editor settings + +compose.my-*.yaml # Your custom compose overrides +scripts/my-*.sh # Your custom scripts +docs/my-*.md # Your custom documentation +.env.local # Local environment overrides +.gitignore.local # Additional gitignore rules +``` + +**⚠️ Modification Needed (May conflict):** + +``` +compose.yaml # Core - use overrides instead +docker-bake.hcl # Build config - use custom files +images/*/Dockerfile # Core images - extend rather than modify +``` + +**❌ Never Modify (Will break upstream sync):** + +``` +.github/workflows/ # CI/CD pipelines +images/*/ # Core image definitions +resources/ # Core templates +``` + +## Keeping Fork Updated + +```bash +# Regularly sync with upstream (weekly recommended) +git checkout main +git fetch upstream +git merge upstream/main +git push origin main + +# Update your development branch +git checkout my-custom-setup +git rebase main # Or: git merge main + +# If conflicts occur during rebase: +# 1. Fix conflicts in files +# 2. git add +# 3. git rebase --continue +# Or: git rebase --abort (to cancel) +``` + +## Custom Environment Pattern + +Create override files for your customizations: + +```yaml +# compose.my-env.yaml +version: "3.7" + +services: + backend: + environment: + # Your custom environment variables + - DEVELOPER_MODE=true + - MY_API_KEY=${MY_API_KEY} + volumes: + # Your custom bind mounts + - ./development/my-scripts:/home/frappe/my-scripts + - ./development/my-config:/home/frappe/config + + # Your additional services + my-monitoring: + image: prom/prometheus + ports: + - "9090:9090" + volumes: + - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml +# Use it: +# docker compose -f compose.yaml -f compose.my-env.yaml up +``` + +## .gitignore Strategy + +Add to `.gitignore` (or create `.gitignore.local`): + +```gitignore +# Local environment files +.env.local +*.local.yaml +compose.my-*.yaml + +# Development artifacts +development/frappe-bench/sites/* +development/frappe-bench/apps/* +!development/frappe-bench/apps.json +development/frappe-bench/logs/ +development/frappe-bench/env/ + +# Local customizations +my-local-configs/ +scripts/my-*.sh +docs/internal-*.md + +# IDE +.vscode/settings.json.local +.idea/ + +# Temporary files +*.swp +*.swo +*~ +.DS_Store +``` + +## Contributing Back to Upstream + +```bash +# 1. Create feature branch from main +git checkout main +git pull upstream main +git checkout -b feature/my-improvement + +# 2. Make changes and commit +git add . +git commit -m "feat: add awesome feature" + +# 3. Push to YOUR fork +git push origin feature/my-improvement + +# 4. Create Pull Request on GitHub +# Go to: https://github.com/frappe/frappe_docker +# Click "Compare & pull request" +``` diff --git a/docs/08-reference/04-framework-comparisons.md b/docs/08-reference/04-framework-comparisons.md new file mode 100644 index 00000000..aec78a54 --- /dev/null +++ b/docs/08-reference/04-framework-comparisons.md @@ -0,0 +1,159 @@ +--- +title: 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. + +## Frappe vs Django Concepts + +### Project Structure Comparison + +**Django Project:** + +```python +myproject/ +├── myproject/ # Project settings +│ ├── settings.py +│ ├── urls.py +│ └── wsgi.py +├── blog/ # Django app +│ ├── models.py +│ ├── views.py +│ └── urls.py +├── shop/ # Django app +└── users/ # Django app +``` + +**Frappe Bench:** + +``` +bench/ +├── apps/ +│ ├── frappe/ # Core framework (comparable to Django itself) +│ ├── erpnext/ # Complete business app (like Django + DRF + Celery + admin) +│ ├── hrms/ # HR Management app +│ └── my_custom_app/ # YOUR custom app +└── sites/ + └── mysite.com/ # Site instance (like Django project + database) + ├── site_config.json + └── private/files/ +``` + +### Conceptual Mapping + +| 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 + +5. **API** + - Django: Manual DRF setup, serializers, views + - Frappe: Automatic REST + RPC from DocType definitions + +### Code Comparison Example + +**Creating a "Customer" model:** + +Django (requires ~50+ lines): + +```python +# models.py +class Customer(models.Model): + name = models.CharField(max_length=100) + email = models.EmailField(unique=True) + +# serializers.py +class CustomerSerializer(serializers.ModelSerializer): + # ... + +# views.py +class CustomerViewSet(viewsets.ModelViewSet): + # ... + +# urls.py +router.register(r'customers', CustomerViewSet) + +# admin.py +@admin.register(Customer) +class CustomerAdmin(admin.ModelAdmin): + # ... +``` + +Frappe (DocType JSON + ~10 lines Python): + +```json +// customer.json (auto-generated via UI or code) +{ + "name": "Customer", + "fields": [ + { "fieldname": "customer_name", "fieldtype": "Data" }, + { "fieldname": "email", "fieldtype": "Data", "unique": 1 } + ] +} +``` + +```python +# customer.py (only for custom business logic) +import frappe +from frappe.model.document import Document + +class Customer(Document): + def validate(self): + # Custom validation logic only + pass +``` + +✅ **Automatically includes:** + +- REST API (`/api/resource/Customer`) +- List view, Form view +- Search, Filters, Sorting +- Permissions (Create, Read, Update, Delete) +- Audit trail (created_by, modified_by, versions) +- Print formats, Email templates + +### When to Choose Frappe vs Django + +**Choose Frappe when:** + +- Building business applications (ERP, CRM, project management) +- Need multi-tenancy out-of-the-box +- Want rapid development with auto-generated UI +- Need role-based permissions and workflows +- Building for non-technical users who need customization + +**Choose Django when:** + +- Building consumer web apps (social media, e-commerce frontend) +- Need full control over every aspect +- Have highly custom UI requirements +- Team is already Django-expert +- Building API-only services + +**Hybrid Approach:** +Many teams use both: Frappe for back-office/admin tools, Django for customer-facing web apps. diff --git a/docs/08-reference/05-external-links.md b/docs/08-reference/05-external-links.md new file mode 100644 index 00000000..2eef4f83 --- /dev/null +++ b/docs/08-reference/05-external-links.md @@ -0,0 +1,18 @@ +--- +title: External Links +--- + +# External Links + +## 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 +- [Docker Documentation](https://docs.docker.com) - Docker fundamentals + +## 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 diff --git a/docs/09-concepts/01-custom-app.md b/docs/09-concepts/01-custom-app.md new file mode 100644 index 00000000..bae585ba --- /dev/null +++ b/docs/09-concepts/01-custom-app.md @@ -0,0 +1,64 @@ +--- +title: Custom Apps +--- + +# Frappe Custom Applications + +## What Are Frappe Custom Apps? + +Custom apps are self-contained, modular business applications that extend Frappe's functionality. They follow a convention-over-configuration approach where the framework provides most boilerplate automatically. + +## Custom App Structure + +``` +my_custom_app/ +├── hooks.py # App configuration and hooks into Frappe lifecycle +├── modules.txt # List of business modules in this app +├── my_custom_app/ +│ ├── __init__.py +│ ├── config/ +│ │ └── desktop.py # Desktop workspace icons and shortcuts +│ ├── my_module/ # Business domain module (e.g., sales, inventory) +│ │ ├── doctype/ # Document Types (data models) +│ │ │ ├── customer/ +│ │ │ │ ├── customer.py # Python controller (business logic) +│ │ │ │ ├── customer.json # Model definition (schema, validation) +│ │ │ │ └── customer.js # Frontend logic (UI interactions) +│ │ └── page/ # Custom pages (dashboards, reports) +│ ├── public/ # Static assets (CSS, JS, images) +│ ├── templates/ # Jinja2 templates for web pages +│ └── www/ # Web pages accessible via routes +└── requirements.txt # Python package dependencies +``` + +## Built-in Features (Auto-generated) + +Every Frappe app automatically includes: + +- **REST API** - Automatic CRUD endpoints from DocType definitions +- **Permissions system** - Row-level and field-level access control +- **Audit trails** - Automatic version tracking and change history +- **Custom fields** - Runtime field additions without code changes +- **Workflows** - Configurable approval and state management +- **Reports** - Query builder and report designer +- **Print formats** - PDF generation with custom templates +- **Email integration** - Template-based email sending +- **File attachments** - Document attachment management + +## Creating Custom Apps + +```bash +# Enter the development container +docker exec -it bash + +# Create new app (interactive prompts will ask for details) +bench new-app my_custom_app + +# Install app to a site +bench --site mysite.com install-app my_custom_app + +# Create a new DocType (data model) +bench --site mysite.com console +>>> bench.new_doc("DocType", {...}) +# Or use the web UI: Setup → Customize → DocType → New +``` diff --git a/docs/09-concepts/02-docker-bind-mounts.md b/docs/09-concepts/02-docker-bind-mounts.md new file mode 100644 index 00000000..65b673a8 --- /dev/null +++ b/docs/09-concepts/02-docker-bind-mounts.md @@ -0,0 +1,62 @@ +--- +title: Docker Bind Mounts +--- + +# Docker Bind Mounts + +## What Are Bind Mounts? + +Bind mounts create a direct connection between a directory on your host machine and a directory inside a container. Changes in either location are immediately reflected in the other - perfect for development where you want to edit code on your host and see changes in the container. + +## Bind Mount vs Named Volume vs Anonymous Volume + +| 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 + + # Logs: Access container logs on host for debugging + - ./logs:/home/frappe/frappe-bench/logs + + # Database (not recommended for production) + - ./data/mysql:/var/lib/mysql + + # Named volume for production database + db: + volumes: + - db_data:/var/lib/mysql # Managed by Docker, survives container deletion + +volumes: + db_data: # Define named volume +``` + +## Performance Optimization (macOS/Windows) + +Docker on macOS/Windows uses a VM, making bind mounts slower. Use these flags: + +```yaml +volumes: + # :cached - Host writes are buffered (good for general development) + - ./development:/home/frappe/frappe-bench:cached + + # :delegated - Container writes are buffered (best when container writes heavily) + - ./development:/home/frappe/frappe-bench:delegated + + # :consistent - Full synchronization (slowest but safest) + - ./development:/home/frappe/frappe-bench:consistent +``` + +**Recommendation:** Use `:cached` for most development work on macOS/Windows. diff --git a/docs/09-concepts/index.md b/docs/09-concepts/index.md new file mode 100644 index 00000000..ec28707f --- /dev/null +++ b/docs/09-concepts/index.md @@ -0,0 +1,3 @@ +--- +title: Concepts +---