This commit is contained in:
anvie 2025-09-25 13:50:47 +07:00
commit 022c14871a
18 changed files with 72 additions and 553 deletions

View file

@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
@ -38,7 +38,7 @@ jobs:
run: echo "LATEST_BENCH_RELEASE=$(curl -s 'https://api.github.com/repos/frappe/bench/releases/latest' | jq -r '.tag_name')" >> "$GITHUB_ENV"
- name: Build and test
uses: docker/bake-action@v6.8.0
uses: docker/bake-action@v6.9.0
with:
source: .
targets: bench-test
@ -52,7 +52,7 @@ jobs:
- name: Push
if: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }}
uses: docker/bake-action@v6.8.0
uses: docker/bake-action@v6.9.0
with:
targets: bench
push: true

View file

@ -27,7 +27,7 @@ jobs:
version: develop
push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }}
python_version: 3.11.6
node_version: 18.18.2
node_version: 20.19.2
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -62,10 +62,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.10"

View file

@ -43,7 +43,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
@ -66,7 +66,7 @@ jobs:
echo "NODE_VERSION=${{ inputs.node_version }}" >> "$GITHUB_ENV"
- name: Build
uses: docker/bake-action@v6.8.0
uses: docker/bake-action@v6.9.0
with:
source: .
push: true
@ -74,7 +74,7 @@ jobs:
REGISTRY_USER: localhost:5000/frappe
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.10"
@ -95,7 +95,7 @@ jobs:
- name: Push
if: ${{ inputs.push }}
uses: docker/bake-action@v6.8.0
uses: docker/bake-action@v6.9.0
with:
push: true
set: "*.platform=linux/amd64,linux/arm64"

View file

@ -13,16 +13,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.10.6"
# For shfmt pre-commit hook
- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "^1.14"

View file

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Update pre-commit hooks
uses: vrslev/pre-commit-autoupdate@v1.0.0

View file

@ -9,7 +9,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: This issue has been automatically marked as stale. You have a week to explain why you believe this is an error.

538
README.md
View file

@ -54,544 +54,44 @@ Click below to instantly spin up a Frappe/ERPNext instance in your browser:
<img src="https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png" alt="Try in PWD"/>
</a>
### Option 2: Local Development Setup
### Try on your Dev environment
1. **Clone the repository:**
First clone the repo:
```bash
```sh
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
```
2. **Start the containers:**
Then run: `docker compose -f pwd.yml up -d`
```bash
docker compose -f pwd.yml up -d
```
### To run on ARM64 architecture follow this instructions
3. **Wait for initialization** (approximately 5 minutes)
After you clone the repo and `cd frappe_docker`, run this command to build multi-architecture images specifically for ARM64.
```bash
# Monitor the setup progress
docker compose -f pwd.yml logs -f create-site
```
`docker buildx bake --no-cache --set "*.platform=linux/arm64"`
4. **Access ERPNext:**
and then
- URL: `http://localhost:8080`
- Username: `Administrator`
- Password: `admin`
- add `platform: linux/arm64` to all services in the `pwd.yml`
- replace the current specified versions of erpnext image on `pwd.yml` with `:latest`
### Option 3: Production Setup
Then run: `docker compose -f pwd.yml up -d`
1. **Clone and configure:**
## Final steps
```bash
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
cp example.env .env
# Edit .env file with your configuration
```
Wait for 5 minutes for ERPNext site to be created or check `create-site` container logs before opening browser on port 8080. (username: `Administrator`, password: `admin`)
2. **Deploy with production settings:**
If you ran in a Dev Docker environment, to view container logs: `docker compose -f pwd.yml logs -f create-site`. Don't worry about some of the initial error messages, some services take a while to become ready, and then they go away.
```bash
docker compose up -d
```
# Documentation
### ARM64 Architecture Support
### [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions)
For ARM64 systems (Apple Silicon, Raspberry Pi):
### [Production](#production)
```bash
# Build ARM64 images
docker buildx bake --no-cache --set "*.platform=linux/arm64"
# Modify pwd.yml to add platform: linux/arm64 to all services
# Then deploy
docker compose -f pwd.yml up -d
```
## Bench Wrapper Script
To simplify working with bench commands, we provide a convenient wrapper script `bench.sh` that eliminates the need to type `docker compose exec backend bench` repeatedly.
### Setup
```bash
# Make the script executable (one-time setup)
chmod +x bench.sh
```
### Usage
The script automatically detects which compose file you're using and provides a simpler interface:
```bash
# Instead of: docker compose exec backend bench new-site mysite.local
./bench.sh new-site mysite.local
# Instead of: docker compose exec backend bench --site mysite.local migrate
./bench.sh --site mysite.local migrate
# With specific project name
./bench.sh -p erpnext-prod --site production.local backup
# Get help
./bench.sh --help
```
### Features
- **Auto-detection**: Automatically finds and uses the correct compose file (pwd.yml or compose.yaml)
- **Project support**: Use `-p` flag for specific docker-compose projects
- **Full compatibility**: Supports all bench commands and arguments
- **Error handling**: Checks if containers are running before executing commands
- **Help system**: Built-in help with common command examples
## Deployment Options
### Development Environment
Perfect for developers working on Frappe apps:
```bash
# Setup development environment with VSCode integration
cp -R devcontainer-example .devcontainer
cp -R development/vscode-example development/.vscode
# Open in VSCode with Dev Containers extension
code .
# Then: "Reopen in Container"
```
**Features:**
- Hot-reload support
- Debugging capabilities
- Pre-configured VSCode settings
- Multiple Python/Node versions
### Production Environment
For production deployments:
```bash
# Using standard compose file
docker compose up -d
# With external database/Redis
# Configure DB_HOST, REDIS_CACHE, REDIS_QUEUE in .env
docker compose up -d
```
**Features:**
- Auto-restart on failure
- Health checks
- Log rotation
- Backup capabilities
### Single Server Setup
Simplified setup for single server deployments:
```bash
docker compose -f pwd.yml up -d
```
This creates a complete ERPNext instance with all required services.
## Architecture
The Frappe Docker setup consists of multiple interconnected services:
### Core Services
| Service | Purpose | Port |
| --------------- | --------------------------- | ---- |
| **backend** | Gunicorn application server | 8000 |
| **frontend** | Nginx reverse proxy | 8080 |
| **websocket** | Socket.io real-time server | 9000 |
| **scheduler** | Background job scheduler | - |
| **queue-short** | Short-running job worker | - |
| **queue-long** | Long-running job worker | - |
### Supporting Services
| Service | Purpose | Default |
| --------------- | --------------------------- | ------------ |
| **db** | MariaDB/PostgreSQL database | MariaDB 10.6 |
| **redis-cache** | Redis cache server | Redis 6.2 |
| **redis-queue** | Redis queue server | Redis 6.2 |
### Service Flow
```
User Request → Nginx (frontend) → Gunicorn (backend) → Database
↓ ↓
WebSocket Redis Cache
Job Queues → Workers
```
## Common Tasks
### Using the Bench Wrapper Script
For convenience, we provide a `bench.sh` wrapper script that simplifies running bench commands from your host machine.
```bash
# Make the script executable (first time only)
chmod +x bench.sh
# Create a new site
./bench.sh new-site mysite.local --admin-password=admin --install-app erpnext
# Run migrations
./bench.sh --site mysite.local migrate
# Backup a site
./bench.sh --site mysite.local backup
# Get help
./bench.sh --help
```
The script automatically detects which compose file you're using and handles the docker compose execution for you.
### Site Management
#### Create a new site
Using wrapper script:
```bash
./bench.sh new-site mysite.local \
--mariadb-user-host-login-scope=% \
--db-root-password=admin \
--admin-password=admin \
--install-app erpnext
```
Or directly with docker compose:
```bash
docker compose exec backend bench new-site mysite.local \
--mariadb-user-host-login-scope=% \
--db-root-password=admin \
--admin-password=admin \
--install-app erpnext
```
#### List all sites
Using wrapper script:
```bash
./bench.sh --site all list-apps
```
Or directly:
```bash
docker compose exec backend bench --site all list-apps
```
#### Migrate a site
Using wrapper script:
```bash
./bench.sh --site mysite.local migrate
```
Or directly:
```bash
docker compose exec backend bench --site mysite.local migrate
```
#### Backup a site
Using wrapper script:
```bash
./bench.sh --site mysite.local backup
```
Or directly:
```bash
docker compose exec backend bench --site mysite.local backup
```
### App Management
#### Install an app
Using wrapper script:
```bash
# Get the app
./bench.sh get-app https://github.com/frappe/app_name
# Install on site
./bench.sh --site mysite.local install-app app_name
```
Or directly:
```bash
# Get the app
docker compose exec backend bench get-app https://github.com/frappe/app_name
# Install on site
docker compose exec backend bench --site mysite.local install-app app_name
```
#### Update apps
Using wrapper script:
```bash
./bench.sh update --pull --apps
```
Or directly:
```bash
docker compose exec backend bench update --pull --apps
```
### Database Operations
#### Access MariaDB console
```bash
docker compose exec db mysql -uroot -padmin
```
#### Import database
Using wrapper script:
```bash
./bench.sh --site mysite.local --force restore path/to/backup.sql.gz
```
Or directly:
```bash
docker compose exec backend bench --site mysite.local \
--force restore path/to/backup.sql.gz
```
### Monitoring & Logs
#### View all logs
```bash
docker compose logs -f
```
#### View specific service logs
```bash
docker compose logs -f backend
docker compose logs -f frontend
```
#### Check service health
```bash
docker compose ps
docker compose exec backend healthcheck.sh
```
### Security & SSL
#### Setup Let's Encrypt SSL
```bash
# Configure in .env
LETSENCRYPT_EMAIL=your@email.com
SITES=`yourdomain.com`
# Deploy with Traefik
docker compose -f compose.yaml -f overrides/compose.https.yaml up -d
```
## Configuration
### Environment Variables
Create a `.env` file from the example:
```bash
cp example.env .env
```
Key configuration options:
| Variable | Description | Default |
| ------------------------- | ------------------------- | ---------- |
| `ERPNEXT_VERSION` | ERPNext version to deploy | `v15.69.2` |
| `DB_PASSWORD` | Database root password | `123` |
| `DB_HOST` | External database host | - |
| `REDIS_CACHE` | External Redis cache URL | - |
| `REDIS_QUEUE` | External Redis queue URL | - |
| `HTTP_PUBLISH_PORT` | HTTP port | `8080` |
| `FRAPPE_SITE_NAME_HEADER` | Site resolution header | `$$host` |
### Custom Apps Configuration
To include custom apps, create `apps.json`:
```json
[
{
"url": "https://github.com/frappe/erpnext",
"branch": "version-15"
},
{
"url": "https://github.com/yourusername/custom-app",
"branch": "main"
}
]
```
Build custom image:
```bash
export APPS_JSON_BASE64=$(base64 -i apps.json)
docker buildx bake -f docker-bake.hcl custom
```
### Multi-tenancy Setup
For hosting multiple sites on different ports:
```yaml
# compose.override.yml
services:
frontend:
ports:
- "8081:8080" # Site 1
- "8082:8080" # Site 2
```
## Advanced Features
### Backup Automation
Setup automated backups to S3:
```bash
# Create backup script
docker compose exec backend push_backup.py \
--site-name mysite.local \
--bucket my-bucket \
--region-name us-east-1 \
--endpoint-url https://s3.amazonaws.com \
--aws-access-key-id KEY \
--aws-secret-access-key SECRET
```
### Custom Build Arguments
Build with specific versions:
```bash
docker buildx bake \
--set "*.args.FRAPPE_VERSION=v15.0.0" \
--set "*.args.ERPNEXT_VERSION=v15.0.0" \
--set "*.args.PYTHON_VERSION=3.11.6" \
--set "*.args.NODE_VERSION=18.18.2"
```
### Development with Bench
Inside development container:
```bash
# Create new bench
bench init --skip-redis-config-generation frappe-bench
cd frappe-bench
# Start bench
bench start
# Create new app
bench new-app my_custom_app
# Install app
bench --site mysite.local install-app my_custom_app
```
## Troubleshooting
### Container won't start
```bash
# Check logs
docker compose logs backend
# Verify configuration
docker compose config
# Restart services
docker compose restart
```
### Site not accessible
```bash
# Check site configuration (using wrapper script)
./bench.sh --site mysite.local show-config
# Or directly
docker compose exec backend bench --site mysite.local show-config
# Verify nginx is running
docker compose exec frontend nginx -t
```
### Database connection issues
```bash
# Test database connection (using wrapper script)
./bench.sh --site mysite.local mariadb
# Or directly
docker compose exec backend bench --site mysite.local mariadb
# Check database logs
docker compose logs db
```
### Permission errors
```bash
# Fix permissions
docker compose exec backend chown -R frappe:frappe /home/frappe/frappe-bench
```
### Reset admin password
```bash
# Using wrapper script
./bench.sh --site mysite.local set-admin-password newpassword
# Or directly
docker compose exec backend bench --site mysite.local set-admin-password newpassword
```
## Documentation
### Essential Guides
- [Frequently Asked Questions](https://github.com/frappe/frappe_docker/wiki/Frequently-Asked-Questions)
- [List of containers](docs/list-of-containers.md)
- [Single Compose Setup](docs/single-compose-setup.md)
- [Environment Variables](docs/environment-variables.md)
- [Site Operations](docs/site-operations.md)
- [Custom Apps](docs/custom-apps.md)

View file

@ -2,7 +2,6 @@ version: "3.7"
services:
mariadb:
image: docker.io/mariadb:10.6
platform: linux/amd64
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
@ -15,7 +14,7 @@ services:
# Enable PostgreSQL only if you use it, see development/README.md for more information.
# postgresql:
# image: postgres:11.8
# image: postgres:14
# environment:
# POSTGRES_PASSWORD: 123
# volumes:
@ -38,15 +37,14 @@ services:
redis-cache:
image: docker.io/redis:alpine
platform: linux/amd64
redis-queue:
image: docker.io/redis:alpine
platform: linux/amd64
frappe:
image: docker.io/frappe/bench:latest
platform: linux/amd64
# If you want to build the current bench image the Containerfile is in this Repo.
# build: ../images/bench
command: sleep infinity
environment:
- SHELL=/bin/bash

View file

@ -9,7 +9,7 @@ variable PYTHON_VERSION {
default = "3.11.6"
}
variable NODE_VERSION {
default = "18.18.2"
default = "20.19.2"
}
variable "FRAPPE_VERSION" {

View file

@ -25,6 +25,10 @@ Frappe framework release. You can find all releases [here](https://github.com/fr
Password for MariaDB (or Postgres) database.
### `DB_PASSWORD_SECRETS_FILE`
Path to the db_password.txt file. Set only if you use docker secrets for the database password (use `overrides/compose.mariadb-secrets.yaml`)
### `DB_HOST`
Hostname for MariaDB (or Postgres) database. Set only if external service for database is used or the container can not be reached by its service name (db) by other containers.

View file

@ -65,7 +65,7 @@ Create a file called `traefik.env` in `~/gitops`
```shell
echo 'TRAEFIK_DOMAIN=traefik.example.com' > ~/gitops/traefik.env
echo 'EMAIL=admin@example.com' >> ~/gitops/traefik.env
echo 'HASHED_PASSWORD='$(openssl passwd -apr1 changeit | sed -e s/\\$/\\$\\$/g) >> ~/gitops/traefik.env
echo "HASHED_PASSWORD='$(openssl passwd -apr1 changeit)'" >> ~/gitops/traefik.env
```
Note:

View file

@ -1,9 +1,12 @@
# Reference: https://github.com/frappe/frappe_docker/blob/main/docs/environment-variables.md
ERPNEXT_VERSION=v15.69.2
ERPNEXT_VERSION=v15.80.0
DB_PASSWORD=123
#Only if you use docker secrets for the db password
DB_PASSWORD_SECRETS_FILE=
# Only if you use external database
DB_HOST=
DB_PORT=

View file

@ -0,0 +1,13 @@
services:
db:
environment:
MYSQL_ROOT_PASSWORD: !reset null
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password
healthcheck:
test: mysqladmin ping -h localhost --password="$(cat /run/secrets/db_password)"
secrets:
- db_password
secrets:
db_password:
file: ${DB_PASSWORD_SECRETS_FILE:?No db secret file set}

View file

@ -10,7 +10,7 @@ services:
db:
image: mariadb:10.6
healthcheck:
test: mysqladmin ping -h localhost --password=${DB_PASSWORD}
test: mysqladmin ping -h localhost --password=${DB_PASSWORD:-123}
interval: 1s
retries: 20
restart: unless-stopped
@ -20,7 +20,7 @@ services:
- --skip-character-set-client-handshake
- --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:?No db password set}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-123}
volumes:
- db-data:/var/lib/mysql

16
pwd.yml
View file

@ -2,7 +2,7 @@ version: "3"
services:
backend:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -18,7 +18,7 @@ services:
MARIADB_ROOT_PASSWORD: admin
configurator:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -47,7 +47,7 @@ services:
- logs:/home/frappe/frappe-bench/logs
create-site:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -102,7 +102,7 @@ services:
- db-data:/var/lib/mysql
frontend:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
depends_on:
@ -128,7 +128,7 @@ services:
- "8080:8080"
queue-long:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -144,7 +144,7 @@ services:
- logs:/home/frappe/frappe-bench/logs
queue-short:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -178,7 +178,7 @@ services:
condition: on-failure
scheduler:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:
@ -192,7 +192,7 @@ services:
- logs:/home/frappe/frappe-bench/logs
websocket:
image: frappe/erpnext:v15.69.2
image: frappe/erpnext:v15.80.0
networks:
- frappe_network
deploy:

View file

@ -1 +1 @@
pytest==8.4.1
pytest==8.4.2

View file

@ -151,6 +151,7 @@ def s3_service(python_path: str, compose: Compose):
subprocess.check_call(cmd)
compose("cp", "tests/_create_bucket.py", "backend:/tmp")
compose.exec("backend", "bench", "pip", "install", "boto3~=1.34.143")
compose.exec(
"-e",
f"S3_ACCESS_KEY={access_key}",